Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, 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 <cassert>
50 : #include <cmath>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Array.functions.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <AirflowNetwork/Solver.hpp>
57 : #include <EnergyPlus/Autosizing/Base.hh>
58 : #include <EnergyPlus/BranchInputManager.hh>
59 : #include <EnergyPlus/BranchNodeConnections.hh>
60 : #include <EnergyPlus/Coils/CoilCoolingDX.hh>
61 : #include <EnergyPlus/DXCoils.hh>
62 : #include <EnergyPlus/Data/EnergyPlusData.hh>
63 : #include <EnergyPlus/DataAirSystems.hh>
64 : #include <EnergyPlus/DataHVACGlobals.hh>
65 : #include <EnergyPlus/DataHeatBalFanSys.hh>
66 : #include <EnergyPlus/DataHeatBalance.hh>
67 : #include <EnergyPlus/DataIPShortCuts.hh>
68 : #include <EnergyPlus/DataSizing.hh>
69 : #include <EnergyPlus/DataZoneControls.hh>
70 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
71 : #include <EnergyPlus/DataZoneEquipment.hh>
72 : #include <EnergyPlus/EMSManager.hh>
73 : #include <EnergyPlus/Fans.hh>
74 : #include <EnergyPlus/FluidProperties.hh>
75 : #include <EnergyPlus/Furnaces.hh>
76 : #include <EnergyPlus/General.hh>
77 : #include <EnergyPlus/GeneralRoutines.hh>
78 : #include <EnergyPlus/GlobalNames.hh>
79 : #include <EnergyPlus/HVACControllers.hh>
80 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
81 : #include <EnergyPlus/HeatingCoils.hh>
82 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
83 : #include <EnergyPlus/IntegratedHeatPump.hh>
84 : #include <EnergyPlus/NodeInputManager.hh>
85 : #include <EnergyPlus/OutAirNodeManager.hh>
86 : #include <EnergyPlus/OutputProcessor.hh>
87 : #include <EnergyPlus/PlantUtilities.hh>
88 : #include <EnergyPlus/Psychrometrics.hh>
89 : #include <EnergyPlus/ScheduleManager.hh>
90 : #include <EnergyPlus/SteamCoils.hh>
91 : #include <EnergyPlus/WaterCoils.hh>
92 : #include <EnergyPlus/WaterToAirHeatPump.hh>
93 : #include <EnergyPlus/WaterToAirHeatPumpSimple.hh>
94 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
95 :
96 : namespace EnergyPlus {
97 :
98 : namespace Furnaces {
99 : // Module containing the Furnace and Unitary System simulation routines
100 :
101 : // MODULE INFORMATION:
102 : // AUTHOR Dan Fisher
103 : // DATE WRITTEN Jan 2001
104 : // MODIFIED Richard Liesen, Feb 2001; Don Shirey, Mar/Oct 2001, Oct 2003
105 : // Richard Raustad, Nov 2006 - allow draw through fan and alternate air flow in cooling,
106 : // heating, and when no cooling or heating is required.
107 : // Bereket Nigusse, FSEC, June 2010 - deprecated supply air flow fraction through controlled
108 : // zone from the furnace object input field. Now, the flow fraction is calculated internally
109 : // B. Nigusse, FSEC, Jan 2012 - added steam and hot water heating coils as an option
110 : // Bo Shen, ORNL, March 2012 - added variable-speed water source heat pump cooling and heating coils, using curve-fits
111 : // Bo Shen, ORNL, July 2012 - added variable-speed air source heat pump cooling and heating coils, using curve-fits
112 : // RE-ENGINEERED na
113 :
114 : // PURPOSE OF THIS MODULE:
115 : // To encapsulate the data and algorithms required to
116 : // manage the Furnace/Unitary System Compound Component
117 :
118 : // METHODOLOGY EMPLOYED:
119 : // Calculates the part-load ratio of the HVAC system to meet the zone sensible load. For non-heat pump HVAC systems,
120 : // if humidity control is specified and the latent capacity at the sensible PLR is insufficient to meet the latent load,
121 : // calculate a latent part-load ratio to meet the zone sensible load (MultiMode dehumidificaiton control) or the zone
122 : // latent load (CoolReheat dehumidification control). Use the greater of the sensible PLR and latent PLR to control
123 : // the HVAC system.
124 : // Subroutines:
125 : // SimFurnace - Top level simulate routine CALLed by other modules. Each child object is simulated a final time after
126 : // the part-load ratio for child components has been determined.
127 : // Note: A supplemental heater augments the heating capacity for both air-to-air and water-to-air heat pump systems.
128 : // A reheat coil is used for the HeatCool furnace/unitarysystem to offset the sensible cooling when the
129 : // dehumidification control type is COOLREHEAT. Both the supplemental and reheat heating coil load is calculated
130 : // in the Calc routines. The actual simulation of these coils is performed in the SimFurnace routine (i.e. the
131 : // supplemental and reheat coil loads are passed as 0 to CalcFurnaceOutput).
132 : // CalcNewZoneHeatOnlyFlowRates - HeatOnly furnace/unitarysystem routine.
133 : // Calculates a part-load ratio to meet the sensible load.
134 : // CalcNewZoneHeatCoolFlowRates - HeatCool furnace/unitarysystem and air-to-air HeatPump routine.
135 : // Calculates a part-load ratio for the system (sensible and/or latent).
136 : // For dehumidification control type COOLREHEAT, both a sensible and latent PLR
137 : // may exist for a single time step (heating and dehumidificaiton can occur). For all
138 : // other system types, only a single PLR is allowed for any given time step.
139 : // Order of simulation depends on dehumidification control option as described below.
140 : // Dehumidificaiton control options (non-heat pump versions):
141 : // Dehumidification Control NONE: Cooling performance is simulated first and then heating performance. If a HX
142 : // assisted cooling coil is selected, the HX is always active (cooling).
143 : // Dehumidification Control COOLREHEAT: For cooling operation, the sensible capacity is calculated to
144 : // meet the thermostat setpoint. If a HX assisted cooling coil is selected,
145 : // the HX is always active. If the latent load is not met by operating the
146 : // system at the sensible PLR, a new PLR is calculated to meet the humidistat
147 : // setpoint. The reheat coil load is then calculated to meet the HEATING
148 : // setpoint temperature.
149 : // Dehumidification Control MULTIMODE: For cooling operation, the sensible capacity is calculated to
150 : // meet the thermostat setpoint. If a HX assisted cooling coil is selected,
151 : // the HX is off for this calculation. If the latent load is not met by operating
152 : // the system at the sensible PLR, a new PLR is calculated with the HX operating
153 : // and the target is the zone SENSIBLE load (thermostat setpoint). Humidity is not
154 : // controlled in this mode. No reheat coil is used in this configuration.
155 : // CalcWaterToAirHeatPump - Water-to-air HeatPump routine.
156 : // Calculates a part-load ratio to meet the sensible load.
157 : // CalcFurnaceOutput - Simulates each child component in order.
158 : // For cooling operation, the heating coil is off.
159 : // For heating operation, the cooling coil is off.
160 : // Reheat or supplemental heating coil is simulated here just to pass the inlet node conditions
161 : // to the output node (actual simulation of these coils is done on the final simulation of the
162 : // child components in SimFurnace).
163 : // Fan is simulated based on placement (drawthru or blowthru).
164 : // REFERENCES:
165 :
166 : // OTHER NOTES:
167 :
168 : // USE STATEMENTS:
169 : // Use statements for data only modules
170 : // Using/Aliasing
171 : using namespace DataLoopNode;
172 : using namespace DataHVACGlobals;
173 : using namespace DataZoneEquipment;
174 : using Psychrometrics::PsyCpAirFnW;
175 : using Psychrometrics::PsyHfgAirFnWTdb;
176 : using Psychrometrics::PsyHFnTdbW;
177 : using Psychrometrics::PsyRhoAirFnPbTdbW;
178 : using Psychrometrics::PsyTdbFnHW;
179 : using namespace ScheduleManager;
180 : using DXCoils::SimDXCoil;
181 : using Fans::SimulateFanComponents;
182 :
183 : // Data
184 : // MODULE PARAMETER DEFINITIONS
185 : static constexpr std::string_view BlankString;
186 :
187 : auto constexpr fluidNameSteam("STEAM");
188 :
189 : // DERIVED TYPE DEFINITIONS
190 :
191 : // MODULE VARIABLE DECLARATIONS:
192 :
193 : // Subroutine Specifications for the Module
194 : // Driver/Manager Routines
195 :
196 : // Get Input routines for module
197 :
198 : // Initialization routines for module
199 :
200 : // Calculate routines to check convergence
201 :
202 : // Supporting routines for module
203 :
204 : // modules for variable speed heat pump
205 :
206 : // Reporting routines for module
207 :
208 : // Object Data
209 :
210 : // Utility routines for module
211 : // na
212 :
213 : // MODULE SUBROUTINES:
214 : //*************************************************************************
215 :
216 : // Functions
217 :
218 6396161 : void SimFurnace(EnergyPlusData &state,
219 : std::string_view FurnaceName,
220 : bool const FirstHVACIteration,
221 : int const AirLoopNum, // Primary air loop number
222 : int &CompIndex // Pointer to which furnace
223 : )
224 : {
225 :
226 : // SUBROUTINE INFORMATION:
227 : // AUTHOR Dan Fisher
228 : // DATE WRITTEN Jan 2001
229 : // MODIFIED Richard Liesen, Oct 2001 - Richard Raustad; Bo Shen, March 2012, for VS WSHP
230 : // RE-ENGINEERED Feb 2001
231 :
232 : // PURPOSE OF THIS SUBROUTINE:
233 : // This subroutine manages Furnace component simulation.
234 :
235 : // METHODOLOGY EMPLOYED:
236 : // Call the calc routine to determine an operating PLR. Resimulate child components at this PLR.
237 : // A supplemental heater augments the heating capacity for both air-to-air and water-to-air heat pump systems.
238 : // A reheat coil is used for the HeatCool furnace/unitarysystem to offset the sensible cooling when the
239 : // dehumidification control type is COOLREHEAT. Both the supplemental and reheat heating coil load is calculated
240 : // in the Calc routines and returned here through subroutine arguments. The actual simulation of these coils is
241 : // performed here (i.e. the supplemental and reheat coil loads are passed as 0 to CalcFurnaceOutput).
242 :
243 : // Using/Aliasing
244 : using HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil;
245 : using namespace DataZoneEnergyDemands;
246 :
247 : using WaterToAirHeatPumpSimple::SimWatertoAirHPSimple;
248 :
249 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
250 : int FurnaceNum; // Furnace number
251 6396161 : Real64 HeatCoilLoad(0.0); // Zone heating coil load
252 : Real64 ReheatCoilLoad; // Load to be met by the reheat coil (if high humidity control)
253 : Real64 ZoneLoad; // Control zone sensible load
254 : Real64 MoistureLoad; // Control zone latent load
255 : Real64 H2OHtOfVap; // Heat of vaporization of air
256 : int FurnaceInletNode; // Inlet node to furnace or unitary system
257 : Real64 FurnaceSavMdot; // saved furnace inlet air mass flow rate [m3/s]
258 6396161 : Real64 Dummy(0.0);
259 : CompressorOperation CompressorOp; // compressor operation; 1=on, 0=off
260 : Real64 OnOffAirFlowRatio; // Ratio of compressor ON air flow to AVERAGE air flow over time step
261 : int FanOpMode; // Fan operating mode (1=CycFanCycCoil, 2=ContFanCycCoil)
262 : bool HXUnitOn; // flag to control HX assisted cooling coil
263 : Real64 ZoneLoadToCoolSPSequenced;
264 : Real64 ZoneLoadToHeatSPSequenced;
265 :
266 : Real64 QActual; // actual heating coil output (W)
267 : bool SuppHeatingCoilFlag; // true if supplemental heating coil
268 : Real64 TempMassFlowRateMaxAvail;
269 :
270 : // Obtains and Allocates Furnace related parameters from input file
271 6396161 : if (state.dataFurnaces->GetFurnaceInputFlag) { // First time subroutine has been entered
272 : // Get the furnace input
273 94 : GetFurnaceInput(state);
274 94 : state.dataFurnaces->GetFurnaceInputFlag = false;
275 : }
276 :
277 : // Find the correct Furnace
278 6396161 : if (CompIndex == 0) {
279 356 : FurnaceNum = UtilityRoutines::FindItemInList(FurnaceName, state.dataFurnaces->Furnace);
280 356 : if (FurnaceNum == 0) {
281 0 : ShowFatalError(state, "SimFurnace: Unit not found=" + std::string{FurnaceName});
282 : }
283 356 : CompIndex = FurnaceNum;
284 : } else {
285 6395805 : FurnaceNum = CompIndex;
286 6395805 : if (FurnaceNum > state.dataFurnaces->NumFurnaces || FurnaceNum < 1) {
287 0 : ShowFatalError(state,
288 0 : format("SimFurnace: Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
289 : FurnaceNum,
290 0 : state.dataFurnaces->NumFurnaces,
291 0 : FurnaceName));
292 : }
293 6395805 : if (state.dataFurnaces->CheckEquipName(FurnaceNum)) {
294 356 : if (FurnaceName != state.dataFurnaces->Furnace(FurnaceNum).Name) {
295 0 : ShowFatalError(state,
296 0 : format("SimFurnace: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
297 : FurnaceNum,
298 : FurnaceName,
299 0 : state.dataFurnaces->Furnace(FurnaceNum).Name));
300 : }
301 356 : state.dataFurnaces->CheckEquipName(FurnaceNum) = false;
302 : }
303 : }
304 :
305 6396161 : HXUnitOn = false;
306 6396161 : OnOffAirFlowRatio = 0.0;
307 : // here we need to deal with sequenced zone equip
308 6396161 : ZoneLoad = 0.0;
309 12791966 : if (state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceCoolingNum > 0 &&
310 6395805 : state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum > 0) {
311 12791610 : ZoneLoadToCoolSPSequenced = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
312 6395805 : .SequencedOutputRequiredToCoolingSP(state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceCoolingNum);
313 12791610 : ZoneLoadToHeatSPSequenced = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
314 6395805 : .SequencedOutputRequiredToHeatingSP(state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum);
315 8459733 : if (ZoneLoadToHeatSPSequenced > 0.0 && ZoneLoadToCoolSPSequenced > 0.0 &&
316 2063928 : state.dataHeatBalFanSys->TempControlType(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) !=
317 : DataHVACGlobals::ThermostatType::SingleCooling) {
318 2000392 : ZoneLoad = ZoneLoadToHeatSPSequenced;
319 4458949 : } else if (ZoneLoadToHeatSPSequenced > 0.0 && ZoneLoadToCoolSPSequenced > 0.0 &&
320 63536 : state.dataHeatBalFanSys->TempControlType(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) ==
321 : DataHVACGlobals::ThermostatType::SingleCooling) {
322 63536 : ZoneLoad = 0.0;
323 7541137 : } else if (ZoneLoadToHeatSPSequenced < 0.0 && ZoneLoadToCoolSPSequenced < 0.0 &&
324 3209260 : state.dataHeatBalFanSys->TempControlType(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) !=
325 : DataHVACGlobals::ThermostatType::SingleHeating) {
326 3184104 : ZoneLoad = ZoneLoadToCoolSPSequenced;
327 1172929 : } else if (ZoneLoadToHeatSPSequenced < 0.0 && ZoneLoadToCoolSPSequenced < 0.0 &&
328 25156 : state.dataHeatBalFanSys->TempControlType(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) ==
329 : DataHVACGlobals::ThermostatType::SingleHeating) {
330 25156 : ZoneLoad = 0.0;
331 1122617 : } else if (ZoneLoadToHeatSPSequenced <= 0.0 && ZoneLoadToCoolSPSequenced >= 0.0) {
332 1122617 : ZoneLoad = 0.0;
333 : }
334 12791610 : MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
335 6395805 : .SequencedOutputRequiredToDehumidSP(state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceCoolingNum);
336 : } else {
337 356 : ZoneLoad =
338 356 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum).RemainingOutputRequired;
339 712 : MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
340 356 : .OutputRequiredToDehumidifyingSP;
341 : }
342 :
343 6396161 : H2OHtOfVap = PsyHfgAirFnWTdb(state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).HumRat,
344 6396161 : state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).Temp);
345 :
346 6396161 : MoistureLoad *= H2OHtOfVap;
347 :
348 : // Initialize Furnace Flows
349 6396161 : InitFurnace(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, FanOpMode, ZoneLoad, MoistureLoad, FirstHVACIteration);
350 :
351 6396161 : FurnaceInletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
352 :
353 : // MassFlowRateMaxAvail issues are impeding non-VAV air loop equipment by limiting air flow
354 : // temporarily open up flow limits while simulating, and then set this same value at the INLET after this parent has simulated
355 6396161 : TempMassFlowRateMaxAvail = state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail;
356 6396161 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate;
357 :
358 6396161 : FurnaceSavMdot = state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate;
359 6396161 : CompressorOp = CompressorOperation::On;
360 6396161 : state.dataFurnaces->CoolHeatPLRRat = 1.0;
361 :
362 : // Simulate correct system type (1 of 4 choices)
363 6396161 : switch (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) {
364 : // Simulate HeatOnly systems:
365 24886 : case Furnace_HeatOnly:
366 : case UnitarySys_HeatOnly: {
367 : // Update the furnace flow rates
368 24886 : CalcNewZoneHeatOnlyFlowRates(state, FurnaceNum, FirstHVACIteration, ZoneLoad, HeatCoilLoad, OnOffAirFlowRatio);
369 :
370 24886 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
371 : // simulate fan
372 74658 : SimulateFanComponents(
373 49772 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
374 : }
375 :
376 : // simulate furnace heating coil
377 24886 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
378 24886 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
379 :
380 24886 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == DrawThru) {
381 : // simulate fan
382 0 : SimulateFanComponents(
383 0 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
384 : }
385 24886 : } break;
386 : // Simulate HeatCool sytems:
387 3804154 : case Furnace_HeatCool:
388 : case UnitarySys_HeatCool: {
389 3804154 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
390 : // variable speed cooling coil
391 1247328 : HeatCoilLoad = 0.0;
392 1247328 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP)
393 0 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).ControlledZoneTemp =
394 0 : state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).Temp;
395 1247328 : SimVariableSpeedHP(state, FurnaceNum, FirstHVACIteration, AirLoopNum, ZoneLoad, MoistureLoad, OnOffAirFlowRatio);
396 : } else {
397 : // calculate the system flow rate
398 2811239 : if (!FirstHVACIteration && state.dataFurnaces->Furnace(FurnaceNum).OpMode == CycFanCycCoil && state.dataFurnaces->CoolingLoad &&
399 254413 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
400 : // for cycling fan, cooling load, check whether furnace can meet load with compressor off
401 5668 : CompressorOp = CompressorOperation::Off;
402 5668 : CalcNewZoneHeatCoolFlowRates(state,
403 : FurnaceNum,
404 : FirstHVACIteration,
405 : CompressorOp,
406 : ZoneLoad,
407 : MoistureLoad,
408 : HeatCoilLoad,
409 : ReheatCoilLoad,
410 : OnOffAirFlowRatio,
411 : HXUnitOn);
412 13344 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio >= 1.0 ||
413 13324 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio >= 1.0 ||
414 3996 : (state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio <= 0.0 &&
415 1988 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio <= 0.0)) {
416 : // compressor on (reset inlet air mass flow rate to starting value)
417 5648 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = FurnaceSavMdot;
418 5648 : CompressorOp = CompressorOperation::On;
419 5648 : CalcNewZoneHeatCoolFlowRates(state,
420 : FurnaceNum,
421 : FirstHVACIteration,
422 : CompressorOp,
423 : ZoneLoad,
424 : MoistureLoad,
425 : HeatCoilLoad,
426 : ReheatCoilLoad,
427 : OnOffAirFlowRatio,
428 : HXUnitOn);
429 : }
430 : } else {
431 : // compressor on
432 2551158 : CalcNewZoneHeatCoolFlowRates(state,
433 : FurnaceNum,
434 : FirstHVACIteration,
435 : CompressorOp,
436 : ZoneLoad,
437 : MoistureLoad,
438 : HeatCoilLoad,
439 : ReheatCoilLoad,
440 : OnOffAirFlowRatio,
441 : HXUnitOn);
442 : }
443 :
444 2556826 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
445 : // simulate fan
446 7551792 : SimulateFanComponents(
447 5034528 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
448 : }
449 :
450 2556826 : if (!state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) {
451 : // simulate furnace heating coil
452 1108758 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
453 1108758 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
454 : }
455 :
456 : // simulate furnace DX cooling coil
457 2556826 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
458 205152 : SimHXAssistedCoolingCoil(state,
459 : BlankString,
460 : FirstHVACIteration,
461 : CompressorOp,
462 51288 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio,
463 51288 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
464 : FanOpMode,
465 : HXUnitOn,
466 : OnOffAirFlowRatio,
467 51288 : state.dataFurnaces->EconomizerFlag);
468 : } else {
469 10022152 : SimDXCoil(state,
470 : BlankString,
471 : CompressorOp,
472 : FirstHVACIteration,
473 2505538 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
474 : FanOpMode,
475 2505538 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio,
476 : OnOffAirFlowRatio,
477 2505538 : state.dataFurnaces->CoolHeatPLRRat);
478 : }
479 :
480 2556826 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) {
481 : // simulate furnace heating coil
482 1448068 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
483 1448068 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
484 : }
485 :
486 2556826 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == DrawThru) {
487 : // simulate fan
488 118686 : SimulateFanComponents(
489 79124 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
490 : }
491 :
492 : // Simulate furnace reheat coil if a humidistat is used or if the reheat coil is present
493 4216140 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat ||
494 1659314 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex > 0) {
495 922386 : SuppHeatingCoilFlag = true; // if truee simulates supplemental heating coil
496 922386 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, FanOpMode, QActual);
497 : }
498 : }
499 3804154 : } break;
500 : // Simulate air-to-air heat pumps:
501 506368 : case UnitarySys_HeatPump_AirToAir: {
502 506368 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingAirToAirVariableSpeed) {
503 : // variable speed heat pump
504 20262 : HeatCoilLoad = 0.0;
505 20262 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
506 10158 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).ControlledZoneTemp =
507 10158 : state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).Temp;
508 10158 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).IDFanID =
509 10158 : state.dataFurnaces->Furnace(FurnaceNum).FanIndex;
510 10158 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).IDFanName = BlankString;
511 10158 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).IDFanPlace =
512 10158 : state.dataFurnaces->Furnace(FurnaceNum).FanPlace;
513 : }
514 :
515 20262 : SimVariableSpeedHP(state, FurnaceNum, FirstHVACIteration, AirLoopNum, ZoneLoad, MoistureLoad, OnOffAirFlowRatio);
516 : } else {
517 : // Update the furnace flow rates
518 689847 : if (!FirstHVACIteration && state.dataFurnaces->Furnace(FurnaceNum).OpMode == CycFanCycCoil && state.dataFurnaces->CoolingLoad &&
519 203741 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
520 : // for cycling fan, cooling load, check whether furnace can meet load with compressor off
521 538 : CompressorOp = CompressorOperation::Off;
522 538 : CalcNewZoneHeatCoolFlowRates(state,
523 : FurnaceNum,
524 : FirstHVACIteration,
525 : CompressorOp,
526 : ZoneLoad,
527 : MoistureLoad,
528 : HeatCoilLoad,
529 : ReheatCoilLoad,
530 : OnOffAirFlowRatio,
531 : HXUnitOn);
532 1482 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio >= 1.0 ||
533 1076 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio >= 1.0 ||
534 406 : (state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio <= 0.0 &&
535 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio <= 0.0)) {
536 : // compressor on (reset inlet air mass flow rate to starting value)
537 132 : CompressorOp = CompressorOperation::On;
538 132 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = FurnaceSavMdot;
539 132 : CalcNewZoneHeatCoolFlowRates(state,
540 : FurnaceNum,
541 : FirstHVACIteration,
542 : CompressorOp,
543 : ZoneLoad,
544 : MoistureLoad,
545 : HeatCoilLoad,
546 : ReheatCoilLoad,
547 : OnOffAirFlowRatio,
548 : HXUnitOn);
549 : }
550 : } else {
551 : // compressor on
552 485568 : CalcNewZoneHeatCoolFlowRates(state,
553 : FurnaceNum,
554 : FirstHVACIteration,
555 : CompressorOp,
556 : ZoneLoad,
557 : MoistureLoad,
558 : HeatCoilLoad,
559 : ReheatCoilLoad,
560 : OnOffAirFlowRatio,
561 : HXUnitOn);
562 : }
563 :
564 486106 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
565 1458318 : SimulateFanComponents(
566 972212 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
567 : }
568 :
569 486106 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
570 0 : SimHXAssistedCoolingCoil(state,
571 : BlankString,
572 : FirstHVACIteration,
573 : CompressorOp,
574 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio,
575 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
576 : FanOpMode,
577 : HXUnitOn,
578 : OnOffAirFlowRatio,
579 0 : state.dataFurnaces->EconomizerFlag);
580 : } else {
581 1458318 : SimDXCoil(state,
582 : BlankString,
583 : CompressorOp,
584 : FirstHVACIteration,
585 486106 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
586 : FanOpMode,
587 486106 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio,
588 : OnOffAirFlowRatio);
589 : }
590 1458318 : SimDXCoil(state,
591 : BlankString,
592 : CompressorOp,
593 : FirstHVACIteration,
594 486106 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
595 : FanOpMode,
596 486106 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio,
597 : OnOffAirFlowRatio);
598 486106 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == DrawThru) {
599 0 : SimulateFanComponents(
600 0 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
601 : }
602 :
603 : // Simulate furnace reheat coil if a humidistat is present, the dehumidification type of coolreheat and
604 : // reheat coil load exists
605 514926 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat &&
606 28820 : ReheatCoilLoad > 0.0) {
607 6014 : SuppHeatingCoilFlag = true; // if truee simulates supplemental heating coil
608 6014 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, FanOpMode, QActual);
609 : } else {
610 480092 : SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
611 480092 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
612 : }
613 : }
614 506368 : } break;
615 : // Simulate water-to-air systems:
616 2060753 : case UnitarySys_HeatPump_WaterToAir: {
617 2060753 : if (state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple) {
618 : // Update the furnace flow rates
619 : // When CompressorOp logic is added to the child cooling coil (COIL:WaterToAirHP:EquationFit:Cooling), then this logic
620 : // needs to be reinstated... to align with Unitary/Furnace HeatCool and Unitary Air-to-Air Heat Pump (see above).
621 2140418 : if (!FirstHVACIteration && state.dataFurnaces->Furnace(FurnaceNum).OpMode == CycFanCycCoil && state.dataFurnaces->CoolingLoad &&
622 429030 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
623 : // for cycling fan, cooling load, check whether furnace can meet load with compressor off
624 0 : CompressorOp = CompressorOperation::Off;
625 0 : CalcNewZoneHeatCoolFlowRates(state,
626 : FurnaceNum,
627 : FirstHVACIteration,
628 : CompressorOp,
629 : ZoneLoad,
630 : MoistureLoad,
631 : HeatCoilLoad,
632 : ReheatCoilLoad,
633 : OnOffAirFlowRatio,
634 : HXUnitOn);
635 0 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio >= 1.0 ||
636 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio >= 1.0 ||
637 0 : (state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio <= 0.0 &&
638 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio <= 0.0)) {
639 : // compressor on (reset inlet air mass flow rate to starting value)
640 0 : CompressorOp = CompressorOperation::On;
641 0 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = FurnaceSavMdot;
642 0 : CalcNewZoneHeatCoolFlowRates(state,
643 : FurnaceNum,
644 : FirstHVACIteration,
645 : CompressorOp,
646 : ZoneLoad,
647 : MoistureLoad,
648 : HeatCoilLoad,
649 : ReheatCoilLoad,
650 : OnOffAirFlowRatio,
651 : HXUnitOn);
652 : }
653 : } else {
654 : // compressor on
655 1711388 : CalcNewZoneHeatCoolFlowRates(state,
656 : FurnaceNum,
657 : FirstHVACIteration,
658 : CompressorOp,
659 : ZoneLoad,
660 : MoistureLoad,
661 : HeatCoilLoad,
662 : ReheatCoilLoad,
663 : OnOffAirFlowRatio,
664 : HXUnitOn);
665 : }
666 1711388 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
667 5134164 : SimulateFanComponents(
668 3422776 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
669 : }
670 :
671 17113880 : SimWatertoAirHPSimple(state,
672 : BlankString,
673 1711388 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
674 1711388 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand,
675 1711388 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand,
676 1711388 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
677 1711388 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac,
678 1711388 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
679 1711388 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
680 1711388 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
681 : CompressorOp,
682 1711388 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio,
683 : FirstHVACIteration);
684 15402492 : SimWatertoAirHPSimple(state,
685 : BlankString,
686 1711388 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
687 1711388 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand,
688 : Dummy,
689 1711388 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
690 1711388 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac,
691 1711388 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
692 1711388 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
693 1711388 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
694 : CompressorOp,
695 1711388 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio,
696 : FirstHVACIteration);
697 :
698 1711388 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == DrawThru) {
699 0 : SimulateFanComponents(
700 0 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
701 : }
702 1757928 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat &&
703 46540 : ReheatCoilLoad > 0.0) {
704 15922 : SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
705 15922 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, FanOpMode, QActual);
706 : } else {
707 1695466 : SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
708 1695466 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
709 : }
710 349365 : } else if (state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_ParEst) {
711 :
712 : // simulate the heat pump
713 118555 : HeatCoilLoad = 0.0;
714 118555 : CalcWaterToAirHeatPump(state, AirLoopNum, FurnaceNum, FirstHVACIteration, CompressorOp, ZoneLoad, MoistureLoad);
715 230810 : } else if (state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_VarSpeedEquationFit) {
716 : // simulate the heat pump
717 230810 : HeatCoilLoad = 0.0;
718 230810 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP)
719 0 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).ControlledZoneTemp =
720 0 : state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).Temp;
721 230810 : SimVariableSpeedHP(state, FurnaceNum, FirstHVACIteration, AirLoopNum, ZoneLoad, MoistureLoad, OnOffAirFlowRatio);
722 :
723 0 : } else if (state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_VarSpeedLooUpTable) {
724 0 : HeatCoilLoad = 0.0; // Added: Used below
725 : } else {
726 0 : assert(false); //? If all possible states covered by if conditions change to HeatCoilLoad = 0.0;
727 : }
728 2060753 : } break;
729 0 : default: {
730 : // will never get here, all system types are simulated above
731 0 : assert(false);
732 : } break;
733 : }
734 :
735 : // set the econo lockout flags
736 10766230 : if (state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio > 0.0 &&
737 4370069 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor) {
738 278779 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithCompressor = true;
739 : } else {
740 6117382 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithCompressor = false;
741 : }
742 :
743 9022549 : if ((HeatCoilLoad > 0.0 || state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio > 0.0) &&
744 3357781 : (state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithCompressor ||
745 1637836 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CanLockoutEconoWithHeating)) {
746 906443 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithHeating = true;
747 : } else {
748 5489718 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).ReqstEconoLockoutWithHeating = false;
749 : }
750 :
751 6396161 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == CycFanCycCoil) {
752 2939273 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio;
753 : } else {
754 3456888 : state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = 1.0; // 1 means constant fan does not cycle.
755 : }
756 :
757 : // Report the current Furnace output
758 6396161 : ReportFurnace(state, FurnaceNum, AirLoopNum);
759 :
760 : // Reset OnOffFanPartLoadFraction to 1 in case another on/off fan is called without a part-load curve
761 6396161 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
762 :
763 6396161 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = TempMassFlowRateMaxAvail;
764 6396161 : }
765 :
766 : // Get Input Section of the Module
767 : //******************************************************************************
768 :
769 94 : void GetFurnaceInput(EnergyPlusData &state)
770 : {
771 :
772 : // SUBROUTINE INFORMATION:
773 : // AUTHOR Richard Liesen
774 : // DATE WRITTEN Feb 2001
775 : // MODIFIED Don Shirey and Rich Raustad, Mar/Oct 2001, Mar 2003
776 : // Bereket Nigusse, April 2010 - deprecated supply air flow fraction through
777 : // controlled zone from the input field.
778 : // Bo Shen, March 2012, add inputs for VS WSHP,
779 : // Bo Shen, ORNL, July 2012 - added variable-speed air source heat pump cooling and heating coils, using curve-fits
780 : // RE-ENGINEERED na
781 :
782 : // PURPOSE OF THIS SUBROUTINE:
783 : // Obtains input data for fans and coils and stores it in the Furnace data structures
784 :
785 : // METHODOLOGY EMPLOYED:
786 : // Uses "Get" routines to read in data.
787 :
788 : // Using/Aliasing
789 : using BranchNodeConnections::SetUpCompSets;
790 : using BranchNodeConnections::TestCompSet;
791 : using NodeInputManager::GetOnlySingleNode;
792 94 : auto &GetWtoAHPSimpleCoilCapacity(WaterToAirHeatPumpSimple::GetCoilCapacity);
793 94 : auto &GetWtoAHPSimpleCoilInletNode(WaterToAirHeatPumpSimple::GetCoilInletNode);
794 94 : auto &GetWtoAHPSimpleCoilOutletNode(WaterToAirHeatPumpSimple::GetCoilOutletNode);
795 94 : auto &GetWtoAHPSimpleCoilIndex(WaterToAirHeatPumpSimple::GetCoilIndex);
796 : using WaterToAirHeatPumpSimple::SetSimpleWSHPData;
797 94 : auto &GetWtoAHPSimpleCoilAirFlow(WaterToAirHeatPumpSimple::GetCoilAirFlowRate);
798 : using VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed;
799 : using VariableSpeedCoils::GetCoilCapacityVariableSpeed;
800 : using VariableSpeedCoils::GetCoilIndexVariableSpeed;
801 : using VariableSpeedCoils::GetCoilInletNodeVariableSpeed;
802 : using VariableSpeedCoils::GetCoilOutletNodeVariableSpeed;
803 : using VariableSpeedCoils::GetVSCoilCondenserInletNode;
804 : using VariableSpeedCoils::SetVarSpeedCoilData;
805 94 : auto &GetWtoAHPCoilCapacity(WaterToAirHeatPump::GetCoilCapacity);
806 94 : auto &GetWtoAHPCoilInletNode(WaterToAirHeatPump::GetCoilInletNode);
807 94 : auto &GetWtoAHPCoilOutletNode(WaterToAirHeatPump::GetCoilOutletNode);
808 94 : auto &GetWtoAHPCoilIndex(WaterToAirHeatPump::GetCoilIndex);
809 94 : auto &GetHeatingCoilCapacity(HeatingCoils::GetCoilCapacity);
810 94 : auto &GetHeatingCoilInletNode(HeatingCoils::GetCoilInletNode);
811 94 : auto &GetHeatingCoilOutletNode(HeatingCoils::GetCoilOutletNode);
812 94 : auto &GetHeatingCoilIndex(HeatingCoils::GetCoilIndex);
813 : using HeatingCoils::GetHeatingCoilPLFCurveIndex;
814 : using HeatingCoils::GetHeatingCoilTypeNum;
815 94 : auto &GetDXCoilCapacity(DXCoils::GetCoilCapacity);
816 94 : auto &GetDXCoilInletNode(DXCoils::GetCoilInletNode);
817 94 : auto &GetDXCoilOutletNode(DXCoils::GetCoilOutletNode);
818 94 : auto &GetDXCoilCondenserInletNode(DXCoils::GetCoilCondenserInletNode);
819 : using DXCoils::GetCoilTypeNum;
820 : using DXCoils::GetDXCoilIndex;
821 : using DXCoils::SetDXCoolingCoilData;
822 94 : auto &GetDXHXAsstdCoilCapacity(HVACHXAssistedCoolingCoil::GetCoilCapacity);
823 94 : auto &GetDXHXAsstdCoilInletNode(HVACHXAssistedCoolingCoil::GetCoilInletNode);
824 94 : auto &GetDXHXAsstdCoilOutletNode(HVACHXAssistedCoolingCoil::GetCoilOutletNode);
825 : using HVACHXAssistedCoolingCoil::GetHXDXCoilIndex;
826 : using HVACHXAssistedCoolingCoil::GetHXDXCoilName;
827 94 : auto &GetHXAssistedCoilTypeNum(HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum);
828 : using HVACHXAssistedCoolingCoil::GetActualDXCoilIndex;
829 : using WaterCoils::GetCoilMaxWaterFlowRate;
830 : using WaterCoils::GetCoilWaterInletNode;
831 94 : auto &GetWaterCoilInletNode(WaterCoils::GetCoilInletNode);
832 94 : auto &GetWaterCoilOutletNode(WaterCoils::GetCoilOutletNode);
833 94 : auto &GetSteamCoilAirInletNode(SteamCoils::GetCoilAirInletNode);
834 : using SteamCoils::GetCoilAirOutletNode;
835 : using SteamCoils::GetCoilSteamInletNode;
836 : using SteamCoils::GetSteamCoilIndex;
837 94 : auto &GetCoilMaxSteamFlowRate(SteamCoils::GetCoilMaxSteamFlowRate);
838 : using Fans::GetFanAvailSchPtr;
839 : using Fans::GetFanDesignVolumeFlowRate;
840 : using Fans::GetFanIndex;
841 : using Fans::GetFanInletNode;
842 : using Fans::GetFanOutletNode;
843 : using Fans::GetFanType;
844 : using FluidProperties::GetSatDensityRefrig;
845 :
846 : using EMSManager::ManageEMS;
847 : using HVACControllers::CheckCoilWaterInletNode;
848 : using IntegratedHeatPump::GetCoilIndexIHP;
849 : using OutAirNodeManager::CheckOutAirNodeNumber;
850 :
851 : // Locals
852 188 : std::string CurrentModuleObject; // Object type for getting and error messages
853 :
854 : // SUBROUTINE PARAMETER DEFINITIONS:
855 94 : auto constexpr getUnitaryHeatOnly("GetUnitaryHeatOnly");
856 94 : auto constexpr getAirLoopHVACHeatCoolInput("GetAirLoopHVACHeatCoolInput");
857 :
858 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
859 : int FurnaceNum; // The Furnace that you are currently loading input into
860 : int GetObjectNum; // The index to each specific object name
861 : int NumFields; // Total number of fields in object
862 : int NumAlphas; // Total number of alpha fields in object
863 : int MaxAlphas; // Maximum number of alpha fields in all objects
864 : int NumNumbers; // Total number of numeric fields in object
865 : int MaxNumbers; // Maximum number of numeric fields in all objects
866 : int IOStatus; // Function call status
867 188 : Array1D<Real64> Numbers; // Numeric data
868 188 : Array1D_string Alphas; // Alpha data
869 188 : Array1D_string cAlphaFields; // Alpha field names
870 188 : Array1D_string cNumericFields; // Numeric field names
871 188 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
872 188 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
873 188 : std::string CompSetFanInlet;
874 188 : std::string CompSetFanOutlet;
875 188 : std::string CompSetCoolInlet;
876 188 : std::string CompSetHeatInlet;
877 188 : std::string CompSetHeatOutlet;
878 94 : bool ErrorsFound(false); // If errors detected in input
879 : bool IsNotOK; // Flag to verify name
880 : int NumHeatOnly; // Number of heat only furnaces
881 : int NumHeatCool; // Number of heat/cool furnaces
882 : int HeatOnlyNum; // Index to heat only furnaces
883 : int HeatCoolNum; // Index to heat/cool furnaces
884 : int NumUnitaryHeatOnly; // Number of heat only unitary systems
885 : int NumUnitaryHeatCool; // Number of heat/cool unitary systems
886 : int UnitaryHeatOnlyNum; // Index to heat only furnaces
887 : int UnitaryHeatCoolNum; // Index to heat/cool unitary systems
888 : int NumWaterToAirHeatPump; // Number of water-to-air heat pumps
889 : int NumHeatPump; // Number of air-to-air or water-to-air heat pumps
890 : int HeatPumpNum; // Index to air-to-air heat pumps
891 : bool AirNodeFound; // Used to determine if control zone is valid
892 : bool AirLoopFound; // Used to determine if control zone is served by furnace air loop
893 : int BranchNum; // Used to determine if control zone is served by furnace air loop
894 : int CompNum; // Used to determine if control zone is served by furnace air loop
895 : int TstatZoneNum; // Used to determine if control zone has a thermostat object
896 : int HStatZoneNum; // Used to determine if control zone has a humidistat object
897 : bool errFlag; // Mining function error flag
898 : int FanInletNode; // Used for node checking warning messages
899 : int FanOutletNode; // Used for node checking warning messages
900 : int CoolingCoilInletNode; // Used for node checking warning messages
901 : int CoolingCoilOutletNode; // Used for node checking warning messages
902 : int HeatingCoilInletNode; // Used for node checking warning messages
903 : int HeatingCoilOutletNode; // Used for node checking warning messages
904 : int SupHeatCoilInletNode; // Used for node checking warning messages
905 : int SupHeatCoilOutletNode; // Used for node checking warning messages
906 : int ReheatCoilInletNode; // Used for node checking warning messages
907 : int ReheatCoilOutletNode; // Used for node checking warning messages
908 : Real64 FanVolFlowRate; // Fan Max Flow Rate from Fan object (for comparisons to validity)
909 : int FurnaceType_Num; // Integer equivalent of Furnace or UnitarySystem "type"
910 188 : std::string CoolingCoilType; // Used in mining function CALLS
911 188 : std::string CoolingCoilName; // Used in mining function CALLS
912 188 : std::string HeatingCoilType; // Used in mining function CALLS
913 188 : std::string HeatingCoilName; // Used in mining function CALLS
914 188 : std::string ReheatingCoilType; // Used in mining function CALLS
915 188 : std::string ReheatingCoilName; // Used in mining function CALLS
916 188 : std::string SuppHeatCoilType; // Used in mining function CALLS
917 188 : std::string SuppHeatCoilName; // Used in mining function CALLS
918 188 : std::string FanType; // Used in mining function CALLS
919 188 : std::string FanName; // Used in mining function CALLS
920 : bool PrintMessage; // Used in mining function CALLS
921 : int HeatingCoilPLFCurveIndex; // index of heating coil PLF curve
922 : int SteamIndex; // steam coil index
923 : Real64 SteamDensity; // density of steam at 100C
924 : int DXCoilIndex; // Index to DX coil in HXAssited object
925 188 : std::string IHPCoilName; // IHP cooling coil name
926 94 : int IHPCoilIndex(0); // IHP cooling coil id
927 94 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
928 : DataLoopNode::ConnectionObjectType currentModuleObjectType;
929 :
930 94 : state.dataFurnaces->GetFurnaceInputFlag = false;
931 94 : MaxNumbers = 0;
932 94 : MaxAlphas = 0;
933 :
934 94 : CurrentModuleObject = "AirLoopHVAC:Unitary:Furnace:HeatOnly";
935 94 : NumHeatOnly = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
936 94 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
937 94 : MaxNumbers = max(MaxNumbers, NumNumbers);
938 94 : MaxAlphas = max(MaxAlphas, NumAlphas);
939 :
940 94 : CurrentModuleObject = "AirLoopHVAC:Unitary:Furnace:HeatCool";
941 94 : NumHeatCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
942 94 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
943 94 : MaxNumbers = max(MaxNumbers, NumNumbers);
944 94 : MaxAlphas = max(MaxAlphas, NumAlphas);
945 :
946 94 : CurrentModuleObject = "AirLoopHVAC:UnitaryHeatOnly";
947 94 : NumUnitaryHeatOnly = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
948 94 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
949 94 : MaxNumbers = max(MaxNumbers, NumNumbers);
950 94 : MaxAlphas = max(MaxAlphas, NumAlphas);
951 :
952 94 : CurrentModuleObject = "AirLoopHVAC:UnitaryHeatCool";
953 94 : NumUnitaryHeatCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
954 94 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
955 94 : MaxNumbers = max(MaxNumbers, NumNumbers);
956 94 : MaxAlphas = max(MaxAlphas, NumAlphas);
957 :
958 94 : CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:AirToAir";
959 94 : NumHeatPump = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
960 94 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
961 94 : MaxNumbers = max(MaxNumbers, NumNumbers);
962 94 : MaxAlphas = max(MaxAlphas, NumAlphas);
963 :
964 94 : CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:WaterToAir";
965 94 : NumWaterToAirHeatPump = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
966 94 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
967 94 : MaxNumbers = max(MaxNumbers, NumNumbers);
968 94 : MaxAlphas = max(MaxAlphas, NumAlphas);
969 :
970 94 : Alphas.allocate(MaxAlphas);
971 94 : Numbers.dimension(MaxNumbers, 0.0);
972 94 : cAlphaFields.allocate(MaxAlphas);
973 94 : cNumericFields.allocate(MaxNumbers);
974 94 : lAlphaBlanks.dimension(MaxAlphas, true);
975 94 : lNumericBlanks.dimension(MaxNumbers, true);
976 :
977 94 : state.dataFurnaces->NumFurnaces = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + NumHeatPump + NumWaterToAirHeatPump;
978 :
979 94 : if (state.dataFurnaces->NumFurnaces > 0) {
980 94 : state.dataFurnaces->Furnace.allocate(state.dataFurnaces->NumFurnaces);
981 94 : state.dataFurnaces->UniqueFurnaceNames.reserve(state.dataFurnaces->NumFurnaces);
982 : }
983 94 : state.dataFurnaces->CheckEquipName.dimension(state.dataFurnaces->NumFurnaces, true);
984 :
985 94 : IHPCoilIndex = 0;
986 :
987 : // Get the data for the HeatOnly Furnace
988 98 : for (HeatOnlyNum = 1; HeatOnlyNum <= NumHeatOnly + NumUnitaryHeatOnly; ++HeatOnlyNum) {
989 :
990 4 : FanInletNode = 0;
991 4 : FanOutletNode = 0;
992 4 : FanVolFlowRate = 0.0;
993 4 : HeatingCoilInletNode = 0;
994 4 : HeatingCoilOutletNode = 0;
995 4 : CoolingCoilType = ' ';
996 4 : CoolingCoilName = ' ';
997 4 : HeatingCoilType = ' ';
998 4 : HeatingCoilName = ' ';
999 :
1000 : // Furnace and UnitarySystem objects are both read in here.
1001 : // Will still have 2 differently named objects for the user, but read in with 1 DO loop.
1002 4 : if (HeatOnlyNum <= NumHeatOnly) {
1003 3 : CurrentModuleObject = "AirLoopHVAC:Unitary:Furnace:HeatOnly";
1004 3 : currentModuleObjectType = DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryFurnaceHeatOnly;
1005 3 : FurnaceType_Num = Furnace_HeatOnly;
1006 3 : GetObjectNum = HeatOnlyNum;
1007 : } else {
1008 1 : CurrentModuleObject = "AirLoopHVAC:UnitaryHeatOnly";
1009 1 : currentModuleObjectType = DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatOnly;
1010 1 : FurnaceType_Num = UnitarySys_HeatOnly;
1011 1 : GetObjectNum = HeatOnlyNum - NumHeatOnly;
1012 : }
1013 :
1014 4 : FurnaceNum = HeatOnlyNum;
1015 4 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num = FurnaceType_Num;
1016 4 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode.allocate(3);
1017 :
1018 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1019 : CurrentModuleObject,
1020 : GetObjectNum,
1021 : Alphas,
1022 : NumAlphas,
1023 : Numbers,
1024 : NumNumbers,
1025 : IOStatus,
1026 : lNumericBlanks,
1027 : lAlphaBlanks,
1028 : cAlphaFields,
1029 : cNumericFields);
1030 :
1031 8 : GlobalNames::VerifyUniqueInterObjectName(
1032 8 : state, state.dataFurnaces->UniqueFurnaceNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1033 :
1034 4 : state.dataFurnaces->Furnace(FurnaceNum).Name = Alphas(1);
1035 4 : if (lAlphaBlanks(2)) {
1036 0 : state.dataFurnaces->Furnace(FurnaceNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
1037 : } else {
1038 4 : state.dataFurnaces->Furnace(FurnaceNum).SchedPtr = GetScheduleIndex(state, Alphas(2));
1039 4 : if (state.dataFurnaces->Furnace(FurnaceNum).SchedPtr == 0) {
1040 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1041 0 : ShowContinueError(state, "Illegal " + cAlphaFields(2) + " = " + Alphas(2));
1042 0 : ErrorsFound = true;
1043 : }
1044 : }
1045 :
1046 4 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum = GetOnlySingleNode(state,
1047 4 : Alphas(3),
1048 : ErrorsFound,
1049 : currentModuleObjectType,
1050 4 : Alphas(1),
1051 : DataLoopNode::NodeFluidType::Air,
1052 : DataLoopNode::ConnectionType::Inlet,
1053 : NodeInputManager::CompFluidStream::Primary,
1054 4 : ObjectIsParent);
1055 4 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum = GetOnlySingleNode(state,
1056 4 : Alphas(4),
1057 : ErrorsFound,
1058 : currentModuleObjectType,
1059 4 : Alphas(1),
1060 : DataLoopNode::NodeFluidType::Air,
1061 : DataLoopNode::ConnectionType::Outlet,
1062 : NodeInputManager::CompFluidStream::Primary,
1063 4 : ObjectIsParent);
1064 :
1065 4 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
1066 :
1067 4 : state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr = GetScheduleIndex(state, Alphas(5));
1068 4 : if (!lAlphaBlanks(5) && state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr == 0) {
1069 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1070 0 : ShowContinueError(state, "Illegal " + cAlphaFields(5) + " = " + Alphas(5));
1071 0 : ErrorsFound = true;
1072 4 : } else if (lAlphaBlanks(5)) {
1073 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode = CycFanCycCoil;
1074 : }
1075 :
1076 : // Get the Controlling Zone or Location of the Furnace Thermostat
1077 :
1078 4 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum = UtilityRoutines::FindItemInList(Alphas(6), state.dataHeatBal->Zone);
1079 4 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum == 0) {
1080 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1081 0 : ShowContinueError(state, "Illegal " + cAlphaFields(6) + " = " + Alphas(6));
1082 0 : ErrorsFound = true;
1083 : }
1084 :
1085 : // Get the node number for the zone with the thermostat
1086 4 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum > 0) {
1087 4 : AirNodeFound = false;
1088 4 : AirLoopFound = false;
1089 4 : int ControlledZoneNum = state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum;
1090 : // Find the controlled zone number for the specified thermostat location
1091 4 : state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
1092 : // Determine if furnace is on air loop served by the thermostat location specified
1093 4 : for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
1094 4 : int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
1095 4 : if (AirLoopNumber > 0) {
1096 4 : for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
1097 4 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
1098 : ++CompNum) {
1099 12 : if (!UtilityRoutines::SameString(
1100 4 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name,
1101 12 : state.dataFurnaces->Furnace(FurnaceNum).Name) ||
1102 8 : !UtilityRoutines::SameString(
1103 4 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
1104 : CurrentModuleObject))
1105 0 : continue;
1106 4 : AirLoopFound = true;
1107 4 : state.dataFurnaces->Furnace(FurnaceNum).ZoneInletNode =
1108 4 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
1109 4 : break;
1110 : }
1111 4 : if (AirLoopFound) break;
1112 : }
1113 10 : for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
1114 12 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum !=
1115 6 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
1116 2 : continue;
1117 4 : AirNodeFound = true;
1118 : }
1119 4 : for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
1120 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum !=
1121 0 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
1122 0 : continue;
1123 0 : AirNodeFound = true;
1124 : }
1125 : }
1126 4 : if (AirLoopFound) break;
1127 : }
1128 4 : if (!AirNodeFound) {
1129 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1130 0 : ShowSevereError(state, "Did not find Air Node (Zone with Thermostat).");
1131 0 : ShowContinueError(state, "Specified " + cAlphaFields(6) + " = " + Alphas(6));
1132 0 : ShowContinueError(
1133 : state, "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
1134 0 : ErrorsFound = true;
1135 : }
1136 4 : if (!AirLoopFound) {
1137 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1138 0 : ShowSevereError(state, "Did not find correct Primary Air Loop.");
1139 0 : ShowContinueError(state, "Specified " + cAlphaFields(6) + " = " + Alphas(6) + " is not served by this AirLoopHVAC equipment.");
1140 0 : ErrorsFound = true;
1141 : }
1142 : }
1143 :
1144 : // Get fan data
1145 4 : FanType = Alphas(7);
1146 4 : FanName = Alphas(8);
1147 4 : errFlag = false;
1148 4 : GetFanType(state, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanType_Num, errFlag, CurrentModuleObject, Alphas(1));
1149 4 : if (errFlag) {
1150 0 : ErrorsFound = true;
1151 : }
1152 4 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleOnOff ||
1153 0 : state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleConstVolume) {
1154 :
1155 4 : ValidateComponent(state, FanType, FanName, IsNotOK, CurrentModuleObject);
1156 4 : if (IsNotOK) {
1157 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1158 0 : ErrorsFound = true;
1159 :
1160 : } else { // mine data from fan object
1161 :
1162 : // Get the fan index
1163 4 : errFlag = false;
1164 4 : GetFanIndex(state, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, errFlag);
1165 4 : if (errFlag) {
1166 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1167 0 : ErrorsFound = true;
1168 : }
1169 :
1170 : // Set the Design Fan Volume Flow Rate
1171 4 : errFlag = false;
1172 4 : FanVolFlowRate = GetFanDesignVolumeFlowRate(state, FanType, FanName, errFlag);
1173 4 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate = FanVolFlowRate;
1174 :
1175 4 : if (errFlag) {
1176 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " =" + Alphas(1));
1177 0 : ErrorsFound = true;
1178 : }
1179 :
1180 : // Get the Fan Inlet Node
1181 4 : errFlag = false;
1182 4 : FanInletNode = GetFanInletNode(state, FanType, FanName, errFlag);
1183 4 : if (errFlag) {
1184 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1185 0 : ErrorsFound = true;
1186 : }
1187 :
1188 : // Get the Fan Outlet Node
1189 4 : errFlag = false;
1190 4 : FanOutletNode = GetFanOutletNode(state, FanType, FanName, errFlag);
1191 4 : if (errFlag) {
1192 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1193 0 : ErrorsFound = true;
1194 : }
1195 :
1196 : // Get the fan's availabitlity schedule
1197 4 : errFlag = false;
1198 4 : state.dataFurnaces->Furnace(FurnaceNum).FanAvailSchedPtr = GetFanAvailSchPtr(state, FanType, FanName, errFlag);
1199 4 : if (errFlag) {
1200 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1201 0 : ErrorsFound = true;
1202 : }
1203 :
1204 : // Check fan's schedule for cycling fan operation if constant volume fan is used
1205 8 : if (state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr > 0 &&
1206 4 : state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleConstVolume) {
1207 0 : if (!CheckScheduleValueMinMax(state, state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr, ">", 0.0, "<=", 1.0)) {
1208 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1209 0 : ShowContinueError(state, "For " + cAlphaFields(7) + " = " + Alphas(7));
1210 0 : ShowContinueError(state, "Fan operating mode must be continuous (fan operating mode schedule values > 0).");
1211 0 : ShowContinueError(state, "Error found in " + cAlphaFields(5) + " = " + Alphas(5));
1212 0 : ShowContinueError(state, "...schedule values must be (>0., <=1.)");
1213 0 : ErrorsFound = true;
1214 : }
1215 4 : } else if (lAlphaBlanks(5) && state.dataFurnaces->Furnace(FurnaceNum).FanType_Num != FanType_SimpleOnOff) {
1216 0 : ShowSevereError(state, CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1217 0 : ShowContinueError(state, cAlphaFields(7) + " = " + Alphas(7));
1218 0 : ShowContinueError(state, "Fan type must be Fan:OnOff when " + cAlphaFields(5) + " = Blank.");
1219 0 : ErrorsFound = true;
1220 : }
1221 :
1222 : } // IF (IsNotOK) THEN
1223 :
1224 : } else { // wrong fan type
1225 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1226 0 : ShowContinueError(state, "Illegal " + cAlphaFields(7) + " = " + Alphas(7));
1227 0 : ErrorsFound = true;
1228 : } // IF (state.dataFurnaces->Furnace(FurnaceNum)%FanType_Num == FanType_SimpleOnOff .OR. &
1229 :
1230 4 : if (UtilityRoutines::SameString(Alphas(9), "BlowThrough")) state.dataFurnaces->Furnace(FurnaceNum).FanPlace = BlowThru;
1231 4 : if (UtilityRoutines::SameString(Alphas(9), "DrawThrough")) state.dataFurnaces->Furnace(FurnaceNum).FanPlace = DrawThru;
1232 4 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == 0) {
1233 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1234 0 : ShowContinueError(state, "Illegal " + cAlphaFields(9) + " = " + Alphas(9));
1235 0 : ErrorsFound = true;
1236 : }
1237 :
1238 : // Get coil data
1239 4 : HeatingCoilType = Alphas(10);
1240 4 : HeatingCoilName = Alphas(11);
1241 4 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType = HeatingCoilType;
1242 4 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName = HeatingCoilName;
1243 8 : if (UtilityRoutines::SameString(HeatingCoilType, "Coil:Heating:Fuel") ||
1244 4 : UtilityRoutines::SameString(HeatingCoilType, "Coil:Heating:Electric")) {
1245 4 : errFlag = false;
1246 4 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = GetHeatingCoilTypeNum(state, HeatingCoilType, HeatingCoilName, errFlag);
1247 4 : if (errFlag) {
1248 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1249 0 : ErrorsFound = true;
1250 : } else {
1251 4 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
1252 4 : if (IsNotOK) {
1253 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1254 0 : ErrorsFound = true;
1255 :
1256 : } else { // mine data from heating coil object
1257 :
1258 : // Get index to Heating Coil
1259 4 : errFlag = false;
1260 4 : GetHeatingCoilIndex(state, HeatingCoilName, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, errFlag);
1261 4 : if (errFlag) {
1262 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1263 0 : ErrorsFound = true;
1264 : }
1265 :
1266 : // Get the furnace design capacity
1267 4 : errFlag = false;
1268 4 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
1269 4 : GetHeatingCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
1270 4 : if (errFlag) {
1271 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " =" + Alphas(1));
1272 0 : ErrorsFound = true;
1273 : }
1274 :
1275 : // Get the Heating Coil Inlet Node
1276 4 : errFlag = false;
1277 4 : HeatingCoilInletNode = GetHeatingCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
1278 4 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirInletNode = HeatingCoilInletNode;
1279 4 : if (errFlag) {
1280 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " =" + Alphas(1));
1281 0 : ErrorsFound = true;
1282 : }
1283 :
1284 : // Get the Heating Coil Outlet Node
1285 4 : errFlag = false;
1286 4 : HeatingCoilOutletNode = GetHeatingCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
1287 4 : if (errFlag) {
1288 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " =" + Alphas(1));
1289 0 : ErrorsFound = true;
1290 : }
1291 :
1292 : } // IF (IsNotOK) THEN
1293 : }
1294 :
1295 0 : } else if (UtilityRoutines::SameString(HeatingCoilType, "Coil:Heating:Water")) {
1296 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = Coil_HeatingWater;
1297 0 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
1298 0 : if (IsNotOK) {
1299 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1300 0 : ErrorsFound = true;
1301 : } else { // mine data from heating coil object
1302 :
1303 : // Get the Heating Coil water Inlet or control Node number
1304 0 : errFlag = false;
1305 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode =
1306 0 : GetCoilWaterInletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
1307 0 : if (errFlag) {
1308 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1309 0 : ErrorsFound = true;
1310 : }
1311 :
1312 : // Get the Heating Coil hot water max volume flow rate
1313 0 : errFlag = false;
1314 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow =
1315 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
1316 0 : if (errFlag) {
1317 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1318 0 : ErrorsFound = true;
1319 : }
1320 :
1321 : // Get the Heating Coil Inlet Node
1322 0 : errFlag = false;
1323 0 : HeatingCoilInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
1324 0 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirInletNode = HeatingCoilInletNode;
1325 0 : if (errFlag) {
1326 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1327 0 : ErrorsFound = true;
1328 : }
1329 :
1330 : // Get the Heating Coil Outlet Node
1331 0 : errFlag = false;
1332 0 : HeatingCoilOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
1333 0 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirOutletNode = HeatingCoilOutletNode;
1334 0 : if (errFlag) {
1335 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1336 0 : ErrorsFound = true;
1337 : }
1338 :
1339 : // check if user has also used a water coil controller, which they should not do
1340 0 : errFlag = false;
1341 0 : CheckCoilWaterInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode, errFlag);
1342 0 : if (!errFlag) { // then did find a controller so that is bad
1343 0 : ShowSevereError(state,
1344 0 : CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name +
1345 : " has a conflicting Controller:WaterCoil object");
1346 0 : ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
1347 0 : ShowContinueError(state, "No water coil controller should be input for the coil.");
1348 0 : ErrorsFound = true;
1349 : }
1350 : }
1351 :
1352 0 : } else if (UtilityRoutines::SameString(HeatingCoilType, "Coil:Heating:Steam")) {
1353 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = Coil_HeatingSteam;
1354 0 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
1355 0 : if (IsNotOK) {
1356 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1357 0 : ErrorsFound = true;
1358 : } else { // mine data from heating coil object
1359 :
1360 0 : errFlag = false;
1361 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex =
1362 0 : GetSteamCoilIndex(state, "COIL:HEATING:STEAM", HeatingCoilName, errFlag);
1363 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex == 0) {
1364 0 : ShowSevereError(state, CurrentModuleObject + " illegal " + cAlphaFields(11) + " = " + HeatingCoilName);
1365 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1366 0 : ErrorsFound = true;
1367 : }
1368 :
1369 : // Get the Heating Coil steam inlet node number
1370 0 : errFlag = false;
1371 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode =
1372 0 : GetCoilSteamInletNode(state, "COIL:HEATING:STEAM", HeatingCoilName, errFlag);
1373 0 : if (errFlag) {
1374 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1375 0 : ErrorsFound = true;
1376 : }
1377 :
1378 : // Get the Heating Coil steam max volume flow rate
1379 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow =
1380 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, errFlag);
1381 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow > 0.0) {
1382 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
1383 0 : SteamDensity =
1384 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, getUnitaryHeatOnly);
1385 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow *= SteamDensity;
1386 : }
1387 :
1388 : // Get the Heating Coil Inlet Node
1389 0 : errFlag = false;
1390 0 : HeatingCoilInletNode =
1391 0 : GetSteamCoilAirInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, HeatingCoilName, errFlag);
1392 0 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirInletNode = HeatingCoilInletNode;
1393 0 : if (errFlag) {
1394 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1395 0 : ErrorsFound = true;
1396 : }
1397 :
1398 : // Get the Heating Coil Outlet Node
1399 0 : errFlag = false;
1400 0 : HeatingCoilOutletNode =
1401 0 : GetCoilAirOutletNode(state, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, HeatingCoilName, errFlag);
1402 0 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirOutletNode = HeatingCoilOutletNode;
1403 0 : if (errFlag) {
1404 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1405 0 : ErrorsFound = true;
1406 : }
1407 : }
1408 :
1409 : } else {
1410 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1411 0 : ShowContinueError(state, "Illegal " + cAlphaFields(11) + " = " + Alphas(11));
1412 0 : ErrorsFound = true;
1413 : } // IF (Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
1414 :
1415 : // Add component sets array
1416 4 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
1417 4 : CompSetFanInlet = Alphas(3);
1418 4 : CompSetFanOutlet = state.dataLoopNodes->NodeID(FanOutletNode);
1419 4 : CompSetHeatInlet = state.dataLoopNodes->NodeID(FanOutletNode);
1420 4 : CompSetHeatOutlet = Alphas(4);
1421 : // Fan inlet node name must not be the same as the furnace inlet node name
1422 4 : if (FanInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
1423 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1424 0 : if (FurnaceType_Num == Furnace_HeatOnly) {
1425 0 : ShowContinueError(
1426 : state, "When a blow through fan is specified, the fan inlet node name must be the same as the furnace inlet node name.");
1427 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
1428 0 : ShowContinueError(state,
1429 0 : "...Furnace inlet node name = " +
1430 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
1431 : } else {
1432 0 : ShowContinueError(
1433 : state,
1434 : "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system inlet node name.");
1435 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
1436 0 : ShowContinueError(state,
1437 0 : "...Unitary System inlet node name = " +
1438 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
1439 : }
1440 0 : ErrorsFound = true;
1441 : }
1442 : // Fan outlet node name must be the same as the heating coil inlet node name
1443 4 : if (FanOutletNode != HeatingCoilInletNode) {
1444 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1445 0 : ShowContinueError(
1446 : state,
1447 : "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil inlet node name.");
1448 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
1449 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
1450 0 : ErrorsFound = true;
1451 : }
1452 : // Heating coil outlet node name must be the same as the furnace outlet node name
1453 4 : if (HeatingCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
1454 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1455 0 : if (FurnaceType_Num == Furnace_HeatOnly) {
1456 0 : ShowContinueError(state,
1457 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the furnace "
1458 : "outlet node name.");
1459 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
1460 0 : ShowContinueError(state,
1461 0 : "...Furnace outlet node name = " +
1462 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
1463 : } else {
1464 0 : ShowContinueError(state,
1465 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the unitary "
1466 : "system outlet node name.");
1467 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
1468 0 : ShowContinueError(state,
1469 0 : "...UnitarySystem outlet node name = " +
1470 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
1471 : }
1472 0 : ErrorsFound = true;
1473 : }
1474 : } else { // draw through fan
1475 0 : CompSetHeatInlet = Alphas(3);
1476 0 : CompSetHeatOutlet = state.dataLoopNodes->NodeID(FanInletNode);
1477 0 : CompSetFanInlet = state.dataLoopNodes->NodeID(FanInletNode);
1478 0 : CompSetFanOutlet = Alphas(4);
1479 : // Heating coil inlet node name must not be the same as the furnace inlet node name
1480 0 : if (HeatingCoilInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
1481 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1482 0 : if (FurnaceType_Num == Furnace_HeatOnly) {
1483 0 : ShowContinueError(state,
1484 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the furnace "
1485 : "inlet node name.");
1486 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
1487 0 : ShowContinueError(state,
1488 0 : "...Furnace inlet node name = " +
1489 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
1490 : } else {
1491 0 : ShowContinueError(state,
1492 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
1493 : "system inlet node name.");
1494 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
1495 0 : ShowContinueError(state,
1496 0 : "...UnitarySystem inlet node name = " +
1497 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
1498 : }
1499 0 : ErrorsFound = true;
1500 : }
1501 : // Heating coil outlet node name must be the same as the fan inlet node name
1502 0 : if (HeatingCoilOutletNode != FanInletNode) {
1503 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1504 0 : ShowContinueError(
1505 : state,
1506 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan inlet node name.");
1507 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
1508 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
1509 0 : ErrorsFound = true;
1510 : }
1511 : // Fan coil outlet node name must be the same as the furnace outlet node name
1512 0 : if (FanOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
1513 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1514 0 : if (FurnaceType_Num == Furnace_HeatOnly) {
1515 0 : ShowContinueError(
1516 : state,
1517 : "When a draw through fan is specified, the fan outlet node name must be the same as the furnace outlet node name.");
1518 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
1519 0 : ShowContinueError(state,
1520 0 : "...Furnace outlet node name = " +
1521 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
1522 : } else {
1523 0 : ShowContinueError(state,
1524 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
1525 : "outlet node name.");
1526 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
1527 0 : ShowContinueError(state,
1528 0 : "...UnitarySystem outlet node name = " +
1529 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
1530 : }
1531 0 : ErrorsFound = true;
1532 : }
1533 : }
1534 :
1535 : // Add fan to component sets array
1536 16 : SetUpCompSets(
1537 16 : state, CurrentModuleObject, state.dataFurnaces->Furnace(FurnaceNum).Name, Alphas(7), Alphas(8), CompSetFanInlet, CompSetFanOutlet);
1538 : // Add heating coil to component sets array
1539 16 : SetUpCompSets(state,
1540 : CurrentModuleObject,
1541 4 : state.dataFurnaces->Furnace(FurnaceNum).Name,
1542 4 : Alphas(10),
1543 4 : Alphas(11),
1544 : CompSetHeatInlet,
1545 4 : CompSetHeatOutlet);
1546 :
1547 : // Set the furnace max outlet temperature
1548 4 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp = Numbers(1);
1549 :
1550 : // Set the furnace design fan volumetric flow rate
1551 4 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = Numbers(2);
1552 :
1553 : // Compare the flow rates.
1554 4 : if (FanVolFlowRate != DataSizing::AutoSize && state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate != DataSizing::AutoSize) {
1555 4 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate > FanVolFlowRate) {
1556 0 : ShowWarningError(state, CurrentModuleObject + " = " + Alphas(1));
1557 0 : ShowContinueError(state,
1558 0 : "... The " + cNumericFields(2) + " > Max Volume Flow Rate defined in the associated fan object, should be <=.");
1559 0 : ShowContinueError(state,
1560 0 : format("... Entered value = {:.4R}... Fan [{} = {}] Max Value = {:.4R}",
1561 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate,
1562 : FanType,
1563 : FanName,
1564 0 : FanVolFlowRate));
1565 0 : ShowContinueError(state, " The HVAC system flow rate is reset to the fan flow rate and the simulation continues.");
1566 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = FanVolFlowRate;
1567 : }
1568 : }
1569 4 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate != DataSizing::AutoSize) {
1570 4 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate <= 0.0) {
1571 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1572 0 : ShowContinueError(state, "... The " + cNumericFields(2) + " <= 0.0, it must be > 0.0.");
1573 0 : ShowContinueError(state, format("... Entered value = {:.2R}", state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate));
1574 0 : ErrorsFound = true;
1575 : }
1576 : }
1577 :
1578 : // HeatOnly furnace has only 1 flow rate, initialize other variables used in this module
1579 4 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow = state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate;
1580 4 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow = state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate;
1581 4 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow = state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate;
1582 4 : state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl = AirFlowControlConstFan::UseCompressorOnFlow;
1583 :
1584 : // Set heating convergence tolerance
1585 4 : state.dataFurnaces->Furnace(FurnaceNum).HeatingConvergenceTolerance = 0.001;
1586 :
1587 : // set minimum outdoor temperature for compressor operation
1588 4 : SetMinOATCompressor(state, FurnaceNum, cCurrentModuleObject, ErrorsFound);
1589 :
1590 : } // End of the HeatOnly Furnace Loop
1591 :
1592 : // Get the data for the HeatCool Furnace or UnitarySystem
1593 275 : for (HeatCoolNum = 1; HeatCoolNum <= NumHeatCool + NumUnitaryHeatCool; ++HeatCoolNum) {
1594 :
1595 181 : FanInletNode = 0;
1596 181 : FanOutletNode = 0;
1597 181 : FanVolFlowRate = 0.0;
1598 181 : CoolingCoilInletNode = 0;
1599 181 : CoolingCoilOutletNode = 0;
1600 181 : HeatingCoilInletNode = 0;
1601 181 : HeatingCoilOutletNode = 0;
1602 181 : ReheatCoilInletNode = 0;
1603 181 : ReheatCoilOutletNode = 0;
1604 181 : CoolingCoilType = ' ';
1605 181 : CoolingCoilName = ' ';
1606 181 : HeatingCoilType = ' ';
1607 181 : HeatingCoilName = ' ';
1608 :
1609 : // Furnace and UnitarySystem objects are both read in here.
1610 : // Will still have 2 differently named objects for the user, but read in with 1 DO loop.
1611 181 : if (HeatCoolNum <= NumHeatCool) {
1612 108 : CurrentModuleObject = "AirLoopHVAC:Unitary:Furnace:HeatCool";
1613 108 : currentModuleObjectType = DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryFurnaceHeatCool;
1614 108 : FurnaceType_Num = Furnace_HeatCool;
1615 108 : GetObjectNum = HeatCoolNum;
1616 : } else {
1617 73 : CurrentModuleObject = "AirLoopHVAC:UnitaryHeatCool";
1618 73 : currentModuleObjectType = DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCool;
1619 73 : FurnaceType_Num = UnitarySys_HeatCool;
1620 73 : GetObjectNum = HeatCoolNum - NumHeatCool;
1621 : }
1622 :
1623 181 : FurnaceNum = HeatCoolNum + NumHeatOnly + NumUnitaryHeatOnly;
1624 181 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num = FurnaceType_Num;
1625 181 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode.allocate(3);
1626 :
1627 181 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1628 : CurrentModuleObject,
1629 : GetObjectNum,
1630 : Alphas,
1631 : NumAlphas,
1632 : Numbers,
1633 : NumNumbers,
1634 : IOStatus,
1635 : lNumericBlanks,
1636 : lAlphaBlanks,
1637 : cAlphaFields,
1638 : cNumericFields);
1639 :
1640 362 : GlobalNames::VerifyUniqueInterObjectName(
1641 362 : state, state.dataFurnaces->UniqueFurnaceNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
1642 :
1643 181 : state.dataFurnaces->Furnace(FurnaceNum).Name = Alphas(1);
1644 181 : if (lAlphaBlanks(2)) {
1645 58 : state.dataFurnaces->Furnace(FurnaceNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
1646 : } else {
1647 123 : state.dataFurnaces->Furnace(FurnaceNum).SchedPtr = GetScheduleIndex(state, Alphas(2));
1648 123 : if (state.dataFurnaces->Furnace(FurnaceNum).SchedPtr == 0) {
1649 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1650 0 : ShowContinueError(state, "Illegal " + cAlphaFields(2) + " = " + Alphas(2));
1651 0 : ErrorsFound = true;
1652 : }
1653 : }
1654 :
1655 181 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum = GetOnlySingleNode(state,
1656 181 : Alphas(3),
1657 : ErrorsFound,
1658 : currentModuleObjectType,
1659 181 : Alphas(1),
1660 : DataLoopNode::NodeFluidType::Air,
1661 : DataLoopNode::ConnectionType::Inlet,
1662 : NodeInputManager::CompFluidStream::Primary,
1663 181 : ObjectIsParent);
1664 181 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum = GetOnlySingleNode(state,
1665 181 : Alphas(4),
1666 : ErrorsFound,
1667 : currentModuleObjectType,
1668 181 : Alphas(1),
1669 : DataLoopNode::NodeFluidType::Air,
1670 : DataLoopNode::ConnectionType::Outlet,
1671 : NodeInputManager::CompFluidStream::Primary,
1672 181 : ObjectIsParent);
1673 :
1674 181 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
1675 :
1676 181 : state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr = GetScheduleIndex(state, Alphas(5));
1677 181 : if (!lAlphaBlanks(5) && state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr == 0) {
1678 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1679 0 : ShowContinueError(state, "Illegal " + cAlphaFields(5) + " = " + Alphas(5));
1680 0 : ErrorsFound = true;
1681 181 : } else if (lAlphaBlanks(5)) {
1682 20 : state.dataFurnaces->Furnace(FurnaceNum).OpMode = CycFanCycCoil;
1683 : }
1684 :
1685 : // Get the Controlling Zone or Location of the Furnace Thermostat
1686 181 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum = UtilityRoutines::FindItemInList(Alphas(6), state.dataHeatBal->Zone);
1687 181 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum == 0) {
1688 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1689 0 : ShowContinueError(state, "Illegal " + cAlphaFields(6) + " = " + Alphas(6));
1690 0 : ErrorsFound = true;
1691 : }
1692 :
1693 : // Get the node number for the zone with the thermostat
1694 181 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum > 0) {
1695 181 : AirNodeFound = false;
1696 181 : AirLoopFound = false;
1697 181 : int ControlledZoneNum = state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum;
1698 : // Find the controlled zone number for the specified thermostat location
1699 181 : state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
1700 : // Determine if system is on air loop served by the thermostat location specified
1701 186 : for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
1702 186 : int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
1703 186 : if (AirLoopNumber > 0) {
1704 191 : for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
1705 354 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
1706 : ++CompNum) {
1707 1047 : if (!UtilityRoutines::SameString(
1708 1228 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name, Alphas(1)) ||
1709 362 : !UtilityRoutines::SameString(
1710 181 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
1711 : CurrentModuleObject))
1712 168 : continue;
1713 181 : AirLoopFound = true;
1714 181 : state.dataFurnaces->Furnace(FurnaceNum).ZoneInletNode =
1715 181 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
1716 181 : break;
1717 : }
1718 186 : if (AirLoopFound) break;
1719 : }
1720 2184 : for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
1721 3996 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum !=
1722 1998 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
1723 1812 : continue;
1724 186 : AirNodeFound = true;
1725 : }
1726 187 : for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
1727 2 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum !=
1728 1 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
1729 0 : continue;
1730 1 : AirNodeFound = true;
1731 : }
1732 : }
1733 186 : if (AirLoopFound) break;
1734 : }
1735 181 : if (!AirNodeFound) {
1736 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1737 0 : ShowContinueError(state, "Did not find air node (zone with thermostat).");
1738 0 : ShowContinueError(state, "Specified " + cAlphaFields(6) + " = " + Alphas(6));
1739 0 : ShowContinueError(
1740 : state, "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
1741 0 : ErrorsFound = true;
1742 : }
1743 181 : if (!AirLoopFound) {
1744 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1745 0 : ShowSevereError(state, "Did not find correct AirLoopHVAC.");
1746 0 : ShowContinueError(state, "Specified " + cAlphaFields(6) + " = " + Alphas(6));
1747 0 : ErrorsFound = true;
1748 : }
1749 : }
1750 :
1751 : // Get fan data
1752 181 : FanType = Alphas(7);
1753 181 : FanName = Alphas(8);
1754 :
1755 181 : errFlag = false;
1756 181 : GetFanType(state, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanType_Num, errFlag, CurrentModuleObject, Alphas(1));
1757 181 : if (errFlag) {
1758 0 : ErrorsFound = true;
1759 : }
1760 :
1761 186 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleOnOff ||
1762 5 : state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleConstVolume) {
1763 181 : ValidateComponent(state, FanType, FanName, IsNotOK, CurrentModuleObject);
1764 181 : if (IsNotOK) {
1765 0 : ShowContinueError(state, "In Furnace=" + Alphas(1));
1766 0 : ErrorsFound = true;
1767 :
1768 : } else { // mine data from fan object
1769 :
1770 : // Get the fan index
1771 181 : errFlag = false;
1772 181 : GetFanIndex(state, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, errFlag);
1773 181 : if (errFlag) {
1774 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1775 0 : ErrorsFound = true;
1776 : }
1777 :
1778 : // Get the Design Fan Volume Flow Rate
1779 181 : errFlag = false;
1780 181 : FanVolFlowRate = GetFanDesignVolumeFlowRate(state, FanType, FanName, errFlag);
1781 181 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate = FanVolFlowRate;
1782 181 : if (errFlag) {
1783 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
1784 0 : ErrorsFound = true;
1785 : }
1786 :
1787 : // Get the Fan Inlet Node
1788 181 : errFlag = false;
1789 181 : FanInletNode = GetFanInletNode(state, FanType, FanName, errFlag);
1790 181 : if (errFlag) {
1791 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1792 0 : ErrorsFound = true;
1793 : }
1794 :
1795 : // Get the Fan Outlet Node
1796 181 : errFlag = false;
1797 181 : FanOutletNode = GetFanOutletNode(state, FanType, FanName, errFlag);
1798 181 : if (errFlag) {
1799 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1800 0 : ErrorsFound = true;
1801 : }
1802 :
1803 : // Get the fan's availability schedule
1804 181 : errFlag = false;
1805 181 : state.dataFurnaces->Furnace(FurnaceNum).FanAvailSchedPtr = GetFanAvailSchPtr(state, FanType, FanName, errFlag);
1806 181 : if (errFlag) {
1807 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1808 0 : ErrorsFound = true;
1809 : }
1810 :
1811 : // Check fan's schedule for cycling fan operation if constant volume fan is used
1812 342 : if (state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr > 0 &&
1813 161 : state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleConstVolume) {
1814 5 : if (!CheckScheduleValueMinMax(state, state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr, ">", 0.0, "<=", 1.0)) {
1815 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1816 0 : ShowContinueError(state, "For " + cAlphaFields(7) + " = " + Alphas(7));
1817 0 : ShowContinueError(state, "Fan operating mode must be continuous (fan operating mode schedule values > 0).");
1818 0 : ShowContinueError(state, "Error found in " + cAlphaFields(5) + " = " + Alphas(5));
1819 0 : ShowContinueError(state, "...schedule values must be (>0., <=1.)");
1820 0 : ErrorsFound = true;
1821 : }
1822 176 : } else if (lAlphaBlanks(5) && state.dataFurnaces->Furnace(FurnaceNum).FanType_Num != FanType_SimpleOnOff) {
1823 0 : ShowSevereError(state, CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1824 0 : ShowContinueError(state, cAlphaFields(7) + " = " + Alphas(7));
1825 0 : ShowContinueError(state, "Fan type must be Fan:OnOff when " + cAlphaFields(5) + " = Blank.");
1826 0 : ErrorsFound = true;
1827 : }
1828 :
1829 : } // IF (IsNotOK) THEN
1830 :
1831 : } else {
1832 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1833 0 : ShowContinueError(state, "Illegal " + cAlphaFields(7) + " = " + Alphas(7));
1834 0 : ErrorsFound = true;
1835 : } // IF (TFurnace(FurnaceNum)%FanType_Num == FanType_SimpleOnOff .OR. &, etc.
1836 :
1837 181 : if (UtilityRoutines::SameString(Alphas(9), "BlowThrough")) state.dataFurnaces->Furnace(FurnaceNum).FanPlace = BlowThru;
1838 181 : if (UtilityRoutines::SameString(Alphas(9), "DrawThrough")) state.dataFurnaces->Furnace(FurnaceNum).FanPlace = DrawThru;
1839 181 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == 0) {
1840 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
1841 0 : ShowContinueError(state, "Illegal " + cAlphaFields(9) + " = " + Alphas(9));
1842 0 : ErrorsFound = true;
1843 : }
1844 :
1845 : // Get coil data
1846 181 : HeatingCoilType = Alphas(10);
1847 181 : HeatingCoilName = Alphas(11);
1848 181 : HeatingCoilPLFCurveIndex = 0;
1849 181 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType = HeatingCoilType;
1850 181 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName = HeatingCoilName;
1851 364 : if (UtilityRoutines::SameString(HeatingCoilType, "Coil:Heating:Fuel") ||
1852 183 : UtilityRoutines::SameString(HeatingCoilType, "Coil:Heating:Electric")) {
1853 181 : errFlag = false;
1854 181 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = GetHeatingCoilTypeNum(state, HeatingCoilType, HeatingCoilName, errFlag);
1855 181 : if (errFlag) {
1856 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1857 0 : ErrorsFound = true;
1858 : } else {
1859 :
1860 181 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
1861 181 : if (IsNotOK) {
1862 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1863 0 : ErrorsFound = true;
1864 :
1865 : } else { // mine data from heating coil
1866 :
1867 : // Get heating coil index
1868 181 : errFlag = false;
1869 181 : GetHeatingCoilIndex(state, HeatingCoilName, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, errFlag);
1870 181 : if (errFlag) {
1871 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1872 0 : ErrorsFound = true;
1873 : }
1874 :
1875 : // Get the design heating capacity
1876 181 : errFlag = false;
1877 181 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
1878 181 : GetHeatingCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
1879 181 : if (errFlag) {
1880 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1881 0 : ErrorsFound = true;
1882 : }
1883 :
1884 : // Get the Heating Coil Inlet Node
1885 181 : errFlag = false;
1886 181 : HeatingCoilInletNode = GetHeatingCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
1887 181 : if (errFlag) {
1888 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1889 0 : ErrorsFound = true;
1890 : }
1891 :
1892 : // Get the Heating Coil Outlet Node
1893 181 : errFlag = false;
1894 181 : HeatingCoilOutletNode = GetHeatingCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
1895 181 : if (errFlag) {
1896 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1897 0 : ErrorsFound = true;
1898 : }
1899 :
1900 : // Get the Heating Coil PLF Curve Index
1901 181 : errFlag = false;
1902 181 : HeatingCoilPLFCurveIndex = GetHeatingCoilPLFCurveIndex(state, HeatingCoilType, HeatingCoilName, errFlag);
1903 181 : if (errFlag) {
1904 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1905 0 : ErrorsFound = true;
1906 : }
1907 :
1908 : } // IF (IsNotOK) THEN
1909 : }
1910 :
1911 0 : } else if (UtilityRoutines::SameString(HeatingCoilType, "Coil:Heating:Water")) {
1912 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = Coil_HeatingWater;
1913 0 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
1914 0 : if (IsNotOK) {
1915 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1916 0 : ErrorsFound = true;
1917 : } else { // mine data from heating coil object
1918 :
1919 : // Get the Heating Coil water Inlet or control Node number
1920 0 : errFlag = false;
1921 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode =
1922 0 : GetCoilWaterInletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
1923 0 : if (errFlag) {
1924 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1925 0 : ErrorsFound = true;
1926 : }
1927 :
1928 : // Get the Heating Coil hot water max volume flow rate
1929 0 : errFlag = false;
1930 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow =
1931 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
1932 0 : if (errFlag) {
1933 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1934 0 : ErrorsFound = true;
1935 : }
1936 :
1937 : // Get the Heating Coil Inlet Node
1938 0 : errFlag = false;
1939 0 : HeatingCoilInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
1940 0 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirInletNode = HeatingCoilInletNode;
1941 0 : if (errFlag) {
1942 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1943 0 : ErrorsFound = true;
1944 : }
1945 :
1946 : // Get the Heating Coil Outlet Node
1947 0 : errFlag = false;
1948 0 : HeatingCoilOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
1949 0 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirOutletNode = HeatingCoilOutletNode;
1950 0 : if (errFlag) {
1951 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1952 0 : ErrorsFound = true;
1953 : }
1954 :
1955 : // check if user has also used a water coil controller, which they should not do
1956 0 : errFlag = false;
1957 0 : CheckCoilWaterInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode, errFlag);
1958 0 : if (!errFlag) { // then did find a controller so that is bad
1959 0 : ShowSevereError(state,
1960 0 : CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name +
1961 : " has a conflicting Controller:WaterCoil object");
1962 0 : ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
1963 0 : ShowContinueError(state, "No water coil controller should be input for the coil.");
1964 0 : ErrorsFound = true;
1965 : }
1966 : }
1967 :
1968 0 : } else if (UtilityRoutines::SameString(HeatingCoilType, "Coil:Heating:Steam")) {
1969 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = Coil_HeatingSteam;
1970 0 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
1971 0 : if (IsNotOK) {
1972 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1973 0 : ErrorsFound = true;
1974 : } else { // mine data from heating coil object
1975 :
1976 0 : errFlag = false;
1977 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex =
1978 0 : GetSteamCoilIndex(state, "COIL:HEATING:STEAM", HeatingCoilName, errFlag);
1979 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex == 0) {
1980 0 : ShowSevereError(state, CurrentModuleObject + " illegal " + cAlphaFields(11) + " = " + HeatingCoilName);
1981 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1982 0 : ErrorsFound = true;
1983 : }
1984 :
1985 : // Get the Heating Coil steam inlet node number
1986 0 : errFlag = false;
1987 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode =
1988 0 : GetCoilSteamInletNode(state, "Coil:Heating:Steam", HeatingCoilName, errFlag);
1989 0 : if (errFlag) {
1990 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
1991 0 : ErrorsFound = true;
1992 : }
1993 :
1994 : // Get the Heating Coil steam max volume flow rate
1995 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow =
1996 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, errFlag);
1997 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow > 0.0) {
1998 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
1999 0 : SteamDensity =
2000 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, getAirLoopHVACHeatCoolInput);
2001 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow *= SteamDensity;
2002 : }
2003 :
2004 : // Get the Heating Coil Inlet Node
2005 0 : errFlag = false;
2006 0 : HeatingCoilInletNode =
2007 0 : GetSteamCoilAirInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, HeatingCoilName, errFlag);
2008 0 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirInletNode = HeatingCoilInletNode;
2009 0 : if (errFlag) {
2010 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2011 0 : ErrorsFound = true;
2012 : }
2013 :
2014 : // Get the Heating Coil Outlet Node
2015 0 : errFlag = false;
2016 0 : HeatingCoilOutletNode =
2017 0 : GetCoilAirOutletNode(state, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, HeatingCoilName, errFlag);
2018 0 : state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirOutletNode = HeatingCoilOutletNode;
2019 0 : if (errFlag) {
2020 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2021 0 : ErrorsFound = true;
2022 : }
2023 : }
2024 :
2025 : } else {
2026 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2027 0 : ShowContinueError(state, "Illegal " + cAlphaFields(11) + " = " + Alphas(11));
2028 0 : ErrorsFound = true;
2029 : } // IF (Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
2030 :
2031 : // Get Cooling Coil Information if available
2032 181 : CoolingCoilType = Alphas(12);
2033 181 : CoolingCoilName = Alphas(13);
2034 : // Find the type of coil. Do not print message since this may not be the correct coil type.
2035 181 : errFlag = false;
2036 181 : PrintMessage = false;
2037 :
2038 539 : if (UtilityRoutines::SameString(CoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED") ||
2039 358 : UtilityRoutines::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
2040 4 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num = Coil_CoolingAirToAirVariableSpeed;
2041 4 : if (UtilityRoutines::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE"))
2042 0 : state.dataFurnaces->Furnace(FurnaceNum).bIsIHP = true;
2043 : } else {
2044 177 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num =
2045 354 : GetCoilTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, PrintMessage);
2046 : }
2047 :
2048 : // If coil type not found, check to see if a HX assisted cooling coil is used.
2049 181 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == 0) {
2050 3 : errFlag = false;
2051 3 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num =
2052 6 : GetHXAssistedCoilTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, PrintMessage);
2053 : }
2054 :
2055 181 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingSingleSpeed) {
2056 174 : ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
2057 174 : if (IsNotOK) {
2058 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2059 0 : ErrorsFound = true;
2060 :
2061 : } else { // mine data from DX cooling coil
2062 :
2063 : // Get DX cooling coil index
2064 174 : GetDXCoilIndex(state, CoolingCoilName, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, IsNotOK);
2065 174 : if (IsNotOK) {
2066 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2067 0 : ErrorsFound = true;
2068 : }
2069 :
2070 : // Get DX cooling coil capacity
2071 174 : errFlag = false;
2072 174 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
2073 174 : GetDXCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
2074 174 : if (errFlag) {
2075 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2076 0 : ErrorsFound = true;
2077 : }
2078 :
2079 : // Get the Cooling Coil Nodes
2080 174 : errFlag = false;
2081 174 : CoolingCoilInletNode = GetDXCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
2082 174 : CoolingCoilOutletNode = GetDXCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
2083 174 : if (errFlag) {
2084 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2085 0 : ErrorsFound = true;
2086 : }
2087 :
2088 : // Get outdoor condenser node from DX coil object
2089 174 : errFlag = false;
2090 174 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
2091 0 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
2092 0 : IHPCoilIndex = GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
2093 0 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(IHPCoilIndex).SCCoilName;
2094 0 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
2095 : } else {
2096 0 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
2097 : }
2098 : } else {
2099 174 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum =
2100 174 : GetDXCoilCondenserInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
2101 : }
2102 174 : if (errFlag) {
2103 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2104 0 : ErrorsFound = true;
2105 : }
2106 :
2107 : } // IF (IsNotOK) THEN
2108 :
2109 : // Push heating coil PLF curve index to DX coil
2110 174 : if (HeatingCoilPLFCurveIndex > 0) {
2111 48 : SetDXCoolingCoilData(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, ErrorsFound, HeatingCoilPLFCurveIndex);
2112 : }
2113 :
2114 7 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
2115 3 : ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
2116 3 : if (IsNotOK) {
2117 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2118 0 : ErrorsFound = true;
2119 :
2120 : } else { // mine data from heat exchanger assisted cooling coil
2121 :
2122 : // Get DX heat exchanger assisted cooling coil index
2123 3 : GetHXDXCoilIndex(state, CoolingCoilName, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, IsNotOK);
2124 3 : if (IsNotOK) {
2125 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2126 0 : ErrorsFound = true;
2127 : }
2128 :
2129 : // Get DX cooling coil capacity
2130 3 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
2131 3 : GetDXHXAsstdCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
2132 3 : errFlag = false;
2133 3 : if (errFlag) {
2134 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2135 0 : ErrorsFound = true;
2136 : }
2137 :
2138 : // Get the Cooling Coil Nodes
2139 3 : errFlag = false;
2140 3 : CoolingCoilInletNode = GetDXHXAsstdCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
2141 3 : CoolingCoilOutletNode = GetDXHXAsstdCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
2142 3 : if (errFlag) {
2143 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2144 0 : ErrorsFound = true;
2145 : }
2146 :
2147 : // Get outdoor condenser node from heat exchanger assisted DX coil object
2148 3 : errFlag = false;
2149 6 : std::string ChildCoolingCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, CoolingCoilType, CoolingCoilName, IsNotOK);
2150 6 : std::string ChildCoolingCoilType = HVACHXAssistedCoolingCoil::GetHXDXCoilType(state, CoolingCoilType, CoolingCoilName, IsNotOK);
2151 3 : if (IsNotOK) {
2152 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, Alphas(1)));
2153 0 : ErrorsFound = true;
2154 : }
2155 :
2156 : // if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
2157 3 : if (UtilityRoutines::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
2158 :
2159 1 : int childCCIndex = CoilCoolingDX::factory(state, ChildCoolingCoilName);
2160 1 : if (childCCIndex < 0) {
2161 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, Alphas(1)));
2162 0 : errFlag = true;
2163 0 : ErrorsFound = true;
2164 : }
2165 1 : auto &newCoil = state.dataCoilCooingDX->coilCoolingDXs[childCCIndex];
2166 :
2167 1 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = newCoil.condInletNodeIndex;
2168 :
2169 : }
2170 : // else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
2171 2 : else if (UtilityRoutines::SameString(ChildCoolingCoilType, "Coil:Cooling:DX:VariableSpeed")) {
2172 0 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
2173 0 : IHPCoilIndex = GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
2174 0 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(IHPCoilIndex).SCCoilName;
2175 0 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
2176 : } else {
2177 0 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
2178 : }
2179 : } else {
2180 2 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetDXCoilCondenserInletNode(
2181 4 : state, "COIL:COOLING:DX:SINGLESPEED", GetHXDXCoilName(state, CoolingCoilType, CoolingCoilName, errFlag), errFlag);
2182 : }
2183 :
2184 3 : if (errFlag) {
2185 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2186 0 : ErrorsFound = true;
2187 : }
2188 :
2189 : // Push heating coil PLF curve index to DX coil
2190 3 : if (HeatingCoilPLFCurveIndex > 0) {
2191 : // get the actual index to the DX cooling coil object
2192 0 : DXCoilIndex = GetActualDXCoilIndex(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
2193 0 : state.dataFurnaces->Furnace(FurnaceNum).ActualDXCoilIndexForHXAssisted = DXCoilIndex;
2194 : int ActualCoolCoilType =
2195 0 : HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, true);
2196 0 : if (ActualCoolCoilType == DataHVACGlobals::CoilDX_CoolingSingleSpeed) {
2197 0 : SetDXCoolingCoilData(state, DXCoilIndex, ErrorsFound, HeatingCoilPLFCurveIndex);
2198 : }
2199 : // what could we do for VS coil here? odd thing here
2200 : }
2201 :
2202 : } // IF (IsNotOK) THEN
2203 4 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
2204 : // BOS ADDED, AUG/2012, VARIIABLE SPEED DX COOLING COIL
2205 : // Furnace(FurnaceNum)%DXCoolCoilType = 'COIL:COOLING:DX:VARIABLESPEED'
2206 : // Furnace(FurnaceNum)%DXCoolCoilName = CoolingCoilName
2207 4 : if (UtilityRoutines::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE"))
2208 0 : state.dataFurnaces->Furnace(FurnaceNum).bIsIHP = true;
2209 4 : ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
2210 :
2211 4 : if (IsNotOK) {
2212 0 : ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + Alphas(1) + "\".");
2213 0 : ErrorsFound = true;
2214 : } else {
2215 4 : errFlag = false;
2216 4 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
2217 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex = GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
2218 0 : IHPCoilName =
2219 0 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilName;
2220 : } else {
2221 4 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex =
2222 4 : GetCoilIndexVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
2223 4 : IHPCoilName = CoolingCoilName;
2224 : }
2225 :
2226 4 : if (errFlag) {
2227 0 : ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + Alphas(1) + "\".");
2228 0 : ErrorsFound = true;
2229 : }
2230 :
2231 4 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
2232 0 : CoolingCoilInletNode = GetCoilInletNodeVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
2233 0 : CoolingCoilOutletNode = GetCoilOutletNodeVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
2234 0 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
2235 : } else {
2236 4 : CoolingCoilInletNode = GetCoilInletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
2237 4 : CoolingCoilOutletNode = GetCoilOutletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
2238 4 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
2239 : }
2240 :
2241 4 : if (errFlag) {
2242 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2243 0 : ErrorsFound = true;
2244 : }
2245 : }
2246 : } else {
2247 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2248 0 : ShowContinueError(state, "Illegal " + cAlphaFields(12) + " = " + Alphas(12));
2249 0 : ErrorsFound = true;
2250 : }
2251 :
2252 384 : if (UtilityRoutines::SameString(Alphas(14), "None") || UtilityRoutines::SameString(Alphas(14), "Multimode") ||
2253 203 : UtilityRoutines::SameString(Alphas(14), "CoolReheat")) {
2254 181 : AirNodeFound = false;
2255 181 : if (UtilityRoutines::SameString(Alphas(14), "Multimode")) {
2256 3 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::Multimode;
2257 3 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = true;
2258 3 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num != CoilDX_CoolingHXAssisted) {
2259 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2260 0 : ShowContinueError(state, "Illegal " + cAlphaFields(14) + " = " + Alphas(14));
2261 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted Cooling Coil.");
2262 0 : if (lAlphaBlanks(15)) {
2263 0 : ShowContinueError(state,
2264 : "Dehumidification control type is assumed to be None since a reheat coil has not been specified and "
2265 : "the simulation continues.");
2266 0 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
2267 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::None;
2268 : } else {
2269 0 : ShowContinueError(state, "Dehumidification control type is assumed to be CoolReheat and the simulation continues.");
2270 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::CoolReheat;
2271 : }
2272 : }
2273 : }
2274 181 : if (UtilityRoutines::SameString(Alphas(14), "CoolReheat")) {
2275 22 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::CoolReheat;
2276 22 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = true;
2277 22 : if (lAlphaBlanks(15)) {
2278 0 : ShowWarningError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
2279 0 : ShowContinueError(state,
2280 : "Dehumidification control type is assumed to be None since a reheat coil has not been specified and the "
2281 : "simulation continues.");
2282 0 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
2283 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::None;
2284 : }
2285 : }
2286 181 : if (UtilityRoutines::SameString(Alphas(14), "None")) {
2287 156 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::None;
2288 156 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
2289 : }
2290 181 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat) {
2291 62 : for (HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
2292 74 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum !=
2293 37 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
2294 12 : continue;
2295 25 : AirNodeFound = true;
2296 : }
2297 25 : if (!AirNodeFound) {
2298 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2299 0 : ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
2300 0 : ShowContinueError(state, "Specified " + cAlphaFields(6) + " = " + Alphas(6));
2301 0 : ErrorsFound = true;
2302 : }
2303 : }
2304 : } else { // invalid input
2305 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2306 0 : ShowContinueError(state, "Illegal " + cAlphaFields(14) + " = " + Alphas(14));
2307 0 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
2308 0 : ErrorsFound = true;
2309 : }
2310 :
2311 : // Check placement of cooling coil with respect to fan placement and dehumidification control type
2312 181 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
2313 280 : if (FanOutletNode == HeatingCoilInletNode &&
2314 102 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num != DehumidificationControlMode::CoolReheat) {
2315 102 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream = false;
2316 : }
2317 : } else {
2318 5 : if (HeatingCoilOutletNode == CoolingCoilInletNode &&
2319 2 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num != DehumidificationControlMode::CoolReheat) {
2320 2 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream = false;
2321 : }
2322 : }
2323 :
2324 : // Get reheat coil data if humidistat is used
2325 181 : ReheatingCoilType = Alphas(15);
2326 181 : ReheatingCoilName = Alphas(16);
2327 181 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType = ReheatingCoilType;
2328 181 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName = ReheatingCoilName;
2329 181 : errFlag = false;
2330 181 : if (!lAlphaBlanks(15)) {
2331 48 : if (UtilityRoutines::SameString(ReheatingCoilType, "Coil:Heating:Fuel") ||
2332 48 : UtilityRoutines::SameString(ReheatingCoilType, "Coil:Heating:Electric") ||
2333 25 : UtilityRoutines::SameString(ReheatingCoilType, "Coil:Heating:Desuperheater")) {
2334 :
2335 23 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num =
2336 23 : GetHeatingCoilTypeNum(state, ReheatingCoilType, ReheatingCoilName, errFlag);
2337 23 : if (errFlag) {
2338 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2339 0 : ErrorsFound = true;
2340 : } else {
2341 :
2342 23 : ValidateComponent(state, ReheatingCoilType, ReheatingCoilName, IsNotOK, CurrentModuleObject);
2343 23 : if (IsNotOK) {
2344 0 : ShowContinueError(state, "In " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
2345 0 : ErrorsFound = true;
2346 :
2347 : } else { // mine data from reheat coil
2348 :
2349 : // Get the heating coil index
2350 23 : GetHeatingCoilIndex(state, ReheatingCoilName, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, IsNotOK);
2351 23 : if (IsNotOK) {
2352 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2353 0 : ErrorsFound = true;
2354 : }
2355 :
2356 : // Get the design supplemental heating capacity
2357 23 : errFlag = false;
2358 23 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity =
2359 23 : GetHeatingCoilCapacity(state, ReheatingCoilType, ReheatingCoilName, errFlag);
2360 23 : if (errFlag) {
2361 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2362 0 : ErrorsFound = true;
2363 : }
2364 :
2365 : // Get the Reheat Coil Inlet Node
2366 23 : errFlag = false;
2367 23 : ReheatCoilInletNode = GetHeatingCoilInletNode(state, ReheatingCoilType, ReheatingCoilName, errFlag);
2368 23 : if (errFlag) {
2369 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
2370 0 : ErrorsFound = true;
2371 : }
2372 :
2373 : // Get the Reheat Coil Outlet Node
2374 23 : errFlag = false;
2375 23 : ReheatCoilOutletNode = GetHeatingCoilOutletNode(state, ReheatingCoilType, ReheatingCoilName, errFlag);
2376 23 : if (errFlag) {
2377 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
2378 0 : ErrorsFound = true;
2379 : }
2380 :
2381 : } // IF (IsNotOK) THEN
2382 : }
2383 :
2384 0 : } else if (UtilityRoutines::SameString(ReheatingCoilType, "Coil:Heating:Water")) {
2385 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num = Coil_HeatingWater;
2386 0 : ValidateComponent(state, ReheatingCoilType, ReheatingCoilName, IsNotOK, CurrentModuleObject);
2387 0 : if (IsNotOK) {
2388 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2389 0 : ErrorsFound = true;
2390 : } else { // mine data from heating coil object
2391 :
2392 : // Get the Heating Coil water Inlet or control Node number
2393 0 : errFlag = false;
2394 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode =
2395 0 : GetCoilWaterInletNode(state, "Coil:Heating:Water", ReheatingCoilName, errFlag);
2396 0 : if (errFlag) {
2397 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2398 0 : ErrorsFound = true;
2399 : }
2400 :
2401 : // Get the ReHeat Coil hot water max volume flow rate
2402 0 : errFlag = false;
2403 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
2404 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", ReheatingCoilName, errFlag);
2405 0 : if (errFlag) {
2406 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2407 0 : ErrorsFound = true;
2408 : }
2409 :
2410 : // Get the ReHeat Coil Inlet Node
2411 0 : errFlag = false;
2412 0 : ReheatCoilInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", ReheatingCoilName, errFlag);
2413 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirInletNode = ReheatCoilInletNode;
2414 0 : if (errFlag) {
2415 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2416 0 : ErrorsFound = true;
2417 : }
2418 :
2419 : // Get the ReHeat Coil Outlet Node
2420 0 : errFlag = false;
2421 0 : ReheatCoilOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", ReheatingCoilName, errFlag);
2422 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirOutletNode = ReheatCoilOutletNode;
2423 0 : if (errFlag) {
2424 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2425 0 : ErrorsFound = true;
2426 : }
2427 :
2428 : // check if user has also used a water coil controller, which they should not do
2429 0 : errFlag = false;
2430 0 : CheckCoilWaterInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode, errFlag);
2431 0 : if (!errFlag) { // then did find a controller so that is bad
2432 0 : ShowSevereError(state,
2433 0 : CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name +
2434 : " has a conflicting Controller:WaterCoil object");
2435 0 : ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
2436 0 : ShowContinueError(state, "No water coil controller should be input for the coil.");
2437 0 : ErrorsFound = true;
2438 : }
2439 : }
2440 :
2441 0 : } else if (UtilityRoutines::SameString(ReheatingCoilType, "Coil:Heating:Steam")) {
2442 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num = Coil_HeatingSteam;
2443 0 : ValidateComponent(state, ReheatingCoilType, ReheatingCoilName, IsNotOK, CurrentModuleObject);
2444 0 : if (IsNotOK) {
2445 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2446 0 : ErrorsFound = true;
2447 : } else { // mine data from heating coil object
2448 :
2449 0 : errFlag = false;
2450 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex =
2451 0 : GetSteamCoilIndex(state, "COIL:HEATING:STEAM", ReheatingCoilName, errFlag);
2452 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex == 0) {
2453 0 : ShowSevereError(state, CurrentModuleObject + " illegal " + cAlphaFields(11) + " = " + ReheatingCoilName);
2454 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2455 0 : ErrorsFound = true;
2456 : }
2457 :
2458 : // Get the Heating Coil steam inlet node number
2459 0 : errFlag = false;
2460 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode =
2461 0 : GetCoilSteamInletNode(state, "Coil:Heating:Steam", ReheatingCoilName, errFlag);
2462 0 : if (errFlag) {
2463 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2464 0 : ErrorsFound = true;
2465 : }
2466 :
2467 : // Get the Heating Coil steam max volume flow rate
2468 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
2469 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, errFlag);
2470 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow > 0.0) {
2471 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
2472 0 : SteamDensity = GetSatDensityRefrig(
2473 0 : state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, getAirLoopHVACHeatCoolInput);
2474 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
2475 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, errFlag) * SteamDensity;
2476 : }
2477 :
2478 : // Get the Heating Coil Inlet Node
2479 0 : errFlag = false;
2480 0 : ReheatCoilInletNode =
2481 0 : GetSteamCoilAirInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, ReheatingCoilName, errFlag);
2482 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirInletNode = ReheatCoilInletNode;
2483 0 : if (errFlag) {
2484 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2485 0 : ErrorsFound = true;
2486 : }
2487 :
2488 : // Get the Heating Coil Outlet Node
2489 0 : errFlag = false;
2490 0 : ReheatCoilOutletNode =
2491 0 : GetCoilAirOutletNode(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, ReheatingCoilName, errFlag);
2492 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirOutletNode = ReheatCoilOutletNode;
2493 0 : if (errFlag) {
2494 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
2495 0 : ErrorsFound = true;
2496 : }
2497 : }
2498 :
2499 : } else { // Illeagal heating coil
2500 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2501 0 : ShowContinueError(state, "Illegal " + cAlphaFields(15) + " = " + Alphas(15));
2502 0 : ErrorsFound = true;
2503 : } // IF (Furnace(FurnaceNum)%SuppHeatCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
2504 :
2505 : } // IF(.NOT. lAlphaBlanks(15))THEN
2506 :
2507 181 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
2508 :
2509 178 : if (FanInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
2510 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2511 0 : if (FurnaceType_Num == Furnace_HeatCool) {
2512 0 : ShowContinueError(
2513 : state, "When a blow through fan is specified, the fan inlet node name must be the same as the furnace inlet node name.");
2514 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
2515 0 : ShowContinueError(state,
2516 0 : "...Furnace inlet node name = " +
2517 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
2518 : } else {
2519 0 : ShowContinueError(
2520 : state,
2521 : "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system inlet node name.");
2522 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
2523 0 : ShowContinueError(state,
2524 0 : "...UnitarySystem inlet node name = " +
2525 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
2526 : }
2527 0 : ErrorsFound = true;
2528 : }
2529 178 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) {
2530 76 : if (FanOutletNode != CoolingCoilInletNode) {
2531 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2532 0 : ShowContinueError(
2533 : state,
2534 : "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil inlet node name.");
2535 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
2536 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
2537 0 : ErrorsFound = true;
2538 : }
2539 76 : if (CoolingCoilOutletNode != HeatingCoilInletNode) {
2540 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2541 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
2542 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
2543 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
2544 0 : ErrorsFound = true;
2545 : }
2546 177 : if ((state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
2547 130 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) ||
2548 : ReheatCoilInletNode > 0) {
2549 22 : if (HeatingCoilOutletNode != ReheatCoilInletNode) {
2550 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2551 0 : ShowContinueError(state,
2552 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
2553 : "reheat coil inlet node name.");
2554 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
2555 0 : ShowContinueError(state, "...Reheat coil inlet node name = " + state.dataLoopNodes->NodeID(ReheatCoilInletNode));
2556 0 : ErrorsFound = true;
2557 : }
2558 22 : if (ReheatCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
2559 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2560 0 : if (FurnaceType_Num == Furnace_HeatCool) {
2561 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the furnace outlet node name.");
2562 0 : ShowContinueError(state, "...Reheat coil outlet node name = " + state.dataLoopNodes->NodeID(ReheatCoilOutletNode));
2563 0 : ShowContinueError(state,
2564 0 : "...Furnace outlet node name = " +
2565 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2566 : } else {
2567 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
2568 0 : ShowContinueError(state, "...Reheat coil outlet node name = " + state.dataLoopNodes->NodeID(ReheatCoilOutletNode));
2569 0 : ShowContinueError(state,
2570 0 : "...UnitarySystem outlet node name = " +
2571 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2572 : }
2573 0 : ErrorsFound = true;
2574 : }
2575 : } else { // IF((Furnace(FurnaceNum)%Humidistat ...
2576 : // Heating coil outlet node name must be the same as the furnace outlet node name
2577 54 : if (HeatingCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
2578 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2579 0 : if (FurnaceType_Num == Furnace_HeatOnly) {
2580 0 : ShowContinueError(state,
2581 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
2582 : "furnace outlet node name.");
2583 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
2584 0 : ShowContinueError(state,
2585 0 : "...Furnace outlet node name = " +
2586 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2587 : } else {
2588 0 : ShowContinueError(state,
2589 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
2590 : "unitary system outlet node name.");
2591 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
2592 0 : ShowContinueError(state,
2593 0 : "...UnitarySystem outlet node name = " +
2594 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2595 : }
2596 0 : ErrorsFound = true;
2597 : }
2598 : }
2599 : } else { // IF(Furnace(FurnaceNum)%CoolingCoilUpstream)THEN
2600 102 : if (FanOutletNode != HeatingCoilInletNode) {
2601 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2602 0 : ShowContinueError(
2603 : state,
2604 : "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil inlet node name.");
2605 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
2606 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
2607 0 : ErrorsFound = true;
2608 : }
2609 102 : if (HeatingCoilOutletNode != CoolingCoilInletNode) {
2610 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2611 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
2612 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
2613 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
2614 0 : ErrorsFound = true;
2615 : }
2616 102 : if (CoolingCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
2617 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2618 0 : if (FurnaceType_Num == Furnace_HeatCool) {
2619 0 : ShowContinueError(state,
2620 : "When a blow through fan is specified, the cooling coil outlet node name must be the same as the "
2621 : "furnace outlet node name.");
2622 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
2623 0 : ShowContinueError(state,
2624 0 : "...Furnace outlet node name = " +
2625 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2626 : } else {
2627 0 : ShowContinueError(state,
2628 : "When a blow through fan is specified, the cooling coil outlet node name must be the same as the "
2629 : "unitary system outlet node name.");
2630 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
2631 0 : ShowContinueError(state,
2632 0 : "...UnitarySystem outlet node name = " +
2633 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2634 : }
2635 0 : ErrorsFound = true;
2636 : }
2637 : }
2638 :
2639 : } else { // ELSE from IF(Furnace(FurnaceNum)%FanPlace .EQ. BlowThru)THEN
2640 :
2641 3 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) {
2642 1 : if (CoolingCoilInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
2643 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2644 0 : if (FurnaceType_Num == Furnace_HeatCool) {
2645 0 : ShowContinueError(state,
2646 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the "
2647 : "furnace inlet node name.");
2648 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
2649 0 : ShowContinueError(state,
2650 0 : "...Furnace inlet node name = " +
2651 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
2652 : } else {
2653 0 : ShowContinueError(state,
2654 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the "
2655 : "unitary system inlet node name.");
2656 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
2657 0 : ShowContinueError(state,
2658 0 : "...UnitarySystem inlet node name = " +
2659 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
2660 : }
2661 0 : ErrorsFound = true;
2662 : }
2663 1 : if (CoolingCoilOutletNode != HeatingCoilInletNode) {
2664 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2665 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
2666 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
2667 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
2668 0 : ErrorsFound = true;
2669 : }
2670 1 : if (HeatingCoilOutletNode != FanInletNode) {
2671 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2672 0 : ShowContinueError(
2673 : state,
2674 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan inlet node name.");
2675 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
2676 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
2677 0 : ErrorsFound = true;
2678 : }
2679 2 : if ((state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
2680 2 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) ||
2681 : ReheatCoilInletNode > 0) {
2682 1 : if (FanOutletNode != ReheatCoilInletNode) {
2683 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2684 0 : ShowContinueError(state,
2685 : "When a draw through fan is specified, the fan outlet node name must be the same as the reheat coil "
2686 : "inlet node name.");
2687 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
2688 0 : ShowContinueError(state, "...Reheat coil inlet node name = " + state.dataLoopNodes->NodeID(ReheatCoilInletNode));
2689 0 : ErrorsFound = true;
2690 : }
2691 1 : if (ReheatCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
2692 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2693 0 : if (FurnaceType_Num == Furnace_HeatCool) {
2694 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the furnace outlet node name.");
2695 0 : ShowContinueError(state, "...Reheat coil outlet node name = " + state.dataLoopNodes->NodeID(ReheatCoilOutletNode));
2696 0 : ShowContinueError(state,
2697 0 : "...Furnace outlet node name = " +
2698 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2699 : } else {
2700 0 : ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
2701 0 : ShowContinueError(state, "...Reheat coil outlet node name = " + state.dataLoopNodes->NodeID(ReheatCoilOutletNode));
2702 0 : ShowContinueError(state,
2703 0 : "...UnitarySystem outlet node name = " +
2704 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2705 : }
2706 0 : ErrorsFound = true;
2707 : }
2708 : } else {
2709 0 : if (FanOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
2710 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2711 0 : ShowContinueError(state,
2712 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
2713 : "outlet node name.");
2714 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
2715 0 : ShowContinueError(state,
2716 0 : "...Unitary system outlet node name = " +
2717 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2718 0 : ErrorsFound = true;
2719 : }
2720 : }
2721 : } else { // IF(Furnace(FurnaceNum)%CoolingCoilUpstream)THEN
2722 2 : if (HeatingCoilInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
2723 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2724 0 : if (FurnaceType_Num == Furnace_HeatCool) {
2725 0 : ShowContinueError(state,
2726 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the "
2727 : "furnace inlet node name.");
2728 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
2729 0 : ShowContinueError(state,
2730 0 : "...Furnace inlet node name = " +
2731 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
2732 : } else {
2733 0 : ShowContinueError(state,
2734 : "When a draw through fan is specified, the heating coil inlet node name must be the same as the "
2735 : "unitary system inlet node name.");
2736 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
2737 0 : ShowContinueError(state,
2738 0 : "...UnitarySystem inlet node name = " +
2739 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
2740 : }
2741 0 : ErrorsFound = true;
2742 : }
2743 2 : if (HeatingCoilOutletNode != CoolingCoilInletNode) {
2744 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2745 0 : ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
2746 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
2747 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
2748 0 : ErrorsFound = true;
2749 : }
2750 2 : if (CoolingCoilOutletNode != FanInletNode) {
2751 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2752 0 : ShowContinueError(
2753 : state,
2754 : "When a draw through fan is specified, the cooling coil outlet node name must be the same as the fan inlet node name.");
2755 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
2756 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
2757 0 : ErrorsFound = true;
2758 : }
2759 2 : if (FanOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
2760 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
2761 0 : if (FurnaceType_Num == Furnace_HeatCool) {
2762 0 : ShowContinueError(
2763 : state,
2764 : "When a draw through fan is specified, the fan outlet node name must be the same as the furnace outlet node name.");
2765 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
2766 0 : ShowContinueError(state,
2767 0 : "...Furnace outlet node name = " +
2768 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2769 : } else {
2770 0 : ShowContinueError(state,
2771 : "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
2772 : "outlet node name.");
2773 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
2774 0 : ShowContinueError(state,
2775 0 : "...UnitarySystem outlet node name = " +
2776 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
2777 : }
2778 0 : ErrorsFound = true;
2779 : }
2780 : }
2781 : } // ELSE from IF(Furnace(FurnaceNum)%FanPlace .EQ. BlowThru)THEN
2782 :
2783 : // Add fan to component sets array
2784 905 : SetUpCompSets(state,
2785 : CurrentModuleObject,
2786 181 : Alphas(1),
2787 181 : Alphas(7),
2788 181 : Alphas(8),
2789 181 : state.dataLoopNodes->NodeID(FanInletNode),
2790 181 : state.dataLoopNodes->NodeID(FanOutletNode));
2791 :
2792 : // Add DX cooling coil to component sets array
2793 181 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
2794 0 : SetUpCompSets(state,
2795 : CurrentModuleObject,
2796 0 : Alphas(1),
2797 0 : Alphas(12),
2798 0 : Alphas(13) + " Cooling Coil",
2799 0 : state.dataLoopNodes->NodeID(CoolingCoilInletNode),
2800 0 : state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
2801 : } else {
2802 905 : SetUpCompSets(state,
2803 : CurrentModuleObject,
2804 181 : Alphas(1),
2805 181 : Alphas(12),
2806 181 : Alphas(13),
2807 181 : state.dataLoopNodes->NodeID(CoolingCoilInletNode),
2808 181 : state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
2809 : }
2810 :
2811 : // Add heating coil to component sets array
2812 181 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
2813 0 : SetUpCompSets(state,
2814 : CurrentModuleObject,
2815 0 : Alphas(1),
2816 0 : Alphas(10),
2817 0 : Alphas(11) + " Heating Coil",
2818 0 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
2819 0 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
2820 : } else {
2821 905 : SetUpCompSets(state,
2822 : CurrentModuleObject,
2823 181 : Alphas(1),
2824 181 : Alphas(10),
2825 181 : Alphas(11),
2826 181 : state.dataLoopNodes->NodeID(HeatingCoilInletNode),
2827 181 : state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
2828 : }
2829 :
2830 181 : if (ReheatCoilInletNode > 0) {
2831 :
2832 : // Add reheating coil to component sets array
2833 115 : SetUpCompSets(state,
2834 : CurrentModuleObject,
2835 23 : Alphas(1),
2836 23 : Alphas(15),
2837 23 : Alphas(16),
2838 23 : state.dataLoopNodes->NodeID(ReheatCoilInletNode),
2839 23 : state.dataLoopNodes->NodeID(ReheatCoilOutletNode));
2840 : }
2841 :
2842 : // Set the furnace max outlet temperature
2843 181 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp = Numbers(1);
2844 :
2845 181 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow = Numbers(2);
2846 337 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow <= 0 &&
2847 156 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow != DataSizing::AutoSize) {
2848 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2849 0 : ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(2), Numbers(2)));
2850 0 : ErrorsFound = true;
2851 : }
2852 :
2853 181 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow = Numbers(3);
2854 337 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow <= 0 &&
2855 156 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow != DataSizing::AutoSize) {
2856 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2857 0 : ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(3), Numbers(3)));
2858 0 : ErrorsFound = true;
2859 : }
2860 :
2861 181 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow = Numbers(4);
2862 335 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow < 0 &&
2863 154 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
2864 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2865 0 : ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(4), Numbers(4)));
2866 0 : ErrorsFound = true;
2867 : }
2868 :
2869 181 : if (Numbers(2) != DataSizing::AutoSize && Numbers(3) != DataSizing::AutoSize && Numbers(4) != DataSizing::AutoSize) {
2870 25 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = max(Numbers(2), Numbers(3), Numbers(4));
2871 : } else {
2872 156 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = DataSizing::AutoSize;
2873 : }
2874 :
2875 181 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
2876 4 : errFlag = false;
2877 4 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
2878 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex = GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
2879 0 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilName;
2880 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow =
2881 0 : GetCoilAirFlowRateVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
2882 : } else {
2883 4 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow =
2884 4 : GetCoilAirFlowRateVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
2885 : }
2886 :
2887 4 : if (errFlag) {
2888 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2889 0 : ErrorsFound = true;
2890 : }
2891 :
2892 4 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow =
2893 4 : min(state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow, state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow);
2894 4 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow != DataSizing::AutoSize &&
2895 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow != DataSizing::AutoSize) {
2896 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate =
2897 0 : max(state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow, state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow);
2898 : } else {
2899 4 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = DataSizing::AutoSize;
2900 : }
2901 : }
2902 :
2903 181 : if (FanVolFlowRate != DataSizing::AutoSize) {
2904 25 : if (FanVolFlowRate < state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow &&
2905 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow != DataSizing::AutoSize) {
2906 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2907 0 : ShowContinueError(
2908 : state,
2909 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
2910 : FanVolFlowRate,
2911 0 : FanName));
2912 0 : ShowContinueError(state, " The " + cNumericFields(2) + " is reset to the fan flow rate and the simulation continues.");
2913 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow = FanVolFlowRate;
2914 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = FanVolFlowRate;
2915 : }
2916 25 : if (FanVolFlowRate < state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow &&
2917 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow != DataSizing::AutoSize) {
2918 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
2919 0 : ShowContinueError(
2920 : state,
2921 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
2922 : FanVolFlowRate,
2923 0 : FanName));
2924 0 : ShowContinueError(state, " The " + cNumericFields(3) + " is reset to the fan flow rate and the simulation continues.");
2925 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow = FanVolFlowRate;
2926 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = FanVolFlowRate;
2927 : }
2928 : }
2929 :
2930 181 : if (state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr > 0) {
2931 161 : if (!CheckScheduleValueMinMax(state, state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr, ">=", 0.0, "<=", 0.0)) {
2932 : // set air flow control mode:
2933 : // UseCompressorOnFlow = operate at last cooling or heating air flow requested when compressor is off
2934 : // UseCompressorOffFlow = operate at value specified by user
2935 : // AirFlowControl only valid if fan opmode = ContFanCycComp
2936 96 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow == 0.0) {
2937 1 : state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl = AirFlowControlConstFan::UseCompressorOnFlow;
2938 : } else {
2939 95 : state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl = AirFlowControlConstFan::UseCompressorOffFlow;
2940 : }
2941 : }
2942 : }
2943 :
2944 181 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
2945 4 : errFlag = false;
2946 4 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
2947 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex = GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
2948 0 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilName;
2949 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
2950 0 : GetCoilCapacityVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
2951 : } else {
2952 4 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
2953 4 : GetCoilCapacityVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
2954 : }
2955 :
2956 4 : if (errFlag) {
2957 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
2958 0 : ErrorsFound = true;
2959 : }
2960 : }
2961 :
2962 : // Set heating convergence tolerance
2963 181 : state.dataFurnaces->Furnace(FurnaceNum).HeatingConvergenceTolerance = 0.001;
2964 :
2965 : // Set cooling convergence tolerance
2966 181 : state.dataFurnaces->Furnace(FurnaceNum).CoolingConvergenceTolerance = 0.001;
2967 :
2968 : // set minimum outdoor temperature for compressor operation
2969 181 : SetMinOATCompressor(state, FurnaceNum, cCurrentModuleObject, ErrorsFound);
2970 :
2971 : } // End of the HeatCool Furnace Loop
2972 :
2973 : // Get the data for the Unitary System HeatPump AirToAir (UnitarySystem:HeatPump:AirToAir)
2974 126 : for (HeatPumpNum = 1; HeatPumpNum <= NumHeatPump; ++HeatPumpNum) {
2975 :
2976 32 : CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:AirToAir";
2977 32 : FanInletNode = 0;
2978 32 : FanOutletNode = 0;
2979 32 : CoolingCoilInletNode = 0;
2980 32 : CoolingCoilOutletNode = 0;
2981 32 : HeatingCoilInletNode = 0;
2982 32 : HeatingCoilOutletNode = 0;
2983 32 : SupHeatCoilInletNode = 0;
2984 32 : SupHeatCoilOutletNode = 0;
2985 32 : CoolingCoilType = ' ';
2986 32 : CoolingCoilName = ' ';
2987 32 : HeatingCoilType = ' ';
2988 32 : HeatingCoilName = ' ';
2989 :
2990 32 : FurnaceNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + HeatPumpNum;
2991 32 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode.allocate(3);
2992 :
2993 32 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
2994 : CurrentModuleObject,
2995 : HeatPumpNum,
2996 : Alphas,
2997 : NumAlphas,
2998 : Numbers,
2999 : NumNumbers,
3000 : IOStatus,
3001 : lNumericBlanks,
3002 : lAlphaBlanks,
3003 : cAlphaFields,
3004 : cNumericFields);
3005 :
3006 64 : GlobalNames::VerifyUniqueInterObjectName(
3007 64 : state, state.dataFurnaces->UniqueFurnaceNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
3008 :
3009 32 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num = UnitarySys_HeatPump_AirToAir;
3010 32 : state.dataFurnaces->Furnace(FurnaceNum).Name = Alphas(1);
3011 32 : if (lAlphaBlanks(2)) {
3012 6 : state.dataFurnaces->Furnace(FurnaceNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
3013 : } else {
3014 26 : state.dataFurnaces->Furnace(FurnaceNum).SchedPtr = GetScheduleIndex(state, Alphas(2));
3015 26 : if (state.dataFurnaces->Furnace(FurnaceNum).SchedPtr == 0) {
3016 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3017 0 : ShowContinueError(state, "Illegal " + cAlphaFields(2) + " = " + Alphas(2));
3018 0 : ErrorsFound = true;
3019 : }
3020 : }
3021 :
3022 32 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum =
3023 64 : GetOnlySingleNode(state,
3024 32 : Alphas(3),
3025 : ErrorsFound,
3026 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir,
3027 32 : Alphas(1),
3028 : DataLoopNode::NodeFluidType::Air,
3029 : DataLoopNode::ConnectionType::Inlet,
3030 : NodeInputManager::CompFluidStream::Primary,
3031 32 : ObjectIsParent);
3032 :
3033 32 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum =
3034 64 : GetOnlySingleNode(state,
3035 32 : Alphas(4),
3036 : ErrorsFound,
3037 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir,
3038 32 : Alphas(1),
3039 : DataLoopNode::NodeFluidType::Air,
3040 : DataLoopNode::ConnectionType::Outlet,
3041 : NodeInputManager::CompFluidStream::Primary,
3042 32 : ObjectIsParent);
3043 :
3044 32 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
3045 :
3046 : // Get the Controlling Zone or Location of the Furnace Thermostat
3047 32 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum = UtilityRoutines::FindItemInList(Alphas(5), state.dataHeatBal->Zone);
3048 32 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum == 0) {
3049 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3050 0 : ShowContinueError(state, "Illegal " + cAlphaFields(5) + " = " + Alphas(5));
3051 0 : ErrorsFound = true;
3052 : }
3053 :
3054 : // Get the node number for the zone with the thermostat
3055 32 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum > 0) {
3056 32 : AirNodeFound = false;
3057 32 : AirLoopFound = false;
3058 32 : int ControlledZoneNum = state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum;
3059 : // Find the controlled zone number for the specified thermostat location
3060 32 : state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
3061 : // Determine if furnace is on air loop served by the thermostat location specified
3062 32 : for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
3063 32 : int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
3064 32 : if (AirLoopNumber > 0) {
3065 32 : for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
3066 59 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
3067 : ++CompNum) {
3068 177 : if (!UtilityRoutines::SameString(
3069 209 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name, Alphas(1)) ||
3070 64 : !UtilityRoutines::SameString(
3071 32 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
3072 : CurrentModuleObject))
3073 27 : continue;
3074 32 : AirLoopFound = true;
3075 32 : state.dataFurnaces->Furnace(FurnaceNum).ZoneInletNode =
3076 32 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
3077 32 : break;
3078 : }
3079 32 : if (AirLoopFound) break;
3080 : }
3081 109 : for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
3082 154 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum !=
3083 77 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
3084 45 : continue;
3085 32 : AirNodeFound = true;
3086 : }
3087 32 : for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
3088 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum !=
3089 0 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
3090 0 : continue;
3091 0 : AirNodeFound = true;
3092 : }
3093 : }
3094 32 : if (AirLoopFound) break;
3095 : }
3096 32 : if (!AirNodeFound) {
3097 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3098 0 : ShowContinueError(state, "Did not find air node (zone with thermostat).");
3099 0 : ShowContinueError(state, "Specified " + cAlphaFields(5) + " = " + Alphas(5));
3100 0 : ShowContinueError(
3101 : state, "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
3102 0 : ErrorsFound = true;
3103 : }
3104 32 : if (!AirLoopFound) {
3105 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3106 0 : ShowSevereError(state, "Did not find correct AirLoopHVAC.");
3107 0 : ShowContinueError(state, "Specified " + cAlphaFields(5) + " = " + Alphas(5));
3108 0 : ErrorsFound = true;
3109 : }
3110 : }
3111 :
3112 : // Get fan data
3113 32 : FanType = Alphas(6);
3114 32 : FanName = Alphas(7);
3115 :
3116 32 : errFlag = false;
3117 32 : GetFanType(state, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanType_Num, errFlag, CurrentModuleObject, Alphas(1));
3118 32 : if (errFlag) {
3119 0 : ErrorsFound = true;
3120 : }
3121 :
3122 32 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleOnOff ||
3123 0 : state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleConstVolume) {
3124 32 : ValidateComponent(state, FanType, FanName, IsNotOK, CurrentModuleObject);
3125 32 : if (IsNotOK) {
3126 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3127 0 : ErrorsFound = true;
3128 :
3129 : } else { // mine data from fan object
3130 :
3131 : // Get the fan index
3132 32 : errFlag = false;
3133 32 : GetFanIndex(state, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, errFlag);
3134 32 : if (errFlag) {
3135 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3136 0 : ErrorsFound = true;
3137 : }
3138 :
3139 : // Get the fan inlet node number
3140 32 : errFlag = false;
3141 32 : FanInletNode = GetFanInletNode(state, FanType, FanName, errFlag);
3142 32 : if (errFlag) {
3143 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3144 0 : ErrorsFound = true;
3145 : }
3146 :
3147 : // Get the fan outlet node number
3148 32 : errFlag = false;
3149 32 : FanOutletNode = GetFanOutletNode(state, FanType, FanName, errFlag);
3150 32 : if (errFlag) {
3151 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3152 0 : ErrorsFound = true;
3153 : }
3154 :
3155 : // Get the fan availability schedule
3156 32 : errFlag = false;
3157 32 : state.dataFurnaces->Furnace(FurnaceNum).FanAvailSchedPtr = GetFanAvailSchPtr(state, FanType, FanName, errFlag);
3158 32 : if (errFlag) {
3159 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3160 0 : ErrorsFound = true;
3161 : }
3162 :
3163 : // Get the Design Fan Volume Flow Rate
3164 32 : errFlag = false;
3165 32 : FanVolFlowRate = GetFanDesignVolumeFlowRate(state, FanType, FanName, errFlag);
3166 32 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate = FanVolFlowRate;
3167 32 : if (errFlag) {
3168 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3169 0 : ErrorsFound = true;
3170 : }
3171 :
3172 : } // IF (IsNotOK) THEN
3173 :
3174 : } else {
3175 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3176 0 : ShowContinueError(state, "Illegal " + cAlphaFields(6) + " = " + Alphas(6));
3177 0 : ErrorsFound = true;
3178 : }
3179 :
3180 : // Get heating coil type and name data
3181 32 : HeatingCoilType = Alphas(8);
3182 32 : HeatingCoilName = Alphas(9);
3183 :
3184 32 : errFlag = false;
3185 :
3186 95 : if (UtilityRoutines::SameString(HeatingCoilType, "COIL:HEATING:DX:VARIABLESPEED") ||
3187 63 : UtilityRoutines::SameString(HeatingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
3188 2 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = Coil_HeatingAirToAirVariableSpeed;
3189 2 : if (UtilityRoutines::SameString(HeatingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE"))
3190 1 : state.dataFurnaces->Furnace(FurnaceNum).bIsIHP = true;
3191 : } else {
3192 30 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = GetCoilTypeNum(state, HeatingCoilType, HeatingCoilName, errFlag);
3193 : }
3194 :
3195 32 : if (errFlag) {
3196 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3197 0 : ErrorsFound = true;
3198 : }
3199 :
3200 32 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == CoilDX_HeatingEmpirical) {
3201 30 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
3202 30 : if (IsNotOK) {
3203 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3204 0 : ErrorsFound = true;
3205 :
3206 : } else { // mine data from DX heating coil
3207 :
3208 30 : GetDXCoilIndex(state, HeatingCoilName, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, IsNotOK);
3209 30 : if (IsNotOK) {
3210 0 : ShowContinueError(state, "...occurs " + CurrentModuleObject + " = " + Alphas(1));
3211 0 : ErrorsFound = true;
3212 : }
3213 :
3214 : // Get the Heating Coil Node Names
3215 30 : errFlag = false;
3216 30 : HeatingCoilInletNode = GetDXCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
3217 30 : HeatingCoilOutletNode = GetDXCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
3218 30 : if (errFlag) {
3219 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3220 0 : ErrorsFound = true;
3221 : }
3222 :
3223 : // Get the design heating capacity
3224 30 : errFlag = false;
3225 30 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
3226 30 : GetDXCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
3227 30 : if (errFlag) {
3228 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " =" + Alphas(1));
3229 0 : ErrorsFound = true;
3230 : }
3231 :
3232 : } // IF (IsNotOK) THEN
3233 2 : } else if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingAirToAirVariableSpeed) {
3234 2 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
3235 2 : if (IsNotOK) {
3236 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3237 0 : ErrorsFound = true;
3238 : } else {
3239 2 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3240 1 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex = GetCoilIndexIHP(state, HeatingCoilType, HeatingCoilName, errFlag);
3241 1 : IHPCoilIndex = state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex;
3242 1 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(IHPCoilIndex).SHCoilName;
3243 1 : HeatingCoilInletNode = GetCoilInletNodeVariableSpeed(state, "COIL:HEATING:DX:VARIABLESPEED", IHPCoilName, errFlag);
3244 1 : HeatingCoilOutletNode = GetCoilOutletNodeVariableSpeed(state, "COIL:HEATING:DX:VARIABLESPEED", IHPCoilName, errFlag);
3245 : } else {
3246 1 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex =
3247 1 : GetCoilIndexVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
3248 1 : HeatingCoilInletNode = GetCoilInletNodeVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
3249 1 : HeatingCoilOutletNode = GetCoilOutletNodeVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
3250 : }
3251 : }
3252 : } else {
3253 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3254 0 : ShowContinueError(state, "Illegal " + cAlphaFields(8) + " = " + Alphas(8));
3255 0 : ErrorsFound = true;
3256 : }
3257 :
3258 : // Get Cooling Coil Information if available
3259 32 : CoolingCoilType = Alphas(10);
3260 32 : CoolingCoilName = Alphas(11);
3261 :
3262 95 : if (UtilityRoutines::SameString(CoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED") ||
3263 63 : UtilityRoutines::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
3264 2 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num = Coil_CoolingAirToAirVariableSpeed;
3265 2 : if (UtilityRoutines::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE"))
3266 1 : state.dataFurnaces->Furnace(FurnaceNum).bIsIHP = true;
3267 : }
3268 :
3269 32 : ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
3270 :
3271 32 : if (IsNotOK) {
3272 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3273 0 : ErrorsFound = true;
3274 :
3275 : } else { // mine data from DX cooling coil
3276 :
3277 32 : errFlag = false;
3278 32 : PrintMessage = false;
3279 :
3280 32 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num != Coil_CoolingAirToAirVariableSpeed) {
3281 30 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num =
3282 60 : GetCoilTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, PrintMessage);
3283 : }
3284 :
3285 : // If coil type not found, check to see if a HX assisted cooling coil is used.
3286 32 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == 0) {
3287 0 : errFlag = false;
3288 0 : PrintMessage = false;
3289 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num =
3290 0 : GetHXAssistedCoilTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, PrintMessage);
3291 : }
3292 :
3293 32 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingSingleSpeed) {
3294 :
3295 : // Get the cooling coil node numbers
3296 30 : errFlag = false;
3297 30 : GetDXCoilIndex(state, CoolingCoilName, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, errFlag);
3298 30 : CoolingCoilInletNode = GetDXCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
3299 30 : CoolingCoilOutletNode = GetDXCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
3300 30 : if (errFlag) {
3301 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3302 0 : ErrorsFound = true;
3303 : }
3304 :
3305 : // Get the DX cooling coil design capacity
3306 30 : errFlag = false;
3307 30 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
3308 30 : GetDXCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
3309 30 : if (errFlag) {
3310 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3311 0 : ErrorsFound = true;
3312 : }
3313 :
3314 2 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
3315 :
3316 : // Get the cooling coil node numbers
3317 0 : errFlag = false;
3318 0 : GetHXDXCoilIndex(state, CoolingCoilName, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, errFlag);
3319 0 : CoolingCoilInletNode = GetDXHXAsstdCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
3320 0 : CoolingCoilOutletNode = GetDXHXAsstdCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
3321 0 : if (errFlag) {
3322 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3323 0 : ErrorsFound = true;
3324 : }
3325 :
3326 : // Get the heat exchanger assisted cooling coil design capacity
3327 0 : errFlag = false;
3328 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
3329 0 : GetDXHXAsstdCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
3330 0 : if (errFlag) {
3331 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3332 0 : ErrorsFound = true;
3333 : }
3334 :
3335 : // get the actual index to the DX cooling coil object
3336 0 : DXCoilIndex = GetActualDXCoilIndex(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
3337 0 : state.dataFurnaces->Furnace(FurnaceNum).ActualDXCoilIndexForHXAssisted = DXCoilIndex;
3338 :
3339 2 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
3340 : // BOS ADDED, AUG/2012, VARIIABLE SPEED DX COOLING COIL
3341 : // Furnace(FurnaceNum)%DXCoolCoilType = 'COIL:COOLING:DX:VARIABLESPEED'
3342 : // Furnace(FurnaceNum)%DXCoolCoilName = CoolingCoilName
3343 2 : ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
3344 2 : if (IsNotOK) {
3345 0 : ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + Alphas(1) + "\".");
3346 0 : ErrorsFound = true;
3347 : } else {
3348 2 : errFlag = false;
3349 2 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3350 1 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex =
3351 1 : GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
3352 1 : IHPCoilName =
3353 1 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilName;
3354 : } else {
3355 1 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex =
3356 1 : GetCoilIndexVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
3357 1 : IHPCoilName = CoolingCoilName;
3358 : }
3359 :
3360 2 : if (errFlag) {
3361 0 : ShowContinueError(state, "...specified in " + CurrentModuleObject + "=\"" + Alphas(1) + "\".");
3362 0 : ErrorsFound = true;
3363 : }
3364 :
3365 2 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3366 1 : CoolingCoilInletNode = GetCoilInletNodeVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
3367 1 : CoolingCoilOutletNode = GetCoilOutletNodeVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
3368 1 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
3369 : } else {
3370 1 : CoolingCoilInletNode = GetCoilInletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
3371 1 : CoolingCoilOutletNode = GetCoilOutletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
3372 1 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
3373 : }
3374 :
3375 2 : if (errFlag) {
3376 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3377 0 : ErrorsFound = true;
3378 : }
3379 : }
3380 : } else {
3381 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3382 0 : ShowContinueError(state, "Illegal " + cAlphaFields(10) + " = " + Alphas(10));
3383 0 : ErrorsFound = true;
3384 : }
3385 : }
3386 :
3387 34 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed &&
3388 2 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingAirToAirVariableSpeed) {
3389 : // Furnace(FurnaceNum)%WatertoAirHPType = WatertoAir_VarSpeedEquationFit
3390 2 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3391 3 : SetVarSpeedCoilData(
3392 : state,
3393 1 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilIndex,
3394 : ErrorsFound,
3395 : _,
3396 1 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SHCoilIndex);
3397 : } else {
3398 3 : SetVarSpeedCoilData(state,
3399 1 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
3400 : ErrorsFound,
3401 : _,
3402 1 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex);
3403 : }
3404 : }
3405 :
3406 : // Get supplemental heating coil information
3407 32 : SuppHeatCoilType = Alphas(12);
3408 32 : SuppHeatCoilName = Alphas(13);
3409 32 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType = SuppHeatCoilType;
3410 32 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName = SuppHeatCoilName;
3411 32 : errFlag = false;
3412 73 : if (UtilityRoutines::SameString(SuppHeatCoilType, "Coil:Heating:Fuel") ||
3413 41 : UtilityRoutines::SameString(SuppHeatCoilType, "Coil:Heating:Electric")) {
3414 :
3415 31 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num =
3416 31 : GetHeatingCoilTypeNum(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
3417 31 : if (errFlag) {
3418 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3419 0 : ErrorsFound = true;
3420 : } else {
3421 31 : IsNotOK = false;
3422 31 : ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
3423 31 : if (IsNotOK) {
3424 0 : ShowContinueError(state, "In " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3425 0 : ErrorsFound = true;
3426 :
3427 : } else { // mine data from the supplemental heating coil
3428 :
3429 31 : GetHeatingCoilIndex(state, SuppHeatCoilName, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, IsNotOK);
3430 31 : if (IsNotOK) {
3431 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3432 0 : ErrorsFound = true;
3433 : }
3434 :
3435 : // Get the Supplemental Heating Coil Inlet Node Number
3436 31 : errFlag = false;
3437 31 : SupHeatCoilInletNode = GetHeatingCoilInletNode(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
3438 31 : if (errFlag) {
3439 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3440 0 : ErrorsFound = true;
3441 : }
3442 :
3443 : // Get the Supplemental Heating Coil Outlet Node Number
3444 31 : errFlag = false;
3445 31 : SupHeatCoilOutletNode = GetHeatingCoilOutletNode(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
3446 :
3447 31 : if (errFlag) {
3448 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3449 0 : ErrorsFound = true;
3450 : }
3451 :
3452 : // Get the supplemental heating coil design capacity
3453 31 : errFlag = false;
3454 31 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity =
3455 31 : GetHeatingCoilCapacity(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
3456 31 : if (errFlag) {
3457 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3458 0 : ErrorsFound = true;
3459 : }
3460 :
3461 : } // IF (IsNotOK) THEN
3462 : }
3463 1 : } else if (UtilityRoutines::SameString(SuppHeatCoilType, "Coil:Heating:Water")) {
3464 1 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num = Coil_HeatingWater;
3465 1 : ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
3466 1 : if (IsNotOK) {
3467 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3468 0 : ErrorsFound = true;
3469 : } else { // mine data from heating coil object
3470 :
3471 : // Get the Heating Coil water Inlet or control Node number
3472 1 : errFlag = false;
3473 1 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode =
3474 2 : GetCoilWaterInletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
3475 1 : if (errFlag) {
3476 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3477 0 : ErrorsFound = true;
3478 : }
3479 :
3480 : // Get the ReHeat Coil hot water max volume flow rate
3481 1 : errFlag = false;
3482 1 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
3483 2 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
3484 1 : if (errFlag) {
3485 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3486 0 : ErrorsFound = true;
3487 : }
3488 :
3489 : // Get the ReHeat Coil Inlet Node
3490 1 : errFlag = false;
3491 1 : SupHeatCoilInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
3492 1 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirInletNode = SupHeatCoilInletNode;
3493 1 : if (errFlag) {
3494 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3495 0 : ErrorsFound = true;
3496 : }
3497 :
3498 : // Get the ReHeat Coil Outlet Node
3499 1 : errFlag = false;
3500 1 : SupHeatCoilOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
3501 1 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirOutletNode = SupHeatCoilOutletNode;
3502 1 : if (errFlag) {
3503 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3504 0 : ErrorsFound = true;
3505 : }
3506 1 : errFlag = false;
3507 1 : CheckCoilWaterInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode, errFlag);
3508 1 : if (!errFlag) { // then did find a controller so that is bad
3509 0 : ShowSevereError(state,
3510 0 : CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name +
3511 : " has a conflicting Controller:WaterCoil object");
3512 0 : ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
3513 0 : ShowContinueError(state, "No water coil controller should be input for the coil.");
3514 0 : ErrorsFound = true;
3515 : }
3516 : }
3517 :
3518 0 : } else if (UtilityRoutines::SameString(SuppHeatCoilType, "Coil:Heating:Steam")) {
3519 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num = Coil_HeatingSteam;
3520 0 : ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
3521 0 : if (IsNotOK) {
3522 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3523 0 : ErrorsFound = true;
3524 : } else { // mine data from heating coil object
3525 :
3526 0 : errFlag = false;
3527 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex =
3528 0 : GetSteamCoilIndex(state, "COIL:HEATING:STEAM", SuppHeatCoilName, errFlag);
3529 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex == 0) {
3530 0 : ShowSevereError(state, CurrentModuleObject + " illegal " + cAlphaFields(12) + " = " + SuppHeatCoilName);
3531 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3532 0 : ErrorsFound = true;
3533 : }
3534 :
3535 : // Get the Heating Coil steam inlet node number
3536 0 : errFlag = false;
3537 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode =
3538 0 : GetCoilSteamInletNode(state, "Coil:Heating:Steam", SuppHeatCoilName, errFlag);
3539 0 : if (errFlag) {
3540 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3541 0 : ErrorsFound = true;
3542 : }
3543 :
3544 : // Get the Heating Coil steam max volume flow rate
3545 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
3546 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, errFlag);
3547 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow > 0.0) {
3548 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
3549 0 : SteamDensity =
3550 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, getAirLoopHVACHeatCoolInput);
3551 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
3552 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, errFlag) * SteamDensity;
3553 : }
3554 :
3555 : // Get the Heating Coil Inlet Node
3556 0 : errFlag = false;
3557 0 : SupHeatCoilInletNode =
3558 0 : GetSteamCoilAirInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, SuppHeatCoilName, errFlag);
3559 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirInletNode = SupHeatCoilInletNode;
3560 0 : if (errFlag) {
3561 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3562 0 : ErrorsFound = true;
3563 : }
3564 :
3565 : // Get the Heating Coil Outlet Node
3566 0 : errFlag = false;
3567 0 : SupHeatCoilOutletNode =
3568 0 : GetCoilAirOutletNode(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, SuppHeatCoilName, errFlag);
3569 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirOutletNode = SupHeatCoilOutletNode;
3570 0 : if (errFlag) {
3571 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3572 0 : ErrorsFound = true;
3573 : }
3574 : }
3575 :
3576 : } else {
3577 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3578 0 : ShowContinueError(state, "Illegal " + cAlphaFields(12) + " = " + Alphas(12));
3579 0 : ErrorsFound = true;
3580 : } // IF (Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
3581 :
3582 32 : if (UtilityRoutines::SameString(Alphas(14), "BlowThrough")) state.dataFurnaces->Furnace(FurnaceNum).FanPlace = BlowThru;
3583 32 : if (UtilityRoutines::SameString(Alphas(14), "DrawThrough")) state.dataFurnaces->Furnace(FurnaceNum).FanPlace = DrawThru;
3584 32 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == 0) {
3585 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3586 0 : ShowContinueError(state, "Illegal " + cAlphaFields(14) + " = " + Alphas(14));
3587 0 : ErrorsFound = true;
3588 : }
3589 :
3590 32 : state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr = GetScheduleIndex(state, Alphas(15));
3591 32 : if (!lAlphaBlanks(15) && state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr == 0) {
3592 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3593 0 : ShowContinueError(state, "Illegal " + cAlphaFields(15) + " = " + Alphas(15));
3594 0 : ErrorsFound = true;
3595 32 : } else if (lAlphaBlanks(15)) {
3596 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode = CycFanCycCoil;
3597 0 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num != FanType_SimpleOnOff) {
3598 0 : ShowSevereError(state, CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
3599 0 : ShowContinueError(state, cAlphaFields(6) + " = " + Alphas(6));
3600 0 : ShowContinueError(state, "Fan type must be Fan:OnOff when " + cAlphaFields(15) + " = Blank.");
3601 0 : ErrorsFound = true;
3602 : }
3603 : }
3604 :
3605 32 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleConstVolume) {
3606 0 : if (state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr > 0) {
3607 0 : if (!CheckScheduleValueMinMax(state, state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr, ">", 0.0, "<=", 1.0)) {
3608 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3609 0 : ShowContinueError(state, "For " + cAlphaFields(7) + " = " + Alphas(7));
3610 0 : ShowContinueError(state, "Fan operating mode must be continuous (fan operating mode schedule values > 0).");
3611 0 : ShowContinueError(state, "Error found in " + cAlphaFields(15) + " = " + Alphas(15));
3612 0 : ShowContinueError(state, "...schedule values must be (>0., <=1.)");
3613 0 : ErrorsFound = true;
3614 : }
3615 : }
3616 : }
3617 :
3618 : // Dehumidification Control Type
3619 96 : if (UtilityRoutines::SameString(Alphas(16), "None") || UtilityRoutines::SameString(Alphas(16), "Multimode") ||
3620 64 : UtilityRoutines::SameString(Alphas(16), "CoolReheat")) {
3621 3 : AirNodeFound = false;
3622 3 : if (UtilityRoutines::SameString(Alphas(16), "Multimode")) {
3623 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::Multimode;
3624 0 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = true;
3625 0 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num != CoilDX_CoolingHXAssisted) {
3626 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3627 0 : ShowContinueError(state, "Illegal " + cAlphaFields(16) + " = " + Alphas(16));
3628 0 : ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted Cooling Coil.");
3629 0 : ErrorsFound = true;
3630 : }
3631 : }
3632 3 : if (UtilityRoutines::SameString(Alphas(16), "CoolReheat")) {
3633 3 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::CoolReheat;
3634 3 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = true;
3635 : }
3636 3 : if (UtilityRoutines::SameString(Alphas(16), "None")) {
3637 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::None;
3638 0 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
3639 : }
3640 3 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat) {
3641 6 : for (HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
3642 6 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum !=
3643 3 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
3644 0 : continue;
3645 3 : AirNodeFound = true;
3646 : }
3647 3 : if (!AirNodeFound) {
3648 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3649 0 : ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
3650 0 : ShowContinueError(state, "Specified " + cAlphaFields(5) + " = " + Alphas(5));
3651 0 : ErrorsFound = true;
3652 : }
3653 : }
3654 : } else { // invalid input or blank
3655 29 : if (!lAlphaBlanks(16)) {
3656 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3657 0 : ShowContinueError(state, "Illegal " + cAlphaFields(16) + " = " + Alphas(16));
3658 0 : ErrorsFound = true;
3659 : } else {
3660 29 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
3661 29 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::None;
3662 : }
3663 : }
3664 :
3665 : // Check node names for child components
3666 32 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
3667 32 : if (FanInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
3668 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3669 0 : ShowContinueError(
3670 : state,
3671 : "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system inlet node name.");
3672 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
3673 0 : ShowContinueError(state,
3674 0 : "...Unitary system inlet node name = " +
3675 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
3676 0 : ErrorsFound = true;
3677 : }
3678 32 : if (FanOutletNode != CoolingCoilInletNode) {
3679 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3680 0 : ShowContinueError(
3681 : state,
3682 : "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil inlet node name.");
3683 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
3684 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
3685 0 : ErrorsFound = true;
3686 : }
3687 32 : if (CoolingCoilOutletNode != HeatingCoilInletNode) {
3688 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3689 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
3690 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
3691 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
3692 0 : ErrorsFound = true;
3693 : }
3694 32 : if (HeatingCoilOutletNode != SupHeatCoilInletNode) {
3695 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3696 0 : ShowContinueError(state,
3697 : "When a blow through fan is specified, the heating coil outlet node name must be the same as the supplemental "
3698 : "heating coil inlet node name.");
3699 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
3700 0 : ShowContinueError(state, "...Supplemental heating coil inlet node name = " + state.dataLoopNodes->NodeID(SupHeatCoilInletNode));
3701 0 : ErrorsFound = true;
3702 : }
3703 32 : if (SupHeatCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
3704 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3705 0 : ShowContinueError(state,
3706 : "The supplemental heating coil outlet node name must be the same as the unitary system outlet node name.");
3707 0 : ShowContinueError(state, "...Supplemental heating coil outlet node name = " + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
3708 0 : ShowContinueError(state,
3709 0 : "...Unitary system outlet node name = " +
3710 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
3711 0 : ErrorsFound = true;
3712 : }
3713 : } else {
3714 0 : if (CoolingCoilInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
3715 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3716 0 : ShowContinueError(state,
3717 : "When a draw through fan is specified, the cooling coil inlet node name must be the same as the unitary system "
3718 : "inlet node name.");
3719 0 : ShowContinueError(state, "...Cooling coil inlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
3720 0 : ShowContinueError(state,
3721 0 : "...Unitary system inlet node name = " +
3722 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
3723 0 : ErrorsFound = true;
3724 : }
3725 0 : if (CoolingCoilOutletNode != HeatingCoilInletNode) {
3726 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3727 0 : ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
3728 0 : ShowContinueError(state, "...Cooling coil outlet node name = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
3729 0 : ShowContinueError(state, "...Heating coil inlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
3730 0 : ErrorsFound = true;
3731 : }
3732 0 : if (HeatingCoilOutletNode != FanInletNode) {
3733 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3734 0 : ShowContinueError(
3735 : state,
3736 : "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan inlet node name.");
3737 0 : ShowContinueError(state, "...Heating coil outlet node name = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
3738 0 : ShowContinueError(state, "...Fan inlet node name = " + state.dataLoopNodes->NodeID(FanInletNode));
3739 0 : ErrorsFound = true;
3740 : }
3741 0 : if (FanOutletNode != SupHeatCoilInletNode) {
3742 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3743 0 : ShowContinueError(state,
3744 : "When a draw through fan is specified, the fan outlet node name must be the same as the supplemental heating "
3745 : "coil inlet node name.");
3746 0 : ShowContinueError(state, "...Fan outlet node name = " + state.dataLoopNodes->NodeID(FanOutletNode));
3747 0 : ShowContinueError(state, "...Supplemental heating coil inlet node name = " + state.dataLoopNodes->NodeID(SupHeatCoilInletNode));
3748 0 : ErrorsFound = true;
3749 : }
3750 0 : if (SupHeatCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
3751 0 : ShowSevereError(state, "For " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
3752 0 : ShowContinueError(state,
3753 : "The supplemental heating coil outlet node name must be the same as the unitary system outlet node name.");
3754 0 : ShowContinueError(state, "...Supplemental heating coil outlet node name = " + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
3755 0 : ShowContinueError(state,
3756 0 : "...Unitary system outlet node name = " +
3757 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
3758 0 : ErrorsFound = true;
3759 : }
3760 : }
3761 :
3762 : // Add component sets array
3763 32 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
3764 32 : CompSetFanInlet = Alphas(3);
3765 32 : CompSetCoolInlet = "UNDEFINED";
3766 : } else {
3767 0 : CompSetFanInlet = "UNDEFINED";
3768 0 : CompSetCoolInlet = Alphas(3);
3769 : }
3770 32 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(6), Alphas(7), CompSetFanInlet, "UNDEFINED");
3771 :
3772 : // Add DX cooling coil to component sets array
3773 32 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3774 1 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(10), Alphas(11) + " Cooling Coil", CompSetCoolInlet, "UNDEFINED");
3775 : } else {
3776 31 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(10), Alphas(11), CompSetCoolInlet, "UNDEFINED");
3777 : }
3778 : // Add DX heating coil to component sets array
3779 32 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3780 1 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(8), Alphas(9) + " Heating Coil", "UNDEFINED", "UNDEFINED");
3781 : } else {
3782 31 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(8), Alphas(9), "UNDEFINED", "UNDEFINED");
3783 : }
3784 :
3785 : // Add supplemental heating coil to component sets array
3786 32 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(12), Alphas(13), "UNDEFINED", Alphas(4));
3787 :
3788 32 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow = Numbers(1);
3789 46 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow <= 0 &&
3790 14 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow != DataSizing::AutoSize) {
3791 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3792 0 : ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(1), Numbers(1)));
3793 0 : ErrorsFound = true;
3794 : }
3795 :
3796 32 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow = Numbers(2);
3797 46 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow <= 0 &&
3798 14 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow != DataSizing::AutoSize) {
3799 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3800 0 : ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(2), Numbers(2)));
3801 0 : ErrorsFound = true;
3802 : }
3803 :
3804 32 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow = Numbers(3);
3805 43 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow < 0 &&
3806 11 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
3807 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3808 0 : ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(3), Numbers(3)));
3809 0 : ErrorsFound = true;
3810 : }
3811 :
3812 32 : if (state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr > 0) {
3813 64 : if (!CheckScheduleValueMinMax(
3814 32 : state, state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr, ">=", 0.0, "<=", 0.0)) { // Autodesk:Note Range is 0 to 0?
3815 : // set air flow control mode:
3816 : // UseCompressorOnFlow = operate at last cooling or heating air flow requested when compressor is off
3817 : // UseCompressorOffFlow = operate at value specified by user
3818 : // AirFlowControl only valid if fan opmode = ContFanCycComp
3819 15 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow == 0.0) {
3820 0 : state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl = AirFlowControlConstFan::UseCompressorOnFlow;
3821 : } else {
3822 15 : state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl = AirFlowControlConstFan::UseCompressorOffFlow;
3823 : }
3824 : }
3825 : }
3826 :
3827 32 : if (Numbers(1) != DataSizing::AutoSize && Numbers(2) != DataSizing::AutoSize && Numbers(3) != DataSizing::AutoSize) {
3828 18 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = max(Numbers(1), Numbers(2), Numbers(3));
3829 : } else {
3830 14 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = DataSizing::AutoSize;
3831 : }
3832 :
3833 32 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingAirToAirVariableSpeed) {
3834 2 : errFlag = false;
3835 :
3836 2 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3837 1 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SHCoilName;
3838 1 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow =
3839 2 : GetCoilAirFlowRateVariableSpeed(state, "COIL:HEATING:DX:VARIABLESPEED", IHPCoilName, errFlag);
3840 1 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilName;
3841 1 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow =
3842 2 : GetCoilAirFlowRateVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
3843 : } else {
3844 1 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow =
3845 1 : GetCoilAirFlowRateVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
3846 1 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow =
3847 1 : GetCoilAirFlowRateVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
3848 : }
3849 :
3850 2 : if (errFlag) {
3851 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3852 0 : ErrorsFound = true;
3853 : }
3854 :
3855 2 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow =
3856 2 : min(state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow, state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow);
3857 4 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow != DataSizing::AutoSize &&
3858 2 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow != DataSizing::AutoSize) {
3859 2 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate =
3860 2 : max(state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow, state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow);
3861 : } else {
3862 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = DataSizing::AutoSize;
3863 : }
3864 : }
3865 :
3866 32 : if (FanVolFlowRate != DataSizing::AutoSize) {
3867 18 : if (FanVolFlowRate < state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow &&
3868 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow != DataSizing::AutoSize) {
3869 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3870 0 : ShowContinueError(
3871 : state,
3872 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
3873 : FanVolFlowRate,
3874 0 : FanName));
3875 0 : ShowContinueError(state, " The " + cNumericFields(1) + " is reset to the fan flow rate and the simulation continues.");
3876 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow = FanVolFlowRate;
3877 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = FanVolFlowRate;
3878 : }
3879 18 : if (FanVolFlowRate < state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow &&
3880 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow != DataSizing::AutoSize) {
3881 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
3882 0 : ShowContinueError(
3883 : state,
3884 0 : format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
3885 : FanVolFlowRate,
3886 0 : FanName));
3887 0 : ShowContinueError(state, " The " + cNumericFields(2) + " is reset to the fan flow rate and the simulation continues.");
3888 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow = FanVolFlowRate;
3889 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = FanVolFlowRate;
3890 : }
3891 : }
3892 :
3893 : // Set heating convergence tolerance
3894 32 : state.dataFurnaces->Furnace(FurnaceNum).HeatingConvergenceTolerance = 0.001;
3895 :
3896 : // Mine heatpump outdoor condenser node from DX coil object
3897 32 : errFlag = false;
3898 32 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingSingleSpeed) {
3899 30 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum =
3900 30 : GetDXCoilCondenserInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
3901 2 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
3902 2 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3903 1 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilName;
3904 1 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
3905 : } else {
3906 1 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
3907 : }
3908 : } else {
3909 0 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = GetDXCoilCondenserInletNode(
3910 0 : state, "Coil:Cooling:DX:SingleSpeed", GetHXDXCoilName(state, CoolingCoilType, CoolingCoilName, errFlag), errFlag);
3911 : }
3912 32 : if (errFlag) {
3913 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3914 0 : ErrorsFound = true;
3915 : }
3916 :
3917 32 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingAirToAirVariableSpeed) {
3918 2 : errFlag = false;
3919 2 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3920 1 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SHCoilName;
3921 1 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
3922 2 : GetCoilCapacityVariableSpeed(state, "Coil:Heating:DX:VariableSpeed", IHPCoilName, errFlag);
3923 : } else {
3924 1 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
3925 1 : GetCoilCapacityVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
3926 : }
3927 :
3928 2 : if (errFlag) {
3929 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3930 0 : ErrorsFound = true;
3931 : }
3932 : }
3933 :
3934 32 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
3935 2 : errFlag = false;
3936 2 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
3937 1 : IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilName;
3938 1 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
3939 2 : GetCoilCapacityVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
3940 : } else {
3941 1 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
3942 1 : GetCoilCapacityVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
3943 : }
3944 :
3945 2 : if (errFlag) {
3946 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
3947 0 : ErrorsFound = true;
3948 : }
3949 : }
3950 :
3951 : // Set cooling convergence tolerance
3952 32 : state.dataFurnaces->Furnace(FurnaceNum).CoolingConvergenceTolerance = 0.001;
3953 :
3954 : // Set the furnace max outlet temperature
3955 32 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp = Numbers(4);
3956 :
3957 : // Set maximum supply air temperature for supplemental heating coil
3958 32 : state.dataFurnaces->Furnace(FurnaceNum).MaxOATSuppHeat = Numbers(5);
3959 :
3960 : // set minimum outdoor temperature for compressor operation
3961 32 : SetMinOATCompressor(state, FurnaceNum, cCurrentModuleObject, ErrorsFound);
3962 :
3963 : } // End of the Unitary System HeatPump Loop
3964 :
3965 : // Get the Input for the Water to Air Heat Pump (UnitarySystem:HeatPump:WaterToAir)
3966 233 : for (HeatPumpNum = 1; HeatPumpNum <= NumWaterToAirHeatPump; ++HeatPumpNum) {
3967 :
3968 139 : CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:WaterToAir";
3969 139 : FanInletNode = 0;
3970 139 : FanOutletNode = 0;
3971 139 : CoolingCoilInletNode = 0;
3972 139 : CoolingCoilOutletNode = 0;
3973 139 : HeatingCoilInletNode = 0;
3974 139 : HeatingCoilOutletNode = 0;
3975 139 : SupHeatCoilInletNode = 0;
3976 139 : SupHeatCoilOutletNode = 0;
3977 139 : CoolingCoilType = ' ';
3978 139 : CoolingCoilName = ' ';
3979 139 : HeatingCoilType = ' ';
3980 139 : HeatingCoilName = ' ';
3981 :
3982 139 : FurnaceNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + NumHeatPump + HeatPumpNum;
3983 139 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode.allocate(3);
3984 :
3985 139 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3986 : CurrentModuleObject,
3987 : HeatPumpNum,
3988 : Alphas,
3989 : NumAlphas,
3990 : Numbers,
3991 : NumNumbers,
3992 : IOStatus,
3993 : lNumericBlanks,
3994 : lAlphaBlanks,
3995 : cAlphaFields,
3996 : cNumericFields);
3997 :
3998 278 : GlobalNames::VerifyUniqueInterObjectName(
3999 278 : state, state.dataFurnaces->UniqueFurnaceNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
4000 :
4001 139 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num = UnitarySys_HeatPump_WaterToAir;
4002 139 : state.dataFurnaces->Furnace(FurnaceNum).Name = Alphas(1);
4003 139 : if (lAlphaBlanks(2)) {
4004 0 : state.dataFurnaces->Furnace(FurnaceNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
4005 : } else {
4006 139 : state.dataFurnaces->Furnace(FurnaceNum).SchedPtr = GetScheduleIndex(state, Alphas(2));
4007 139 : if (state.dataFurnaces->Furnace(FurnaceNum).SchedPtr == 0) {
4008 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4009 0 : ShowContinueError(state, "Illegal " + cAlphaFields(2) + " = " + Alphas(2));
4010 0 : ErrorsFound = true;
4011 : }
4012 : }
4013 :
4014 139 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum =
4015 278 : GetOnlySingleNode(state,
4016 139 : Alphas(3),
4017 : ErrorsFound,
4018 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpWaterToAir,
4019 139 : Alphas(1),
4020 : DataLoopNode::NodeFluidType::Air,
4021 : DataLoopNode::ConnectionType::Inlet,
4022 : NodeInputManager::CompFluidStream::Primary,
4023 139 : ObjectIsParent);
4024 :
4025 139 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum =
4026 278 : GetOnlySingleNode(state,
4027 139 : Alphas(4),
4028 : ErrorsFound,
4029 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpWaterToAir,
4030 139 : Alphas(1),
4031 : DataLoopNode::NodeFluidType::Air,
4032 : DataLoopNode::ConnectionType::Outlet,
4033 : NodeInputManager::CompFluidStream::Primary,
4034 139 : ObjectIsParent);
4035 :
4036 139 : TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
4037 :
4038 : // Get the Controlling Zone or Location of the Furnace Thermostat
4039 139 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum = UtilityRoutines::FindItemInList(Alphas(5), state.dataHeatBal->Zone);
4040 139 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum == 0) {
4041 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4042 0 : ShowContinueError(state, "Illegal " + cAlphaFields(5) + " = " + Alphas(5));
4043 0 : ErrorsFound = true;
4044 : }
4045 :
4046 : // Get the node number for the zone with the thermostat
4047 139 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum > 0) {
4048 139 : AirNodeFound = false;
4049 139 : AirLoopFound = false;
4050 139 : int ControlledZoneNum = state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum;
4051 : // Find the controlled zone number for the specified thermostat location
4052 139 : state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
4053 : // Determine if furnace is on air loop served by the thermostat location specified
4054 139 : for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
4055 139 : int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
4056 139 : if (AirLoopNumber > 0) {
4057 139 : for (BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
4058 268 : for (CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
4059 : ++CompNum) {
4060 804 : if (!UtilityRoutines::SameString(
4061 943 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name, Alphas(1)) ||
4062 278 : !UtilityRoutines::SameString(
4063 139 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
4064 : CurrentModuleObject))
4065 129 : continue;
4066 139 : AirLoopFound = true;
4067 139 : state.dataFurnaces->Furnace(FurnaceNum).ZoneInletNode =
4068 139 : state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
4069 139 : break;
4070 : }
4071 139 : if (AirLoopFound) break;
4072 : }
4073 7066 : for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
4074 13854 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum !=
4075 6927 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
4076 6788 : continue;
4077 139 : AirNodeFound = true;
4078 : }
4079 139 : for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
4080 0 : if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum !=
4081 0 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
4082 0 : continue;
4083 0 : AirNodeFound = true;
4084 : }
4085 : }
4086 139 : if (AirLoopFound) break;
4087 : }
4088 139 : if (!AirNodeFound) {
4089 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4090 0 : ShowContinueError(state, "Did not find air node (zone with thermostat).");
4091 0 : ShowContinueError(state, "Specified " + cAlphaFields(5) + " = " + Alphas(5));
4092 0 : ShowContinueError(
4093 : state, "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
4094 0 : ErrorsFound = true;
4095 : }
4096 139 : if (!AirLoopFound) {
4097 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4098 0 : ShowSevereError(state, "Did not find correct AirLoopHVAC.");
4099 0 : ShowContinueError(state, "Specified " + cAlphaFields(5) + " = " + Alphas(5));
4100 0 : ErrorsFound = true;
4101 : }
4102 : }
4103 :
4104 : // Get fan data
4105 139 : FanType = Alphas(6);
4106 139 : FanName = Alphas(7);
4107 139 : errFlag = false;
4108 139 : GetFanType(state, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanType_Num, errFlag, CurrentModuleObject, Alphas(1));
4109 139 : if (errFlag) {
4110 0 : ErrorsFound = true;
4111 : }
4112 :
4113 139 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleOnOff) {
4114 139 : ValidateComponent(state, FanType, FanName, IsNotOK, CurrentModuleObject);
4115 139 : if (IsNotOK) {
4116 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4117 0 : ErrorsFound = true;
4118 : } else {
4119 139 : errFlag = false;
4120 139 : GetFanIndex(state, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, errFlag);
4121 139 : if (errFlag) {
4122 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4123 0 : ErrorsFound = true;
4124 : }
4125 139 : errFlag = false;
4126 139 : FanInletNode = GetFanInletNode(state, FanType, FanName, errFlag);
4127 139 : if (errFlag) {
4128 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4129 0 : ErrorsFound = true;
4130 : }
4131 139 : errFlag = false;
4132 139 : FanOutletNode = GetFanOutletNode(state, FanType, FanName, errFlag);
4133 139 : if (errFlag) {
4134 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4135 0 : ErrorsFound = true;
4136 : }
4137 139 : errFlag = false;
4138 139 : state.dataFurnaces->Furnace(FurnaceNum).FanAvailSchedPtr = GetFanAvailSchPtr(state, FanType, FanName, errFlag);
4139 139 : if (errFlag) {
4140 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4141 0 : ErrorsFound = true;
4142 : }
4143 : }
4144 : } else {
4145 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4146 0 : ShowContinueError(state, "Illegal " + cAlphaFields(6) + " = " + Alphas(6));
4147 0 : ErrorsFound = true;
4148 : }
4149 :
4150 : // Get heating coil type and name data
4151 139 : if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION") {
4152 14 : HeatingCoilType = Alphas(8);
4153 14 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = Coil_HeatingWaterToAirHP;
4154 14 : HeatingCoilName = Alphas(9);
4155 14 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
4156 14 : if (IsNotOK) {
4157 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4158 0 : ErrorsFound = true;
4159 : } else {
4160 14 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex = GetWtoAHPCoilIndex(state, HeatingCoilType, HeatingCoilName, errFlag);
4161 14 : HeatingCoilInletNode = GetWtoAHPCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
4162 14 : HeatingCoilOutletNode = GetWtoAHPCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
4163 : }
4164 125 : } else if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
4165 111 : HeatingCoilType = Alphas(8);
4166 111 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = Coil_HeatingWaterToAirHPSimple;
4167 111 : HeatingCoilName = Alphas(9);
4168 111 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
4169 111 : if (IsNotOK) {
4170 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4171 0 : ErrorsFound = true;
4172 : } else {
4173 111 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex =
4174 111 : GetWtoAHPSimpleCoilIndex(state, HeatingCoilType, HeatingCoilName, errFlag);
4175 111 : HeatingCoilInletNode = GetWtoAHPSimpleCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
4176 111 : HeatingCoilOutletNode = GetWtoAHPSimpleCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
4177 : }
4178 14 : } else if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
4179 14 : HeatingCoilType = Alphas(8);
4180 14 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num = Coil_HeatingWaterToAirHPVSEquationFit;
4181 14 : HeatingCoilName = Alphas(9);
4182 14 : ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
4183 14 : if (IsNotOK) {
4184 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4185 0 : ErrorsFound = true;
4186 : } else {
4187 14 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex =
4188 14 : GetCoilIndexVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
4189 14 : HeatingCoilInletNode = GetCoilInletNodeVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
4190 14 : HeatingCoilOutletNode = GetCoilOutletNodeVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
4191 : }
4192 : } else {
4193 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4194 0 : ShowContinueError(state, "Illegal " + cAlphaFields(8) + " = " + Alphas(8));
4195 0 : ErrorsFound = true;
4196 : }
4197 :
4198 : // Get Cooling Coil Information if available
4199 139 : if (Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION") {
4200 14 : CoolingCoilType = Alphas(10);
4201 14 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num = Coil_CoolingWaterToAirHP;
4202 14 : CoolingCoilName = Alphas(11);
4203 14 : ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
4204 14 : if (IsNotOK) {
4205 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4206 0 : ErrorsFound = true;
4207 : } else {
4208 14 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex = GetWtoAHPCoilIndex(state, CoolingCoilType, CoolingCoilName, errFlag);
4209 14 : CoolingCoilInletNode = GetWtoAHPCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
4210 14 : CoolingCoilOutletNode = GetWtoAHPCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
4211 : }
4212 125 : } else if (Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
4213 111 : CoolingCoilType = Alphas(10);
4214 111 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num = Coil_CoolingWaterToAirHPSimple;
4215 111 : CoolingCoilName = Alphas(11);
4216 111 : ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
4217 111 : if (IsNotOK) {
4218 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4219 0 : ErrorsFound = true;
4220 : } else {
4221 111 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex =
4222 111 : GetWtoAHPSimpleCoilIndex(state, CoolingCoilType, CoolingCoilName, errFlag);
4223 111 : CoolingCoilInletNode = GetWtoAHPSimpleCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
4224 111 : CoolingCoilOutletNode = GetWtoAHPSimpleCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
4225 : }
4226 14 : } else if (Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
4227 14 : CoolingCoilType = Alphas(10);
4228 14 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num = Coil_CoolingWaterToAirHPVSEquationFit;
4229 14 : CoolingCoilName = Alphas(11);
4230 14 : ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
4231 14 : if (IsNotOK) {
4232 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4233 0 : ErrorsFound = true;
4234 : } else {
4235 14 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex =
4236 14 : GetCoilIndexVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
4237 14 : CoolingCoilInletNode = GetCoilInletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
4238 14 : CoolingCoilOutletNode = GetCoilOutletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
4239 : }
4240 : } else {
4241 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4242 0 : ShowContinueError(state, "Illegal " + cAlphaFields(10) + " = " + Alphas(10));
4243 0 : ErrorsFound = true;
4244 : }
4245 :
4246 139 : if (NumAlphas >= 18) {
4247 : // get water flow mode info before CALL SetSimpleWSHPData
4248 0 : if (UtilityRoutines::SameString(Alphas(18), "Constant")) state.dataFurnaces->Furnace(FurnaceNum).WaterCyclingMode = WaterConstant;
4249 0 : if (UtilityRoutines::SameString(Alphas(18), "Cycling")) state.dataFurnaces->Furnace(FurnaceNum).WaterCyclingMode = WaterCycling;
4250 0 : if (UtilityRoutines::SameString(Alphas(18), "ConstantOnDemand"))
4251 0 : state.dataFurnaces->Furnace(FurnaceNum).WaterCyclingMode = WaterConstantOnDemand;
4252 : // default to draw through if not specified in input
4253 0 : if (lAlphaBlanks(18)) state.dataFurnaces->Furnace(FurnaceNum).WaterCyclingMode = WaterCycling;
4254 : } else {
4255 139 : state.dataFurnaces->Furnace(FurnaceNum).WaterCyclingMode = WaterCycling;
4256 : }
4257 139 : if (state.dataFurnaces->Furnace(FurnaceNum).WaterCyclingMode == 0) {
4258 0 : ShowSevereError(state, CurrentModuleObject + " illegal " + cAlphaFields(18) + " = " + Alphas(18));
4259 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4260 0 : ErrorsFound = true;
4261 : }
4262 :
4263 : // end get water flow mode info
4264 139 : if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT" && Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
4265 111 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType = WatertoAir_Simple;
4266 333 : SetSimpleWSHPData(state,
4267 111 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
4268 : ErrorsFound,
4269 111 : state.dataFurnaces->Furnace(FurnaceNum).WaterCyclingMode,
4270 : _,
4271 111 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex);
4272 42 : } else if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION" &&
4273 14 : Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION") {
4274 14 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType = WatertoAir_ParEst;
4275 28 : } else if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT" &&
4276 14 : Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
4277 14 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType = WatertoAir_VarSpeedEquationFit;
4278 42 : SetVarSpeedCoilData(state,
4279 14 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
4280 : ErrorsFound,
4281 : _,
4282 14 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex);
4283 : } else {
4284 0 : ShowContinueError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
4285 0 : ShowContinueError(state, "Cooling coil and heating coil should be of same general type");
4286 0 : ErrorsFound = true;
4287 : }
4288 :
4289 : // Get supplemental heating coil information
4290 :
4291 139 : SuppHeatCoilType = Alphas(12);
4292 139 : SuppHeatCoilName = Alphas(13);
4293 139 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType = SuppHeatCoilType;
4294 139 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName = SuppHeatCoilName;
4295 139 : errFlag = false;
4296 374 : if (UtilityRoutines::SameString(SuppHeatCoilType, "Coil:Heating:Fuel") ||
4297 235 : UtilityRoutines::SameString(SuppHeatCoilType, "Coil:Heating:Electric")) {
4298 :
4299 139 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num =
4300 139 : GetHeatingCoilTypeNum(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
4301 139 : if (errFlag) {
4302 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4303 0 : ErrorsFound = true;
4304 : } else {
4305 139 : IsNotOK = false;
4306 139 : ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
4307 139 : if (IsNotOK) {
4308 0 : ShowContinueError(state, "In " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
4309 0 : ErrorsFound = true;
4310 :
4311 : } else { // mine data from the supplemental heating coil
4312 :
4313 139 : GetHeatingCoilIndex(state, SuppHeatCoilName, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, IsNotOK);
4314 139 : if (IsNotOK) {
4315 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4316 0 : ErrorsFound = true;
4317 : }
4318 :
4319 : // Get the Supplemental Heating Coil Inlet Node Number
4320 139 : errFlag = false;
4321 139 : SupHeatCoilInletNode = GetHeatingCoilInletNode(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
4322 139 : if (errFlag) {
4323 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " \"" + Alphas(1) + "\"");
4324 0 : ErrorsFound = true;
4325 : }
4326 :
4327 : // Get the Supplemental Heating Coil Outlet Node Number
4328 139 : errFlag = false;
4329 139 : SupHeatCoilOutletNode = GetHeatingCoilOutletNode(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
4330 139 : if (errFlag) {
4331 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4332 0 : ErrorsFound = true;
4333 : }
4334 :
4335 : // Get the supplemental heating coil design capacity
4336 139 : errFlag = false;
4337 139 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity =
4338 139 : GetHeatingCoilCapacity(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
4339 139 : if (errFlag) {
4340 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4341 0 : ErrorsFound = true;
4342 : }
4343 :
4344 : } // IF (IsNotOK) THEN
4345 : }
4346 0 : } else if (UtilityRoutines::SameString(SuppHeatCoilType, "Coil:Heating:Water")) {
4347 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num = Coil_HeatingWater;
4348 0 : ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
4349 0 : if (IsNotOK) {
4350 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4351 0 : ErrorsFound = true;
4352 : } else { // mine data from heating coil object
4353 :
4354 : // Get the Heating Coil water Inlet or control Node number
4355 0 : errFlag = false;
4356 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode =
4357 0 : GetCoilWaterInletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
4358 0 : if (errFlag) {
4359 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4360 0 : ErrorsFound = true;
4361 : }
4362 :
4363 : // Get the ReHeat Coil hot water max volume flow rate
4364 0 : errFlag = false;
4365 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
4366 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
4367 0 : if (errFlag) {
4368 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4369 0 : ErrorsFound = true;
4370 : }
4371 :
4372 : // Get the ReHeat Coil Inlet Node
4373 0 : errFlag = false;
4374 0 : SupHeatCoilInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
4375 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirInletNode = SupHeatCoilInletNode;
4376 0 : if (errFlag) {
4377 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4378 0 : ErrorsFound = true;
4379 : }
4380 :
4381 : // Get the ReHeat Coil Outlet Node
4382 0 : errFlag = false;
4383 0 : SupHeatCoilOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
4384 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirOutletNode = SupHeatCoilOutletNode;
4385 0 : if (errFlag) {
4386 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4387 0 : ErrorsFound = true;
4388 : }
4389 :
4390 0 : errFlag = false;
4391 0 : CheckCoilWaterInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode, errFlag);
4392 0 : if (!errFlag) { // then did find a controller so that is bad
4393 0 : ShowSevereError(state,
4394 0 : CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name +
4395 : " has a conflicting Controller:WaterCoil object");
4396 0 : ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
4397 0 : ShowContinueError(state, "No water coil controller should be input for the coil.");
4398 0 : ErrorsFound = true;
4399 : }
4400 : }
4401 :
4402 0 : } else if (UtilityRoutines::SameString(SuppHeatCoilType, "Coil:Heating:Steam")) {
4403 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num = Coil_HeatingSteam;
4404 0 : ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
4405 0 : if (IsNotOK) {
4406 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4407 0 : ErrorsFound = true;
4408 : } else { // mine data from heating coil object
4409 :
4410 0 : errFlag = false;
4411 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex = GetSteamCoilIndex(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
4412 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex == 0) {
4413 0 : ShowSevereError(state, CurrentModuleObject + " illegal " + cAlphaFields(12) + " = " + SuppHeatCoilName);
4414 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4415 0 : ErrorsFound = true;
4416 : }
4417 :
4418 : // Get the Heating Coil steam inlet node number
4419 0 : errFlag = false;
4420 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode =
4421 0 : GetCoilSteamInletNode(state, "Coil:Heating:Steam", SuppHeatCoilName, errFlag);
4422 0 : if (errFlag) {
4423 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4424 0 : ErrorsFound = true;
4425 : }
4426 :
4427 : // Get the Heating Coil steam max volume flow rate
4428 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
4429 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, errFlag);
4430 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow > 0.0) {
4431 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
4432 0 : SteamDensity =
4433 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, getAirLoopHVACHeatCoolInput);
4434 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
4435 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, errFlag) * SteamDensity;
4436 : }
4437 :
4438 : // Get the Heating Coil Inlet Node
4439 0 : errFlag = false;
4440 0 : SupHeatCoilInletNode =
4441 0 : GetSteamCoilAirInletNode(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, SuppHeatCoilName, errFlag);
4442 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirInletNode = SupHeatCoilInletNode;
4443 0 : if (errFlag) {
4444 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4445 0 : ErrorsFound = true;
4446 : }
4447 :
4448 : // Get the Heating Coil Outlet Node
4449 0 : errFlag = false;
4450 0 : SupHeatCoilOutletNode =
4451 0 : GetCoilAirOutletNode(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, SuppHeatCoilName, errFlag);
4452 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirOutletNode = SupHeatCoilOutletNode;
4453 0 : if (errFlag) {
4454 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4455 0 : ErrorsFound = true;
4456 : }
4457 : }
4458 :
4459 : } else {
4460 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4461 0 : ShowContinueError(state, "Illegal " + cAlphaFields(12) + " = " + Alphas(12));
4462 0 : ErrorsFound = true;
4463 : } // IF (Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
4464 :
4465 139 : if (lAlphaBlanks(14)) {
4466 0 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum = 0;
4467 : } else {
4468 139 : state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum =
4469 278 : GetOnlySingleNode(state,
4470 139 : Alphas(14),
4471 : ErrorsFound,
4472 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpWaterToAir,
4473 139 : Alphas(1),
4474 : DataLoopNode::NodeFluidType::Air,
4475 : DataLoopNode::ConnectionType::OutsideAirReference,
4476 : NodeInputManager::CompFluidStream::Primary,
4477 139 : ObjectIsNotParent);
4478 : // need better verification.
4479 139 : if (!CheckOutAirNodeNumber(state, state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum)) {
4480 0 : ShowSevereError(state, "For " + CurrentModuleObject + " = " + Alphas(1));
4481 0 : ShowContinueError(state, " Node name of outdoor dry-bulb temperature sensor not valid outdoor air node= " + Alphas(14));
4482 0 : ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
4483 0 : ErrorsFound = true;
4484 : }
4485 : }
4486 :
4487 139 : if (UtilityRoutines::SameString(Alphas(15), "BlowThrough")) state.dataFurnaces->Furnace(FurnaceNum).FanPlace = BlowThru;
4488 139 : if (UtilityRoutines::SameString(Alphas(15), "DrawThrough")) state.dataFurnaces->Furnace(FurnaceNum).FanPlace = DrawThru;
4489 139 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == 0) {
4490 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4491 0 : ShowContinueError(state, "Illegal " + cAlphaFields(15) + " = " + Alphas(15));
4492 0 : ErrorsFound = true;
4493 : }
4494 :
4495 139 : state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr = GetScheduleIndex(state, Alphas(16));
4496 139 : if (!lAlphaBlanks(16) && state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr == 0) {
4497 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4498 0 : ShowContinueError(state, "Illegal " + cAlphaFields(16) + " = " + Alphas(16));
4499 0 : ErrorsFound = true;
4500 139 : } else if (lAlphaBlanks(16)) {
4501 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode = CycFanCycCoil;
4502 0 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num != FanType_SimpleOnOff) {
4503 0 : ShowSevereError(state, CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
4504 0 : ShowContinueError(state, cAlphaFields(6) + " = " + Alphas(6));
4505 0 : ShowContinueError(state, "Fan type must be Fan:OnOff when " + cAlphaFields(16) + " = Blank.");
4506 0 : ErrorsFound = true;
4507 : }
4508 : }
4509 :
4510 : // add the Dehumidification Type
4511 139 : if (UtilityRoutines::SameString(Alphas(17), "None") || UtilityRoutines::SameString(Alphas(17), "CoolReheat")) {
4512 10 : AirNodeFound = false;
4513 10 : if (UtilityRoutines::SameString(Alphas(17), "CoolReheat")) {
4514 10 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::CoolReheat;
4515 10 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = true;
4516 10 : if (lAlphaBlanks(17)) {
4517 0 : ShowWarningError(state, CurrentModuleObject + " \"" + Alphas(1) + "\"");
4518 0 : ShowContinueError(state,
4519 : "Dehumidification control type is assumed to be None since a supplemental reheat coil has not been "
4520 : "specified and the simulation continues.");
4521 0 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
4522 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::None;
4523 : }
4524 : }
4525 10 : if (UtilityRoutines::SameString(Alphas(17), "None")) {
4526 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::None;
4527 0 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
4528 : }
4529 10 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat) {
4530 60 : for (HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
4531 100 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum !=
4532 50 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
4533 40 : continue;
4534 10 : AirNodeFound = true;
4535 : }
4536 10 : if (!AirNodeFound) {
4537 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4538 0 : ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
4539 0 : ShowContinueError(state, "Specified " + cAlphaFields(5) + " = " + Alphas(5));
4540 0 : ErrorsFound = true;
4541 : }
4542 : }
4543 : } else { // invalid input or blank
4544 129 : if (!lAlphaBlanks(17)) {
4545 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
4546 0 : ShowContinueError(state, "Illegal " + cAlphaFields(17) + " = " + Alphas(17));
4547 0 : ErrorsFound = true;
4548 : } else {
4549 129 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat = false;
4550 129 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num = DehumidificationControlMode::None;
4551 : }
4552 : }
4553 :
4554 : // Add fan to component sets array
4555 :
4556 139 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
4557 139 : CompSetFanInlet = Alphas(3);
4558 139 : CompSetCoolInlet = "UNDEFINED";
4559 139 : if (FanInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
4560 0 : ShowSevereError(
4561 0 : state, "For " + CurrentModuleObject + " = " + Alphas(1) + ", Mismatch between unitary system inlet node and fan inlet node.");
4562 0 : ShowContinueError(state, "..For \"BlowThrough\" fan, the inlet node name for the HeatPump should match the fan inlet node name.");
4563 0 : ShowContinueError(
4564 0 : state, "..HeatPump Inlet Node = " + state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
4565 0 : ShowContinueError(state, "..Fan Inlet Node = " + state.dataLoopNodes->NodeID(FanInletNode));
4566 0 : ErrorsFound = true;
4567 : }
4568 139 : if (FanOutletNode != CoolingCoilInletNode) {
4569 0 : ShowSevereError(
4570 0 : state, "For " + CurrentModuleObject + " = " + Alphas(1) + ", Mismatch between fan outlet node and cooling coil inlet node.");
4571 0 : ShowContinueError(state, "..For \"BlowThrough\" fan, the fan outlet node name must match the cooling coil inlet node name.");
4572 0 : ShowContinueError(state, "..Fan outlet node = " + state.dataLoopNodes->NodeID(FanOutletNode));
4573 0 : ShowContinueError(state, "..Cooling coil inlet node = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
4574 0 : ErrorsFound = true;
4575 : }
4576 139 : if (CoolingCoilOutletNode != HeatingCoilInletNode) {
4577 0 : ShowSevereError(state,
4578 0 : "For " + CurrentModuleObject + " = " + Alphas(1) +
4579 : ", Mismatch between cooling coil outlet node and heating coil inlet node.");
4580 0 : ShowContinueError(state, "..The cooling coil outlet node name must match the heating coil inlet node name.");
4581 0 : ShowContinueError(state, "..Cooling coil outlet node = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
4582 0 : ShowContinueError(state, "..Heating coil inlet node = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
4583 0 : ErrorsFound = true;
4584 : }
4585 139 : if (HeatingCoilOutletNode != SupHeatCoilInletNode) {
4586 0 : ShowSevereError(state,
4587 0 : "For " + CurrentModuleObject + " = " + Alphas(1) +
4588 : ", Mismatch between heating coil outlet node and supplemental heating coil inlet node.");
4589 0 : ShowContinueError(
4590 : state,
4591 : "..For \"BlowThrough\" fan, the heating coil outlet node name must match the supplemental heating coil inlet node name.");
4592 0 : ShowContinueError(state, "..Heating coil outlet node = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
4593 0 : ShowContinueError(state, "..Supplemental heating coil inlet node = " + state.dataLoopNodes->NodeID(SupHeatCoilInletNode));
4594 0 : ErrorsFound = true;
4595 : }
4596 139 : if (SupHeatCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
4597 0 : ShowSevereError(state,
4598 0 : "For " + CurrentModuleObject + " = " + Alphas(1) +
4599 : ", Mismatch between supplemental heating coil outlet node and HeatPump outlet node.");
4600 0 : ShowContinueError(state, "..The supplemental heating coil outlet node name must match the HeatPump outlet node name.");
4601 0 : ShowContinueError(state, "..Supplemental heating coil outlet node = " + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
4602 0 : ShowContinueError(state,
4603 0 : "..HeatPump outlet node = " +
4604 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
4605 0 : ErrorsFound = true;
4606 : }
4607 : } else {
4608 0 : CompSetFanInlet = "UNDEFINED";
4609 0 : CompSetCoolInlet = Alphas(3);
4610 0 : if (CoolingCoilInletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum) {
4611 0 : ShowSevereError(state,
4612 0 : "For " + CurrentModuleObject + " = " + Alphas(1) +
4613 : ", Mismatch between unitary system inlet node and cooling coil inlet node.");
4614 0 : ShowContinueError(
4615 : state, "..For \"DrawThrough\" fan, the inlet node name for the HeatPump should match the cooling coil inlet node name.");
4616 0 : ShowContinueError(state,
4617 0 : "..HeatPump inlet node = " +
4618 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum));
4619 0 : ShowContinueError(state, "..Cooling coil inlet node = " + state.dataLoopNodes->NodeID(CoolingCoilInletNode));
4620 0 : ErrorsFound = true;
4621 : }
4622 0 : if (CoolingCoilOutletNode != HeatingCoilInletNode) {
4623 0 : ShowSevereError(state,
4624 0 : "For " + CurrentModuleObject + " = " + Alphas(1) +
4625 : ", Mismatch between cooling coil outlet node and heating coil inlet node.");
4626 0 : ShowContinueError(state, "..The outlet node name for the cooling coil should match the heating coil inlet node name.");
4627 0 : ShowContinueError(state, "..Cooling coil outlet node = " + state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
4628 0 : ShowContinueError(state, "..Heating coil inlet node = " + state.dataLoopNodes->NodeID(HeatingCoilInletNode));
4629 0 : ErrorsFound = true;
4630 : }
4631 0 : if (HeatingCoilOutletNode != FanInletNode) {
4632 0 : ShowSevereError(
4633 0 : state, "For " + CurrentModuleObject + " = " + Alphas(1) + ", Mismatch between heating coil outlet node and fan inlet node.");
4634 0 : ShowContinueError(state,
4635 : "..For \"DrawThrough\" fan, the outlet node name for the heating coil should match the fan inlet node name.");
4636 0 : ShowContinueError(state, "..Heating coil outlet node = " + state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
4637 0 : ShowContinueError(state, "..Fan inlet node = " + state.dataLoopNodes->NodeID(FanInletNode));
4638 0 : ErrorsFound = true;
4639 : }
4640 0 : if (FanOutletNode != SupHeatCoilInletNode) {
4641 0 : ShowSevereError(state,
4642 0 : "For " + CurrentModuleObject + " = " + Alphas(1) +
4643 : ", Mismatch between fan outlet node and supplemental heating coil inlet node.");
4644 0 : ShowContinueError(
4645 : state,
4646 : "..For \"DrawThrough\" fan, the outlet node name for the fan should match the supplemental heating coil inlet node name.");
4647 0 : ShowContinueError(state, "..Fan outlet node = " + state.dataLoopNodes->NodeID(FanOutletNode));
4648 0 : ShowContinueError(state, "..Supplemental heating coil inlet node = " + state.dataLoopNodes->NodeID(SupHeatCoilInletNode));
4649 0 : ErrorsFound = true;
4650 : }
4651 0 : if (SupHeatCoilOutletNode != state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum) {
4652 0 : ShowSevereError(state,
4653 0 : "For " + CurrentModuleObject + " = " + Alphas(1) +
4654 : ", Mismatch between supplemental heating coil outlet node and HeatPump outlet node.");
4655 0 : ShowContinueError(state, "..The supplemental heating coil outlet node name must match the HeatPump outlet node name.");
4656 0 : ShowContinueError(state, "..Supplemental heating coil outlet node = " + state.dataLoopNodes->NodeID(SupHeatCoilOutletNode));
4657 0 : ShowContinueError(state,
4658 0 : "..HeatPump outlet node = " +
4659 0 : state.dataLoopNodes->NodeID(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum));
4660 0 : ErrorsFound = true;
4661 : }
4662 : }
4663 : // (Set up validation here for the fan or cooling coil inlet?)
4664 139 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(6), Alphas(7), CompSetFanInlet, "UNDEFINED");
4665 :
4666 : // Add DX heating coil to component sets array
4667 139 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(8), Alphas(9), "UNDEFINED", "UNDEFINED");
4668 :
4669 : // Add DX cooling coil to component sets array
4670 139 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(10), Alphas(11), CompSetCoolInlet, "UNDEFINED");
4671 :
4672 : // Add supplemental heating coil to component sets array
4673 139 : SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(12), Alphas(13), "UNDEFINED", Alphas(4));
4674 :
4675 : // Set the Design Fan Volume Flow Rate
4676 139 : errFlag = false;
4677 139 : FanVolFlowRate = GetFanDesignVolumeFlowRate(state, FanType, FanName, errFlag);
4678 139 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate = FanVolFlowRate;
4679 139 : if (errFlag) {
4680 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4681 0 : ErrorsFound = true;
4682 : }
4683 :
4684 : // CR8094 - simple water to air heat pump MUST operate at the same flow rate specified in the coil objects
4685 : // Furnace(FurnaceNum)%DesignFanVolFlowRate = Numbers(1)
4686 : // Furnace(FurnaceNum)%MaxHeatAirVolFlow = Furnace(FurnaceNum)%DesignFanVolFlowRate
4687 : // Furnace(FurnaceNum)%MaxCoolAirVolFlow = Furnace(FurnaceNum)%DesignFanVolFlowRate
4688 :
4689 : // parameter estimate model only specifies air flow rate in parent object
4690 139 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHP) {
4691 14 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow = Numbers(1);
4692 14 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow = Numbers(1);
4693 : // simple HP model specifies air flow rate in both the parent and child coils. Use coil air flow rates.
4694 : // simple HP model air flow rate input will not be used.
4695 125 : } else if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHPSimple) {
4696 111 : errFlag = false;
4697 111 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow =
4698 111 : GetWtoAHPSimpleCoilAirFlow(state, HeatingCoilType, HeatingCoilName, errFlag);
4699 111 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow =
4700 111 : GetWtoAHPSimpleCoilAirFlow(state, CoolingCoilType, CoolingCoilName, errFlag);
4701 111 : if (errFlag) {
4702 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4703 0 : ErrorsFound = true;
4704 : }
4705 14 : } else if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHPVSEquationFit) {
4706 14 : errFlag = false;
4707 14 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow =
4708 14 : GetCoilAirFlowRateVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
4709 14 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow =
4710 14 : GetCoilAirFlowRateVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
4711 14 : if (errFlag) {
4712 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4713 0 : ErrorsFound = true;
4714 : }
4715 : }
4716 :
4717 139 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow =
4718 139 : min(state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow, state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow);
4719 182 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow != DataSizing::AutoSize &&
4720 43 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow != DataSizing::AutoSize) {
4721 43 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate =
4722 43 : max(state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow, state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow);
4723 : } else {
4724 96 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = DataSizing::AutoSize;
4725 : }
4726 :
4727 139 : state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl = AirFlowControlConstFan::UseCompressorOnFlow;
4728 :
4729 139 : if (FanVolFlowRate != DataSizing::AutoSize && state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate != DataSizing::AutoSize) {
4730 43 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate > FanVolFlowRate) {
4731 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4732 0 : ShowContinueError(state, "... has a Cooling or Heating Air Flow Rate > Max Fan Volume Flow Rate, should be <=.");
4733 0 : ShowContinueError(state,
4734 0 : format("... Entered value={:.2R}... Fan [{}:{}] Max Value={:.2R}",
4735 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate,
4736 : FanType,
4737 : FanName,
4738 0 : FanVolFlowRate));
4739 : }
4740 : }
4741 139 : if (FanVolFlowRate != DataSizing::AutoSize && state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate != DataSizing::AutoSize) {
4742 43 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate <= 0.0) {
4743 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4744 0 : ShowContinueError(state, "... has a Design Fan Flow Rate <= 0.0, it must be >0.0");
4745 0 : ShowContinueError(state, format("... Entered value={:.2R}", state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate));
4746 0 : ErrorsFound = true;
4747 : }
4748 : }
4749 :
4750 : // Set the heat pump heating coil capacity
4751 : // Get from coil module.
4752 139 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHP) {
4753 14 : errFlag = false;
4754 14 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
4755 14 : GetWtoAHPCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
4756 14 : if (errFlag) {
4757 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4758 0 : ErrorsFound = true;
4759 : }
4760 125 : } else if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHPSimple) {
4761 111 : errFlag = false;
4762 111 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
4763 111 : GetWtoAHPSimpleCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
4764 111 : if (errFlag) {
4765 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4766 0 : ErrorsFound = true;
4767 : }
4768 14 : } else if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHPVSEquationFit) {
4769 14 : errFlag = false;
4770 14 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
4771 14 : GetCoilCapacityVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
4772 14 : if (errFlag) {
4773 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4774 0 : ErrorsFound = true;
4775 : }
4776 : }
4777 : // Set the heat pump heating coil convergence
4778 139 : state.dataFurnaces->Furnace(FurnaceNum).HeatingConvergenceTolerance = Numbers(2);
4779 : // Set the heat pump cooling coil capacity (Total capacity)
4780 : // Get from coil module.
4781 139 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingWaterToAirHP) {
4782 14 : errFlag = false;
4783 14 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
4784 14 : GetWtoAHPCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
4785 14 : if (errFlag) {
4786 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4787 0 : ErrorsFound = true;
4788 : }
4789 125 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingWaterToAirHPSimple) {
4790 111 : errFlag = false;
4791 111 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
4792 111 : GetWtoAHPSimpleCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
4793 111 : if (errFlag) {
4794 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4795 0 : ErrorsFound = true;
4796 : }
4797 14 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingWaterToAirHPVSEquationFit) {
4798 14 : errFlag = false;
4799 14 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity =
4800 14 : GetCoilCapacityVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
4801 14 : if (errFlag) {
4802 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
4803 0 : ErrorsFound = true;
4804 : }
4805 : }
4806 : // Set the heat pump cooling coil convergence
4807 139 : state.dataFurnaces->Furnace(FurnaceNum).CoolingConvergenceTolerance = Numbers(3);
4808 : // Set the heatpump cycling rate
4809 139 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour = Numbers(4);
4810 :
4811 : // Set the heat pump time constant
4812 139 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant = Numbers(5);
4813 :
4814 : // Set the heat pump on-cycle power use fraction
4815 139 : state.dataFurnaces->Furnace(FurnaceNum).OnCyclePowerFraction = Numbers(6);
4816 :
4817 : // Set the heat pump fan delay time
4818 139 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime = Numbers(7);
4819 :
4820 : // Set the heatpump design supplemental heating capacity
4821 : // Get from coil module.
4822 :
4823 : // Set the heatpump max outlet temperature
4824 139 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp = Numbers(8);
4825 :
4826 : // Set maximum supply air temperature for supplemental heating coil
4827 139 : state.dataFurnaces->Furnace(FurnaceNum).MaxOATSuppHeat = Numbers(9);
4828 :
4829 : // set minimum outdoor temperature for compressor operation
4830 139 : SetMinOATCompressor(state, FurnaceNum, cCurrentModuleObject, ErrorsFound);
4831 :
4832 : } // End of the Unitary System WaterToAirHeatPump Loop
4833 :
4834 94 : Alphas.deallocate();
4835 94 : Numbers.deallocate();
4836 :
4837 94 : if (ErrorsFound) {
4838 0 : ShowFatalError(state, "Errors found in getting Furnace or Unitary System input.");
4839 : }
4840 :
4841 97 : for (HeatOnlyNum = 1; HeatOnlyNum <= NumHeatOnly; ++HeatOnlyNum) {
4842 3 : FurnaceNum = HeatOnlyNum;
4843 : // Setup Report variables for the Furnace that are not reported in the components themselves
4844 12 : SetupOutputVariable(state,
4845 : "Unitary System Fan Part Load Ratio",
4846 : OutputProcessor::Unit::None,
4847 3 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio,
4848 : OutputProcessor::SOVTimeStepType::System,
4849 : OutputProcessor::SOVStoreType::Average,
4850 6 : state.dataFurnaces->Furnace(FurnaceNum).Name);
4851 3 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4852 0 : SetupEMSActuator(state,
4853 : "AirLoopHVAC:Unitary:Furnace:HeatOnly",
4854 0 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4855 : "Autosized Supply Air Flow Rate",
4856 : "[m3/s]",
4857 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideOn,
4858 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideValue);
4859 : }
4860 : }
4861 :
4862 95 : for (UnitaryHeatOnlyNum = NumHeatOnly + 1; UnitaryHeatOnlyNum <= NumHeatOnly + NumUnitaryHeatOnly; ++UnitaryHeatOnlyNum) {
4863 1 : FurnaceNum = UnitaryHeatOnlyNum;
4864 : // Setup Report variables for Unitary System that are not reported in the components themselves
4865 4 : SetupOutputVariable(state,
4866 : "Unitary System Fan Part Load Ratio",
4867 : OutputProcessor::Unit::None,
4868 1 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio,
4869 : OutputProcessor::SOVTimeStepType::System,
4870 : OutputProcessor::SOVStoreType::Average,
4871 2 : state.dataFurnaces->Furnace(FurnaceNum).Name);
4872 1 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4873 0 : SetupEMSActuator(state,
4874 : "AirLoopHVAC:UnitaryHeatOnly",
4875 0 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4876 : "Autosized Supply Air Flow Rate",
4877 : "[m3/s]",
4878 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideOn,
4879 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideValue);
4880 : }
4881 : }
4882 :
4883 202 : for (HeatCoolNum = NumHeatOnly + NumUnitaryHeatOnly + 1; HeatCoolNum <= NumHeatOnly + NumUnitaryHeatOnly + NumHeatCool; ++HeatCoolNum) {
4884 108 : FurnaceNum = HeatCoolNum;
4885 : // Setup Report variables for the Furnace that are not reported in the components themselves
4886 432 : SetupOutputVariable(state,
4887 : "Unitary System Fan Part Load Ratio",
4888 : OutputProcessor::Unit::None,
4889 108 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio,
4890 : OutputProcessor::SOVTimeStepType::System,
4891 : OutputProcessor::SOVStoreType::Average,
4892 216 : state.dataFurnaces->Furnace(FurnaceNum).Name);
4893 432 : SetupOutputVariable(state,
4894 : "Unitary System Compressor Part Load Ratio",
4895 : OutputProcessor::Unit::None,
4896 108 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio,
4897 : OutputProcessor::SOVTimeStepType::System,
4898 : OutputProcessor::SOVStoreType::Average,
4899 216 : state.dataFurnaces->Furnace(FurnaceNum).Name);
4900 :
4901 108 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4902 96 : SetupEMSActuator(state,
4903 : "AirLoopHVAC:Unitary:Furnace:HeatCool",
4904 24 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4905 : "Autosized Supply Air Flow Rate",
4906 : "[m3/s]",
4907 24 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideOn,
4908 72 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideValue);
4909 96 : SetupEMSActuator(state,
4910 : "AirLoopHVAC:Unitary:Furnace:HeatCool",
4911 24 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4912 : "Autosized Supply Air Flow Rate During Cooling Operation",
4913 : "[m3/s]",
4914 24 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlowEMSOverrideOn,
4915 72 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlowEMSOverrideValue);
4916 96 : SetupEMSActuator(state,
4917 : "AirLoopHVAC:Unitary:Furnace:HeatCool",
4918 24 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4919 : "Autosized Supply Air Flow Rate During Heating Operation",
4920 : "[m3/s]",
4921 24 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlowEMSOverrideOn,
4922 72 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlowEMSOverrideValue);
4923 96 : SetupEMSActuator(state,
4924 : "AirLoopHVAC:Unitary:Furnace:HeatCool",
4925 24 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4926 : "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
4927 : "[m3/s]",
4928 24 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlowEMSOverrideOn,
4929 72 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlowEMSOverrideValue);
4930 : }
4931 : }
4932 :
4933 167 : for (UnitaryHeatCoolNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + 1;
4934 167 : UnitaryHeatCoolNum <= NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool;
4935 : ++UnitaryHeatCoolNum) {
4936 73 : FurnaceNum = UnitaryHeatCoolNum;
4937 : // Setup Report variables for Unitary System that are not reported in the components themselves
4938 292 : SetupOutputVariable(state,
4939 : "Unitary System Fan Part Load Ratio",
4940 : OutputProcessor::Unit::None,
4941 73 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio,
4942 : OutputProcessor::SOVTimeStepType::System,
4943 : OutputProcessor::SOVStoreType::Average,
4944 146 : state.dataFurnaces->Furnace(FurnaceNum).Name);
4945 292 : SetupOutputVariable(state,
4946 : "Unitary System Compressor Part Load Ratio",
4947 : OutputProcessor::Unit::None,
4948 73 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio,
4949 : OutputProcessor::SOVTimeStepType::System,
4950 : OutputProcessor::SOVStoreType::Average,
4951 146 : state.dataFurnaces->Furnace(FurnaceNum).Name);
4952 73 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
4953 80 : SetupEMSActuator(state,
4954 : "AirLoopHVAC:UnitaryHeatCool",
4955 20 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4956 : "Autosized Supply Air Flow Rate",
4957 : "[m3/s]",
4958 20 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideOn,
4959 60 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideValue);
4960 80 : SetupEMSActuator(state,
4961 : "AirLoopHVAC:UnitaryHeatCool",
4962 20 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4963 : "Autosized Supply Air Flow Rate During Cooling Operation",
4964 : "[m3/s]",
4965 20 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlowEMSOverrideOn,
4966 60 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlowEMSOverrideValue);
4967 80 : SetupEMSActuator(state,
4968 : "AirLoopHVAC:UnitaryHeatCool",
4969 20 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4970 : "Autosized Supply Air Flow Rate During Heating Operation",
4971 : "[m3/s]",
4972 20 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlowEMSOverrideOn,
4973 60 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlowEMSOverrideValue);
4974 80 : SetupEMSActuator(state,
4975 : "AirLoopHVAC:UnitaryHeatCool",
4976 20 : state.dataFurnaces->Furnace(FurnaceNum).Name,
4977 : "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
4978 : "[m3/s]",
4979 20 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlowEMSOverrideOn,
4980 60 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlowEMSOverrideValue);
4981 : }
4982 : }
4983 :
4984 126 : for (HeatPumpNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + 1;
4985 126 : HeatPumpNum <= state.dataFurnaces->NumFurnaces - NumWaterToAirHeatPump;
4986 : ++HeatPumpNum) {
4987 32 : FurnaceNum = HeatPumpNum;
4988 : // Setup Report variables for Unitary System that are not reported in the components themselves
4989 128 : SetupOutputVariable(state,
4990 : "Unitary System Fan Part Load Ratio",
4991 : OutputProcessor::Unit::None,
4992 32 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio,
4993 : OutputProcessor::SOVTimeStepType::System,
4994 : OutputProcessor::SOVStoreType::Average,
4995 64 : state.dataFurnaces->Furnace(FurnaceNum).Name);
4996 128 : SetupOutputVariable(state,
4997 : "Unitary System Compressor Part Load Ratio",
4998 : OutputProcessor::Unit::None,
4999 32 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio,
5000 : OutputProcessor::SOVTimeStepType::System,
5001 : OutputProcessor::SOVStoreType::Average,
5002 64 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5003 128 : SetupOutputVariable(state,
5004 : "Unitary System Dehumidification Induced Heating Demand Rate",
5005 : OutputProcessor::Unit::W,
5006 32 : state.dataFurnaces->Furnace(FurnaceNum).DehumidInducedHeatingDemandRate,
5007 : OutputProcessor::SOVTimeStepType::System,
5008 : OutputProcessor::SOVStoreType::Average,
5009 64 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5010 :
5011 32 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5012 20 : SetupEMSActuator(state,
5013 : "AirLoopHVAC:UnitaryHeatPump:AirToAir",
5014 5 : state.dataFurnaces->Furnace(FurnaceNum).Name,
5015 : "Autosized Supply Air Flow Rate",
5016 : "[m3/s]",
5017 5 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideOn,
5018 15 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideValue);
5019 : }
5020 : }
5021 :
5022 233 : for (HeatPumpNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + NumHeatPump + 1;
5023 233 : HeatPumpNum <= state.dataFurnaces->NumFurnaces;
5024 : ++HeatPumpNum) {
5025 139 : FurnaceNum = HeatPumpNum;
5026 : // Setup Report variables for Unitary System that are not reported in the components themselves
5027 556 : SetupOutputVariable(state,
5028 : "Unitary System Fan Part Load Ratio",
5029 : OutputProcessor::Unit::None,
5030 139 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio,
5031 : OutputProcessor::SOVTimeStepType::System,
5032 : OutputProcessor::SOVStoreType::Average,
5033 278 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5034 556 : SetupOutputVariable(state,
5035 : "Unitary System Compressor Part Load Ratio",
5036 : OutputProcessor::Unit::None,
5037 139 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio,
5038 : OutputProcessor::SOVTimeStepType::System,
5039 : OutputProcessor::SOVStoreType::Average,
5040 278 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5041 556 : SetupOutputVariable(state,
5042 : "Unitary System Requested Sensible Cooling Rate",
5043 : OutputProcessor::Unit::W,
5044 139 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand,
5045 : OutputProcessor::SOVTimeStepType::System,
5046 : OutputProcessor::SOVStoreType::Average,
5047 278 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5048 556 : SetupOutputVariable(state,
5049 : "Unitary System Requested Latent Cooling Rate",
5050 : OutputProcessor::Unit::W,
5051 139 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand,
5052 : OutputProcessor::SOVTimeStepType::System,
5053 : OutputProcessor::SOVStoreType::Average,
5054 278 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5055 556 : SetupOutputVariable(state,
5056 : "Unitary System Requested Heating Rate",
5057 : OutputProcessor::Unit::W,
5058 139 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand,
5059 : OutputProcessor::SOVTimeStepType::System,
5060 : OutputProcessor::SOVStoreType::Average,
5061 278 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5062 556 : SetupOutputVariable(state,
5063 : "Unitary System Dehumidification Induced Heating Demand Rate",
5064 : OutputProcessor::Unit::W,
5065 139 : state.dataFurnaces->Furnace(FurnaceNum).DehumidInducedHeatingDemandRate,
5066 : OutputProcessor::SOVTimeStepType::System,
5067 : OutputProcessor::SOVStoreType::Average,
5068 278 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5069 :
5070 139 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5071 384 : SetupEMSActuator(state,
5072 : "AirLoopHVAC:UnitaryHeatPump:WaterToAir",
5073 96 : state.dataFurnaces->Furnace(FurnaceNum).Name,
5074 : "Autosized Supply Air Flow Rate",
5075 : "[m3/s]",
5076 96 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideOn,
5077 288 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideValue);
5078 : }
5079 : }
5080 :
5081 94 : if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
5082 154 : for (FurnaceNum = 1; FurnaceNum <= state.dataFurnaces->NumFurnaces; ++FurnaceNum) {
5083 435 : SetupEMSInternalVariable(state,
5084 : "Unitary HVAC Design Heating Capacity",
5085 145 : state.dataFurnaces->Furnace(FurnaceNum).Name,
5086 : "[W]",
5087 435 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity);
5088 435 : SetupEMSInternalVariable(state,
5089 : "Unitary HVAC Design Cooling Capacity",
5090 145 : state.dataFurnaces->Furnace(FurnaceNum).Name,
5091 : "[W]",
5092 435 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity);
5093 580 : SetupEMSActuator(state,
5094 : "Unitary HVAC",
5095 145 : state.dataFurnaces->Furnace(FurnaceNum).Name,
5096 : "Sensible Load Request",
5097 : "[W]",
5098 145 : state.dataFurnaces->Furnace(FurnaceNum).EMSOverrideSensZoneLoadRequest,
5099 435 : state.dataFurnaces->Furnace(FurnaceNum).EMSSensibleZoneLoadValue);
5100 580 : SetupEMSActuator(state,
5101 : "Unitary HVAC",
5102 145 : state.dataFurnaces->Furnace(FurnaceNum).Name,
5103 : "Moisture Load Request",
5104 : "[W]",
5105 145 : state.dataFurnaces->Furnace(FurnaceNum).EMSOverrideMoistZoneLoadRequest,
5106 435 : state.dataFurnaces->Furnace(FurnaceNum).EMSMoistureZoneLoadValue);
5107 : }
5108 : }
5109 : bool anyRan;
5110 94 : ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyRan, ObjexxFCL::Optional_int_const());
5111 94 : }
5112 :
5113 : // End of Get Input subroutines for this Module
5114 : //******************************************************************************
5115 :
5116 : // Beginning Initialization Section of the Module
5117 : //******************************************************************************
5118 :
5119 6396161 : void InitFurnace(EnergyPlusData &state,
5120 : int const FurnaceNum, // index to Furnace
5121 : int const AirLoopNum, // index to air loop
5122 : Real64 &OnOffAirFlowRatio, // ratio of on to off air mass flow rate
5123 : int &OpMode, // fan operating mode
5124 : Real64 &ZoneLoad, // zone sensible load to be met (modified here as needed) (W)
5125 : Real64 &MoistureLoad, // zone moisture load (W)
5126 : bool const FirstHVACIteration // TRUE if first HVAC iteration
5127 : )
5128 : {
5129 :
5130 : // SUBROUTINE INFORMATION:
5131 : // AUTHOR Richard J. Liesen
5132 : // DATE WRITTEN Feb 2001
5133 : // MODIFIED Oct 2001, Richard Raustad
5134 : // Sep 2008, R. Raustad - revised logic to determine load to be met
5135 : // Bereket Nigusse, June 2010 - added a procedure to calculate supply air flow fraction
5136 : // through controlled zone
5137 : // Bo Shen, March 2012 - for VS WSHP
5138 : // Bo Shen, ORNL, July 2012 - added variable-speed air source heat pump cooling and heating coils, using curve-fits
5139 :
5140 : // RE-ENGINEERED na
5141 :
5142 : // PURPOSE OF THIS SUBROUTINE:
5143 : // This subroutine is for initializations of the Furnace Components.
5144 :
5145 : // METHODOLOGY EMPLOYED:
5146 : // Uses the status flags to trigger initializations.
5147 : // The HeatCool furnace/unitarysystem and air-to-air heat pump may have alternate air flow rates
5148 : // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
5149 : // air flow rates during InitFurnace. Use these flow rates during the Calc routines to set the
5150 : // average mass flow rates based on PLR.
5151 :
5152 : // REFERENCES:
5153 :
5154 : // Using/Aliasing
5155 : using Fans::GetFanDesignVolumeFlowRate;
5156 : using Fans::GetFanSpeedRatioCurveIndex;
5157 :
5158 : using PlantUtilities::ScanPlantLoopsForObject;
5159 : using SteamCoils::SimulateSteamCoilComponents;
5160 6396161 : auto &GetCoilMaxSteamFlowRate(SteamCoils::GetCoilMaxSteamFlowRate);
5161 6396161 : auto &GetSteamCoilCapacity(SteamCoils::GetCoilCapacity);
5162 : using Fans::GetFanVolFlow;
5163 : using FluidProperties::GetDensityGlycol;
5164 : using FluidProperties::GetSatDensityRefrig;
5165 : using PlantUtilities::InitComponentNodes;
5166 : using PlantUtilities::SetComponentFlowRate;
5167 : using WaterCoils::GetCoilMaxWaterFlowRate;
5168 : using WaterCoils::SimulateWaterCoilComponents;
5169 :
5170 : // Locals
5171 : // SUBROUTINE ARGUMENT DEFINITIONS:
5172 :
5173 : // SUBROUTINE PARAMETER DEFINITIONS:
5174 6396161 : Real64 constexpr Small5WLoad(5.0);
5175 6396161 : auto constexpr RoutineName("InitFurnace");
5176 :
5177 : // INTERFACE BLOCK SPECIFICATIONS
5178 : // na
5179 :
5180 : // DERIVED TYPE DEFINITIONS
5181 : // na
5182 :
5183 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
5184 : bool errFlag; // error flag for mining functions
5185 : Real64 FanVolFlowRate; // fan volumetric flow rate (m3/s)
5186 : Real64 QZnReq; // furnace load based on control zone frac (W)
5187 : Real64 PartLoadRatio; // furnace part-load ratio
5188 : Real64 SensibleOutput; // no load sensible output (coils off) (W)
5189 : Real64 LatentOutput; // no load latent output (coils off) (W)
5190 : Real64 QToCoolSetPt; // sensible load to cooling setpoint (W)
5191 : Real64 QToHeatSetPt; // sensible load to heating setpoint (W)
5192 : int ZoneInNode; // Zone inlet node number in the controlled zone
5193 : // calculation (kg/kg)
5194 : Real64 DeltaMassRate; // Difference of mass flow rate between
5195 : // inlet node and system outlet node
5196 : Real64 MassFlowRate; // mass flow rate to calculate loss
5197 12792322 : std::string FanType; // used in warning messages
5198 12792322 : std::string FanName; // used in warning messages
5199 :
5200 6396161 : int ZoneInSysIndex(0); // number of zone inlet nodes counter in an airloop
5201 6396161 : int NumAirLoopZones(0); // number of zone inlet nodes in an air loop
5202 6396161 : int ZoneInletNodeNum(0); // zone inlet nodes node number
5203 6396161 : Real64 SumOfMassFlowRateMax(0.0); // the sum of mass flow rates at inlet to zones in an airloop
5204 6396161 : Real64 CntrlZoneTerminalUnitMassFlowRateMax(0.0); // Maximum mass flow rate through controlled zone terminal unit
5205 :
5206 6396161 : bool ErrorsFound(false); // flag returned from mining call
5207 6396161 : Real64 mdot(0.0); // local temporary for mass flow rate (kg/s)
5208 6396161 : Real64 rho(0.0); // local for fluid density
5209 6396161 : int SteamIndex(0); // index of steam quality for steam heating coil
5210 6396161 : Real64 SteamDensity(0.0); // density of steam at 100C, used for steam heating coils
5211 6396161 : Real64 CoilMaxVolFlowRate(0.0); // coil fluid maximum volume flow rate
5212 6396161 : Real64 QActual(0.0); // coil actual capacity
5213 6396161 : Real64 SUPHEATERLOAD(0.0); // SUPPLEMENTAL HEATER LOAD
5214 : int NumOfSpeedCooling; // Number of speeds for cooling
5215 : int NumOfSpeedHeating; // Number of speeds for heating
5216 : int InNode; // Inlet node number in MSHP loop
5217 : int OutNode; // Outlet node number in MSHP loop
5218 : Real64 RhoAir; // Air density at InNode
5219 6396161 : int IHPIndex(0); // coil id of IHP coil
5220 : Furnaces::ModeOfOperation OperatingMode; // track cooling, heating, and no cooling or heating modes
5221 : Furnaces::ModeOfOperation OperatingModeMinusOne;
5222 : Furnaces::ModeOfOperation OperatingModeMinusTwo;
5223 : bool Oscillate; // detection of oscillating operating modes
5224 :
5225 6396161 : InNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
5226 6396161 : OutNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
5227 :
5228 6396161 : auto &Node(state.dataLoopNodes->Node);
5229 :
5230 6396161 : if (state.dataFurnaces->InitFurnaceMyOneTimeFlag) {
5231 : // initialize the environment and sizing flags
5232 94 : state.dataFurnaces->MyEnvrnFlag.allocate(state.dataFurnaces->NumFurnaces);
5233 94 : state.dataFurnaces->MySizeFlag.allocate(state.dataFurnaces->NumFurnaces);
5234 94 : state.dataFurnaces->MySecondOneTimeFlag.allocate(state.dataFurnaces->NumFurnaces);
5235 94 : state.dataFurnaces->MyFanFlag.allocate(state.dataFurnaces->NumFurnaces);
5236 94 : state.dataFurnaces->MyCheckFlag.allocate(state.dataFurnaces->NumFurnaces);
5237 94 : state.dataFurnaces->MyFlowFracFlag.allocate(state.dataFurnaces->NumFurnaces);
5238 94 : state.dataFurnaces->MyPlantScanFlag.allocate(state.dataFurnaces->NumFurnaces);
5239 94 : state.dataFurnaces->MySuppCoilPlantScanFlag.allocate(state.dataFurnaces->NumFurnaces);
5240 94 : state.dataFurnaces->MyEnvrnFlag = true;
5241 94 : state.dataFurnaces->MySizeFlag = true;
5242 94 : state.dataFurnaces->MySecondOneTimeFlag = true;
5243 94 : state.dataFurnaces->MyFanFlag = true;
5244 94 : state.dataFurnaces->MyCheckFlag = true;
5245 94 : state.dataFurnaces->MyFlowFracFlag = true;
5246 94 : state.dataFurnaces->InitFurnaceMyOneTimeFlag = false;
5247 94 : state.dataFurnaces->MyPlantScanFlag = true;
5248 94 : state.dataFurnaces->MySuppCoilPlantScanFlag = true;
5249 : }
5250 :
5251 6396161 : if (state.dataGlobal->BeginEnvrnFlag && state.dataFurnaces->MyAirLoopPass) {
5252 573 : state.dataFurnaces->AirLoopPass = 0;
5253 573 : state.dataFurnaces->MyAirLoopPass = false;
5254 : }
5255 6396161 : if (!state.dataGlobal->BeginEnvrnFlag) {
5256 6376106 : state.dataFurnaces->MyAirLoopPass = true;
5257 : }
5258 :
5259 6396161 : ++state.dataFurnaces->AirLoopPass;
5260 6396161 : if (state.dataFurnaces->AirLoopPass > 2) state.dataFurnaces->AirLoopPass = 1;
5261 :
5262 6396161 : if (!state.dataGlobal->SysSizingCalc && state.dataFurnaces->MySizeFlag(FurnaceNum)) {
5263 : // for each furnace, do the sizing once.
5264 356 : SizeFurnace(state, FurnaceNum, FirstHVACIteration);
5265 356 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac = 1.0;
5266 :
5267 356 : state.dataFurnaces->MySizeFlag(FurnaceNum) = false;
5268 : // Pass the fan cycling schedule index up to the air loop. Set the air loop unitary system flag.
5269 356 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).CycFanSchedPtr = state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr;
5270 356 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = true;
5271 : // RR this is wrong, Op mode needs to be updated each time atep
5272 356 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).FanOpMode = state.dataFurnaces->Furnace(FurnaceNum).OpMode;
5273 :
5274 : // Check that heat pump heating capacity is within 20% of cooling capacity
5275 356 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir) {
5276 96 : if (std::abs(state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity -
5277 64 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity) /
5278 64 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity >
5279 : 0.2) {
5280 0 : ShowWarningError(state,
5281 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
5282 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
5283 : "\" heating capacity is disproportionate (> 20% different) to total cooling capacity");
5284 : }
5285 : }
5286 : }
5287 :
5288 6396161 : if (!state.dataGlobal->DoingSizing && state.dataFurnaces->MySecondOneTimeFlag(FurnaceNum)) {
5289 : // sizing all done. check fan air flow rates
5290 622 : errFlag = false;
5291 622 : FanVolFlowRate = GetFanDesignVolumeFlowRate(state, BlankString, BlankString, errFlag, state.dataFurnaces->Furnace(FurnaceNum).FanIndex);
5292 622 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate = FanVolFlowRate;
5293 622 : if (errFlag) {
5294 0 : ShowContinueError(state,
5295 0 : "...occurs in " + cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " =" +
5296 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5297 : }
5298 622 : if (FanVolFlowRate != DataSizing::AutoSize) {
5299 356 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate > FanVolFlowRate) {
5300 0 : ShowWarningError(state,
5301 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + '=' +
5302 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
5303 : " has a Design Fan Volume Flow Rate > Max Fan Volume Flow Rate, should be <=");
5304 0 : ShowContinueError(state,
5305 0 : format("... Entered value={:.2R}... Fan [{}] Max Value={:.2R}",
5306 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate,
5307 0 : cFanTypes(state.dataFurnaces->Furnace(FurnaceNum).FanType_Num),
5308 0 : FanVolFlowRate));
5309 : }
5310 356 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate <= 0.0) {
5311 0 : ShowSevereError(state,
5312 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + '=' +
5313 0 : state.dataFurnaces->Furnace(FurnaceNum).Name + " has a Design Fan Volume Flow Rate <= 0.0, it must be >0.0");
5314 0 : ShowContinueError(state, format("... Entered value={:.2R}", state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate));
5315 : }
5316 :
5317 356 : state.dataFurnaces->MySecondOneTimeFlag(FurnaceNum) = false;
5318 : }
5319 : }
5320 :
5321 : // Scan hot water and steam heating coil plant components for one time initializations
5322 6396161 : if (state.dataFurnaces->MyPlantScanFlag(FurnaceNum) && allocated(state.dataPlnt->PlantLoop)) {
5323 712 : if ((state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWater) ||
5324 356 : (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingSteam)) {
5325 :
5326 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWater) {
5327 :
5328 0 : errFlag = false;
5329 0 : ScanPlantLoopsForObject(state,
5330 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
5331 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
5332 0 : state.dataFurnaces->Furnace(FurnaceNum).plantLoc,
5333 : errFlag,
5334 : _,
5335 : _,
5336 : _,
5337 : _,
5338 : _);
5339 0 : if (errFlag) {
5340 0 : ShowFatalError(state, "InitFurnace: Program terminated for previous conditions.");
5341 : }
5342 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow =
5343 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName, ErrorsFound);
5344 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow > 0.0) {
5345 0 : rho = GetDensityGlycol(state,
5346 0 : state.dataPlnt->PlantLoop(state.dataFurnaces->Furnace(FurnaceNum).plantLoc.loopNum).FluidName,
5347 : DataGlobalConstants::HWInitConvTemp,
5348 0 : state.dataPlnt->PlantLoop(state.dataFurnaces->Furnace(FurnaceNum).plantLoc.loopNum).FluidIndex,
5349 0 : RoutineName);
5350 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow *= rho;
5351 : }
5352 0 : } else if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingSteam) {
5353 :
5354 0 : errFlag = false;
5355 0 : ScanPlantLoopsForObject(state,
5356 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
5357 : DataPlant::PlantEquipmentType::CoilSteamAirHeating,
5358 0 : state.dataFurnaces->Furnace(FurnaceNum).plantLoc,
5359 : errFlag,
5360 : _,
5361 : _,
5362 : _,
5363 : _,
5364 : _);
5365 0 : if (errFlag) {
5366 0 : ShowFatalError(state, "InitFurnace: Program terminated for previous conditions.");
5367 : }
5368 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow =
5369 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, ErrorsFound);
5370 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow > 0.0) {
5371 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
5372 0 : SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, RoutineName);
5373 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow *= SteamDensity;
5374 : }
5375 : }
5376 : // fill outlet node for coil
5377 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilOutletNode =
5378 0 : DataPlant::CompData::getPlantComponent(state, state.dataFurnaces->Furnace(FurnaceNum).plantLoc).NodeNumOut;
5379 0 : state.dataFurnaces->MyPlantScanFlag(FurnaceNum) = false;
5380 : } else { // pthp not connected to plant
5381 356 : state.dataFurnaces->MyPlantScanFlag(FurnaceNum) = false;
5382 : }
5383 6395805 : } else if (state.dataFurnaces->MyPlantScanFlag(FurnaceNum) && !state.dataGlobal->AnyPlantInModel) {
5384 0 : state.dataFurnaces->MyPlantScanFlag(FurnaceNum) = false;
5385 : }
5386 :
5387 : // Scan Supplemental hot water and steam heating coil plant components for one time initializations
5388 6396161 : if (state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) && allocated(state.dataPlnt->PlantLoop)) {
5389 711 : if ((state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num == Coil_HeatingWater) ||
5390 355 : (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num == Coil_HeatingSteam)) {
5391 :
5392 1 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num == Coil_HeatingWater) {
5393 1 : errFlag = false;
5394 3 : ScanPlantLoopsForObject(state,
5395 1 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
5396 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
5397 1 : state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc,
5398 : errFlag,
5399 : _,
5400 : _,
5401 : _,
5402 : _,
5403 : _);
5404 1 : if (errFlag) {
5405 0 : ShowFatalError(state, "InitFurnace: Program terminated for previous conditions.");
5406 : }
5407 1 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
5408 2 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName, ErrorsFound);
5409 1 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow > 0.0) {
5410 2 : rho = GetDensityGlycol(state,
5411 1 : state.dataPlnt->PlantLoop(state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc.loopNum).FluidName,
5412 : DataGlobalConstants::HWInitConvTemp,
5413 1 : state.dataPlnt->PlantLoop(state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc.loopNum).FluidIndex,
5414 1 : RoutineName);
5415 1 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow *= rho;
5416 : }
5417 0 : } else if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num == Coil_HeatingSteam) {
5418 0 : errFlag = false;
5419 0 : ScanPlantLoopsForObject(state,
5420 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
5421 : DataPlant::PlantEquipmentType::CoilSteamAirHeating,
5422 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc,
5423 : errFlag,
5424 : _,
5425 : _,
5426 : _,
5427 : _,
5428 : _);
5429 0 : if (errFlag) {
5430 0 : ShowFatalError(state, "InitFurnace: Program terminated for previous conditions.");
5431 : }
5432 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow =
5433 0 : GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, ErrorsFound);
5434 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow > 0.0) {
5435 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
5436 0 : SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, RoutineName);
5437 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow *= SteamDensity;
5438 : }
5439 : }
5440 : // fill outlet node for coil
5441 1 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilOutletNode =
5442 1 : DataPlant::CompData::getPlantComponent(state, state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc).NodeNumOut;
5443 1 : state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) = false;
5444 : } else { // pthp not connected to plant
5445 355 : state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) = false;
5446 : }
5447 :
5448 6395805 : } else if (state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) && !state.dataGlobal->AnyPlantInModel) {
5449 0 : state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) = false;
5450 : }
5451 :
5452 : // Do the Begin Environment initializations
5453 6396161 : if (state.dataGlobal->BeginEnvrnFlag && state.dataFurnaces->MyEnvrnFlag(FurnaceNum)) {
5454 : // Change the Volume Flow Rates to Mass Flow Rates
5455 2271 : state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate =
5456 2271 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
5457 2271 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow =
5458 2271 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
5459 2271 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow =
5460 2271 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
5461 2271 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirMassFlow =
5462 2271 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
5463 2271 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 0.0;
5464 2271 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
5465 2271 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
5466 2271 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
5467 2271 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
5468 :
5469 2271 : state.dataFurnaces->Furnace(FurnaceNum).SenLoadLoss = 0.0;
5470 2271 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat) {
5471 351 : state.dataFurnaces->Furnace(FurnaceNum).LatLoadLoss = 0.0;
5472 : }
5473 :
5474 : // set fluid-side hardware limits
5475 2271 : if (state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode > 0) {
5476 :
5477 0 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
5478 : // If water coil max water flow rate is autosized, simulate once in order to mine max flow rate
5479 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWater) {
5480 0 : SimulateWaterCoilComponents(state,
5481 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
5482 : FirstHVACIteration,
5483 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex);
5484 0 : CoilMaxVolFlowRate = GetCoilMaxWaterFlowRate(
5485 0 : state, "Coil:Heating:Water", state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName, ErrorsFound);
5486 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
5487 0 : rho = GetDensityGlycol(state,
5488 0 : state.dataPlnt->PlantLoop(state.dataFurnaces->Furnace(FurnaceNum).plantLoc.loopNum).FluidName,
5489 : DataGlobalConstants::HWInitConvTemp,
5490 0 : state.dataPlnt->PlantLoop(state.dataFurnaces->Furnace(FurnaceNum).plantLoc.loopNum).FluidIndex,
5491 0 : RoutineName);
5492 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
5493 : }
5494 : }
5495 : // If steam coil max steam flow rate is autosized, simulate once in order to mine max flow rate
5496 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingSteam) {
5497 0 : SimulateSteamCoilComponents(state,
5498 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
5499 : FirstHVACIteration,
5500 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
5501 : 1.0,
5502 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
5503 0 : CoilMaxVolFlowRate = GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex, ErrorsFound);
5504 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
5505 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
5506 0 : SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, RoutineName);
5507 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
5508 : }
5509 : }
5510 : }
5511 :
5512 0 : InitComponentNodes(state,
5513 : 0.0,
5514 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow,
5515 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode,
5516 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilOutletNode);
5517 : }
5518 2271 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode > 0) {
5519 7 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
5520 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num == Coil_HeatingWater) {
5521 : // If water coil max water flow rate is autosized, simulate once in order to mine max flow rate
5522 0 : SimulateWaterCoilComponents(state,
5523 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
5524 : FirstHVACIteration,
5525 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex);
5526 0 : CoilMaxVolFlowRate = GetCoilMaxWaterFlowRate(
5527 0 : state, "Coil:Heating:Water", state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName, ErrorsFound);
5528 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
5529 0 : rho = GetDensityGlycol(state,
5530 0 : state.dataPlnt->PlantLoop(state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc.loopNum).FluidName,
5531 : DataGlobalConstants::HWInitConvTemp,
5532 0 : state.dataPlnt->PlantLoop(state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc.loopNum).FluidIndex,
5533 0 : RoutineName);
5534 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
5535 : }
5536 : }
5537 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num == Coil_HeatingSteam) {
5538 0 : SimulateSteamCoilComponents(state,
5539 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
5540 : FirstHVACIteration,
5541 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex,
5542 : 1.0,
5543 : QActual); // QCoilReq, simulate any load > 0 to get max capacity
5544 0 : CoilMaxVolFlowRate = GetCoilMaxSteamFlowRate(state, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, ErrorsFound);
5545 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
5546 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
5547 0 : SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, state.dataFurnaces->TempSteamIn, 1.0, SteamIndex, RoutineName);
5548 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
5549 : }
5550 : }
5551 0 : InitComponentNodes(state,
5552 : 0.0,
5553 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow,
5554 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode,
5555 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilOutletNode);
5556 : }
5557 : }
5558 2271 : state.dataFurnaces->MyEnvrnFlag(FurnaceNum) = false;
5559 : }
5560 :
5561 6396161 : if (!state.dataGlobal->BeginEnvrnFlag) {
5562 6376106 : state.dataFurnaces->MyEnvrnFlag(FurnaceNum) = true;
5563 : }
5564 :
5565 6396161 : if (state.dataFurnaces->MyFanFlag(FurnaceNum)) {
5566 622 : if (state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate != DataSizing::AutoSize) {
5567 356 : if (state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate > 0.0) {
5568 356 : state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio =
5569 356 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow / state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate;
5570 356 : state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio =
5571 356 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow / state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate;
5572 712 : state.dataFurnaces->Furnace(FurnaceNum).NoHeatCoolSpeedRatio = state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow /
5573 356 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate;
5574 : }
5575 356 : if (GetFanSpeedRatioCurveIndex(state, FanType, FanName, state.dataFurnaces->Furnace(FurnaceNum).FanIndex) > 0) {
5576 0 : if (state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate == state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow &&
5577 0 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate == state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow &&
5578 0 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate ==
5579 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow) {
5580 0 : ShowWarningError(state,
5581 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
5582 0 : state.dataFurnaces->Furnace(FurnaceNum).Name + "\"");
5583 0 : ShowContinueError(state, "...For fan type and name = " + FanType + " \"" + FanName + "\"");
5584 0 : ShowContinueError(state,
5585 : "...Fan power ratio function of speed ratio curve has no impact if fan volumetric flow rate is the same as "
5586 : "the unitary system volumetric flow rate.");
5587 0 : ShowContinueError(state,
5588 0 : format("...Fan volumetric flow rate = {:.5R} m3/s.",
5589 0 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate));
5590 0 : ShowContinueError(state,
5591 0 : format("...Unitary system volumetric flow rate = {:.5R} m3/s.",
5592 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow));
5593 : }
5594 : }
5595 356 : state.dataFurnaces->MyFanFlag(FurnaceNum) = false;
5596 : } else {
5597 266 : state.dataFurnaces->Furnace(FurnaceNum).ActualFanVolFlowRate =
5598 532 : GetFanDesignVolumeFlowRate(state, BlankString, BlankString, errFlag, state.dataFurnaces->Furnace(FurnaceNum).FanIndex);
5599 : }
5600 : }
5601 :
5602 6396161 : if (allocated(state.dataZoneEquip->ZoneEquipConfig) && state.dataFurnaces->MyCheckFlag(FurnaceNum)) {
5603 356 : int zoneNum = state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum;
5604 356 : int zoneInlet = state.dataFurnaces->Furnace(FurnaceNum).ZoneInletNode;
5605 356 : int coolingPriority = 0;
5606 356 : int heatingPriority = 0;
5607 : // setup furnace zone equipment sequence information based on finding matching air terminal
5608 356 : if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex > 0) {
5609 356 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex)
5610 356 : .getPrioritiesForInletNode(state, zoneInlet, coolingPriority, heatingPriority);
5611 356 : state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceCoolingNum = coolingPriority;
5612 356 : state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum = heatingPriority;
5613 : }
5614 356 : state.dataFurnaces->MyCheckFlag(FurnaceNum) = false;
5615 712 : if (state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceCoolingNum == 0 ||
5616 356 : state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum == 0) {
5617 0 : ShowSevereError(state,
5618 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
5619 0 : state.dataFurnaces->Furnace(FurnaceNum).Name + "\": Airloop air terminal in the zone equipment list for zone = " +
5620 0 : state.dataHeatBal->Zone(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum).Name +
5621 : " not found or is not allowed Zone Equipment Cooling or Heating Sequence = 0.");
5622 0 : ShowFatalError(state,
5623 0 : "Subroutine InitFurnace: Errors found in getting " +
5624 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) +
5625 : " input. Preceding condition(s) causes termination.");
5626 : }
5627 : }
5628 :
5629 : // Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
5630 6396161 : NumAirLoopZones =
5631 6396161 : state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
5632 6396161 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataFurnaces->MyFlowFracFlag(FurnaceNum)) {
5633 356 : state.dataFurnaces->FlowFracFlagReady = true;
5634 787 : for (ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
5635 : // zone inlet nodes for cooling
5636 431 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled > 0) {
5637 431 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
5638 : // the data structure for the zones inlet nodes has not been filled
5639 0 : state.dataFurnaces->FlowFracFlagReady = false;
5640 : }
5641 : }
5642 : // zone inlet nodes for heating
5643 431 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
5644 0 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
5645 : // the data structure for the zones inlet nodes has not been filled
5646 0 : state.dataFurnaces->FlowFracFlagReady = false;
5647 : }
5648 : }
5649 : }
5650 : }
5651 :
5652 6396161 : if (state.dataFurnaces->MyFlowFracFlag(FurnaceNum)) {
5653 356 : if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataFurnaces->FlowFracFlagReady) {
5654 356 : SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
5655 787 : for (ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
5656 431 : ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex);
5657 431 : SumOfMassFlowRateMax += Node(ZoneInletNodeNum).MassFlowRateMax;
5658 862 : if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZoneInSysIndex) ==
5659 431 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) {
5660 356 : CntrlZoneTerminalUnitMassFlowRateMax = Node(ZoneInletNodeNum).MassFlowRateMax;
5661 : }
5662 : }
5663 356 : if (SumOfMassFlowRateMax != 0.0) {
5664 356 : if (CntrlZoneTerminalUnitMassFlowRateMax >= SmallAirVolFlow) {
5665 356 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac = CntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
5666 : } else {
5667 0 : ShowSevereError(state,
5668 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " = " +
5669 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5670 0 : ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
5671 : }
5672 1424 : BaseSizer::reportSizerOutput(state,
5673 356 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
5674 356 : state.dataFurnaces->Furnace(FurnaceNum).Name,
5675 : "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
5676 712 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac);
5677 356 : state.dataFurnaces->MyFlowFracFlag(FurnaceNum) = false;
5678 : }
5679 : }
5680 : }
5681 :
5682 : // Calculate air distribution losses
5683 6396161 : if (!FirstHVACIteration && state.dataFurnaces->AirLoopPass == 1) {
5684 2296980 : ZoneInNode = state.dataFurnaces->Furnace(FurnaceNum).ZoneInletNode;
5685 2296980 : MassFlowRate = Node(ZoneInNode).MassFlowRate / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac;
5686 2296980 : if (state.afn->distribution_simulated) {
5687 244382 : DeltaMassRate = Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).MassFlowRate -
5688 122191 : Node(ZoneInNode).MassFlowRate / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac;
5689 122191 : if (DeltaMassRate < 0.0) DeltaMassRate = 0.0;
5690 : } else {
5691 2174789 : MassFlowRate = Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).MassFlowRate;
5692 2174789 : DeltaMassRate = 0.0;
5693 : }
5694 2296980 : Real64 TotalOutput(0.0); // total output rate, {W}
5695 2296980 : Real64 SensibleOutputDelta(0.0); // delta sensible output rate, {W}
5696 2296980 : Real64 LatentOutputDelta(0.0); // delta latent output rate, {W}
5697 2296980 : Real64 TotalOutputDelta(0.0); // delta total output rate, {W}
5698 13781880 : CalcZoneSensibleLatentOutput(MassFlowRate,
5699 2296980 : Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).Temp,
5700 2296980 : Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).HumRat,
5701 2296980 : Node(ZoneInNode).Temp,
5702 2296980 : Node(ZoneInNode).HumRat,
5703 2296980 : state.dataFurnaces->Furnace(FurnaceNum).SenLoadLoss,
5704 2296980 : state.dataFurnaces->Furnace(FurnaceNum).LatLoadLoss,
5705 : TotalOutput);
5706 9187920 : CalcZoneSensibleLatentOutput(DeltaMassRate,
5707 2296980 : Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).Temp,
5708 2296980 : Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).HumRat,
5709 2296980 : Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).Temp,
5710 2296980 : Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).HumRat,
5711 : SensibleOutputDelta,
5712 : LatentOutputDelta,
5713 : TotalOutputDelta);
5714 2296980 : state.dataFurnaces->Furnace(FurnaceNum).SenLoadLoss = state.dataFurnaces->Furnace(FurnaceNum).SenLoadLoss + SensibleOutputDelta;
5715 2296980 : if (std::abs(state.dataFurnaces->Furnace(FurnaceNum).SensibleLoadMet) > 0.0) {
5716 1466719 : if (std::abs(state.dataFurnaces->Furnace(FurnaceNum).SenLoadLoss / state.dataFurnaces->Furnace(FurnaceNum).SensibleLoadMet) < 0.001)
5717 1313351 : state.dataFurnaces->Furnace(FurnaceNum).SenLoadLoss = 0.0;
5718 : }
5719 2296980 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat) {
5720 279735 : state.dataFurnaces->Furnace(FurnaceNum).LatLoadLoss = state.dataFurnaces->Furnace(FurnaceNum).LatLoadLoss + LatentOutputDelta;
5721 279735 : if (std::abs(state.dataFurnaces->Furnace(FurnaceNum).LatentLoadMet) > 0.0) {
5722 249072 : if (std::abs(state.dataFurnaces->Furnace(FurnaceNum).LatLoadLoss / state.dataFurnaces->Furnace(FurnaceNum).LatentLoadMet) < 0.001)
5723 245335 : state.dataFurnaces->Furnace(FurnaceNum).LatLoadLoss = 0.0;
5724 : }
5725 : }
5726 : }
5727 :
5728 6396161 : if (state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr > 0) {
5729 6054281 : if (GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).FanSchedPtr) == 0.0) {
5730 2597393 : state.dataFurnaces->Furnace(FurnaceNum).OpMode = CycFanCycCoil;
5731 : } else {
5732 3456888 : state.dataFurnaces->Furnace(FurnaceNum).OpMode = ContFanCycCoil;
5733 : }
5734 6054281 : if (AirLoopNum > 0) {
5735 6054281 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).FanOpMode = state.dataFurnaces->Furnace(FurnaceNum).OpMode;
5736 : }
5737 : }
5738 :
5739 6396161 : OpMode = state.dataFurnaces->Furnace(FurnaceNum).OpMode;
5740 6396161 : state.dataFurnaces->EconomizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
5741 :
5742 6396161 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac > 0.0) {
5743 6396161 : QZnReq = ZoneLoad / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac;
5744 6396161 : MoistureLoad /= state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac;
5745 6396161 : ZoneLoad = QZnReq;
5746 : } else {
5747 0 : QZnReq = ZoneLoad;
5748 : }
5749 :
5750 : // Original thermostat control logic (works only for cycling fan systems)
5751 8396267 : if (QZnReq > SmallLoad && QZnReq > (Small5WLoad / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac) &&
5752 2000106 : !state.dataZoneEnergyDemand->CurDeadBandOrSetback(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)) {
5753 1987690 : state.dataFurnaces->HeatingLoad = true;
5754 1987690 : state.dataFurnaces->CoolingLoad = false;
5755 7590890 : } else if (QZnReq < (-1.0 * SmallLoad) &&
5756 7589641 : std::abs(QZnReq) > (Small5WLoad / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac) &&
5757 3181170 : !state.dataZoneEnergyDemand->CurDeadBandOrSetback(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)) {
5758 3181049 : state.dataFurnaces->HeatingLoad = false;
5759 3181049 : state.dataFurnaces->CoolingLoad = true;
5760 : } else {
5761 1227422 : state.dataFurnaces->HeatingLoad = false;
5762 1227422 : state.dataFurnaces->CoolingLoad = false;
5763 : }
5764 :
5765 14734520 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
5766 7950546 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
5767 2410118 : (state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple ||
5768 349365 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_VarSpeedEquationFit))) {
5769 2448566 : if (MoistureLoad < 0.0 && state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
5770 127698 : state.dataFurnaces->HPDehumidificationLoadFlag = true;
5771 127698 : state.dataFurnaces->HeatingLoad = false;
5772 127698 : state.dataFurnaces->CoolingLoad = true;
5773 : } else {
5774 2320868 : state.dataFurnaces->HPDehumidificationLoadFlag = false;
5775 : }
5776 : }
5777 :
5778 : // Check for heat only furnace
5779 12774729 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != Furnace_HeatOnly &&
5780 6378568 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatOnly) {
5781 :
5782 6371275 : if (GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0) {
5783 12479392 : if ((state.dataFurnaces->HeatingLoad || state.dataFurnaces->CoolingLoad) ||
5784 1449140 : (state.dataFurnaces->Furnace(FurnaceNum).Humidistat && MoistureLoad < 0.0)) {
5785 5402148 : PartLoadRatio = 1.0;
5786 : } else {
5787 720925 : PartLoadRatio = 0.0;
5788 : }
5789 : } else {
5790 248202 : PartLoadRatio = 0.0;
5791 : }
5792 : } else {
5793 24886 : PartLoadRatio = 1.0;
5794 : }
5795 :
5796 : // get current time step operating capacity of water and steam coils
5797 : // (dependent on entering water and steam temperature)
5798 6396161 : if (FirstHVACIteration) {
5799 1765439 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWater) {
5800 : // set water-side mass flow rates
5801 0 : Node(state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
5802 0 : mdot = state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow;
5803 0 : SetComponentFlowRate(state,
5804 : mdot,
5805 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode,
5806 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilOutletNode,
5807 0 : state.dataFurnaces->Furnace(FurnaceNum).plantLoc);
5808 : // simulate water coil to find operating capacity
5809 0 : SimulateWaterCoilComponents(state,
5810 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
5811 : FirstHVACIteration,
5812 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
5813 : QActual);
5814 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity = QActual;
5815 :
5816 : } // from IF(state.dataFurnaces->Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingWater) THEN
5817 :
5818 1765439 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingSteam) {
5819 : // set air-side and steam-side mass flow rates
5820 0 : Node(state.dataFurnaces->Furnace(FurnaceNum).HWCoilAirInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
5821 0 : mdot = state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow;
5822 0 : SetComponentFlowRate(state,
5823 : mdot,
5824 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode,
5825 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilOutletNode,
5826 0 : state.dataFurnaces->Furnace(FurnaceNum).plantLoc);
5827 :
5828 : // simulate steam coil to find operating capacity
5829 0 : SimulateSteamCoilComponents(state,
5830 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
5831 : FirstHVACIteration,
5832 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
5833 : 1.0,
5834 : QActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
5835 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
5836 0 : GetSteamCoilCapacity(state,
5837 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType,
5838 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
5839 : ErrorsFound);
5840 :
5841 : } // from IF(Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingSteam) THEN
5842 :
5843 1765439 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num == Coil_HeatingWater) {
5844 :
5845 : // set air-side and steam-side mass flow rates
5846 3810 : Node(state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
5847 3810 : mdot = state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow;
5848 11430 : SetComponentFlowRate(state,
5849 : mdot,
5850 3810 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode,
5851 3810 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilOutletNode,
5852 3810 : state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc);
5853 :
5854 : // simulate water coil to find operating capacity
5855 11430 : SimulateWaterCoilComponents(state,
5856 3810 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
5857 : FirstHVACIteration,
5858 3810 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex,
5859 : QActual);
5860 3810 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity = QActual;
5861 :
5862 : } // from IF(Furnace(FurnaceNum)%SuppHeatCoilType_Num == Coil_HeatingWater) THEN
5863 1765439 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num == Coil_HeatingSteam) {
5864 : // set air-side and steam-side mass flow rates
5865 0 : Node(state.dataFurnaces->Furnace(FurnaceNum).SuppCoilAirInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
5866 0 : mdot = state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow;
5867 0 : SetComponentFlowRate(state,
5868 : mdot,
5869 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode,
5870 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilOutletNode,
5871 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc);
5872 :
5873 : // simulate steam coil to find operating capacity
5874 0 : SimulateSteamCoilComponents(state,
5875 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
5876 : FirstHVACIteration,
5877 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex,
5878 : 1.0,
5879 : QActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
5880 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity =
5881 0 : GetSteamCoilCapacity(state,
5882 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType,
5883 0 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
5884 : ErrorsFound);
5885 :
5886 : } // from IF(Furnace(FurnaceNum)%SuppHeatCoilType_Num == Coil_HeatingSteam) THEN
5887 : } // from IF( FirstHVACIteration ) THEN
5888 :
5889 6396161 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) { // BoS, variable-speed water source hp
5890 : // Furnace(FurnaceNum)%IdleMassFlowRate = RhoAir*Furnace(FurnaceNum)%IdleVolumeAirRate
5891 1498400 : NumOfSpeedCooling = state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling;
5892 1498400 : NumOfSpeedHeating = state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating;
5893 : // IF MSHP system was not autosized and the fan is autosized, check that fan volumetric flow rate is greater than MSHP flow rates
5894 1498400 : if (state.dataFurnaces->Furnace(FurnaceNum).CheckFanFlow) {
5895 20 : state.dataFurnaces->CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:VariableSpeed";
5896 20 : GetFanVolFlow(state, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow);
5897 :
5898 20 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) // set max fan flow rate to the IHP collection
5899 : {
5900 1 : IHPIndex = state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex;
5901 : }
5902 :
5903 20 : if (state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow != DataSizing::AutoSize) {
5904 : // Check fan versus system supply air flow rates
5905 32 : if (state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow + 1e-10 <
5906 16 : state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(NumOfSpeedCooling)) {
5907 0 : ShowWarningError(state,
5908 0 : format("{} - air flow rate = {:.7T} in fan object is less than the MSHP system air flow rate when cooling "
5909 : "is required ({:.7T}).",
5910 0 : state.dataFurnaces->CurrentModuleObject,
5911 0 : state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow,
5912 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(NumOfSpeedCooling)));
5913 0 : ShowContinueError(
5914 : state, " The MSHP system flow rate when cooling is required is reset to the fan flow rate and the simulation continues.");
5915 0 : ShowContinueError(
5916 0 : state, " Occurs in " + state.dataFurnaces->CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
5917 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(NumOfSpeedCooling) =
5918 0 : state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow;
5919 :
5920 0 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) // set max fan flow rate to the IHP collection
5921 : {
5922 0 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).MaxCoolAirVolFlow =
5923 0 : state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow;
5924 0 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).MaxCoolAirMassFlow =
5925 0 : state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow * state.dataEnvrn->StdRhoAir;
5926 : }
5927 :
5928 : // Check flow rates in other speeds and ensure flow rates are not above the max flow rate
5929 0 : for (int i = NumOfSpeedCooling - 1; i >= 1; --i) {
5930 0 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(i) >
5931 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(i + 1)) {
5932 0 : ShowContinueError(state,
5933 0 : format(" The MSHP system flow rate when cooling is required is reset to the flow rate at higher "
5934 : "speed and the simulation continues at Speed{}.",
5935 0 : i));
5936 0 : ShowContinueError(state,
5937 0 : " Occurs in " + state.dataFurnaces->CurrentModuleObject + " = " +
5938 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5939 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(i) =
5940 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(i + 1);
5941 : }
5942 : }
5943 : }
5944 16 : if (NumOfSpeedHeating > 0) {
5945 32 : if (state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow + 1e-10 <
5946 16 : state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(NumOfSpeedHeating)) {
5947 0 : ShowWarningError(state,
5948 0 : format("{} - air flow rate = {:.7T} in fan object is less than the MSHP system air flow rate when "
5949 : "heating is required ({:.7T}).",
5950 0 : state.dataFurnaces->CurrentModuleObject,
5951 0 : state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow,
5952 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(NumOfSpeedHeating)));
5953 0 : ShowContinueError(
5954 : state,
5955 : " The MSHP system flow rate when heating is required is reset to the fan flow rate and the simulation continues.");
5956 0 : ShowContinueError(state,
5957 0 : " Occurs in " + state.dataFurnaces->CurrentModuleObject + " = " +
5958 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
5959 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(NumOfSpeedHeating) =
5960 0 : state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow;
5961 :
5962 0 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) // set max fan flow rate to the IHP collection
5963 : {
5964 0 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex)
5965 0 : .MaxHeatAirVolFlow = state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow;
5966 0 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex)
5967 0 : .MaxHeatAirMassFlow = state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow * state.dataEnvrn->StdRhoAir;
5968 : }
5969 :
5970 0 : for (int i = NumOfSpeedHeating - 1; i >= 1; --i) {
5971 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(i) >
5972 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(i + 1)) {
5973 0 : ShowContinueError(state,
5974 0 : format(" The MSHP system flow rate when heating is required is reset to the flow rate at "
5975 : "higher speed and the simulation continues at Speed{}.",
5976 0 : i));
5977 0 : ShowContinueError(state,
5978 0 : " Occurs in " + state.dataFurnaces->CurrentModuleObject +
5979 0 : " system = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
5980 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(i) =
5981 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(i + 1);
5982 : }
5983 : }
5984 : }
5985 : }
5986 16 : if (state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow < state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate &&
5987 0 : state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate != 0.0) {
5988 0 : ShowWarningError(state,
5989 0 : format("{} - air flow rate = {:.7T} in fan object is less than the MSHP system air flow rate when no "
5990 : "heating or cooling is needed ({:.7T}).",
5991 0 : state.dataFurnaces->CurrentModuleObject,
5992 0 : state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow,
5993 0 : state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate));
5994 0 : ShowContinueError(state,
5995 : " The MSHP system flow rate when no heating or cooling is needed is reset to the fan flow rate and the "
5996 : "simulation continues.");
5997 0 : ShowContinueError(
5998 0 : state, " Occurs in " + state.dataFurnaces->CurrentModuleObject + " = " + state.dataFurnaces->Furnace(FurnaceNum).Name);
5999 0 : state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate = state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow;
6000 : }
6001 16 : RhoAir = state.dataEnvrn->StdRhoAir;
6002 : // set the mass flow rates from the reset volume flow rates
6003 176 : for (int i = 1; i <= NumOfSpeedCooling; ++i) {
6004 160 : state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(i) =
6005 160 : RhoAir * state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(i);
6006 160 : if (state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow > 0.0) {
6007 160 : state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(i) =
6008 160 : state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(i) / state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow;
6009 : }
6010 : }
6011 176 : for (int i = 1; i <= NumOfSpeedHeating; ++i) {
6012 160 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(i) =
6013 160 : RhoAir * state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(i);
6014 160 : if (state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow > 0.0) {
6015 160 : state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(i) =
6016 160 : state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(i) / state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow;
6017 : }
6018 : }
6019 16 : state.dataFurnaces->Furnace(FurnaceNum).IdleMassFlowRate = RhoAir * state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate;
6020 16 : if (state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow > 0.0) {
6021 16 : state.dataFurnaces->Furnace(FurnaceNum).IdleSpeedRatio =
6022 16 : state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate / state.dataFurnaces->Furnace(FurnaceNum).FanVolFlow;
6023 : }
6024 : // set the node max and min mass flow rates based on reset volume flow rates
6025 16 : if (NumOfSpeedCooling > 0 && NumOfSpeedHeating == 0) {
6026 0 : Node(InNode).MassFlowRateMax = max(state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(NumOfSpeedCooling),
6027 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow);
6028 0 : Node(InNode).MassFlowRateMaxAvail = max(state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(NumOfSpeedCooling),
6029 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow);
6030 16 : } else if (NumOfSpeedCooling == 0 && NumOfSpeedHeating > 0) {
6031 0 : Node(InNode).MassFlowRateMax = max(state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow,
6032 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(NumOfSpeedHeating));
6033 0 : Node(InNode).MassFlowRateMaxAvail = max(state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow,
6034 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(NumOfSpeedHeating));
6035 : } else {
6036 16 : Node(InNode).MassFlowRateMax = max(state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(NumOfSpeedCooling),
6037 16 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(NumOfSpeedHeating));
6038 16 : Node(InNode).MassFlowRateMaxAvail = max(state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(NumOfSpeedCooling),
6039 16 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(NumOfSpeedHeating));
6040 : }
6041 16 : Node(InNode).MassFlowRateMin = 0.0;
6042 16 : Node(InNode).MassFlowRateMinAvail = 0.0;
6043 16 : Node(OutNode) = Node(InNode);
6044 : }
6045 : }
6046 :
6047 1498400 : state.dataFurnaces->Furnace(FurnaceNum).CheckFanFlow = false;
6048 :
6049 1498400 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6050 : } else {
6051 4897761 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6052 : }
6053 :
6054 : // Check ventilation/fan load for constant fan systems to see if load to be met changes
6055 : // Same IF logic used in Subroutine SetAverageAirFlow to determine if unit is ON or OFF
6056 :
6057 6396161 : QToCoolSetPt = 0.0;
6058 6396161 : QToHeatSetPt = 0.0;
6059 12867709 : if (OpMode == ContFanCycCoil && GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0 &&
6060 6482172 : ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).FanAvailSchedPtr) > 0.0 || state.dataHVACGlobal->TurnFansOn) &&
6061 3230462 : !state.dataHVACGlobal->TurnFansOff)) {
6062 :
6063 3230462 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
6064 1465646 : CalcVarSpeedHeatPump(state,
6065 : FurnaceNum,
6066 : false,
6067 : CompressorOperation::Off,
6068 : 1,
6069 : 0.0,
6070 : 0.0,
6071 : SensibleOutput,
6072 : LatentOutput,
6073 : 0.0,
6074 : 0.0,
6075 : OnOffAirFlowRatio,
6076 : SUPHEATERLOAD);
6077 : } else {
6078 1764816 : CalcFurnaceOutput(state,
6079 : FurnaceNum,
6080 : false,
6081 : 0,
6082 : CompressorOperation::Off,
6083 : 0.0,
6084 : 0.0,
6085 : 0.0,
6086 : 0.0,
6087 : SensibleOutput,
6088 : LatentOutput,
6089 : OnOffAirFlowRatio,
6090 : false);
6091 : }
6092 :
6093 3230462 : if (state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac > 0.0) {
6094 6460924 : if (state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceCoolingNum > 0 &&
6095 3230462 : state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum > 0) {
6096 6460924 : QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
6097 3230462 : .SequencedOutputRequiredToCoolingSP(state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceCoolingNum) /
6098 3230462 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac;
6099 6460924 : QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
6100 3230462 : .SequencedOutputRequiredToHeatingSP(state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum) /
6101 3230462 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac;
6102 : } else {
6103 0 : QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
6104 0 : .OutputRequiredToCoolingSP /
6105 0 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac;
6106 0 : QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
6107 0 : .OutputRequiredToHeatingSP /
6108 0 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac;
6109 : }
6110 : // If the furnace has a net cooling capacity (SensibleOutput < 0) and
6111 : // the zone temp is above the Tstat heating setpoint (QToHeatSetPt < 0) and
6112 : // the net cooling capacity does not just offset the cooling load
6113 3934204 : if (SensibleOutput < 0.0 && QToHeatSetPt < 0.0 &&
6114 703742 : std::abs(QToCoolSetPt - SensibleOutput) > (Small5WLoad / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac)) {
6115 : // Only switch modes when humidistat is not used or no moisture load exists, otherwise let
6116 : // reheat coil pick up load
6117 : // IF((SensibleOutput .LT. QToHeatSetPt .AND. .NOT. Furnace(FurnaceNum)%Humidistat) .OR. &
6118 : // (SensibleOutput .LT. QToHeatSetPt .AND. Furnace(FurnaceNum)%Humidistat .AND. MoistureLoad .GE. 0.0))THEN
6119 1406694 : if ((SensibleOutput < QToHeatSetPt && !state.dataFurnaces->Furnace(FurnaceNum).Humidistat) ||
6120 699893 : (SensibleOutput < QToHeatSetPt && state.dataFurnaces->Furnace(FurnaceNum).Humidistat && MoistureLoad >= 0.0)) {
6121 4627 : QZnReq = QToHeatSetPt;
6122 4627 : state.dataFurnaces->CoolingLoad = false;
6123 : // Don't set mode TRUE unless mode is allowed. Also check for floating zone.
6124 9254 : if (state.dataHeatBalFanSys->TempControlType(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) ==
6125 9250 : DataHVACGlobals::ThermostatType::SingleCooling ||
6126 4623 : state.dataHeatBalFanSys->TempControlType(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) ==
6127 : DataHVACGlobals::ThermostatType::Uncontrolled) {
6128 4 : state.dataFurnaces->HeatingLoad = false;
6129 : } else {
6130 4623 : state.dataFurnaces->HeatingLoad = true;
6131 : }
6132 :
6133 4627 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
6134 347 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6135 347 : CalcVarSpeedHeatPump(state,
6136 : FurnaceNum,
6137 : false,
6138 : CompressorOperation::Off,
6139 : 1,
6140 : 0.0,
6141 : 0.0,
6142 : SensibleOutput,
6143 : LatentOutput,
6144 : 0.0,
6145 : 0.0,
6146 : OnOffAirFlowRatio,
6147 : SUPHEATERLOAD);
6148 : } else {
6149 4280 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6150 4280 : CalcFurnaceOutput(state,
6151 : FurnaceNum,
6152 : false,
6153 : 0,
6154 : CompressorOperation::Off,
6155 : 0.0,
6156 : 0.0,
6157 : 0.0,
6158 : 0.0,
6159 : SensibleOutput,
6160 : LatentOutput,
6161 : OnOffAirFlowRatio,
6162 : false);
6163 : }
6164 4627 : if (SensibleOutput > QToHeatSetPt) {
6165 : // If changing operating mode (flow rates) does not overshoot heating setpoint, turn off heating
6166 0 : QZnReq = 0.0;
6167 0 : state.dataFurnaces->HeatingLoad = false;
6168 0 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
6169 0 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6170 : // CALL SetOnOffMassFlowRateVSCoil(FurnaceNum, Furnace(FurnaceNum)%ControlZoneNum, FirstHVACIteration, &
6171 : // AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio)
6172 : } else {
6173 0 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6174 : }
6175 : }
6176 698415 : } else if (SensibleOutput < QZnReq) {
6177 : // If the net cooling capacity meets the zone cooling load but does not overshoot heating setpoint, turn off cooling
6178 : // (dehumidification may still occur)
6179 65110 : QZnReq = 0.0;
6180 65110 : state.dataFurnaces->CoolingLoad = false;
6181 65110 : if (state.dataFurnaces->HPDehumidificationLoadFlag) {
6182 124 : state.dataFurnaces->CoolingLoad = true;
6183 124 : state.dataFurnaces->HeatingLoad = false;
6184 : }
6185 65110 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
6186 799 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6187 : // CALL SetOnOffMassFlowRateVSCoil(FurnaceNum, Furnace(FurnaceNum)%ControlZoneNum, FirstHVACIteration, &
6188 : // AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio)
6189 : } else {
6190 64311 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6191 : }
6192 : }
6193 : // the net cooling capacity just offsets the cooling load, turn off cooling
6194 2528120 : } else if (SensibleOutput < 0.0 && QToCoolSetPt < 0.0 &&
6195 700 : std::abs(QToCoolSetPt - SensibleOutput) <
6196 700 : (Small5WLoad / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac)) {
6197 700 : state.dataFurnaces->CoolingLoad = false;
6198 700 : if (state.dataFurnaces->HPDehumidificationLoadFlag) {
6199 0 : state.dataFurnaces->CoolingLoad = true;
6200 0 : state.dataFurnaces->HeatingLoad = false;
6201 : }
6202 : } // SensibleOutput .LT. 0.0d0 .AND. QToHeatSetPt .LT. 0.0d0
6203 :
6204 : // If the furnace has a net heating capacity and the zone temp is below the Tstat cooling setpoint and
6205 : // the net heating capacity does not just offset the heating load
6206 4111690 : if (SensibleOutput > 0.0 && QToCoolSetPt > 0.0 &&
6207 881228 : std::abs(SensibleOutput - QToHeatSetPt) > (Small5WLoad / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac)) {
6208 880807 : if (SensibleOutput > QToCoolSetPt) {
6209 103441 : QZnReq = QToCoolSetPt;
6210 : // Don't set mode TRUE unless mode is allowed. Also check for floating zone.
6211 206882 : if (state.dataHeatBalFanSys->TempControlType(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) ==
6212 206838 : DataHVACGlobals::ThermostatType::SingleHeating ||
6213 103397 : state.dataHeatBalFanSys->TempControlType(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) ==
6214 : DataHVACGlobals::ThermostatType::Uncontrolled) {
6215 44 : state.dataFurnaces->CoolingLoad = false;
6216 : } else {
6217 103397 : state.dataFurnaces->CoolingLoad = true;
6218 : }
6219 103441 : state.dataFurnaces->HeatingLoad = false;
6220 :
6221 103441 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
6222 7163 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6223 : // CALL SetOnOffMassFlowRateVSCoil(FurnaceNum, Furnace(FurnaceNum)%ControlZoneNum, FirstHVACIteration, &
6224 : // AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio)
6225 7163 : CalcVarSpeedHeatPump(state,
6226 : FurnaceNum,
6227 : false,
6228 : CompressorOperation::Off,
6229 : 1,
6230 : 0.0,
6231 : 0.0,
6232 : SensibleOutput,
6233 : LatentOutput,
6234 : 0.0,
6235 : 0.0,
6236 : OnOffAirFlowRatio,
6237 : SUPHEATERLOAD);
6238 : } else {
6239 96278 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6240 96278 : CalcFurnaceOutput(state,
6241 : FurnaceNum,
6242 : false,
6243 : 0,
6244 : CompressorOperation::Off,
6245 : 0.0,
6246 : 0.0,
6247 : 0.0,
6248 : 0.0,
6249 : SensibleOutput,
6250 : LatentOutput,
6251 : OnOffAirFlowRatio,
6252 : false);
6253 : }
6254 103441 : if (SensibleOutput < QToCoolSetPt) {
6255 : // If changing operating mode (flow rates) does not overshoot cooling setpoint, turn off cooling
6256 0 : if (state.dataFurnaces->HPDehumidificationLoadFlag) {
6257 0 : state.dataFurnaces->CoolingLoad = true;
6258 0 : state.dataFurnaces->HeatingLoad = false;
6259 : } else {
6260 0 : QZnReq = 0.0;
6261 0 : state.dataFurnaces->CoolingLoad = false;
6262 : }
6263 0 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
6264 0 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6265 : // CALL SetOnOffMassFlowRateVSCoil(FurnaceNum, Furnace(FurnaceNum)%ControlZoneNum, FirstHVACIteration, &
6266 : // AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio)
6267 : } else {
6268 0 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6269 : }
6270 : }
6271 777366 : } else if (SensibleOutput > QZnReq) {
6272 : // If the net heating capacity meets the zone heating load but does not overshoot, turn off heating
6273 682264 : QZnReq = 0.0;
6274 682264 : state.dataFurnaces->HeatingLoad = false;
6275 682264 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
6276 : // CALL SetOnOffMassFlowRateVSCoil(FurnaceNum, Furnace(FurnaceNum)%ControlZoneNum, FirstHVACIteration, &
6277 : // AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio)
6278 81150 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6279 : } else {
6280 601114 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6281 : }
6282 : }
6283 : // the net heating capacity just offsets the heating load, turn off heating
6284 2350076 : } else if (SensibleOutput > 0.0 && QToHeatSetPt > 0.0 &&
6285 421 : std::abs(SensibleOutput - QToHeatSetPt) <
6286 421 : (Small5WLoad / state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac)) {
6287 421 : state.dataFurnaces->HeatingLoad = false;
6288 : } // SensibleOutput .GT. 0.0d0 .AND. QToCoolSetPt .GT. 0.0d0
6289 : } // Furnace(FurnaceNum)%ControlZoneMassFlowFrac .GT. 0.0d0
6290 3230462 : ZoneLoad = QZnReq;
6291 : } // OpMode .EQ. ContFanCycCoil
6292 :
6293 6396161 : if (FirstHVACIteration) {
6294 1765439 : state.dataFurnaces->Furnace(FurnaceNum).iterationCounter = 0;
6295 1765439 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode = Furnaces::ModeOfOperation::NoCoolHeat;
6296 : }
6297 6396161 : state.dataFurnaces->Furnace(FurnaceNum).iterationCounter += 1;
6298 :
6299 : // push iteration mode stack and set current mode
6300 6396161 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode(3) = state.dataFurnaces->Furnace(FurnaceNum).iterationMode(2);
6301 6396161 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode(2) = state.dataFurnaces->Furnace(FurnaceNum).iterationMode(1);
6302 6396161 : if (state.dataFurnaces->CoolingLoad) {
6303 3386359 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode(1) = Furnaces::ModeOfOperation::CoolingMode;
6304 3009802 : } else if (state.dataFurnaces->HeatingLoad) {
6305 1944980 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode(1) = Furnaces::ModeOfOperation::HeatingMode;
6306 : } else {
6307 1064822 : state.dataFurnaces->Furnace(FurnaceNum).iterationMode(1) = Furnaces::ModeOfOperation::NoCoolHeat;
6308 : }
6309 :
6310 : // IF small loads to meet or not converging, just shut down unit
6311 6396161 : if (std::abs(ZoneLoad) < Small5WLoad) {
6312 1138159 : ZoneLoad = 0.0;
6313 1138159 : state.dataFurnaces->CoolingLoad = false;
6314 1138159 : state.dataFurnaces->HeatingLoad = false;
6315 5258002 : } else if (state.dataFurnaces->Furnace(FurnaceNum).iterationCounter > (state.dataHVACGlobal->MinAirLoopIterationsAfterFirst + 4)) {
6316 : // attempt to lock output (air flow) if oscillations are detected
6317 2017392 : OperatingMode = state.dataFurnaces->Furnace(FurnaceNum).iterationMode(1);
6318 2017392 : OperatingModeMinusOne = state.dataFurnaces->Furnace(FurnaceNum).iterationMode(2);
6319 2017392 : OperatingModeMinusTwo = state.dataFurnaces->Furnace(FurnaceNum).iterationMode(3);
6320 2017392 : Oscillate = true;
6321 2017392 : if (OperatingMode == OperatingModeMinusOne && OperatingMode == OperatingModeMinusTwo) Oscillate = false;
6322 2017392 : if (Oscillate) {
6323 32 : if (QToCoolSetPt < 0.0) {
6324 8 : state.dataFurnaces->HeatingLoad = false;
6325 8 : state.dataFurnaces->CoolingLoad = true;
6326 8 : ZoneLoad = QToCoolSetPt;
6327 24 : } else if (QToHeatSetPt > 0.0) {
6328 0 : state.dataFurnaces->HeatingLoad = true;
6329 0 : state.dataFurnaces->CoolingLoad = false;
6330 0 : ZoneLoad = QToHeatSetPt;
6331 : } else {
6332 24 : state.dataFurnaces->HeatingLoad = false;
6333 24 : state.dataFurnaces->CoolingLoad = false;
6334 24 : ZoneLoad = 0.0;
6335 : }
6336 : }
6337 : }
6338 :
6339 : // EMS override point
6340 6396161 : if (state.dataFurnaces->Furnace(FurnaceNum).EMSOverrideSensZoneLoadRequest)
6341 0 : ZoneLoad = state.dataFurnaces->Furnace(FurnaceNum).EMSSensibleZoneLoadValue;
6342 6396161 : if (state.dataFurnaces->Furnace(FurnaceNum).EMSOverrideMoistZoneLoadRequest)
6343 0 : MoistureLoad = state.dataFurnaces->Furnace(FurnaceNum).EMSMoistureZoneLoadValue;
6344 12792322 : if (state.dataFurnaces->Furnace(FurnaceNum).EMSOverrideSensZoneLoadRequest ||
6345 6396161 : state.dataFurnaces->Furnace(FurnaceNum).EMSOverrideMoistZoneLoadRequest) {
6346 0 : if ((ZoneLoad != 0.0) && (state.dataFurnaces->Furnace(FurnaceNum).EMSOverrideSensZoneLoadRequest)) {
6347 0 : PartLoadRatio = 1.0;
6348 0 : } else if ((MoistureLoad != 0.0) && (state.dataFurnaces->Furnace(FurnaceNum).EMSOverrideMoistZoneLoadRequest)) {
6349 0 : PartLoadRatio = 1.0;
6350 : } else {
6351 0 : PartLoadRatio = 0.0;
6352 : }
6353 0 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
6354 0 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio);
6355 : // CALL SetOnOffMassFlowRateVSCoil(FurnaceNum, Furnace(FurnaceNum)%ControlZoneNum, FirstHVACIteration, &
6356 : // AirLoopNum, OnOffAirFlowRatio, OpMode, QZnReq, MoistureLoad, PartLoadRatio)
6357 : } else {
6358 0 : SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, OpMode, ZoneLoad, MoistureLoad, PartLoadRatio);
6359 : }
6360 : }
6361 :
6362 : // AirflowNetwork global variable
6363 6396161 : if (state.afn->distribution_simulated) {
6364 328068 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
6365 : }
6366 6396161 : }
6367 :
6368 7251603 : void SetOnOffMassFlowRate(EnergyPlusData &state,
6369 : int const FurnaceNum, // index to furnace
6370 : [[maybe_unused]] int const AirLoopNum, // index to air loop !unused1208
6371 : Real64 &OnOffAirFlowRatio, // ratio of coil on to coil off air flow rate
6372 : int const OpMode, // fan operating mode
6373 : [[maybe_unused]] Real64 const ZoneLoad, // sensible load to be met (W) !unused1208
6374 : Real64 const MoistureLoad, // moisture load to be met (W)
6375 : Real64 const PartLoadRatio // coil part-load ratio
6376 : )
6377 : {
6378 :
6379 : // SUBROUTINE INFORMATION:
6380 : // AUTHOR Richard Raustad
6381 : // DATE WRITTEN Sep 2008
6382 : // MODIFIED na
6383 : // RE-ENGINEERED na
6384 :
6385 : // PURPOSE OF THIS SUBROUTINE:
6386 : // This subroutine is for initializations of the Furnace Components.
6387 :
6388 : // METHODOLOGY EMPLOYED:
6389 : // The HeatCool furnace/unitarysystem and air-to-air heat pump may have alternate air flow rates
6390 : // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
6391 : // air flow rates. Use these flow rates during the Calc routines to set the average mass flow rates
6392 : // based on PLR.
6393 :
6394 : // REFERENCES:
6395 : // na
6396 :
6397 : // Using/Aliasing
6398 :
6399 : // Locals
6400 : // SUBROUTINE ARGUMENT DEFINITIONS:
6401 :
6402 : // SUBROUTINE PARAMETER DEFINITIONS:
6403 : // na
6404 :
6405 : // INTERFACE BLOCK SPECIFICATIONS
6406 : // na
6407 :
6408 : // DERIVED TYPE DEFINITIONS
6409 : // na
6410 :
6411 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6412 : // na
6413 :
6414 : // Check for heat only furnace
6415 14485613 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != Furnace_HeatOnly &&
6416 7234010 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatOnly) {
6417 :
6418 : // Set the system mass flow rates
6419 7226717 : if (OpMode == ContFanCycCoil) {
6420 : // Set the compressor or coil ON mass flow rate
6421 : // constant fan mode
6422 4312330 : if (state.dataFurnaces->HeatingLoad) {
6423 : // IF a heating and moisture load exists, operate at the cooling mass flow rate ELSE operate at the heating flow rate
6424 471128 : if (MoistureLoad < 0.0 && state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
6425 7836 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
6426 6846 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
6427 6846 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
6428 : } else {
6429 456446 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow;
6430 456446 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio;
6431 : }
6432 463292 : state.dataFurnaces->Furnace(FurnaceNum).LastMode = Furnaces::ModeOfOperation::HeatingMode;
6433 : // IF a cooling load exists, operate at the cooling mass flow rate
6434 3849038 : } else if (state.dataFurnaces->CoolingLoad) {
6435 2247785 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
6436 2247785 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
6437 2247785 : state.dataFurnaces->Furnace(FurnaceNum).LastMode = Furnaces::ModeOfOperation::CoolingMode;
6438 : // If no load exists, set the compressor on mass flow rate.
6439 : // Set equal the mass flow rate when no heating or cooling is needed if no moisture load exists.
6440 : // If the user has set the off mass flow rate to 0, set according to the last operating mode.
6441 : } else {
6442 2158075 : if (MoistureLoad < 0.0 && state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
6443 556822 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
6444 526328 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
6445 526328 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
6446 : } else {
6447 1074925 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirMassFlow;
6448 1074925 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio;
6449 : // User may have entered a 0 for MaxNoCoolHeatAirMassFlow
6450 1074925 : if (state.dataFurnaces->CompOnMassFlow == 0.0) {
6451 33634 : if (state.dataFurnaces->Furnace(FurnaceNum).LastMode == Furnaces::ModeOfOperation::HeatingMode) {
6452 3390 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow;
6453 3390 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio;
6454 : } else {
6455 30244 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
6456 30244 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
6457 : }
6458 : }
6459 : }
6460 : }
6461 :
6462 : // Set the compressor or coil OFF mass flow rate based on LOGICAL flag
6463 : // UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
6464 4312330 : if (state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl == AirFlowControlConstFan::UseCompressorOnFlow) {
6465 1061086 : if (state.dataFurnaces->Furnace(FurnaceNum).LastMode == Furnaces::ModeOfOperation::HeatingMode) {
6466 157048 : if (MoistureLoad < 0.0 && state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
6467 4344 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
6468 0 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
6469 0 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
6470 : } else {
6471 152704 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow;
6472 152704 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio;
6473 : }
6474 : } else {
6475 908382 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
6476 908382 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
6477 : }
6478 : // ELSE use the user specified value
6479 : } else {
6480 3251244 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirMassFlow;
6481 3251244 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).NoHeatCoolSpeedRatio;
6482 : }
6483 : } else {
6484 : // cycling fan mode
6485 5829946 : if (state.dataFurnaces->HeatingLoad ||
6486 1458731 : (state.dataFurnaces->Furnace(FurnaceNum).Humidistat && MoistureLoad < 0.0 &&
6487 6812 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat)) {
6488 :
6489 1480844 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat && MoistureLoad < 0.0 &&
6490 4596 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
6491 1176 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
6492 1176 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
6493 1176 : state.dataFurnaces->Furnace(FurnaceNum).LastMode = Furnaces::ModeOfOperation::CoolingMode;
6494 : } else {
6495 1475072 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow;
6496 1475072 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio;
6497 1475072 : state.dataFurnaces->Furnace(FurnaceNum).LastMode = Furnaces::ModeOfOperation::HeatingMode;
6498 : }
6499 1438139 : } else if (state.dataFurnaces->CoolingLoad) {
6500 1228985 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
6501 1228985 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
6502 : } else {
6503 209154 : state.dataFurnaces->CompOnMassFlow = 0.0;
6504 209154 : state.dataFurnaces->CompOnFlowRatio = 0.0;
6505 : }
6506 2914387 : state.dataFurnaces->CompOffMassFlow = 0.0;
6507 2914387 : state.dataFurnaces->CompOffFlowRatio = 0.0;
6508 : }
6509 : } else { // Is a HeatOnly furnace
6510 :
6511 24886 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate;
6512 24886 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio;
6513 24886 : if (OpMode == ContFanCycCoil) {
6514 0 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirMassFlow;
6515 0 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio;
6516 : } else {
6517 24886 : state.dataFurnaces->CompOffMassFlow = 0.0;
6518 24886 : state.dataFurnaces->CompOffFlowRatio = 0.0;
6519 : }
6520 :
6521 : } // End check for heat only furnace or water-to-air heat pump
6522 :
6523 : // Set the system mass flow rates
6524 7251603 : SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
6525 7251603 : }
6526 :
6527 356 : void SizeFurnace(EnergyPlusData &state, int const FurnaceNum, bool const FirstHVACIteration)
6528 : {
6529 :
6530 : // SUBROUTINE INFORMATION:
6531 : // AUTHOR Fred Buhl
6532 : // DATE WRITTEN January 2002
6533 : // MODIFIED Bereket Nigusse, May 2010, removed the autosize option for the input field supply air
6534 : // flow fraction through controlled zone.
6535 : // Bo Shen, March 2012, size the air flow rates at individual speed levels for VS WSHP
6536 : // Bo Shen, ORNL, July 2012 - added variable-speed air source heat pump cooling and heating coils, using curve-fits
6537 : // RE-ENGINEERED na
6538 :
6539 : // PURPOSE OF THIS SUBROUTINE:
6540 : // This subroutine is for sizing Furnace Components for which nominal cpacities
6541 : // and flow rates have not been specified in the input
6542 :
6543 : // METHODOLOGY EMPLOYED:
6544 : // Obtains heating capacities and flow rates from the zone or system sizing arrays.
6545 : // NOTE: In UNITARYSYSTEM:HEATPUMP:AIRTOAIR we are sizing the heating capacity to be
6546 : // equal to the cooling capacity. Thus the cooling and
6547 : // and heating capacities of a DX heat pump system will be identical. In real life the ARI
6548 : // heating and cooling capacities are close but not identical.
6549 :
6550 : // REFERENCES:
6551 : // na
6552 :
6553 : // Using/Aliasing
6554 : using namespace DataSizing;
6555 : using EMSManager::ManageEMS;
6556 :
6557 : using HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil;
6558 : using IntegratedHeatPump::SizeIHP;
6559 : using VariableSpeedCoils::SimVariableSpeedCoils;
6560 : using WaterToAirHeatPumpSimple::SimWatertoAirHPSimple;
6561 :
6562 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
6563 : int ThisCtrlZoneNum; // the controlled zone number of the control zone !!!
6564 : int Iter; // iteration count
6565 : Real64 MulSpeedFlowScale; // variable speed air flow scaling factor
6566 356 : int IHPCoilIndex(0); // refer to cooling or heating coil in IHP
6567 356 : Real64 dummy(0.0);
6568 : bool anyRan;
6569 356 : ManageEMS(state, EMSManager::EMSCallFrom::UnitarySystemSizing, anyRan, ObjexxFCL::Optional_int_const()); // calling point
6570 :
6571 356 : ThisCtrlZoneNum = 0;
6572 356 : state.dataSize->DXCoolCap = 0.0;
6573 356 : state.dataSize->UnitaryHeatCap = 0.0;
6574 356 : state.dataSize->SuppHeatCap = 0.0;
6575 :
6576 356 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
6577 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanVecIndex = state.dataFurnaces->Furnace(FurnaceNum).FanIndex;
6578 0 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanModelType = DataAirSystems::ObjectVectorOOFanSystemModel;
6579 0 : state.dataSize->DataFanEnumType = DataAirSystems::ObjectVectorOOFanSystemModel;
6580 0 : state.dataSize->DataFanIndex = state.dataFurnaces->Furnace(FurnaceNum).FanIndex;
6581 : } else {
6582 356 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).SupFanNum = state.dataFurnaces->Furnace(FurnaceNum).FanIndex;
6583 356 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanModelType = DataAirSystems::StructArrayLegacyFanModels;
6584 356 : state.dataSize->DataFanEnumType = DataAirSystems::StructArrayLegacyFanModels;
6585 356 : state.dataSize->DataFanIndex = state.dataFurnaces->Furnace(FurnaceNum).FanIndex;
6586 : }
6587 356 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
6588 353 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanLocation = DataAirSystems::FanPlacement::BlowThru;
6589 3 : } else if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == DrawThru) {
6590 3 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanLocation = DataAirSystems::FanPlacement::DrawThru;
6591 : }
6592 :
6593 356 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingSingleSpeed) {
6594 204 : SimDXCoil(state, BlankString, CompressorOperation::On, true, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, 1, 0.0);
6595 152 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
6596 3 : int HXCC_Index = state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex;
6597 3 : int childCCType_Num = state.dataHVACAssistedCC->HXAssistedCoil(HXCC_Index).CoolingCoilType_Num;
6598 3 : if (childCCType_Num == DataHVACGlobals::CoilDX_Cooling) {
6599 1 : int childCCIndex = state.dataHVACAssistedCC->HXAssistedCoil(HXCC_Index).CoolingCoilIndex;
6600 1 : if (childCCIndex < 0) {
6601 0 : ShowContinueError(state, "Occurs in sizing HeatExchangerAssistedCoolingCoil.");
6602 : }
6603 1 : auto &newCoil = state.dataCoilCooingDX->coilCoolingDXs[childCCIndex];
6604 1 : newCoil.size(state);
6605 : }
6606 6 : SimHXAssistedCoolingCoil(state,
6607 : BlankString,
6608 : true,
6609 : CompressorOperation::On,
6610 : 0.0,
6611 3 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
6612 : 1,
6613 : false,
6614 : 1.0,
6615 : false);
6616 149 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingWaterToAirHPSimple) {
6617 777 : SimWatertoAirHPSimple(state,
6618 : BlankString,
6619 111 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
6620 111 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand,
6621 111 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand,
6622 : 0,
6623 : 0.0,
6624 111 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
6625 111 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
6626 111 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
6627 : CompressorOperation::Off,
6628 : 0.0,
6629 : FirstHVACIteration); // CoolPartLoadRatio
6630 111 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHPSimple) {
6631 666 : SimWatertoAirHPSimple(state,
6632 : BlankString,
6633 111 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
6634 111 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand,
6635 : dummy,
6636 : 0.0,
6637 : 0.0,
6638 111 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
6639 111 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
6640 111 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
6641 : CompressorOperation::Off,
6642 : 0.0,
6643 : FirstHVACIteration);
6644 : }
6645 62 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingWaterToAirHPVSEquationFit ||
6646 24 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
6647 20 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
6648 1 : SizeIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex);
6649 1 : IHPCoilIndex = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SCCoilIndex;
6650 1 : state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling = state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).NumOfSpeeds;
6651 2 : MulSpeedFlowScale = state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).RatedAirVolFlowRate /
6652 1 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex)
6653 1 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).NormSpedLevel);
6654 1 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).CoolVolFlowScale =
6655 : MulSpeedFlowScale;
6656 : } else {
6657 95 : SimVariableSpeedCoils(state,
6658 : BlankString,
6659 19 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
6660 : 0,
6661 19 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
6662 19 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
6663 19 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
6664 : CompressorOperation::Off,
6665 : 0.0,
6666 : 1,
6667 : 0.0,
6668 : 0.0,
6669 : 0.0,
6670 : 0.0); // conduct the sizing operation in the VS WSHP
6671 19 : state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling =
6672 19 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).NumOfSpeeds;
6673 19 : MulSpeedFlowScale =
6674 19 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).RatedAirVolFlowRate /
6675 19 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex)
6676 19 : .MSRatedAirVolFlowRate(
6677 19 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).NormSpedLevel);
6678 19 : IHPCoilIndex = state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex;
6679 : }
6680 :
6681 220 : for (Iter = 1; Iter <= state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling; ++Iter) {
6682 200 : state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(Iter) =
6683 200 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(Iter) * MulSpeedFlowScale;
6684 200 : state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(Iter) =
6685 200 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirMassFlowRate(Iter) * MulSpeedFlowScale;
6686 200 : state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(Iter) =
6687 400 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(Iter) /
6688 200 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex)
6689 200 : .MSRatedAirVolFlowRate(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling);
6690 : }
6691 :
6692 26 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHPVSEquationFit ||
6693 6 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingAirToAirVariableSpeed) {
6694 :
6695 16 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
6696 1 : SizeIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex);
6697 1 : IHPCoilIndex = state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SHCoilIndex;
6698 1 : state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating = state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).NumOfSpeeds;
6699 2 : MulSpeedFlowScale = state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).RatedAirVolFlowRate /
6700 1 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex)
6701 1 : .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).NormSpedLevel);
6702 1 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).HeatVolFlowScale =
6703 : MulSpeedFlowScale;
6704 : } else {
6705 75 : SimVariableSpeedCoils(state,
6706 : BlankString,
6707 15 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
6708 : 0,
6709 15 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
6710 15 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
6711 15 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
6712 : CompressorOperation::Off,
6713 : 0.0,
6714 : 1,
6715 : 0.0,
6716 : 0.0,
6717 : 0.0,
6718 : 0.0); // conduct the sizing operation in the VS WSHP
6719 15 : state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating =
6720 15 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).NumOfSpeeds;
6721 15 : MulSpeedFlowScale =
6722 15 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).RatedAirVolFlowRate /
6723 15 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex)
6724 15 : .MSRatedAirVolFlowRate(
6725 15 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).NormSpedLevel);
6726 15 : IHPCoilIndex = state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex;
6727 : }
6728 :
6729 176 : for (Iter = 1; Iter <= state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating; ++Iter) {
6730 160 : state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(Iter) =
6731 160 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(Iter) * MulSpeedFlowScale;
6732 160 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(Iter) =
6733 160 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirMassFlowRate(Iter) * MulSpeedFlowScale;
6734 160 : state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(Iter) =
6735 320 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(Iter) /
6736 160 : state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex)
6737 160 : .MSRatedAirVolFlowRate(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating);
6738 : }
6739 : }
6740 :
6741 20 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating > 0) {
6742 16 : state.dataFurnaces->Furnace(FurnaceNum).IdleMassFlowRate =
6743 16 : min(state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(1), state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(1));
6744 16 : state.dataFurnaces->Furnace(FurnaceNum).IdleSpeedRatio = min(state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(1),
6745 16 : state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(1));
6746 16 : state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate =
6747 16 : min(state.dataFurnaces->Furnace(FurnaceNum).HeatVolumeFlowRate(1), state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(1));
6748 : } else {
6749 4 : state.dataFurnaces->Furnace(FurnaceNum).IdleMassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(1);
6750 4 : state.dataFurnaces->Furnace(FurnaceNum).IdleSpeedRatio = state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(1);
6751 4 : state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate = state.dataFurnaces->Furnace(FurnaceNum).CoolVolumeFlowRate(1);
6752 : }
6753 :
6754 20 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == ContFanCycCoil) {
6755 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow = state.dataFurnaces->Furnace(FurnaceNum).IdleVolumeAirRate;
6756 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirMassFlow = state.dataFurnaces->Furnace(FurnaceNum).IdleMassFlowRate;
6757 0 : state.dataFurnaces->Furnace(FurnaceNum).NoHeatCoolSpeedRatio = state.dataFurnaces->Furnace(FurnaceNum).IdleSpeedRatio;
6758 : }
6759 : }
6760 :
6761 356 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate == AutoSize) {
6762 :
6763 266 : if (state.dataSize->CurSysNum > 0) {
6764 :
6765 532 : CheckSysSizing(
6766 532 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6767 266 : if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= SmallAirVolFlow) {
6768 266 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate =
6769 266 : state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
6770 : } else {
6771 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate = 0.0;
6772 : }
6773 :
6774 266 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideOn) {
6775 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate =
6776 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRateEMSOverrideValue;
6777 : }
6778 :
6779 1064 : BaseSizer::reportSizerOutput(state,
6780 266 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
6781 266 : state.dataFurnaces->Furnace(FurnaceNum).Name,
6782 : "Supply Air Flow Rate [m3/s]",
6783 532 : state.dataFurnaces->Furnace(FurnaceNum).DesignFanVolFlowRate);
6784 : }
6785 : }
6786 :
6787 356 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow == AutoSize) {
6788 :
6789 266 : if (state.dataSize->CurSysNum > 0) {
6790 :
6791 532 : CheckSysSizing(
6792 532 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6793 266 : if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= SmallAirVolFlow) {
6794 266 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow =
6795 266 : state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
6796 : } else {
6797 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow = 0.0;
6798 : }
6799 :
6800 266 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlowEMSOverrideOn) {
6801 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow =
6802 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlowEMSOverrideValue;
6803 : }
6804 1064 : BaseSizer::reportSizerOutput(state,
6805 266 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
6806 266 : state.dataFurnaces->Furnace(FurnaceNum).Name,
6807 : "Supply Air Flow Rate During Heating Operation [m3/s]",
6808 532 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirVolFlow);
6809 : }
6810 : }
6811 :
6812 356 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow == AutoSize) {
6813 :
6814 266 : if (state.dataSize->CurSysNum > 0) {
6815 :
6816 532 : CheckSysSizing(
6817 532 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6818 266 : if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= SmallAirVolFlow) {
6819 266 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow =
6820 266 : state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
6821 : } else {
6822 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow = 0.0;
6823 : }
6824 :
6825 266 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlowEMSOverrideOn) {
6826 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow =
6827 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlowEMSOverrideValue;
6828 : }
6829 :
6830 1064 : BaseSizer::reportSizerOutput(state,
6831 266 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
6832 266 : state.dataFurnaces->Furnace(FurnaceNum).Name,
6833 : "Supply Air Flow Rate During Cooling Operation [m3/s]",
6834 532 : state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirVolFlow);
6835 : }
6836 : }
6837 :
6838 356 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow == AutoSize) {
6839 :
6840 261 : if (state.dataSize->CurSysNum > 0) {
6841 :
6842 522 : CheckSysSizing(
6843 522 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6844 261 : if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= SmallAirVolFlow) {
6845 261 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow =
6846 261 : state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
6847 : } else {
6848 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow = 0.0;
6849 : }
6850 :
6851 261 : if (state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlowEMSOverrideOn) {
6852 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow =
6853 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlowEMSOverrideValue;
6854 : }
6855 :
6856 1044 : BaseSizer::reportSizerOutput(state,
6857 261 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
6858 261 : state.dataFurnaces->Furnace(FurnaceNum).Name,
6859 : "Supply Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
6860 522 : state.dataFurnaces->Furnace(FurnaceNum).MaxNoCoolHeatAirVolFlow);
6861 : }
6862 : }
6863 :
6864 356 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity == AutoSize) {
6865 :
6866 266 : if (state.dataSize->CurSysNum > 0) {
6867 :
6868 518 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
6869 252 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir) {
6870 :
6871 220 : CheckSysSizing(
6872 220 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6873 :
6874 110 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num == Coil_HeatingWaterToAirHPSimple) {
6875 96 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity =
6876 96 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex)
6877 96 : .RatedCapHeat;
6878 : } else {
6879 14 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity = state.dataSize->DXCoolCap;
6880 : }
6881 :
6882 : } else {
6883 :
6884 312 : CheckSysSizing(
6885 312 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6886 :
6887 156 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatCap;
6888 : }
6889 :
6890 266 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity < SmallLoad) {
6891 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity = 0.0;
6892 : }
6893 :
6894 1064 : BaseSizer::reportSizerOutput(state,
6895 266 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
6896 266 : state.dataFurnaces->Furnace(FurnaceNum).Name,
6897 : "Nominal Heating Capacity [W]",
6898 532 : state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity);
6899 : }
6900 : }
6901 :
6902 356 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity == AutoSize) {
6903 :
6904 266 : if (state.dataSize->CurSysNum > 0) {
6905 :
6906 532 : CheckSysSizing(
6907 532 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6908 266 : if (state.dataSize->DXCoolCap >= SmallLoad) {
6909 266 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity = state.dataSize->DXCoolCap;
6910 : } else {
6911 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity = 0.0;
6912 : }
6913 1064 : BaseSizer::reportSizerOutput(state,
6914 266 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
6915 266 : state.dataFurnaces->Furnace(FurnaceNum).Name,
6916 : "Nominal Cooling Capacity [W]",
6917 532 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity);
6918 : }
6919 : }
6920 :
6921 356 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp == AutoSize) {
6922 :
6923 83 : if (state.dataSize->CurSysNum > 0) {
6924 :
6925 166 : CheckSysSizing(
6926 166 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6927 83 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatSupTemp;
6928 332 : BaseSizer::reportSizerOutput(state,
6929 83 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
6930 83 : state.dataFurnaces->Furnace(FurnaceNum).Name,
6931 : "Maximum Supply Air Temperature from Supplemental Heater [C]",
6932 166 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp);
6933 : }
6934 : }
6935 :
6936 356 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity == AutoSize) {
6937 :
6938 110 : if (state.dataSize->CurSysNum > 0) {
6939 :
6940 220 : CheckSysSizing(
6941 220 : state, cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num), state.dataFurnaces->Furnace(FurnaceNum).Name);
6942 206 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
6943 96 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir) {
6944 : // set the supplemental heating capacity to the actual heating load
6945 110 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity =
6946 110 : state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatCap;
6947 : // if reheat needed for humidity control, make sure supplemental heating is at least as big
6948 : // as the cooling capacity
6949 110 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
6950 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
6951 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity =
6952 0 : max(state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity,
6953 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity);
6954 0 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity < SmallLoad) {
6955 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity = 0.0;
6956 : }
6957 : }
6958 :
6959 : } else {
6960 :
6961 0 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
6962 0 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
6963 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity =
6964 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignCoolingCapacity;
6965 : } else {
6966 0 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity = 0.0;
6967 : }
6968 : }
6969 :
6970 440 : BaseSizer::reportSizerOutput(state,
6971 110 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
6972 110 : state.dataFurnaces->Furnace(FurnaceNum).Name,
6973 : "Supplemental Heating Coil Nominal Capacity [W]",
6974 220 : state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity);
6975 : }
6976 : }
6977 :
6978 356 : state.dataSize->UnitaryHeatCap = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity;
6979 356 : state.dataSize->SuppHeatCap = state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity;
6980 356 : }
6981 :
6982 : // End Initialization Section of the Module
6983 : //******************************************************************************
6984 :
6985 : // Beginning of Update subroutines for the Furnace Module
6986 : // *****************************************************************************
6987 :
6988 24886 : void CalcNewZoneHeatOnlyFlowRates(EnergyPlusData &state,
6989 : int const FurnaceNum, // Index to furnace
6990 : bool const FirstHVACIteration, // Iteration flag
6991 : Real64 const ZoneLoad, // load to be met by furnace (W)
6992 : Real64 &HeatCoilLoad, // actual load passed to heating coil (W)
6993 : Real64 &OnOffAirFlowRatio // ratio of coil on to coil off air flow rate
6994 : )
6995 : {
6996 : // SUBROUTINE INFORMATION:
6997 : // AUTHOR Richard Liesen
6998 : // DATE WRITTEN Feb 2001
6999 : // MODIFIED Don Shirey and R. Raustad, Mar 2001 & Mar 2003
7000 : // RE-ENGINEERED na
7001 :
7002 : // PURPOSE OF THIS SUBROUTINE:
7003 : // This subroutine updates the coil outlet nodes by simulating a heat-only
7004 : // furnace or unitary system.
7005 :
7006 : // METHODOLOGY EMPLOYED:
7007 : // Determine the operating PLR to meet the zone sensible load.
7008 :
7009 : // REFERENCES:
7010 : // na
7011 :
7012 : // Using/Aliasing
7013 : using namespace ScheduleManager;
7014 :
7015 : // Locals
7016 : // SUBROUTINE ARGUMENT DEFINITIONS:
7017 :
7018 : // SUBROUTINE PARAMETER DEFINITIONS:
7019 24886 : int constexpr MaxIter(15); // maximum number of iterations
7020 24886 : Real64 constexpr MinPLR(0.0); // minimum part load ratio allowed
7021 :
7022 : // INTERFACE BLOCK SPECIFICATIONS
7023 : // na
7024 :
7025 : // DERIVED TYPE DEFINITIONS
7026 : // na
7027 :
7028 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7029 24886 : Real64 Error(1.0);
7030 : Real64 SystemSensibleLoad; // Sensible load to be met by furnace (W)
7031 : Real64 FullSensibleOutput; // Full sensible output of furnace (W)
7032 : Real64 FullLatentOutput; // Full latent output of furnace = 0 (W)
7033 : Real64 NoSensibleOutput; // Sensible output of furnace with no heating allowed (W)
7034 : Real64 NoLatentOutput; // Latent output of furnace = 0 (W)
7035 : Real64 PartLoadRatio; // Part load ratio of furnace
7036 : Real64 HeatErrorToler; // Error tolerance in heating mode
7037 : Real64 IterRelax; // Relaxation factor for iterations
7038 : Real64 ActualSensibleOutput; // Actual furnace sensible capacity
7039 : Real64 ActualLatentOutput; // Actual furnace latent capacity = 0
7040 : Real64 deltaT; // Heater outlet temp minus design heater outlet temp
7041 : // CHARACTER(len=20) :: ErrNum = ' ' ! For displaying error message in cooling
7042 : // INTEGER,SAVE :: ErrCount = 0
7043 : int FurnaceInletNode; // Node number of furnace inlet
7044 : int FurnaceOutletNode; // Node number of furnace outlet
7045 : int OpMode; // Mode of Operation (fan cycling or fan continuous)
7046 : // Set local variables
7047 :
7048 : // Retrieve the load on the controlled zone
7049 24886 : FurnaceOutletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
7050 24886 : FurnaceInletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
7051 24886 : int ControlZoneNode = state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone;
7052 24886 : OpMode = state.dataFurnaces->Furnace(FurnaceNum).OpMode;
7053 24886 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate;
7054 24886 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 0.0;
7055 : // OnOffAirFlowRatio = 1.0
7056 :
7057 24886 : auto &Node(state.dataLoopNodes->Node);
7058 : // Calculate the Cp Air of zone
7059 24886 : Real64 cpair = PsyCpAirFnW(Node(ControlZoneNode).HumRat);
7060 :
7061 24886 : if (FirstHVACIteration) {
7062 10752 : HeatCoilLoad = ZoneLoad;
7063 10752 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
7064 10752 : Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7065 : } else {
7066 : // If Furnace runs then set HeatCoilLoad on Heating Coil and the Mass Flow
7067 40670 : if ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0) &&
7068 26536 : (Node(FurnaceInletNode).MassFlowRate > 0.0) && (state.dataFurnaces->HeatingLoad)) {
7069 :
7070 5589 : Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7071 5589 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity;
7072 5589 : SystemSensibleLoad = ZoneLoad;
7073 :
7074 : // Get no load result
7075 5589 : if (OpMode == CycFanCycCoil) {
7076 5589 : Node(FurnaceInletNode).MassFlowRate = 0.0;
7077 : }
7078 5589 : if (OpMode == ContFanCycCoil) {
7079 0 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // The on/off fan will not cycle, so set part-load fraction = 1
7080 : }
7081 :
7082 : // Set the inlet mass flow rate based on user specified coil OFF flow rate
7083 5589 : PartLoadRatio = 0.0;
7084 5589 : SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
7085 :
7086 5589 : CalcFurnaceOutput(state,
7087 : FurnaceNum,
7088 : FirstHVACIteration,
7089 : OpMode,
7090 : CompressorOperation::On,
7091 : 0.0,
7092 : 0.0,
7093 : 0.0,
7094 : 0.0,
7095 : NoSensibleOutput,
7096 : NoLatentOutput,
7097 : OnOffAirFlowRatio,
7098 : false);
7099 :
7100 5589 : Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7101 :
7102 : // Set fan part-load fraction equal to 1 while getting full load result
7103 5589 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
7104 5589 : OnOffAirFlowRatio = 1.0;
7105 :
7106 : // Get full load result
7107 5589 : CalcFurnaceOutput(state,
7108 : FurnaceNum,
7109 : FirstHVACIteration,
7110 : OpMode,
7111 : CompressorOperation::On,
7112 : 0.0,
7113 : 1.0,
7114 : HeatCoilLoad,
7115 : 0.0,
7116 : FullSensibleOutput,
7117 : FullLatentOutput,
7118 : OnOffAirFlowRatio,
7119 : false);
7120 :
7121 : // Since we are heating, we expect FullSensibleOutput to be > 0 and FullSensibleOutput > NoSensibleOutput
7122 : // Check that this is the case; if not set PartLoadRatio = 0.0d0 (off) and return
7123 :
7124 5589 : if (FullSensibleOutput > NoSensibleOutput) {
7125 5589 : PartLoadRatio =
7126 5589 : max(MinPLR, min(1.0, std::abs(SystemSensibleLoad - NoSensibleOutput) / std::abs(FullSensibleOutput - NoSensibleOutput)));
7127 5589 : if (OpMode == CycFanCycCoil) {
7128 5589 : Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace * PartLoadRatio;
7129 5589 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * PartLoadRatio;
7130 : } else { // ContFanCycCoil
7131 0 : if (Node(FurnaceOutletNode).Temp > state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp) {
7132 0 : deltaT = Node(FurnaceOutletNode).Temp - state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp;
7133 0 : if (HeatCoilLoad > state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity)
7134 0 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity;
7135 0 : HeatCoilLoad -= Node(FurnaceInletNode).MassFlowRate * cpair * deltaT;
7136 : } else {
7137 0 : HeatCoilLoad = SystemSensibleLoad - NoSensibleOutput;
7138 : }
7139 : }
7140 :
7141 : // Calculate the part load ratio through iteration
7142 5589 : HeatErrorToler =
7143 5589 : state.dataFurnaces->Furnace(FurnaceNum).HeatingConvergenceTolerance; // Error tolerance for convergence from input deck
7144 5589 : Error = 1.0; // initialize error value for comparison against tolerance
7145 5589 : state.dataFurnaces->Iter = 0; // initialize iteration counter
7146 5589 : IterRelax = 0.9; // relaxation factor for iterations
7147 7545 : while (state.dataFurnaces->Iter <= MaxIter) {
7148 :
7149 6567 : if (OpMode == CycFanCycCoil)
7150 6567 : Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace * PartLoadRatio;
7151 6567 : CalcFurnaceOutput(state,
7152 : FurnaceNum,
7153 : FirstHVACIteration,
7154 : OpMode,
7155 : CompressorOperation::On,
7156 : 0.0,
7157 : PartLoadRatio,
7158 : HeatCoilLoad,
7159 : 0.0,
7160 : ActualSensibleOutput,
7161 : ActualLatentOutput,
7162 : OnOffAirFlowRatio,
7163 : false);
7164 :
7165 6567 : if (SystemSensibleLoad != 0.0) Error = (SystemSensibleLoad - ActualSensibleOutput) / (SystemSensibleLoad);
7166 6567 : if (std::abs(Error) <= HeatErrorToler) break;
7167 1460 : PartLoadRatio = max(
7168 : MinPLR,
7169 : min(1.0,
7170 1460 : PartLoadRatio + IterRelax * (SystemSensibleLoad - ActualSensibleOutput) / (FullSensibleOutput - NoSensibleOutput)));
7171 :
7172 : // limit the heating coil outlet air temperature to DesignMaxOutletTemp
7173 1460 : if (Node(FurnaceOutletNode).Temp > state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp) {
7174 0 : deltaT = Node(FurnaceOutletNode).Temp - state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp;
7175 0 : if (HeatCoilLoad > state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity)
7176 0 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity;
7177 0 : HeatCoilLoad -= Node(FurnaceInletNode).MassFlowRate * cpair * deltaT;
7178 0 : CalcFurnaceOutput(state,
7179 : FurnaceNum,
7180 : FirstHVACIteration,
7181 : OpMode,
7182 : CompressorOperation::On,
7183 : 0.0,
7184 : PartLoadRatio,
7185 : HeatCoilLoad,
7186 : 0.0,
7187 : ActualSensibleOutput,
7188 : ActualLatentOutput,
7189 : OnOffAirFlowRatio,
7190 : false);
7191 :
7192 0 : if (SystemSensibleLoad != 0.0) Error = (SystemSensibleLoad - ActualSensibleOutput) / (SystemSensibleLoad);
7193 0 : PartLoadRatio = max(MinPLR,
7194 : min(1.0,
7195 0 : PartLoadRatio + IterRelax * (SystemSensibleLoad - ActualSensibleOutput) /
7196 0 : (FullSensibleOutput - NoSensibleOutput)));
7197 : } else {
7198 1460 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * PartLoadRatio;
7199 : }
7200 :
7201 1460 : if (PartLoadRatio == MinPLR) break;
7202 1460 : if (PartLoadRatio == 1.0) break;
7203 978 : ++state.dataFurnaces->Iter;
7204 978 : if (state.dataFurnaces->Iter == 7) IterRelax = 0.7;
7205 978 : if (state.dataFurnaces->Iter == 15) IterRelax = 0.4;
7206 : }
7207 :
7208 5589 : if (state.dataFurnaces->Iter > MaxIter) {
7209 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingMaxIterIndex2 == 0) {
7210 0 : ShowWarningMessage(state,
7211 0 : format("{} \"{}\" -- Exceeded max heating iterations ({}) while adjusting furnace runtime.",
7212 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
7213 0 : state.dataFurnaces->Furnace(FurnaceNum).Name,
7214 0 : MaxIter));
7215 0 : ShowContinueErrorTimeStamp(state, "");
7216 : }
7217 0 : ShowRecurringWarningErrorAtEnd(state,
7218 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
7219 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
7220 : "\" -- Exceeded max heating iterations error continues...",
7221 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingMaxIterIndex2);
7222 : }
7223 :
7224 : } else { // ELSE from IF(FullSensibleOutput.GT.NoSensibleOutput)THEN above
7225 : // Set part load ratio to 1 and run heater at design heating capacity
7226 0 : PartLoadRatio = 1.0;
7227 0 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity;
7228 : }
7229 : // Set the final results
7230 : // IF (OpMode .EQ. CycFanCycCoil) THEN
7231 : // Furnace(FurnaceNum)%MdotFurnace = Furnace(FurnaceNum)%MdotFurnace * PartLoadRatio
7232 : // END IF
7233 5589 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = Node(FurnaceInletNode).MassFlowRate;
7234 :
7235 23903 : } else if ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0) &&
7236 15358 : (Node(FurnaceInletNode).MassFlowRate > 0.0) && (OpMode == ContFanCycCoil)) {
7237 0 : HeatCoilLoad = 0.0;
7238 : } else { // no heating and no flow
7239 8545 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = 0.0;
7240 8545 : HeatCoilLoad = 0.0;
7241 : } // End of the Scheduled Furnace If block
7242 :
7243 : } // End of the FirstHVACIteration control of the mass flow If block
7244 :
7245 : // Set the fan inlet node flow rates
7246 24886 : Node(FurnaceInletNode).MassFlowRateMaxAvail = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7247 24886 : Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7248 24886 : }
7249 :
7250 4760100 : void CalcNewZoneHeatCoolFlowRates(EnergyPlusData &state,
7251 : int const FurnaceNum,
7252 : bool const FirstHVACIteration,
7253 : CompressorOperation const CompressorOp, // compressor operation flag (1=On, 0=Off)
7254 : Real64 const ZoneLoad, // the control zone load (watts)
7255 : Real64 const MoistureLoad, // the control zone latent load (watts)
7256 : Real64 &HeatCoilLoad, // Heating load to be met by heating coil ( excluding heat pump DX coil)
7257 : Real64 &ReheatCoilLoad, // Heating load to be met by reheat coil using hstat (excluding HP DX coil)
7258 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON air flow to AVERAGE air flow over time step
7259 : bool &HXUnitOn // flag to control HX based on zone moisture load
7260 : )
7261 : {
7262 : // SUBROUTINE INFORMATION:
7263 : // AUTHOR Richard Liesen
7264 : // DATE WRITTEN Feb 2001
7265 : // MODIFIED R. Raustad and D. Shirey, Feb/Mar/Sept/Oct/Dec 2001, Jan/Oct 2002
7266 : // RE-ENGINEERED R. Raustad, Feb. 2005 (added RegulaFalsi for iteration technique)
7267 :
7268 : // PURPOSE OF THIS SUBROUTINE:
7269 : // This subroutine updates the coil outlet nodes.
7270 :
7271 : // METHODOLOGY EMPLOYED:
7272 : // Determine the operating PLR to meet the zone sensible load. If a humidistat is specified, determine
7273 : // the operating PLR (greater of the sensible and latent PLR) to meet the zone SENSIBLE load
7274 : // (Multimode dehumidification control) or zone LATENT load (CoolReheat dehumidification control).
7275 : // For dehumidification control type COOLREHEAT, both a sensible and latent PLR may exist for a
7276 : // single time step (heating and dehumidificaiton can occur). For all other sytem types,
7277 : // only a single PLR is allowed for any given time step.
7278 : // Order of simulation depends on dehumidification control option as described below.
7279 : // Dehumidificaiton control options:
7280 : // Dehumidification Control NONE: Cooling performance is simulated first and then heating performance. If a HX
7281 : // assisted cooling coil is selected, the HX is always active.
7282 : // Dehumidification Control COOLREHEAT: Continuous Fan Operation:
7283 : // For cooling operation, the sensible and latent capacities are calculated to
7284 : // meet the thermostat setpoint. If a HX assisted cooling coil is selected,
7285 : // the HX is always active. If the latent load is not met by operating the
7286 : // system at the sensible PLR, a new PLR is calculated to meet the humidistat
7287 : // setpoint. The reheat coil load is then calculated to meet the HEATING
7288 : // setpoint temperature.
7289 : // Cycling Fan Operation:
7290 : // The heating part-load ratio is calculated first. Since the fan will be
7291 : // controlled at the higher of the heating or cooling PLR's, a ratio of the
7292 : // cooling to heating PLR is used to pass to the cooling coil (MAX=1). This allows
7293 : // the cooling coil to operate at the heating PLR when the heating PLR is
7294 : // higher than the cooling PLR. The sensible and latent capacities are then
7295 : // calculated to meet the thermostat setpoint.
7296 : // If a HX assisted cooling coil is selected, the HX is always active.
7297 : // If the latent load is not met by operating the system at the sensible PLR,
7298 : // a new PLR is calculated to meet the humidistat setpoint.
7299 : // The reheat coil load is then calculated to meet the HEATING setpoint temperature.
7300 : // Dehumidification Control MULTIMODE: For cooling operation, the sensible and latent capacities are calculated to
7301 : // meet the thermostat setpoint. If a HX assisted cooling coil is selected,
7302 : // the HX is off for this calculation. If the latent load is not met by operating
7303 : // the system at the sensible PLR, a new PLR is calculated with the HX operating
7304 : // and the target is the thermostat setpoint. Humidity is not controlled in this
7305 : // mode. No reheat coil is used in this configuration.
7306 : // Note: A supplemental heater augments the heating capacity for air-to-air heat pumps.
7307 : // A reheat coil is used for the HeatCool furnace/unitarysystem to offset the sensible cooling when the
7308 : // dehumidification control type is COOLREHEAT. Both the supplemental and reheat heating coil load is calculated
7309 : // in the Calc routines. The actual simulation of these coils is performed in the SimFurnace routine (i.e. the
7310 : // supplemental and reheat coil loads are passed as 0 to CalcFurnaceOutput).
7311 :
7312 : // Using/Aliasing
7313 : using namespace ScheduleManager;
7314 : using namespace DataZoneEnergyDemands;
7315 :
7316 : // SUBROUTINE PARAMETER DEFINITIONS:
7317 4760100 : int constexpr MaxIter(100); // maximum number of iterations
7318 4760100 : Real64 constexpr MinPLR(0.0); // minimum part load ratio allowed
7319 :
7320 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
7321 : Real64 SystemMoistureLoad; // Total latent load to be removed by furnace/unitary system
7322 : Real64 deltaT; // Temperature rise across heating coil (C)
7323 : Real64 TempOutHeatingCoil; // Temperature leaving heating coil (C)
7324 : Real64 FullSensibleOutput; // Full sensible output of AC (W)
7325 : Real64 FullLatentOutput; // Full latent output of AC (W)
7326 : Real64 NoCoolOutput; // Sensible output of AC with no cooling allowed (W)
7327 : Real64 NoHeatOutput; // Sensible output of heater with no heating allowed (W)
7328 : Real64 NoLatentOutput; // Latent output of AC with no cooling allowed (W)
7329 : int FurnaceInletNode; // Inlet node to furnace or unitary system
7330 : int FurnaceOutletNode; // Outlet node of furnace or unitary system
7331 : int OpMode; // Mode of Operation (fan cycling = 1 or fan continuous = 2)
7332 : Real64 CoolErrorToler; // Error tolerance in cooling mode
7333 : Real64 HeatErrorToler; // Error tolerance in heating mode
7334 : Real64 ActualSensibleOutput; // Actual furnace sensible capacity
7335 : Real64 ActualLatentOutput; // Actual furnace latent capacity
7336 : Real64 PartLoadRatio; // Part load ratio (greater of sensible or latent part load ratio for cooling,
7337 : // or heating PLR)
7338 : Real64 LatentPartLoadRatio; // Part load ratio to meet dehumidification load
7339 : Real64 TempCoolOutput; // Temporary Sensible output of AC while iterating on PLR (W)
7340 : Real64 TempHeatOutput; // Temporary Sensible output of heating coil while iterating on PLR (W)
7341 : Real64 TempLatentOutput; // Temporary Latent output of AC at increasing PLR (W)
7342 : // ! (Temp variables are used to find min PLR for positive latent removal)
7343 : std::array<Real64, 10> Par; // parameters passed to RegulaFalsi function
7344 : int SolFlag; // return flag from RegulaFalsi
7345 : Real64 TempMinPLR; // Temporary min latent PLR when hum control is required and iter is exceeded
7346 : Real64 TempMinPLR2; // Temporary min latent PLR when cyc fan hum control is required and iter is exceeded
7347 : Real64 TempMaxPLR; // Temporary max latent PLR when hum control is required and iter is exceeded
7348 : Real64 QToHeatSetPt; // Load required to meet heating setpoint temp (>0 is a heating load)
7349 : Real64 CoolingHeatingPLRRatio; // ratio of cooling to heating PLR (MAX=1). Used in heating mode.
7350 : Real64 HeatingSensibleOutput;
7351 : Real64 HeatingLatentOutput;
7352 : Real64 OutdoorDryBulbTemp; // secondary coil (condenser) entering dry bulb temperature
7353 :
7354 4760100 : auto &CoolCoilLoad = state.dataFurnaces->CoolCoilLoad;
7355 4760100 : auto &SystemSensibleLoad = state.dataFurnaces->SystemSensibleLoad;
7356 4760100 : auto &HumControl = state.dataFurnaces->HumControl;
7357 :
7358 : // Set local variables
7359 4760100 : FurnaceOutletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
7360 4760100 : FurnaceInletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
7361 4760100 : int ControlZoneNode = state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone;
7362 4760100 : OpMode = state.dataFurnaces->Furnace(FurnaceNum).OpMode;
7363 4760100 : HumControl = false;
7364 : // Calculate the Cp Air of zone
7365 4760100 : Real64 cpair = PsyCpAirFnW(state.dataLoopNodes->Node(ControlZoneNode).HumRat);
7366 4760100 : NoHeatOutput = 0.0;
7367 4760100 : SystemSensibleLoad = 0.0;
7368 4760100 : ReheatCoilLoad = 0.0;
7369 4760100 : HeatCoilLoad = 0.0;
7370 4760100 : ReheatCoilLoad = 0.0;
7371 4760100 : PartLoadRatio = 0.0;
7372 :
7373 4760100 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir) {
7374 972476 : if (state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex)
7375 486238 : .IsSecondaryDXCoilInZone) { // assumes compressor is in same location as secondary coil
7376 16744 : OutdoorDryBulbTemp =
7377 : state.dataZoneTempPredictorCorrector
7378 16744 : ->zoneHeatBalance(state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).SecZonePtr)
7379 : .ZT;
7380 469494 : } else if (state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).IsSecondaryDXCoilInZone) {
7381 0 : OutdoorDryBulbTemp =
7382 : state.dataZoneTempPredictorCorrector
7383 0 : ->zoneHeatBalance(state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SecZonePtr)
7384 : .ZT;
7385 : } else {
7386 469494 : if (state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum > 0) {
7387 63924 : OutdoorDryBulbTemp = state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum).Temp;
7388 : } else {
7389 405570 : OutdoorDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
7390 : }
7391 : }
7392 : } else {
7393 4273862 : OutdoorDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
7394 : }
7395 4760100 : if (FirstHVACIteration) {
7396 : // Set selected values during first HVAC iteration
7397 :
7398 : // Init for heating
7399 1632047 : if (state.dataFurnaces->HeatingLoad) {
7400 1240904 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
7401 625850 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
7402 114432 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple)) {
7403 166250 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 1.0;
7404 166250 : HeatCoilLoad = 0.0;
7405 166250 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
7406 166250 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
7407 166250 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
7408 : } else { // for furnaces
7409 396986 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 0.0;
7410 396986 : HeatCoilLoad = ZoneLoad;
7411 396986 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7412 396986 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
7413 396986 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
7414 396986 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
7415 : }
7416 563236 : ReheatCoilLoad = 0.0;
7417 563236 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 0.0;
7418 :
7419 : // Init for cooling
7420 1068811 : } else if (state.dataFurnaces->CoolingLoad) {
7421 : // air to air heat pumps
7422 585333 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 1.0;
7423 585333 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 0.0;
7424 585333 : HeatCoilLoad = 0.0;
7425 585333 : ReheatCoilLoad = 0.0;
7426 :
7427 : // Init for moisture load only
7428 : } else {
7429 483478 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 0.0;
7430 483478 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 0.0;
7431 483478 : HeatCoilLoad = 0.0;
7432 483478 : ReheatCoilLoad = 0.0;
7433 483478 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
7434 483478 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
7435 483478 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
7436 : }
7437 :
7438 3264094 : SetAverageAirFlow(
7439 : state,
7440 : FurnaceNum,
7441 3264094 : max(state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio, state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio),
7442 : OnOffAirFlowRatio);
7443 : // if dehumidification load exists (for heat pumps) turn on the supplmental heater
7444 1632047 : if (state.dataFurnaces->HPDehumidificationLoadFlag) HumControl = true;
7445 : } else { // not FirstHVACIteration
7446 : // Init for heating
7447 3128053 : if (state.dataFurnaces->HeatingLoad) {
7448 1214645 : CoolCoilLoad = 0.0;
7449 2967788 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
7450 1665853 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
7451 538498 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple)) {
7452 625788 : SystemSensibleLoad = ZoneLoad;
7453 625788 : SystemMoistureLoad = 0.0;
7454 625788 : HeatCoilLoad = 0.0;
7455 625788 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = SystemSensibleLoad;
7456 625788 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
7457 625788 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
7458 : } else {
7459 588857 : SystemMoistureLoad = MoistureLoad;
7460 588857 : HeatCoilLoad = ZoneLoad;
7461 : }
7462 :
7463 : // Init for cooling
7464 1913408 : } else if (state.dataFurnaces->CoolingLoad) {
7465 1370237 : CoolCoilLoad = ZoneLoad;
7466 1370237 : SystemMoistureLoad = MoistureLoad;
7467 1370237 : HeatCoilLoad = 0.0;
7468 1370237 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = std::abs(CoolCoilLoad);
7469 1370237 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = std::abs(SystemMoistureLoad);
7470 1370237 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
7471 :
7472 : // Init for latent
7473 : } else {
7474 543171 : SystemMoistureLoad = MoistureLoad;
7475 543171 : CoolCoilLoad = 0.0;
7476 543171 : HeatCoilLoad = 0.0;
7477 : // set report variables
7478 543171 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
7479 543171 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = SystemMoistureLoad;
7480 543171 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
7481 : }
7482 3128053 : HeatingSensibleOutput = 0.0;
7483 3128053 : HeatingLatentOutput = 0.0;
7484 3128053 : ReheatCoilLoad = 0.0;
7485 3128053 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 0.0;
7486 3128053 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 0.0;
7487 3128053 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
7488 3128053 : state.dataFurnaces->Furnace(FurnaceNum).DehumidInducedHeatingDemandRate = 0.0;
7489 :
7490 : // When humidity control is used with cycling fan control and a heating load exists, if a moisture load
7491 : // also exists, the heating PLR must be available for the cooling coil calculations.
7492 : //*********** Heating Section ************
7493 : // If Furnace runs with a heating load then set HeatCoilLoad on Heating Coil and the Mass Flow
7494 : // (Node(FurnaceInletNode)%MassFlowRate .gt. 0.0d0) .and. &
7495 3128053 : if ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0) && (state.dataFurnaces->HeatingLoad)) {
7496 :
7497 : // Heat pumps only calculate a single PLR each time step (i.e. only cooling or heating allowed in a single time step)
7498 2946500 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
7499 1655209 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
7500 538498 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple)) {
7501 :
7502 625788 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7503 :
7504 : // Get no load result
7505 625788 : if (OpMode == CycFanCycCoil) {
7506 590932 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = 0.0;
7507 : }
7508 :
7509 : // Set the inlet mass flow rate based on user specified coil OFF flow rate
7510 625788 : PartLoadRatio = 0.0;
7511 :
7512 625788 : SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
7513 :
7514 : // Set the input parameters for CalcFurnaceOutput
7515 625788 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0; // compressor off
7516 625788 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 0.0;
7517 :
7518 625788 : CalcFurnaceOutput(state,
7519 : FurnaceNum,
7520 : FirstHVACIteration,
7521 : OpMode,
7522 : CompressorOp,
7523 : 0.0,
7524 : MinPLR,
7525 : 0.0,
7526 : 0.0,
7527 : NoHeatOutput,
7528 : NoLatentOutput,
7529 : OnOffAirFlowRatio,
7530 : false);
7531 :
7532 625788 : PartLoadRatio = 1.0;
7533 625788 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7534 :
7535 625788 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 1.0; // compressor ON
7536 625788 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 1.0;
7537 :
7538 : // Set fan part-load fraction equal to 1 while getting full load result
7539 625788 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
7540 625788 : OnOffAirFlowRatio = 1.0;
7541 :
7542 : // Get full load result
7543 625788 : CalcFurnaceOutput(state,
7544 : FurnaceNum,
7545 : FirstHVACIteration,
7546 : OpMode,
7547 : CompressorOp,
7548 : 0.0,
7549 : PartLoadRatio,
7550 : 0.0,
7551 : 0.0,
7552 : FullSensibleOutput,
7553 : FullLatentOutput,
7554 : OnOffAirFlowRatio,
7555 : false);
7556 :
7557 : // Check that SystemSensibleLoad is between FullSensibleOutput and NoHeatOutput
7558 : // If so then calculate PartLoadRatio for the DX Heating coil
7559 625788 : if (SystemSensibleLoad < FullSensibleOutput && SystemSensibleLoad > NoHeatOutput) {
7560 :
7561 : // check bounds on sensible output prior to iteration using RegulaFalsi
7562 544654 : if (FullSensibleOutput < SystemSensibleLoad) {
7563 0 : PartLoadRatio = 1.0;
7564 544654 : } else if (NoHeatOutput > SystemSensibleLoad) {
7565 0 : PartLoadRatio = 0.0;
7566 : } else {
7567 :
7568 : // Calculate the part load ratio through iteration
7569 544654 : HeatErrorToler = state.dataFurnaces->Furnace(FurnaceNum)
7570 : .HeatingConvergenceTolerance; // Error tolerance for convergence from input deck
7571 :
7572 544654 : SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
7573 544654 : Par[0] = double(FurnaceNum);
7574 544654 : Par[1] = 0.0; // FLAG, if 1.0 then FirstHVACIteration equals TRUE, if 0.0 then FirstHVACIteration equals false
7575 544654 : if (FirstHVACIteration) Par[1] = 1.0;
7576 544654 : Par[2] = double(OpMode);
7577 544654 : Par[3] = double(CompressorOp);
7578 544654 : Par[4] = SystemSensibleLoad;
7579 544654 : Par[5] = 0.0; // FLAG, 0.0 if heating load, 1.0 if cooling or moisture load
7580 544654 : Par[6] = 1.0; // FLAG, 0.0 if latent load, 1.0 if sensible load to be met
7581 544654 : Par[7] = OnOffAirFlowRatio; // Ratio of compressor ON mass flow rate to AVERAGE mass flow rate over time step
7582 544654 : Par[8] = 0.0; // HXUnitOn is always false for HX
7583 544654 : Par[9] = 0.0;
7584 : // HeatErrorToler is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
7585 3277668 : auto f = [&state, FurnaceNum, FirstHVACIteration, OpMode, CompressorOp, SystemSensibleLoad](Real64 const PartLoadRatio) {
7586 1638834 : return CalcFurnaceResidual(state,
7587 : PartLoadRatio,
7588 : FurnaceNum,
7589 : FirstHVACIteration,
7590 : OpMode,
7591 : CompressorOp,
7592 : SystemSensibleLoad,
7593 : 0.0, // par6_loadFlag,
7594 : 1.0, // par7_sensLatentFlag,
7595 : 0.0, // par9_HXOnFlag,
7596 : 0.0); // par10_HeatingCoilPLR);
7597 2183488 : };
7598 544654 : General::SolveRoot(state, HeatErrorToler, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
7599 : // OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
7600 544654 : OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
7601 544654 : if (SolFlag < 0) {
7602 0 : if (SolFlag == -1) {
7603 0 : CalcFurnaceOutput(state,
7604 : FurnaceNum,
7605 : FirstHVACIteration,
7606 : OpMode,
7607 : CompressorOp,
7608 : 0.0,
7609 : PartLoadRatio,
7610 : 0.0,
7611 : 0.0,
7612 : TempHeatOutput,
7613 : TempLatentOutput,
7614 : OnOffAirFlowRatio,
7615 : false);
7616 0 : if (std::abs(SystemSensibleLoad - TempHeatOutput) > SmallLoad) {
7617 0 : if (state.dataFurnaces->Furnace(FurnaceNum).DXHeatingMaxIterIndex == 0) {
7618 0 : ShowWarningMessage(state,
7619 0 : "Heating coil control failed to converge for " +
7620 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
7621 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
7622 0 : ShowContinueError(state,
7623 : " Iteration limit exceeded in calculating DX heating coil sensible part-load ratio.");
7624 0 : ShowContinueErrorTimeStamp(
7625 : state,
7626 0 : format("Sensible load to be met by DX heating coil = {:.2T} (watts), sensible output of DX heating "
7627 : "coil = {:.2T} (watts), and the simulation continues.",
7628 : SystemSensibleLoad,
7629 0 : TempHeatOutput));
7630 : }
7631 0 : ShowRecurringWarningErrorAtEnd(
7632 : state,
7633 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
7634 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
7635 : "\" - Iteration limit exceeded in calculating DX sensible heating part-load ratio error continues. "
7636 : "Sensible load statistics:",
7637 0 : state.dataFurnaces->Furnace(FurnaceNum).DXHeatingMaxIterIndex,
7638 : SystemSensibleLoad,
7639 : SystemSensibleLoad);
7640 : }
7641 0 : } else if (SolFlag == -2) {
7642 0 : if (state.dataFurnaces->Furnace(FurnaceNum).DXHeatingRegulaFalsiFailedIndex == 0) {
7643 0 : ShowWarningMessage(state,
7644 0 : "Heating coil control failed for " +
7645 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
7646 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
7647 0 : ShowContinueError(state, " DX sensible heating part-load ratio determined to be outside the range of 0-1.");
7648 0 : ShowContinueErrorTimeStamp(
7649 : state,
7650 0 : format("Sensible load to be met by DX heating coil = {:.2T} (watts), and the simulation continues.",
7651 0 : SystemSensibleLoad));
7652 : }
7653 0 : ShowRecurringWarningErrorAtEnd(
7654 : state,
7655 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
7656 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
7657 : "\" - DX sensible heating part-load ratio out of range error continues. Sensible load statistics:",
7658 0 : state.dataFurnaces->Furnace(FurnaceNum).DXHeatingRegulaFalsiFailedIndex,
7659 : SystemSensibleLoad,
7660 : SystemSensibleLoad);
7661 : }
7662 : }
7663 : }
7664 :
7665 544654 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = PartLoadRatio;
7666 : // Check if Heat Pump compressor is allowed to run based on outdoor temperature
7667 544654 : if (OutdoorDryBulbTemp > state.dataFurnaces->Furnace(FurnaceNum).MinOATCompressorHeating) {
7668 544642 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadRatio;
7669 : } else {
7670 12 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
7671 544654 : }
7672 81134 : } else if (SystemSensibleLoad > FullSensibleOutput) {
7673 : // SystemSensibleLoad is greater than full DX Heating coil output so heat pump runs entire
7674 : // timestep and additional supplemental heating is required
7675 81134 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 1.0;
7676 81134 : if (OutdoorDryBulbTemp > state.dataFurnaces->Furnace(FurnaceNum).MinOATCompressorHeating) {
7677 : // Check to see if Heat Pump compressor was allowed to run based on outdoor temperature
7678 4130 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 1.0;
7679 : } else {
7680 77004 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
7681 : }
7682 0 : } else if (SystemSensibleLoad < NoHeatOutput) {
7683 : // SystemSensibleLoad is less than minimum DX Heating coil output so heat pump does not run and
7684 : // the load will be met by the supplemental heater
7685 0 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
7686 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 1.0;
7687 : }
7688 625788 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio == 1.0) {
7689 : // Determine the load on the supplemental heating coil
7690 81134 : if ((SystemSensibleLoad - FullSensibleOutput) > state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity) {
7691 24994 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignSuppHeatingCapacity;
7692 49988 : TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceOutletNode).Temp +
7693 24994 : HeatCoilLoad / (cpair * state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace);
7694 56140 : } else if (SystemSensibleLoad < NoHeatOutput) {
7695 0 : HeatCoilLoad = max(0.0, SystemSensibleLoad); // BG 10/22/2008 need a case for when its all suppl heat
7696 0 : TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceInletNode).Temp +
7697 0 : HeatCoilLoad / (cpair * state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace);
7698 : } else {
7699 56140 : HeatCoilLoad = max(0.0, (SystemSensibleLoad - FullSensibleOutput));
7700 112280 : TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceOutletNode).Temp +
7701 56140 : HeatCoilLoad / (cpair * state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace);
7702 : }
7703 81134 : if (OutdoorDryBulbTemp > state.dataFurnaces->Furnace(FurnaceNum).MaxOATSuppHeat) {
7704 0 : HeatCoilLoad = 0.0;
7705 0 : if (SystemSensibleLoad < NoHeatOutput) {
7706 0 : TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceInletNode).Temp;
7707 : } else {
7708 0 : TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceOutletNode).Temp;
7709 : }
7710 : }
7711 81134 : if ((TempOutHeatingCoil > state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp) && (HeatCoilLoad > 0.0)) {
7712 : // deltaT = Furnace(FurnaceNum)%DesignMaxOutletTemp - Node(FurnaceOutletNode)%Temp
7713 : // BG 10/22/2008 above made no sense if DX heat is off and its all supplemental,
7714 : // because Node(FurnaceOutletNode)%Temp will have been calc'd with full DX heat in last faux call to CalcFurnaceOutput
7715 :
7716 1378 : Real64 cpairSupply = PsyCpAirFnW(state.dataLoopNodes->Node(FurnaceInletNode).HumRat);
7717 1378 : deltaT = (state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp - TempOutHeatingCoil);
7718 1378 : HeatCoilLoad += (state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate * cpairSupply * deltaT);
7719 1378 : HeatCoilLoad = max(0.0, HeatCoilLoad);
7720 : }
7721 : } else {
7722 544654 : HeatCoilLoad = 0.0;
7723 : }
7724 625788 : PartLoadRatio = 0.0;
7725 :
7726 : // HeatCool systems can have both a sensible and latent PLR in a single time step
7727 : // (i.e. both cooling and heating can occur in a single time step)
7728 : } else { // else not a heatpump DX coil ** non-HP heating coils are not DX so testing if OutdoorDryBulbTemp < MinOATCompressorHeating
7729 : // is not necessary **
7730 :
7731 578213 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7732 578213 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity;
7733 578213 : SystemSensibleLoad = ZoneLoad;
7734 :
7735 : // Get no load result
7736 578213 : if (OpMode == CycFanCycCoil) {
7737 432039 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = 0.0;
7738 : }
7739 578213 : if (OpMode == ContFanCycCoil) {
7740 146174 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // The on/off fan will not cycle, so set part-load fraction = 1
7741 : }
7742 :
7743 : // Set the inlet mass flow rate based on user specified coil OFF flow rate
7744 578213 : PartLoadRatio = 0.0;
7745 578213 : SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
7746 :
7747 578213 : CalcFurnaceOutput(state,
7748 : FurnaceNum,
7749 : FirstHVACIteration,
7750 : OpMode,
7751 : CompressorOp,
7752 : 0.0,
7753 : MinPLR,
7754 : 0.0,
7755 : 0.0,
7756 : NoHeatOutput,
7757 : NoLatentOutput,
7758 : OnOffAirFlowRatio,
7759 : false);
7760 :
7761 578213 : if (NoHeatOutput < SystemSensibleLoad) {
7762 578213 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
7763 :
7764 : // Set fan part-load fraction equal to 1 while getting full load result
7765 578213 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
7766 578213 : OnOffAirFlowRatio = 1.0;
7767 :
7768 : // Get full load result
7769 578213 : CalcFurnaceOutput(state,
7770 : FurnaceNum,
7771 : FirstHVACIteration,
7772 : OpMode,
7773 : CompressorOp,
7774 : 0.0,
7775 : 1.0,
7776 : HeatCoilLoad,
7777 : 0.0,
7778 : FullSensibleOutput,
7779 : FullLatentOutput,
7780 : OnOffAirFlowRatio,
7781 : false);
7782 : } else {
7783 0 : FullSensibleOutput = NoHeatOutput + 0.000000001;
7784 : }
7785 :
7786 : // Since we are heating, we expect FullSensibleOutput to be > 0 and FullSensibleOutput > NoSensibleOutput
7787 : // Check that this is the case; if not set PartLoadRatio = 0.0 (off) and return
7788 :
7789 578213 : if (FullSensibleOutput > NoHeatOutput) {
7790 :
7791 : // check bounds on sensible output prior to iteration using RegulaFalsi
7792 523449 : if (FullSensibleOutput <= SystemSensibleLoad) {
7793 95073 : PartLoadRatio = 1.0;
7794 : // save modified HeatCoilLoad in case it was reset because outlet temp > DesignMaxOutletTemp
7795 95073 : if (state.dataFurnaces->ModifiedHeatCoilLoad > 0.0) {
7796 14368 : HeatCoilLoad = state.dataFurnaces->ModifiedHeatCoilLoad;
7797 : } else {
7798 80705 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity;
7799 : }
7800 428376 : } else if (NoHeatOutput >= SystemSensibleLoad) {
7801 0 : PartLoadRatio = 0.0;
7802 0 : HeatCoilLoad = 0.0;
7803 : } else {
7804 :
7805 : // Calculate the part load ratio through iteration
7806 428376 : HeatErrorToler = state.dataFurnaces->Furnace(FurnaceNum)
7807 : .HeatingConvergenceTolerance; // Error tolerance for convergence from input deck
7808 :
7809 428376 : SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
7810 428376 : Par[0] = double(FurnaceNum);
7811 428376 : Par[1] = 0.0; // FLAG, if 1.0 then FirstHVACIteration equals TRUE, if 0.0 then FirstHVACIteration equals false
7812 428376 : if (FirstHVACIteration) Par[1] = 1.0;
7813 428376 : Par[2] = double(OpMode);
7814 428376 : Par[3] = double(CompressorOp);
7815 428376 : Par[4] = SystemSensibleLoad;
7816 428376 : Par[5] = 0.0; // FLAG, 0.0 if heating load, 1.0 if cooling or moisture load
7817 428376 : Par[6] = 1.0; // FLAG, 0.0 if latent load, 1.0 if sensible load to be met
7818 428376 : Par[7] = OnOffAirFlowRatio; // Ratio of compressor ON mass flow rate to AVERAGE mass flow rate over time step
7819 428376 : Par[8] = 0.0; // HXUnitOn is always false for HX
7820 428376 : Par[9] = 0.0;
7821 : // HeatErrorToler is in fraction load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
7822 2579828 : auto f = [&state, FurnaceNum, FirstHVACIteration, OpMode, CompressorOp, SystemSensibleLoad](Real64 const PartLoadRatio) {
7823 1289914 : return CalcFurnaceResidual(state,
7824 : PartLoadRatio,
7825 : FurnaceNum,
7826 : FirstHVACIteration,
7827 : OpMode,
7828 : CompressorOp,
7829 : SystemSensibleLoad,
7830 : 0.0, // par6_loadFlag,
7831 : 1.0, // par7_sensLatentFlag,
7832 : 0.0, // par9_HXOnFlag,
7833 : 0.0); // par10_HeatingCoilPLR);
7834 1718290 : };
7835 428376 : General::SolveRoot(state, HeatErrorToler, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
7836 : // OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
7837 428376 : OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
7838 : // Reset HeatCoilLoad calculated in CalcFurnaceResidual (in case it was reset because output temp >
7839 : // DesignMaxOutletTemp)
7840 428376 : if (state.dataFurnaces->ModifiedHeatCoilLoad > 0.0) {
7841 61646 : HeatCoilLoad = state.dataFurnaces->ModifiedHeatCoilLoad;
7842 : } else {
7843 366730 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * PartLoadRatio;
7844 : }
7845 428376 : if (SolFlag == -1) {
7846 :
7847 : // RegulaFalsi may not find heating PLR when the maximum supply air temperature is exceeded.
7848 : // If iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
7849 0 : TempMaxPLR = -0.1;
7850 0 : TempHeatOutput = NoHeatOutput;
7851 0 : while ((TempHeatOutput - SystemSensibleLoad) < 0.0 && TempMaxPLR < 1.0) {
7852 : // find upper limit of HeatingPLR
7853 0 : TempMaxPLR += 0.1;
7854 0 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * TempMaxPLR;
7855 0 : CalcFurnaceOutput(state,
7856 : FurnaceNum,
7857 : FirstHVACIteration,
7858 : OpMode,
7859 : CompressorOp,
7860 : 0.0,
7861 : TempMaxPLR,
7862 : HeatCoilLoad,
7863 : 0.0,
7864 : TempHeatOutput,
7865 : TempLatentOutput,
7866 : OnOffAirFlowRatio,
7867 : false);
7868 : }
7869 0 : TempMinPLR = TempMaxPLR;
7870 0 : while ((TempHeatOutput - SystemSensibleLoad) > 0.0 && TempMinPLR > 0.0) {
7871 : // pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds
7872 : // SystemSensibleLoad)
7873 0 : TempMaxPLR = TempMinPLR;
7874 : // find minimum limit of HeatingPLR
7875 0 : TempMinPLR -= 0.01;
7876 :
7877 0 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * TempMinPLR;
7878 0 : CalcFurnaceOutput(state,
7879 : FurnaceNum,
7880 : FirstHVACIteration,
7881 : OpMode,
7882 : CompressorOp,
7883 : 0.0,
7884 : TempMinPLR,
7885 : HeatCoilLoad,
7886 : 0.0,
7887 : TempHeatOutput,
7888 : TempLatentOutput,
7889 : OnOffAirFlowRatio,
7890 : false);
7891 : }
7892 : // Now solve again with tighter PLR limits
7893 : auto f =
7894 0 : [&state, FurnaceNum, FirstHVACIteration, OpMode, CompressorOp, SystemSensibleLoad](Real64 const PartLoadRatio) {
7895 0 : return CalcFurnaceResidual(state,
7896 : PartLoadRatio,
7897 : FurnaceNum,
7898 : FirstHVACIteration,
7899 : OpMode,
7900 : CompressorOp,
7901 : SystemSensibleLoad,
7902 : 0.0, // par6_loadFlag,
7903 : 1.0, // par7_sensLatentFlag,
7904 : 0.0, // par9_HXOnFlag,
7905 : 0.0); // par10_HeatingCoilPLR);
7906 0 : };
7907 0 : General::SolveRoot(state, HeatErrorToler, MaxIter, SolFlag, PartLoadRatio, f, TempMinPLR, TempMaxPLR);
7908 0 : if (state.dataFurnaces->ModifiedHeatCoilLoad > 0.0) {
7909 0 : HeatCoilLoad = state.dataFurnaces->ModifiedHeatCoilLoad;
7910 : } else {
7911 0 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * PartLoadRatio;
7912 : }
7913 0 : CalcFurnaceOutput(state,
7914 : FurnaceNum,
7915 : FirstHVACIteration,
7916 : OpMode,
7917 : CompressorOp,
7918 : 0.0,
7919 : PartLoadRatio,
7920 : HeatCoilLoad,
7921 : 0.0,
7922 : TempHeatOutput,
7923 : TempLatentOutput,
7924 : OnOffAirFlowRatio,
7925 : false);
7926 :
7927 : // After iterating with tighter boundaries, if still out of tolerance, show warning.
7928 0 : if (SolFlag == -1 && std::abs(SystemSensibleLoad - TempHeatOutput) > SmallLoad) {
7929 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingMaxIterIndex == 0) {
7930 0 : ShowWarningMessage(state,
7931 0 : "Heating coil control failed to converge for " +
7932 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
7933 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
7934 0 : ShowContinueError(state, " Iteration limit exceeded in calculating heating coil sensible part-load ratio.");
7935 0 : ShowContinueErrorTimeStamp(state,
7936 0 : format("Sensible load to be met by heating coil = {:.2T} (watts), sensible output "
7937 : "of heating coil = {:.2T} (watts), and the simulation continues.",
7938 : SystemSensibleLoad,
7939 0 : TempHeatOutput));
7940 : }
7941 0 : ShowRecurringWarningErrorAtEnd(state,
7942 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
7943 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
7944 : "\" - Iteration limit exceeded in calculating sensible heating part-load "
7945 : "ratio error continues. Sensible load statistics:",
7946 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingMaxIterIndex,
7947 : SystemSensibleLoad,
7948 : SystemSensibleLoad);
7949 : }
7950 428376 : } else if (SolFlag == -2) {
7951 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatingRegulaFalsiFailedIndex == 0) {
7952 0 : ShowWarningMessage(state,
7953 0 : "Heating coil control failed for " +
7954 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
7955 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
7956 0 : ShowContinueError(state, " Sensible heating part-load ratio determined to be outside the range of 0-1.");
7957 0 : ShowContinueErrorTimeStamp(
7958 : state,
7959 0 : format("Sensible load to be met by heating coil = {:.2T} (watts), and the simulation continues.",
7960 0 : SystemSensibleLoad));
7961 : }
7962 0 : ShowRecurringWarningErrorAtEnd(
7963 : state,
7964 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
7965 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
7966 : "\" - Sensible heating part-load ratio out of range error continues. Sensible load statistics:",
7967 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingRegulaFalsiFailedIndex,
7968 : SystemSensibleLoad,
7969 : SystemSensibleLoad);
7970 : }
7971 : }
7972 :
7973 : } else { // ELSE from IF(FullSensibleOutput.GT.NoSensibleOutput)THEN above
7974 : // Set part load ratio to 1 and run heater at design heating capacity
7975 54764 : PartLoadRatio = 1.0;
7976 54764 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity;
7977 : }
7978 :
7979 : } // End of IF HeatPump
7980 :
7981 : } // End of IF for heating
7982 :
7983 : // Non-heat pump systems do not set a heating PLR, set it here for use with the DX cooling coil calculations.
7984 : // Set this variable back to 0 for non-heat pump systems at the end of this routine.
7985 3128053 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = max(PartLoadRatio, state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio);
7986 6256106 : CalcFurnaceOutput(state,
7987 : FurnaceNum,
7988 : FirstHVACIteration,
7989 : OpMode,
7990 : CompressorOp,
7991 : 0.0,
7992 3128053 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio,
7993 : HeatCoilLoad,
7994 : 0.0,
7995 : HeatingSensibleOutput,
7996 : HeatingLatentOutput,
7997 : OnOffAirFlowRatio,
7998 : false);
7999 :
8000 6946676 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
8001 4139419 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
8002 2707308 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple && state.dataFurnaces->CoolingLoad)) {
8003 1032858 : HeatingSensibleOutput = 0.0;
8004 1032858 : HeatingLatentOutput = 0.0;
8005 : }
8006 : //***********Cooling Section*****************
8007 : // Simulate if scheduled ON and cooling load or if a moisture load exists when using a humidistat
8008 : // Check of HeatingLatentOutput is used to reduce overshoot during simultaneous heating and cooling
8009 : // Setback flag is used to avoid continued RH control when Tstat is setback (RH should float down)
8010 6429107 : if ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0 && state.dataFurnaces->CoolingLoad) ||
8011 2134592 : (state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
8012 723251 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat &&
8013 555044 : (SystemMoistureLoad < 0.0 || (SystemMoistureLoad >= 0.0 && HeatingLatentOutput > SystemMoistureLoad &&
8014 11499 : !state.dataZoneEnergyDemand->Setback(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum))))) {
8015 :
8016 : // For cooling operation, the first step is to set the HX operation flag in case a HX assisted coil is used.
8017 : // (if a HX assisted coil is not used, this flag is not used. It's only used in the CALL to SimHXAssistedCoolingCoil)
8018 : // Check the dehumidification control type:
8019 : // For dehumidification control options CoolReheat and None, the HX is always active (locked ON).
8020 : // For dehumidification control option Multimode, the system is operated first with the HX off.
8021 : // If the moisture load is not met, the HX will then be turned on and the system is re-simulated.
8022 :
8023 2774740 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat ||
8024 1239146 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::None) {
8025 1527106 : HXUnitOn = true;
8026 : } else {
8027 8488 : HXUnitOn = false;
8028 : }
8029 :
8030 : // The next step is to determine the system output at no load (PLR=0) and full load (PLR=1)
8031 :
8032 : // Set the inlet mass flow rate based on user specified coil OFF flow rate
8033 1535594 : PartLoadRatio = 0.0;
8034 :
8035 1535594 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0; // compressor off
8036 1535594 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 0.0;
8037 :
8038 : // SetAverageAirFlow calculates the operating mass flow rate based on PLR and the user specified inputs
8039 : // for MaxCoolAirMassFlow and MaxNoCoolHeatAirMassFlow.
8040 : // Air flow rate is set according to max of cooling and heating PLR if heating and latent load exists.
8041 2422740 : if (OpMode == CycFanCycCoil && state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio > 0.0 &&
8042 4 : state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
8043 1535600 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat &&
8044 2 : (SystemMoistureLoad < 0.0 || (SystemMoistureLoad >= 0.0 && HeatingLatentOutput > SystemMoistureLoad &&
8045 0 : !state.dataZoneEnergyDemand->Setback(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)))) {
8046 2 : CoolingHeatingPLRRatio = min(1.0, PartLoadRatio / state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio);
8047 2 : SetAverageAirFlow(
8048 2 : state, FurnaceNum, max(PartLoadRatio, state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio), OnOffAirFlowRatio);
8049 :
8050 : } else {
8051 1535592 : CoolingHeatingPLRRatio = 1.0;
8052 1535592 : SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
8053 : }
8054 :
8055 : // Get no load result (coils simulated OFF)
8056 3071188 : CalcFurnaceOutput(state,
8057 : FurnaceNum,
8058 : FirstHVACIteration,
8059 : OpMode,
8060 : CompressorOp,
8061 : MinPLR,
8062 : PartLoadRatio,
8063 : 0.0,
8064 : 0.0,
8065 : NoCoolOutput,
8066 : NoLatentOutput,
8067 : OnOffAirFlowRatio,
8068 1535594 : HXUnitOn,
8069 : CoolingHeatingPLRRatio);
8070 :
8071 : // Don't calculate full load output if no load output can meet sensible load
8072 1535594 : if (NoCoolOutput >= CoolCoilLoad && (CoolCoilLoad != 0.0 || state.dataFurnaces->HPDehumidificationLoadFlag)) {
8073 : // Set full mass flow rate for full load calculation
8074 1375919 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
8075 :
8076 : // Set fan part-load fraction equal to 1 while getting full load result
8077 1375919 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
8078 1375919 : OnOffAirFlowRatio = 1.0;
8079 1375919 : PartLoadRatio = 1.0;
8080 1375919 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 1.0; // compressor ON
8081 1375919 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 1.0;
8082 :
8083 : // Get full load result (coils simulated full ON)
8084 2751838 : CalcFurnaceOutput(state,
8085 : FurnaceNum,
8086 : FirstHVACIteration,
8087 : OpMode,
8088 : CompressorOp,
8089 : PartLoadRatio,
8090 : 0.0,
8091 : 0.0,
8092 : 0.0,
8093 : FullSensibleOutput,
8094 : FullLatentOutput,
8095 : OnOffAirFlowRatio,
8096 1375919 : HXUnitOn);
8097 : } else {
8098 159675 : FullSensibleOutput = NoCoolOutput - 0.00000001;
8099 : }
8100 :
8101 : // The next step is to compare the results of the full load and no load results
8102 : // 1) Since we are cooling, we expect FullSensibleOutput < NoCoolOutput
8103 : // Check that this is the case; if not set PartLoadRatio = 0.0 (off)
8104 : // 2) Verify that the load to be met is within the range of available output
8105 : // (i.e. between FullSensibleOutput and NoCoolOutput)
8106 : // 3) Set PLR if load is out of range or RegulaFalsi on PLR if system can meet the load
8107 1535594 : if (FullSensibleOutput < NoCoolOutput) {
8108 1531048 : if (CoolCoilLoad != 0.0 || state.dataFurnaces->HPDehumidificationLoadFlag) {
8109 :
8110 : // check bounds on sensible output prior to iteration using RegulaFalsi
8111 : // Negative value represents cooling load, IF FullSensibleOutput .GT. CoolCoilLoad, load is greater than capacity
8112 1373461 : if (FullSensibleOutput >= CoolCoilLoad) {
8113 114046 : PartLoadRatio = 1.0;
8114 : // Likewise IF NoCoolOutput .LT. CoolCoilLoad, then load can be met using only the fan (constant fan mode only)
8115 1259415 : } else if (NoCoolOutput <= CoolCoilLoad) {
8116 2088 : PartLoadRatio = 0.0;
8117 : // ELSE load is between NoCoolOutput and FullSensibleOuput, find PLR required to meet load
8118 : } else {
8119 :
8120 : // Calculate the sensible part load ratio through iteration
8121 1257327 : CoolErrorToler = state.dataFurnaces->Furnace(FurnaceNum)
8122 : .CoolingConvergenceTolerance; // Error tolerance for convergence from input deck
8123 1257327 : SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
8124 1257327 : Par[0] = double(FurnaceNum);
8125 1257327 : Par[1] = 0.0; // FLAG, if 1.0 then FirstHVACIteration equals TRUE, if 0.0 then FirstHVACIteration equals false
8126 1257327 : if (FirstHVACIteration) Par[1] = 1.0;
8127 1257327 : Par[2] = double(OpMode);
8128 1257327 : Par[3] = double(CompressorOp);
8129 1257327 : Par[4] = CoolCoilLoad;
8130 1257327 : Par[5] = 1.0; // FLAG, 0.0 if heating load, 1.0 if cooling or moisture load
8131 1257327 : Par[6] = 1.0; // FLAG, 0.0 if latent load, 1.0 if sensible load to be met
8132 1257327 : Par[7] = OnOffAirFlowRatio; // Ratio of compressor ON mass flow rate to AVERAGE mass flow rate over time step
8133 1257327 : Real64 par8_HXFlag = HXUnitOn ? 1.0 : 0.0;
8134 1257327 : if (HXUnitOn) {
8135 1248925 : Par[8] = 1.0;
8136 : } else {
8137 8402 : Par[8] = 0.0;
8138 : }
8139 : // Par(10) is the heating coil PLR, set this value to 0 for sensible PLR calculations.
8140 1257327 : Par[9] = 0.0;
8141 : // CoolErrorToler is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
8142 : auto f = [&state, FurnaceNum, FirstHVACIteration, OpMode, CompressorOp, CoolCoilLoad, par8_HXFlag](
8143 8748834 : Real64 const PartLoadRatio) {
8144 4374417 : return CalcFurnaceResidual(state,
8145 : PartLoadRatio,
8146 : FurnaceNum,
8147 : FirstHVACIteration,
8148 : OpMode,
8149 : CompressorOp,
8150 : CoolCoilLoad,
8151 : 1.0, // par6_loadFlag,
8152 : 1.0, // par7_sensLatentFlag,
8153 : par8_HXFlag, // par9_HXOnFlag,
8154 : 0.0); // par10_HeatingCoilPLR);
8155 5631744 : };
8156 1257327 : General::SolveRoot(state, CoolErrorToler, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
8157 : // OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
8158 1257327 : OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
8159 1257327 : if (SolFlag < 0) {
8160 30 : if (SolFlag == -1) {
8161 60 : CalcFurnaceOutput(state,
8162 : FurnaceNum,
8163 : FirstHVACIteration,
8164 : OpMode,
8165 : CompressorOp,
8166 : PartLoadRatio,
8167 : 0.0,
8168 : 0.0,
8169 : 0.0,
8170 : TempCoolOutput,
8171 : TempLatentOutput,
8172 : OnOffAirFlowRatio,
8173 30 : HXUnitOn);
8174 30 : if (!state.dataGlobal->WarmupFlag) {
8175 0 : if (std::abs(CoolCoilLoad - TempCoolOutput) > SmallLoad) {
8176 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SensibleMaxIterIndex == 0) {
8177 0 : ShowWarningMessage(state,
8178 0 : "Cooling coil control failed to converge for " +
8179 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
8180 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
8181 0 : ShowContinueError(
8182 : state, " Iteration limit exceeded in calculating DX cooling coil sensible part-load ratio.");
8183 0 : ShowContinueErrorTimeStamp(state,
8184 0 : format("Sensible load to be met by DX coil = {:.2T} (watts), sensible "
8185 : "output of DX coil = {:.2T} (watts), and the simulation continues.",
8186 : CoolCoilLoad,
8187 0 : TempCoolOutput));
8188 : }
8189 0 : ShowRecurringWarningErrorAtEnd(state,
8190 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) +
8191 0 : " \"" + state.dataFurnaces->Furnace(FurnaceNum).Name +
8192 : "\" - Iteration limit exceeded in calculating sensible cooling "
8193 : "part-load ratio error continues. Sensible load statistics:",
8194 0 : state.dataFurnaces->Furnace(FurnaceNum).SensibleMaxIterIndex,
8195 : CoolCoilLoad,
8196 : CoolCoilLoad);
8197 : }
8198 : }
8199 0 : } else if (SolFlag == -2) {
8200 0 : if (!state.dataGlobal->WarmupFlag) {
8201 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SensibleRegulaFalsiFailedIndex == 0) {
8202 0 : ShowWarningMessage(state,
8203 0 : "Cooling coil control failed for " +
8204 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
8205 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
8206 0 : ShowContinueError(state, " Cooling sensible part-load ratio determined to be outside the range of 0-1.");
8207 0 : ShowContinueErrorTimeStamp(state, format(" Cooling sensible load = {:.2T}", CoolCoilLoad));
8208 : }
8209 0 : ShowRecurringWarningErrorAtEnd(
8210 : state,
8211 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
8212 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
8213 : "\" - Cooling sensible part-load ratio out of range error continues. Sensible cooling load "
8214 : "statistics:",
8215 0 : state.dataFurnaces->Furnace(FurnaceNum).SensibleRegulaFalsiFailedIndex,
8216 : CoolCoilLoad,
8217 : CoolCoilLoad);
8218 : }
8219 : }
8220 : }
8221 : }
8222 :
8223 : } else {
8224 157587 : PartLoadRatio = 0.0;
8225 : } // EndIf for IF(CoolCoilLoad.NE.0.0)
8226 :
8227 : // Calculate the delivered capacity from the PLR caculated above
8228 4593144 : CalcFurnaceOutput(state,
8229 : FurnaceNum,
8230 : FirstHVACIteration,
8231 : OpMode,
8232 : CompressorOp,
8233 : PartLoadRatio,
8234 1531048 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio,
8235 : 0.0,
8236 : 0.0,
8237 : TempCoolOutput,
8238 : TempLatentOutput,
8239 : OnOffAirFlowRatio,
8240 1531048 : HXUnitOn);
8241 :
8242 : // Calculate the latent part load ratio through iteration
8243 : // Negative SystemMoistureLoad means dehumidification load is present
8244 : // IF this furnace uses MultiMode control AND there is a moisture load AND the moisture load met by the furnace in
8245 : // cooling only mode above is sufficient to meet the moisture demand OR there is no sensible load (PLR=0 from above)
8246 : // then set LatentPartLoadRatio to 0 (no additional dehumidification is required).
8247 1540052 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::Multimode &&
8248 16704 : ((SystemMoistureLoad < 0.0 && TempLatentOutput < SystemMoistureLoad) || PartLoadRatio == 0.0)) {
8249 516 : LatentPartLoadRatio = 0.0;
8250 : // ELSE calculate a new PLR for valid dehumidification control types if a moisture load exists.
8251 2038483 : } else if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num != DehumidificationControlMode::None &&
8252 415213 : (SystemMoistureLoad < 0.0 ||
8253 231858 : (SystemMoistureLoad >= 0.0 && TempLatentOutput > SystemMoistureLoad &&
8254 10212 : !state.dataZoneEnergyDemand->Setback(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)))) {
8255 :
8256 : // IF the furnace uses dehumidification control MultiMode, turn on the HX and calculate the latent output with
8257 : // the HX ON to compare to the moisture load predicted by the humidistat.
8258 203561 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::Multimode) {
8259 7700 : HXUnitOn = true;
8260 7700 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
8261 : // Set fan part-load fraction equal to 1 while getting full load result
8262 7700 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
8263 7700 : OnOffAirFlowRatio = 1.0;
8264 : // Get full load result
8265 15400 : CalcFurnaceOutput(state,
8266 : FurnaceNum,
8267 : FirstHVACIteration,
8268 : OpMode,
8269 : CompressorOp,
8270 : 1.0,
8271 : 0.0,
8272 : 0.0,
8273 : 0.0,
8274 : TempCoolOutput,
8275 : TempLatentOutput,
8276 : OnOffAirFlowRatio,
8277 7700 : HXUnitOn);
8278 : }
8279 :
8280 : // Set the global cooling to heating PLR ratio. CoolHeatPLRRat = MIN(1,CoolingPLR/HeatingPLR)
8281 203561 : state.dataFurnaces->CoolHeatPLRRat = 1.0; // means cooling dominated operation (applies to cycling fan mode)
8282 :
8283 203561 : if (TempLatentOutput > SystemMoistureLoad) {
8284 : // Set full mass flow rate for full load calculation
8285 199948 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
8286 :
8287 : // Set fan part-load fraction equal to 1 while getting full load result
8288 199948 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
8289 199948 : OnOffAirFlowRatio = 1.0;
8290 199948 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 1.0; // compressor ON
8291 199948 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 1.0;
8292 :
8293 : // Get full load result (coils simulated full ON)
8294 399896 : CalcFurnaceOutput(state,
8295 : FurnaceNum,
8296 : FirstHVACIteration,
8297 : OpMode,
8298 : CompressorOp,
8299 : 1.0,
8300 : 0.0,
8301 : 0.0,
8302 : 0.0,
8303 : TempCoolOutput,
8304 : TempLatentOutput,
8305 : OnOffAirFlowRatio,
8306 199948 : HXUnitOn);
8307 : }
8308 :
8309 : // check bounds on latent output prior to iteration using RegulaFalsi
8310 407122 : if (TempLatentOutput > SystemMoistureLoad ||
8311 59410 : (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::Multimode &&
8312 959 : TempCoolOutput > CoolCoilLoad)) {
8313 145110 : LatentPartLoadRatio = 1.0;
8314 58451 : } else if (NoLatentOutput < SystemMoistureLoad || HeatingLatentOutput < SystemMoistureLoad) {
8315 102 : LatentPartLoadRatio = 0.0;
8316 : } else {
8317 :
8318 58349 : CoolErrorToler = state.dataFurnaces->Furnace(FurnaceNum).CoolingConvergenceTolerance; // Error tolerance for convergence
8319 :
8320 58349 : SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
8321 58349 : Par[0] = double(FurnaceNum);
8322 58349 : Par[1] = 0.0; // FLAG, if 1.0 then FirstHVACIteration equals TRUE, if 0.0 then FirstHVACIteration equals false
8323 58349 : if (FirstHVACIteration) Par[1] = 1.0;
8324 58349 : Par[2] = double(OpMode);
8325 58349 : Par[3] = double(CompressorOp);
8326 : // Multimode always controls to meet the SENSIBLE load (however, HXUnitOn is now TRUE)
8327 : Real64 par4_load;
8328 58349 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::Multimode) {
8329 959 : Par[4] = CoolCoilLoad;
8330 959 : par4_load = CoolCoilLoad;
8331 : } else {
8332 57390 : Par[4] = SystemMoistureLoad;
8333 57390 : par4_load = SystemMoistureLoad;
8334 : }
8335 58349 : Par[5] = 1.0; // FLAG, 0.0 if heating load, 1.0 if cooling or moisture load
8336 : // Multimode always controls to meet the SENSIBLE load (however, HXUnitOn is now TRUE)
8337 : Real64 par6_LatentSens;
8338 58349 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::Multimode) {
8339 959 : par6_LatentSens = 1.0;
8340 959 : Par[6] = 1.0; // FLAG, 0.0 if latent load, 1.0 if sensible load to be met
8341 : } else {
8342 57390 : par6_LatentSens = 0.0;
8343 57390 : Par[6] = 0.0;
8344 : }
8345 58349 : Par[7] = OnOffAirFlowRatio; // Ratio of compressor ON mass flow rate to AVERAGE mass flow rate over time step
8346 58349 : Real64 par8_HXUnit = HXUnitOn ? 1.0 : 0.0;
8347 58349 : if (HXUnitOn) {
8348 58349 : Par[8] = 1.0;
8349 : } else {
8350 0 : Par[8] = 0.0;
8351 : }
8352 : // Par(10) used only with cycling fan.
8353 : // Par(10) is the heating coil PLR, set this value only if there is a heating load (heating PLR > 0)
8354 : // and the latent PLR is being calculated. Otherwise set Par(10) to 0.
8355 : Real64 par9_HtgCoilPLR;
8356 58349 : if (OpMode == CycFanCycCoil && state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio > 0.0 && Par[6] == 0.0) {
8357 0 : par9_HtgCoilPLR = state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio;
8358 0 : Par[9] = state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio;
8359 : } else {
8360 58349 : par9_HtgCoilPLR = 0.0;
8361 58349 : Par[9] = 0.0;
8362 : }
8363 : auto f = [&state,
8364 : FurnaceNum,
8365 : FirstHVACIteration,
8366 : OpMode,
8367 : CompressorOp,
8368 : par4_load,
8369 : par6_LatentSens,
8370 : par8_HXUnit,
8371 955948 : par9_HtgCoilPLR](Real64 const PartLoadRatio) {
8372 477974 : return CalcFurnaceResidual(state,
8373 : PartLoadRatio,
8374 : FurnaceNum,
8375 : FirstHVACIteration,
8376 : OpMode,
8377 : CompressorOp,
8378 : par4_load,
8379 : 1.0, // par6_loadFlag,
8380 : par6_LatentSens, // par7_sensLatentFlag,
8381 : par8_HXUnit, // par9_HXOnFlag,
8382 : par9_HtgCoilPLR); // par10_HeatingCoilPLR);
8383 536323 : };
8384 : // CoolErrorToler is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
8385 58349 : General::SolveRoot(state, CoolErrorToler, MaxIter, SolFlag, LatentPartLoadRatio, f, 0.0, 1.0);
8386 : // OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
8387 58349 : OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
8388 58349 : if (SolFlag == -1) {
8389 : // RegulaFalsi may not find latent PLR when the latent degradation model is used.
8390 : // If iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
8391 106 : TempMaxPLR = -0.1;
8392 106 : TempLatentOutput = NoLatentOutput;
8393 966 : while ((TempLatentOutput - SystemMoistureLoad) > 0.0 && TempMaxPLR < 1.0) {
8394 : // find upper limit of LatentPLR
8395 430 : TempMaxPLR += 0.1;
8396 :
8397 : // Same calculation as is done in Function CalcFurnaceResidual for latent PLR calculation.
8398 : // Set cooling to heating PLR for use with Subroutine CalcFurnaceOutput. IF Par(10) = 0,
8399 : // heating PLR = 0 so set the CoolingHeatingPLRRatio to 1 so the cooling PLR is used in the
8400 : // DX cooling coil calculations.
8401 430 : if (Par[9] > 0.0) {
8402 : // Par(10) = Furnace(FurnaceNum)%HeatPartLoadRatio
8403 : // OpMode = CycFan and Furnace(FurnaceNum)%HeatPartLoadRatio must be > 0 for Part(10) to be
8404 : // greater than 0
8405 0 : CoolingHeatingPLRRatio = min(1.0, TempMaxPLR / state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio);
8406 : } else {
8407 430 : CoolingHeatingPLRRatio = 1.0;
8408 : }
8409 :
8410 860 : CalcFurnaceOutput(state,
8411 : FurnaceNum,
8412 : FirstHVACIteration,
8413 : OpMode,
8414 : CompressorOp,
8415 : TempMaxPLR,
8416 : 0.0,
8417 : 0.0,
8418 : 0.0,
8419 : TempCoolOutput,
8420 : TempLatentOutput,
8421 : OnOffAirFlowRatio,
8422 430 : HXUnitOn,
8423 : CoolingHeatingPLRRatio);
8424 : }
8425 106 : TempMinPLR = TempMaxPLR;
8426 1602 : while ((TempLatentOutput - SystemMoistureLoad) < 0.0 && TempMinPLR > 0.0) {
8427 : // pull upper limit of LatentPLR down to last valid limit (i.e. latent output still exceeds
8428 : // SystemMoisuterLoad) CR7558 - relax final limits to allow HX assisted coils to converge
8429 748 : TempMaxPLR = TempMinPLR + 0.001;
8430 : // find minimum limit of Latent PLR
8431 748 : TempMinPLR -= 0.001;
8432 :
8433 : // Set cooling to heating PLR for use with Subroutine CalcFurnaceOutput.
8434 748 : if (Par[9] > 0.0) {
8435 : // Par(10) = Furnace(FurnaceNum)%HeatPartLoadRatio
8436 : // OpMode = CycFan and Furnace(FurnaceNum)%HeatPartLoadRatio must be > 0 for Part(10) to be
8437 : // greater than 0 Since the latent output of cycling fan systems is 0 at PLR=0, do not allow
8438 : // the PLR to be 0, otherwise RegulaFalsi can fail when a heating and moisture load exists and
8439 : // heating PLR > latent PLR.
8440 0 : TempMinPLR2 = max(0.0000000001, TempMinPLR);
8441 0 : CoolingHeatingPLRRatio = min(1.0, TempMinPLR2 / state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio);
8442 : } else {
8443 748 : TempMinPLR2 = TempMinPLR;
8444 748 : CoolingHeatingPLRRatio = 1.0;
8445 : }
8446 :
8447 1496 : CalcFurnaceOutput(state,
8448 : FurnaceNum,
8449 : FirstHVACIteration,
8450 : OpMode,
8451 : CompressorOp,
8452 : TempMinPLR2,
8453 : 0.0,
8454 : 0.0,
8455 : 0.0,
8456 : TempCoolOutput,
8457 : TempLatentOutput,
8458 : OnOffAirFlowRatio,
8459 748 : HXUnitOn,
8460 : CoolingHeatingPLRRatio);
8461 : }
8462 : // tighter boundary of solution has been found, call RegulaFalsi a second time
8463 : auto f = [&state,
8464 : FurnaceNum,
8465 : FirstHVACIteration,
8466 : OpMode,
8467 : CompressorOp,
8468 : par4_load,
8469 : par6_LatentSens,
8470 : par8_HXUnit,
8471 1168 : par9_HtgCoilPLR](Real64 const PartLoadRatio) {
8472 584 : return CalcFurnaceResidual(state,
8473 : PartLoadRatio,
8474 : FurnaceNum,
8475 : FirstHVACIteration,
8476 : OpMode,
8477 : CompressorOp,
8478 : par4_load,
8479 : 1.0, // par6_loadFlag,
8480 : par6_LatentSens, // par7_sensLatentFlag,
8481 : par8_HXUnit, // par9_HXOnFlag,
8482 : par9_HtgCoilPLR); // par10_HeatingCoilPLR);
8483 690 : };
8484 106 : General::SolveRoot(state, CoolErrorToler, MaxIter, SolFlag, LatentPartLoadRatio, f, TempMinPLR2, TempMaxPLR);
8485 : // OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
8486 106 : OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
8487 106 : if (SolFlag == -1) {
8488 :
8489 : // Set cooling to heating PLR for use with Subroutine CalcFurnaceOutput.
8490 76 : if (Par[9] > 0.0) {
8491 : // Par(10) = Furnace(FurnaceNum)%HeatPartLoadRatio
8492 : // OpMode = CycFan and Furnace(FurnaceNum)%HeatPartLoadRatio must be > 0 for Part(10) to be
8493 : // greater than 0
8494 0 : CoolingHeatingPLRRatio =
8495 0 : min(1.0, LatentPartLoadRatio / state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio);
8496 : } else {
8497 76 : CoolingHeatingPLRRatio = 1.0;
8498 : }
8499 :
8500 152 : CalcFurnaceOutput(state,
8501 : FurnaceNum,
8502 : FirstHVACIteration,
8503 : OpMode,
8504 : CompressorOp,
8505 : LatentPartLoadRatio,
8506 : 0.0,
8507 : 0.0,
8508 : 0.0,
8509 : TempCoolOutput,
8510 : TempLatentOutput,
8511 : OnOffAirFlowRatio,
8512 76 : HXUnitOn,
8513 : CoolingHeatingPLRRatio);
8514 152 : if (std::abs((SystemMoistureLoad - TempLatentOutput) / SystemMoistureLoad) > CoolErrorToler &&
8515 76 : std::abs(SystemMoistureLoad - TempLatentOutput) > 10.0) {
8516 0 : if (!state.dataGlobal->WarmupFlag) {
8517 0 : if (state.dataFurnaces->Furnace(FurnaceNum).LatentMaxIterIndex == 0) {
8518 0 : ShowWarningMessage(state,
8519 0 : "Cooling coil control failed to converge for " +
8520 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
8521 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
8522 0 : ShowContinueError(state,
8523 : " Iteration limit exceeded in calculating cooling coil latent part-load ratio.");
8524 0 : ShowContinueError(
8525 : state,
8526 0 : format(" Latent load convergence error (percent) = {:.2T}",
8527 0 : 100.0 * std::abs((SystemMoistureLoad - TempLatentOutput) / SystemMoistureLoad)));
8528 0 : ShowContinueErrorTimeStamp(state,
8529 0 : format("Moisture load to be met by DX coil = {:.2T} (watts), Latent "
8530 : "output of DX coil = {:.2T} (watts), and the simulation continues.",
8531 : SystemMoistureLoad,
8532 0 : TempLatentOutput));
8533 : }
8534 0 : ShowRecurringWarningErrorAtEnd(
8535 : state,
8536 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
8537 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
8538 : "\" - Iteration limit exceeded in calculating latent part-load ratio error continues. Latent "
8539 : "load convergence error (percent) statistics follow.",
8540 0 : state.dataFurnaces->Furnace(FurnaceNum).LatentMaxIterIndex,
8541 0 : 100.0 * std::abs((SystemMoistureLoad - TempLatentOutput) / SystemMoistureLoad),
8542 0 : 100.0 * std::abs((SystemMoistureLoad - TempLatentOutput) / SystemMoistureLoad));
8543 : }
8544 : }
8545 30 : } else if (SolFlag == -2) {
8546 0 : if (state.dataFurnaces->Furnace(FurnaceNum).LatentRegulaFalsiFailedIndex2 == 0) {
8547 0 : ShowWarningMessage(state,
8548 0 : "Cooling coil control failed for " +
8549 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
8550 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
8551 0 : ShowContinueError(state,
8552 0 : format(" Latent part-load ratio determined to be outside the range of {:.3T} to {:.3T}.",
8553 : TempMinPLR,
8554 0 : TempMaxPLR));
8555 0 : ShowContinueErrorTimeStamp(state,
8556 0 : format("A PLR of {:.3T} will be used and the simulation continues.", TempMinPLR));
8557 : }
8558 0 : ShowRecurringWarningErrorAtEnd(
8559 : state,
8560 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
8561 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
8562 : "\" - Cooling sensible part-load ratio out of range error continues. System moisture load statistics:",
8563 0 : state.dataFurnaces->Furnace(FurnaceNum).LatentRegulaFalsiFailedIndex2,
8564 : SystemMoistureLoad,
8565 : SystemMoistureLoad);
8566 0 : LatentPartLoadRatio = TempMinPLR;
8567 : }
8568 58243 : } else if (SolFlag == -2) {
8569 0 : if (state.dataFurnaces->Furnace(FurnaceNum).LatentRegulaFalsiFailedIndex == 0) {
8570 0 : ShowWarningMessage(state,
8571 0 : "Cooling coil control failed for " +
8572 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
8573 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
8574 0 : ShowContinueError(state, " Latent part-load ratio determined to be outside the range of 0-1.");
8575 0 : ShowContinueErrorTimeStamp(state, "A PLR of 0 will be used and the simulation continues.");
8576 : }
8577 0 : ShowRecurringWarningErrorAtEnd(
8578 : state,
8579 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
8580 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
8581 : "\" - Latent part-load ratio out of range or 0-1 error continues. System moisture load statistics:",
8582 0 : state.dataFurnaces->Furnace(FurnaceNum).LatentRegulaFalsiFailedIndex,
8583 : SystemMoistureLoad,
8584 : SystemMoistureLoad);
8585 0 : LatentPartLoadRatio = 0.0;
8586 : }
8587 : }
8588 :
8589 : // Cooling to heating PLR ratio is now known as CoolHeatPLRRat (Module level global set in CalcFurnaceOutput
8590 : // This same variable is use in Subroutine SimFurnace for final calculations.
8591 : // Get the actual output in case reheat needs to be calculated (HumControl=TRUE [latent PLR > sensible PLR])
8592 407122 : CalcFurnaceOutput(state,
8593 : FurnaceNum,
8594 : FirstHVACIteration,
8595 : OpMode,
8596 : CompressorOp,
8597 : LatentPartLoadRatio,
8598 : 0.0,
8599 : 0.0,
8600 : 0.0,
8601 : ActualSensibleOutput,
8602 : ActualLatentOutput,
8603 : OnOffAirFlowRatio,
8604 203561 : HXUnitOn,
8605 203561 : state.dataFurnaces->CoolHeatPLRRat);
8606 :
8607 : } else {
8608 1326971 : LatentPartLoadRatio = 0.0;
8609 : } // ENDIF for valid dehumidification control types
8610 :
8611 : // IF a humidistat is used and there is a moisture load, check if the latent PLR is greater than the (sensible) PLR
8612 : // IF(LatentPartLoadRatio .GT. PartLoadRatio .and. SystemMoistureLoad .lt. 0.0 .and. Furnace(FurnaceNum)%Humidistat) THEN
8613 1531048 : if (LatentPartLoadRatio > PartLoadRatio && state.dataFurnaces->Furnace(FurnaceNum).Humidistat) {
8614 : // For dehumidification mode CoolReheat, compare the Sensible and Latent PLR values, if latentPLR is greater
8615 : // than PLR (sensible), then overcooling is required and reheat will be activated using the HumControl flag.
8616 200715 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
8617 193101 : PartLoadRatio = LatentPartLoadRatio;
8618 193101 : HumControl = true;
8619 : }
8620 : // For dehumidification mode MultiMode, compare the Sensible and Latent PLR values, if latentPLR is
8621 : // greater than PLR (sensible), then use the latent PLR to control the unit.
8622 : // For MultiMode control, the latent PLR is found by enabling the HX and calculating a PLR required to meet the
8623 : // sensible load. Overcooling is not required, and reheat will not be activated using the HumControl flag.
8624 200715 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::Multimode) {
8625 7614 : PartLoadRatio = LatentPartLoadRatio;
8626 : }
8627 : }
8628 :
8629 1531048 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = PartLoadRatio;
8630 1531048 : if (CompressorOp == CompressorOperation::Off) {
8631 4218 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
8632 : } else {
8633 1526830 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadRatio;
8634 : }
8635 :
8636 : } else { // ELSE from IF(FullSensibleOutput.LT.NoCoolOutput)THEN above
8637 : // CR8679 - Unitary Heat Cool control problem, will not run to meeting cooling load
8638 : // underlying problem is that FullSensibleOutput is greater than 0 due to very high inlet temp, so the system should be on
8639 : // NoCoolOutput was 0 since the defect file is a cycling fan system and the system was turned off
8640 :
8641 : // if FullSensibleOutput > NoCoolOutput, it means the system cannot meet the load and will run full out
8642 : // this same logic for WSHP does not seem to work (only the Unitary Heat Pump Compressor Part-Load Ratio report
8643 : // variable was affected in the HeatPumpWaterToAirRHControl.idf file while other variables showed very small diffs).
8644 : // The defect files meter.csv showed 2% diffs so this IF test is used to keep the results the same in that file.
8645 : // Additional logic is used here to make sure the coil actually turned on, e.g., if DX coil PLR > 0 then set to 1,
8646 : // otherwise 0 (to make sure coil is actually ON and not off due to schedule, OAT, or other reason).
8647 : // The global variable DXCoilPartLoadRatio(DXCoilNum) is not yet used for the WSHP to make the same check.
8648 4546 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir) {
8649 230 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 0.0;
8650 230 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
8651 : } else {
8652 4316 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
8653 :
8654 : // VS coil issue here...
8655 0 : if (state.dataDXCoils->DXCoilPartLoadRatio(state.dataFurnaces->Furnace(FurnaceNum).ActualDXCoilIndexForHXAssisted) >
8656 : 0.0) {
8657 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 1.0;
8658 0 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 1.0;
8659 : } else {
8660 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 0.0;
8661 0 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
8662 : }
8663 : } else {
8664 4316 : if (state.dataDXCoils->DXCoilPartLoadRatio(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex) > 0.0) {
8665 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 1.0;
8666 0 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 1.0;
8667 : } else {
8668 4316 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 0.0;
8669 4316 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
8670 : }
8671 : }
8672 : }
8673 : }
8674 :
8675 : // Calculate the reheat coil output
8676 1535594 : if (HumControl) { // HumControl = .TRUE. if a Humidistat is installed and dehumdification control type is CoolReheat
8677 193101 : if (state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum > 0) {
8678 386202 : QToHeatSetPt = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
8679 193101 : .SequencedOutputRequiredToHeatingSP(state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum) /
8680 193101 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac);
8681 : } else {
8682 0 : QToHeatSetPt = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
8683 0 : .OutputRequiredToHeatingSP /
8684 0 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac);
8685 : }
8686 : // Cooling mode or floating condition and dehumidification is required
8687 193101 : if (QToHeatSetPt < 0.0) {
8688 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
8689 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
8690 180304 : ReheatCoilLoad = max(0.0, (QToHeatSetPt - ActualSensibleOutput));
8691 180304 : state.dataFurnaces->Furnace(FurnaceNum).DehumidInducedHeatingDemandRate = ReheatCoilLoad;
8692 : // Heating mode and dehumidification is required
8693 12797 : } else if (QToHeatSetPt >= 0.0) {
8694 : // Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
8695 : // the heating coil pick up the load due to outdoor air.
8696 12797 : ReheatCoilLoad = max(0.0, (ActualSensibleOutput - NoCoolOutput) * (-1.0));
8697 : // Dehumidification is not required
8698 32726 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
8699 17859 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
8700 7132 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple)) {
8701 9202 : ReheatCoilLoad = max(QToHeatSetPt, QToHeatSetPt - ActualSensibleOutput);
8702 : }
8703 12797 : state.dataFurnaces->Furnace(FurnaceNum).DehumidInducedHeatingDemandRate = max(0.0, ActualSensibleOutput * (-1.0));
8704 : } else {
8705 0 : ReheatCoilLoad = 0.0;
8706 : }
8707 : } else {
8708 : // No humidistat installed
8709 1342493 : ReheatCoilLoad = 0.0;
8710 : }
8711 : } // End of cooling section IF statement
8712 :
8713 3128053 : if (NoHeatOutput > SystemSensibleLoad && ReheatCoilLoad > 0.0) {
8714 : // Reduce reheat coil load if you are controlling high humidity but outside air
8715 : // and/or the supply air fan is providing enough heat to meet the system sensible load.
8716 : // This will bring the zone temp closer to the heating setpoint temp.
8717 0 : ReheatCoilLoad = max(0.0, ReheatCoilLoad - (NoHeatOutput - SystemSensibleLoad));
8718 : }
8719 :
8720 : // Set the final air flow. MdotFurnace will be used to set the fan part-load ratio in ReportFurnace
8721 3128053 : if (HumControl && SystemMoistureLoad < 0.0) {
8722 366418 : if (OpMode == CycFanCycCoil) {
8723 : // set the flow rate at the maximum of the cooling and heating PLR's
8724 856 : SetAverageAirFlow(
8725 : state,
8726 : FurnaceNum,
8727 856 : max(state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio, state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio),
8728 : OnOffAirFlowRatio);
8729 : } else {
8730 : // ELSE set the flow rate at the cooling PLR
8731 182781 : SetAverageAirFlow(state, FurnaceNum, state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio, OnOffAirFlowRatio);
8732 : }
8733 : } else {
8734 5889688 : SetAverageAirFlow(
8735 : state,
8736 : FurnaceNum,
8737 5889688 : max(state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio, state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio),
8738 : OnOffAirFlowRatio);
8739 : }
8740 3128053 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate;
8741 :
8742 7609760 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir ||
8743 4139419 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
8744 1353654 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple)) {
8745 : } else {
8746 : // Non-HeatPump (non-DX) heating coils do not set PLR, reset to 0 here. This variable was set for non-DX
8747 : // coils to allow the SetAverageAirFlow CALL above to set the correct air mass flow rate. See this
8748 : // IF block above in heating section. HeatPLR is not set in the ELSE part of the IF (only HeatCoilLoad is set).
8749 1432111 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 0.0;
8750 : }
8751 :
8752 : //*********HVAC Scheduled OFF*************
8753 : // No heating or cooling or dehumidification
8754 : //!!LKL discrepancy with < 0?
8755 6176162 : if (GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) == 0.0 ||
8756 3048109 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate == 0.0) {
8757 254269 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = 0.0;
8758 254269 : CoolCoilLoad = 0.0;
8759 254269 : HeatCoilLoad = 0.0;
8760 254269 : ReheatCoilLoad = 0.0;
8761 254269 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // System off, so set on/off fan part-load fraction = 1
8762 254269 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio = 0.0;
8763 254269 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio = 0.0;
8764 254269 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
8765 : // set report variables
8766 254269 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
8767 254269 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
8768 254269 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
8769 : }
8770 :
8771 : } // End of the FirstHVACIteration control of the mass flow If block
8772 :
8773 : // Set the fan inlet node flow rates
8774 4760100 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
8775 4760100 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
8776 4760100 : }
8777 :
8778 118555 : void CalcWaterToAirHeatPump(EnergyPlusData &state,
8779 : int const AirLoopNum, // index to air loop
8780 : int const FurnaceNum, // index to Furnace
8781 : bool const FirstHVACIteration, // TRUE on first HVAC iteration
8782 : CompressorOperation const CompressorOp, // compressor operation flag (1=On, 0=Off)
8783 : Real64 const ZoneLoad, // the control zone load (watts)
8784 : Real64 const MoistureLoad // the control zone latent load (watts)
8785 : )
8786 : {
8787 :
8788 : // SUBROUTINE INFORMATION:
8789 : // AUTHOR Dan Fisher
8790 : // DATE WRITTEN Feb 2004
8791 : // MODIFIED R. Raustad (Oct 2006) Revised iteration technique
8792 : // RE-ENGINEERED na
8793 :
8794 : // PURPOSE OF THIS SUBROUTINE:
8795 : // This subroutine manages the heat pump simulation
8796 :
8797 : // METHODOLOGY EMPLOYED:
8798 : // Calculate the part-load ratio required to meet the zone sensible load.
8799 :
8800 : // SUBROUTINE PARAMETER DEFINITIONS:
8801 118555 : int constexpr MaxIter(600); // maximum number of iterations
8802 118555 : Real64 constexpr MinPLR(0.0); // minimum part load ratio allowed
8803 :
8804 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
8805 : Real64 OnOffAirFlowRatio; // Ratio of compressor ON air mass flow to AVERAGE air mass flow over time step
8806 : Real64 ZoneSensLoadMet; // Actual zone sensible load met by heat pump (W)
8807 : Real64 ZoneLatLoadMet; // Actual zone latent load met by heat pump (W)
8808 : Real64 ZoneSensLoadMetFanONCompON; // Max Zone sensible load heat pump can meet (W)
8809 : Real64 ZoneLatLoadMetFanONCompON; // Max Zone latentload heat pump can meet (W)
8810 : Real64 ZoneSensLoadMetFanONCompOFF; // control zone sensible load met using only outside air
8811 : // and fan heat (no coil output) (W)
8812 : Real64 ZoneLatLoadMetFanONCompOFF; // control zone Latent load met using only outside air
8813 : // and fan heat (no coil output) (W)
8814 : Real64 HPCoilSensDemand; // Heat pump sensible demand
8815 : Real64 HPCoilSensCapacity; // Heat pump sensible capacity
8816 : int FurnaceInletNode; // heat pump Inlet node
8817 : int FurnaceOutletNode; // heat pump Outlet node
8818 :
8819 : int OASysInletNode; // node number of return air inlet to OA sys
8820 : int OASysOutletNode; // node number of mixed air outlet of OA sys
8821 : int OpMode; // Mode of Operation (fan cycling = 1 or fan continuous = 2)
8822 : bool HumControl; // Logical flag signaling when dehumidification is required
8823 : Real64 SuppHeatCoilLoad; // Load passed to supplemental heater (W)
8824 : Real64 CoolErrorToler; // convergence tolerance used in cooling mode
8825 : Real64 HeatErrorToler; // convergence tolerance used in heating mode
8826 : int SolFlag; // flag returned from iteration routine to denote problems
8827 : std::array<Real64, 9> Par; // parameters passed to iteration routine
8828 :
8829 118555 : auto &TotalZoneLatentLoad = state.dataFurnaces->TotalZoneLatentLoad;
8830 118555 : auto &TotalZoneSensLoad = state.dataFurnaces->TotalZoneSensLoad;
8831 118555 : auto &CoolPartLoadRatio = state.dataFurnaces->CoolPartLoadRatio;
8832 118555 : auto &HeatPartLoadRatio = state.dataFurnaces->HeatPartLoadRatio;
8833 118555 : auto &Dummy2 = state.dataFurnaces->Dummy2;
8834 :
8835 : // Set local variables
8836 118555 : Dummy2 = 0.0;
8837 118555 : OnOffAirFlowRatio = 1.0;
8838 118555 : FurnaceOutletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
8839 118555 : FurnaceInletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
8840 118555 : if (state.dataAirLoop->AirToOANodeInfo(AirLoopNum).OASysExists) {
8841 40750 : OASysOutletNode = state.dataAirLoop->AirToOANodeInfo(AirLoopNum).OASysOutletNodeNum;
8842 40750 : OASysInletNode = state.dataAirLoop->AirToOANodeInfo(AirLoopNum).OASysInletNodeNum;
8843 : }
8844 118555 : OpMode = state.dataFurnaces->Furnace(FurnaceNum).OpMode;
8845 118555 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate;
8846 118555 : HumControl = false;
8847 :
8848 : //*********INITIAL CALCULATIONS****************
8849 : // set the fan part load fraction
8850 : // Note: OnOffFanPartLoadFraction is passed to the
8851 : // fan module by DataHVACGlobals. It should be
8852 : // set =1 for all cases except cycling fan/cycling
8853 : // coil. For this case it is set to the part load
8854 : // factor. In SimOnOffFan, the part load ratio is
8855 : // divided by the part load factor (OnOffFanPartLoadFraction)
8856 : // in order to match the run time fraction of the cycling
8857 : // fan with the run time fraction of the cycling compressor
8858 118555 : if (FirstHVACIteration) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
8859 :
8860 : // Calc Zone sensible loads for heating (+) and cooling (-)
8861 118555 : TotalZoneSensLoad = ZoneLoad;
8862 :
8863 : // Set latent load for heating
8864 118555 : if (state.dataFurnaces->HeatingLoad) {
8865 55203 : TotalZoneLatentLoad = 0.0;
8866 :
8867 : // Set latent load for cooling and no sensible load condition
8868 : } else {
8869 63352 : TotalZoneLatentLoad = MoistureLoad;
8870 : }
8871 :
8872 : //*********COOLING CALCULATIONS****************
8873 : // IF scheduled on...
8874 : // AND air flow rate is greater than zero...
8875 : // AND the air system has a cooling load and is not set back or in the deadband...
8876 : // OR the system is controlled by a humidistat and there is a latent load
8877 341421 : if ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0 &&
8878 247150 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate > 0.0) &&
8879 147102 : ((state.dataFurnaces->CoolingLoad) ||
8880 55203 : (state.dataFurnaces->Furnace(FurnaceNum).Humidistat && state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand < 0.0))) {
8881 :
8882 : // Set the air flow rate to the design flow rate and set the fan operation fraction to 1 (continuous operation)
8883 36696 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate;
8884 36696 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // see 'Note' under INITIAL CALCULATIONS
8885 :
8886 : // !Set the operation flag to run the fan continuously
8887 : // OpMode = ContFanCycCoil
8888 :
8889 : // Set the input parameters for CalcFurnaceOutput
8890 36696 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
8891 36696 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
8892 36696 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
8893 36696 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0; // compressor off
8894 36696 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump = true; // initialization call to Calc Furnace
8895 36696 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 0.0;
8896 36696 : CoolPartLoadRatio = 0.0;
8897 :
8898 : // Get no load result in order to calculate the effect of the fan and the mixed air equipment
8899 36696 : CalcFurnaceOutput(state,
8900 : FurnaceNum,
8901 : FirstHVACIteration,
8902 : OpMode,
8903 : CompressorOp,
8904 : CoolPartLoadRatio,
8905 : HeatPartLoadRatio,
8906 : Dummy2,
8907 : Dummy2,
8908 : ZoneSensLoadMetFanONCompOFF,
8909 : ZoneLatLoadMetFanONCompOFF,
8910 : OnOffAirFlowRatio,
8911 : false);
8912 :
8913 : // Set the input parameters for CalcFurnaceOutput
8914 36696 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 1.0;
8915 36696 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 1.0; // compressor ON
8916 36696 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 1.0;
8917 36696 : CoolPartLoadRatio = 1.0;
8918 :
8919 : // Get full load result in order to estimate the operating part load ratio for continuous fan operation
8920 36696 : CalcFurnaceOutput(state,
8921 : FurnaceNum,
8922 : FirstHVACIteration,
8923 : OpMode,
8924 : CompressorOp,
8925 : CoolPartLoadRatio,
8926 : HeatPartLoadRatio,
8927 : Dummy2,
8928 : Dummy2,
8929 : ZoneSensLoadMetFanONCompON,
8930 : ZoneLatLoadMetFanONCompON,
8931 : OnOffAirFlowRatio,
8932 : false);
8933 :
8934 : // Calculate the heating coil demand for continuous fan operation as:
8935 : // (the zone sensible load - the zone sensible load met by fan heat and mixed air)
8936 : // Note; The sensible zone load met by fan heat and mixed air is calculated as:
8937 : // mdotsys(control zone inlet enthalpy - control zone outlet enthalpy)
8938 : // This accounts for the negative sign in the equation.
8939 36696 : HPCoilSensDemand = TotalZoneSensLoad - ZoneSensLoadMetFanONCompOFF;
8940 :
8941 : // Calculate the heating coil capacity for continuous fan operation as:
8942 : // (the zone sensible load met by fan heat and mixed air and coil
8943 : // - the zone sensible load met by fan heat and mixed air)
8944 36696 : HPCoilSensCapacity = ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF;
8945 :
8946 : // Calculate the part load ratio for continuous fan operation with cycling coil
8947 36696 : if (HPCoilSensCapacity == 0.0) {
8948 0 : CoolPartLoadRatio = 0.0;
8949 : } else {
8950 36696 : CoolPartLoadRatio = max(MinPLR, min(1.0, std::abs(HPCoilSensDemand) / std::abs(HPCoilSensCapacity)));
8951 : }
8952 :
8953 36696 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump = false;
8954 :
8955 : // check bounds on sensible output prior to iteration using RegulaFalsi
8956 36696 : if (ZoneSensLoadMetFanONCompON > TotalZoneSensLoad) {
8957 2182 : CoolPartLoadRatio = 1.0;
8958 2182 : HPCoilSensDemand = std::abs(ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF);
8959 2182 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = HPCoilSensDemand;
8960 34514 : } else if (ZoneSensLoadMetFanONCompOFF < TotalZoneSensLoad) {
8961 0 : CoolPartLoadRatio = 0.0;
8962 0 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0; // compressor OFF
8963 0 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 0.0;
8964 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
8965 0 : CalcFurnaceOutput(state,
8966 : FurnaceNum,
8967 : FirstHVACIteration,
8968 : OpMode,
8969 : CompressorOp,
8970 : CoolPartLoadRatio,
8971 : HeatPartLoadRatio,
8972 : Dummy2,
8973 : Dummy2,
8974 : ZoneSensLoadMetFanONCompOFF,
8975 : ZoneLatLoadMetFanONCompOFF,
8976 : OnOffAirFlowRatio,
8977 : false);
8978 : } else {
8979 : // Calculate the sensible part load ratio through iteration
8980 34514 : CoolErrorToler = state.dataFurnaces->Furnace(FurnaceNum).CoolingConvergenceTolerance;
8981 34514 : SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
8982 34514 : Par[0] = double(FurnaceNum);
8983 34514 : Par[1] = 0.0; // FLAG, if 1.0 then FirstHVACIteration equals TRUE, if 0.0 then FirstHVACIteration equals false
8984 34514 : if (FirstHVACIteration) Par[1] = 1.0;
8985 34514 : Par[2] = double(OpMode);
8986 34514 : Par[3] = double(CompressorOp);
8987 34514 : Par[4] = TotalZoneSensLoad;
8988 34514 : Par[5] = 1.0; // FLAG, 0.0 if heating load, 1.0 if cooling or moisture load
8989 34514 : Par[6] = 1.0; // FLAG, 0.0 if latent load, 1.0 if sensible load to be met
8990 34514 : Par[7] = ZoneSensLoadMetFanONCompOFF; // Output with fan ON compressor OFF
8991 34514 : Par[8] = 0.0; // HX is off for water-to-air HP
8992 : // CoolErrorToler is in fraction of load, MaxIter = 600, SolFalg = # of iterations or error as appropriate
8993 : auto f = [&state, FurnaceNum, FirstHVACIteration, OpMode, CompressorOp, TotalZoneSensLoad, ZoneSensLoadMetFanONCompOFF](
8994 274136 : Real64 const PartLoadRatio) {
8995 137068 : return CalcWaterToAirResidual(state,
8996 : PartLoadRatio,
8997 : FurnaceNum,
8998 : FirstHVACIteration,
8999 : OpMode,
9000 : CompressorOp,
9001 : TotalZoneSensLoad,
9002 : 1.0,
9003 : 1.0,
9004 : ZoneSensLoadMetFanONCompOFF,
9005 : 0.0);
9006 171582 : };
9007 34514 : General::SolveRoot(state, CoolErrorToler, MaxIter, SolFlag, CoolPartLoadRatio, f, 0.0, 1.0);
9008 34514 : if (SolFlag == -1 && !state.dataGlobal->WarmupFlag && !FirstHVACIteration) {
9009 0 : state.dataHVACGlobal->OnOffFanPartLoadFraction = state.dataFurnaces->OnOffFanPartLoadFractionSave;
9010 0 : CalcFurnaceOutput(state,
9011 : FurnaceNum,
9012 : FirstHVACIteration,
9013 : OpMode,
9014 : CompressorOp,
9015 : CoolPartLoadRatio,
9016 : 0.0,
9017 : 0.0,
9018 : 0.0,
9019 : ZoneSensLoadMet,
9020 : ZoneLatLoadMet,
9021 : OnOffAirFlowRatio,
9022 : false);
9023 0 : if (std::abs(ZoneSensLoadMet - TotalZoneSensLoad) / TotalZoneSensLoad > CoolErrorToler) {
9024 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SensibleMaxIterIndex == 0) {
9025 0 : ShowWarningMessage(state,
9026 0 : "Cooling coil control failed to converge for " +
9027 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
9028 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
9029 0 : ShowContinueError(state, " Iteration limit exceeded in calculating DX cooling coil sensible part-load ratio.");
9030 0 : ShowContinueErrorTimeStamp(state,
9031 0 : format("Sensible load to be met by DX coil = {:.2T} (watts), sensible output of DX coil = "
9032 : "{:.2T} (watts), and the simulation continues.",
9033 : TotalZoneSensLoad,
9034 0 : ZoneSensLoadMet));
9035 : }
9036 0 : ShowRecurringWarningErrorAtEnd(state,
9037 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
9038 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
9039 : "\" - Iteration limit exceeded in calculating sensible cooling part-load ratio error "
9040 : "continues. Sensible load statistics:",
9041 0 : state.dataFurnaces->Furnace(FurnaceNum).SensibleMaxIterIndex,
9042 : TotalZoneSensLoad,
9043 : TotalZoneSensLoad);
9044 : }
9045 34514 : } else if (SolFlag == -2 && !state.dataGlobal->WarmupFlag && !FirstHVACIteration) {
9046 0 : CoolPartLoadRatio = max(MinPLR, min(1.0, std::abs(HPCoilSensDemand) / std::abs(HPCoilSensCapacity)));
9047 0 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
9048 0 : CalcFurnaceOutput(state,
9049 : FurnaceNum,
9050 : FirstHVACIteration,
9051 : OpMode,
9052 : CompressorOp,
9053 : CoolPartLoadRatio,
9054 : 0.0,
9055 : 0.0,
9056 : 0.0,
9057 : ZoneSensLoadMet,
9058 : ZoneLatLoadMet,
9059 : OnOffAirFlowRatio,
9060 : false);
9061 0 : if ((ZoneSensLoadMet - TotalZoneSensLoad) / TotalZoneSensLoad > CoolErrorToler) {
9062 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SensibleRegulaFalsiFailedIndex == 0) {
9063 0 : ShowWarningMessage(state,
9064 0 : "Cooling coil control failed for " +
9065 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
9066 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
9067 0 : ShowContinueError(state, " Cooling sensible part-load ratio determined to be outside the range of 0-1.");
9068 0 : ShowContinueError(
9069 : state,
9070 0 : format(" An estimated part-load ratio = {:.2T} will be used and the simulation continues.", CoolPartLoadRatio));
9071 0 : ShowContinueError(
9072 0 : state, format(" The estimated part-load ratio provides a cooling sensible capacity = {:.2T}", ZoneSensLoadMet));
9073 0 : ShowContinueErrorTimeStamp(state, format(" Cooling sensible load required = {:.2T}", TotalZoneSensLoad));
9074 : }
9075 0 : ShowRecurringWarningErrorAtEnd(
9076 : state,
9077 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
9078 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
9079 : "\" - Cooling sensible part-load ratio out of range error continues. Sensible cooling load statistics:",
9080 0 : state.dataFurnaces->Furnace(FurnaceNum).SensibleRegulaFalsiFailedIndex,
9081 : TotalZoneSensLoad,
9082 : TotalZoneSensLoad);
9083 : }
9084 : }
9085 : }
9086 :
9087 36696 : if (OpMode == CycFanCycCoil) {
9088 36696 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace *= CoolPartLoadRatio;
9089 : }
9090 :
9091 : //*********HEATING CALCULATIONS****************
9092 : // If Furnace runs with a heating load then set HeatCoilLoad on Heating Coil and the Mass Flow
9093 231333 : } else if ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0) &&
9094 137062 : (state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate > 0.0) && state.dataFurnaces->HeatingLoad) {
9095 :
9096 : // Set the air flow rate to the design flow rate and set the fan operation fraction to 1 (continuous operation)
9097 55203 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate;
9098 55203 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // see 'Note' under INITIAL CALCULATIONS
9099 :
9100 : // !Set the operation flag to run the fan continuously
9101 : // OpMode = ContFanCycCoil
9102 :
9103 : // Set the input parameters for CalcFurnaceOutput
9104 55203 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
9105 55203 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
9106 55203 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
9107 55203 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0; // compressor off
9108 55203 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump = true; // initialization call to Calc Furnace
9109 55203 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 0.0;
9110 55203 : HeatPartLoadRatio = 0.0;
9111 :
9112 : // Get no load result in order to calculate the effect of the fan and the mixed air equipment
9113 55203 : CalcFurnaceOutput(state,
9114 : FurnaceNum,
9115 : FirstHVACIteration,
9116 : OpMode,
9117 : CompressorOp,
9118 : CoolPartLoadRatio,
9119 : HeatPartLoadRatio,
9120 : Dummy2,
9121 : Dummy2,
9122 : ZoneSensLoadMetFanONCompOFF,
9123 : ZoneLatLoadMetFanONCompOFF,
9124 : OnOffAirFlowRatio,
9125 : false);
9126 :
9127 : // Set the input parameters for CalcFurnaceOutput
9128 55203 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 1.0;
9129 55203 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 1.0; // compressor ON
9130 55203 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 1.0;
9131 55203 : HeatPartLoadRatio = 1.0;
9132 :
9133 : // Get full load result in order to estimate the operating part load ratio for continuous fan operation
9134 :
9135 55203 : CalcFurnaceOutput(state,
9136 : FurnaceNum,
9137 : FirstHVACIteration,
9138 : OpMode,
9139 : CompressorOp,
9140 : CoolPartLoadRatio,
9141 : HeatPartLoadRatio,
9142 : Dummy2,
9143 : Dummy2,
9144 : ZoneSensLoadMetFanONCompON,
9145 : ZoneLatLoadMetFanONCompON,
9146 : OnOffAirFlowRatio,
9147 : false);
9148 :
9149 : // Calculate the heating coil demand for continuous fan operation as:
9150 : // (the zone sensible load - the zone sensible load met by fan heat and mixed air)
9151 : // Note; The sensible zone load met by fan heat and mixed air is calculated as:
9152 : // mdotsys(control zone inlet enthalpy - control zone outlet enthalpy)
9153 : // This accounts for the negative sign in the equation.
9154 55203 : HPCoilSensDemand = TotalZoneSensLoad - ZoneSensLoadMetFanONCompOFF;
9155 :
9156 : // Calculate the heating coil capacity for continuous fan operation as:
9157 : // (the zone sensible load met by fan heat and mixed air and coil
9158 : // - the zone sensible load met by fan heat and mixed air)
9159 55203 : HPCoilSensCapacity = ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF;
9160 :
9161 : // Calculate the part load ratio for continuous fan operation with cycling coil
9162 55203 : if (HPCoilSensCapacity == 0.0) {
9163 0 : HeatPartLoadRatio = 0.0;
9164 : } else {
9165 55203 : HeatPartLoadRatio = max(MinPLR, min(1.0, std::abs(HPCoilSensDemand) / std::abs(HPCoilSensCapacity)));
9166 : }
9167 :
9168 55203 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump = false;
9169 :
9170 : // check bounds on sensible output prior to iteration using RegulaFalsi
9171 55203 : if (ZoneSensLoadMetFanONCompON < TotalZoneSensLoad) {
9172 4228 : HeatPartLoadRatio = 1.0;
9173 4228 : ZoneSensLoadMet = ZoneSensLoadMetFanONCompON;
9174 4228 : HPCoilSensDemand = std::abs(ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF);
9175 4228 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = HPCoilSensDemand;
9176 50975 : } else if (ZoneSensLoadMetFanONCompOFF > TotalZoneSensLoad) {
9177 0 : HeatPartLoadRatio = 0.0;
9178 0 : ZoneSensLoadMet = ZoneSensLoadMetFanONCompOFF;
9179 0 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0; // compressor ON
9180 0 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = 0.0;
9181 0 : CalcFurnaceOutput(state,
9182 : FurnaceNum,
9183 : FirstHVACIteration,
9184 : OpMode,
9185 : CompressorOp,
9186 : CoolPartLoadRatio,
9187 : HeatPartLoadRatio,
9188 : Dummy2,
9189 : Dummy2,
9190 : ZoneSensLoadMet,
9191 : ZoneLatLoadMet,
9192 : OnOffAirFlowRatio,
9193 : false);
9194 : } else {
9195 : // Calculate the sensible part load ratio through iteration
9196 50975 : HeatErrorToler = state.dataFurnaces->Furnace(FurnaceNum).HeatingConvergenceTolerance;
9197 50975 : SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
9198 50975 : Par[0] = double(FurnaceNum);
9199 50975 : Par[1] = 0.0; // FLAG, if 1.0 then FirstHVACIteration equals TRUE, if 0.0 then FirstHVACIteration equals false
9200 50975 : if (FirstHVACIteration) Par[1] = 1.0;
9201 50975 : Par[2] = double(OpMode);
9202 50975 : Par[3] = double(CompressorOp);
9203 50975 : Par[4] = TotalZoneSensLoad;
9204 50975 : Par[5] = 0.0; // FLAG, 0.0 if heating load, 1.0 if cooling or moisture load
9205 50975 : Par[6] = 1.0; // FLAG, 0.0 if latent load, 1.0 if sensible load to be met
9206 50975 : Par[7] = ZoneSensLoadMetFanONCompOFF; // Output with fan ON compressor OFF
9207 50975 : Par[8] = 0.0; // HX is OFF for water-to-air HP
9208 : // HeatErrorToler is in fraction of load, MaxIter = 600, SolFalg = # of iterations or error as appropriate
9209 : auto f = [&state, FurnaceNum, FirstHVACIteration, OpMode, CompressorOp, TotalZoneSensLoad, ZoneSensLoadMetFanONCompOFF](
9210 407636 : Real64 const PartLoadRatio) {
9211 203818 : return CalcWaterToAirResidual(state,
9212 : PartLoadRatio,
9213 : FurnaceNum,
9214 : FirstHVACIteration,
9215 : OpMode,
9216 : CompressorOp,
9217 : TotalZoneSensLoad,
9218 : 0.0,
9219 : 1.0,
9220 : ZoneSensLoadMetFanONCompOFF,
9221 : 0.0);
9222 254793 : };
9223 50975 : General::SolveRoot(state, HeatErrorToler, MaxIter, SolFlag, HeatPartLoadRatio, f, 0.0, 1.0);
9224 50975 : state.dataHVACGlobal->OnOffFanPartLoadFraction = state.dataFurnaces->OnOffFanPartLoadFractionSave;
9225 50975 : CalcFurnaceOutput(state,
9226 : FurnaceNum,
9227 : FirstHVACIteration,
9228 : OpMode,
9229 : CompressorOp,
9230 : CoolPartLoadRatio,
9231 : HeatPartLoadRatio,
9232 : Dummy2,
9233 : Dummy2,
9234 : ZoneSensLoadMet,
9235 : ZoneLatLoadMet,
9236 : OnOffAirFlowRatio,
9237 : false);
9238 50975 : if (SolFlag == -1 && !state.dataGlobal->WarmupFlag && !FirstHVACIteration) {
9239 0 : if (std::abs(ZoneSensLoadMet - TotalZoneSensLoad) / TotalZoneSensLoad > HeatErrorToler) {
9240 0 : if (state.dataFurnaces->Furnace(FurnaceNum).WSHPHeatMaxIterIndex == 0) {
9241 0 : ShowWarningMessage(state,
9242 0 : "Heating coil control failed to converge for " +
9243 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
9244 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
9245 0 : ShowContinueError(state, " Iteration limit exceeded in calculating DX heating coil sensible part-load ratio.");
9246 0 : ShowContinueErrorTimeStamp(state,
9247 0 : format("Sensible load to be met by DX coil = {:.2T} (watts), sensible output of DX coil = "
9248 : "{:.2T} (watts), and the simulation continues.",
9249 : TotalZoneSensLoad,
9250 0 : ZoneSensLoadMet));
9251 : }
9252 0 : ShowRecurringWarningErrorAtEnd(
9253 : state,
9254 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
9255 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
9256 : "\" - Iteration limit exceeded in calculating sensible heating part-load ratio error continues.",
9257 0 : state.dataFurnaces->Furnace(FurnaceNum).WSHPHeatMaxIterIndex,
9258 : TotalZoneSensLoad,
9259 : TotalZoneSensLoad);
9260 : }
9261 50975 : } else if (SolFlag == -2) {
9262 0 : HeatPartLoadRatio = max(MinPLR, min(1.0, std::abs(HPCoilSensDemand) / std::abs(HPCoilSensCapacity)));
9263 0 : CalcFurnaceOutput(state,
9264 : FurnaceNum,
9265 : FirstHVACIteration,
9266 : OpMode,
9267 : CompressorOp,
9268 : 0.0,
9269 : HeatPartLoadRatio,
9270 : 0.0,
9271 : 0.0,
9272 : ZoneSensLoadMet,
9273 : ZoneLatLoadMet,
9274 : OnOffAirFlowRatio,
9275 : false);
9276 0 : if ((ZoneSensLoadMet - TotalZoneSensLoad) / TotalZoneSensLoad > HeatErrorToler) {
9277 0 : if (state.dataFurnaces->Furnace(FurnaceNum).WSHPHeatRegulaFalsiFailedIndex == 0) {
9278 0 : ShowWarningError(state,
9279 0 : "Heating coil control failed for " +
9280 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + ':' +
9281 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
9282 0 : ShowContinueError(state, " Heating sensible part-load ratio determined to be outside the range of 0-1.");
9283 0 : ShowContinueError(
9284 : state,
9285 0 : format(" An estimated part-load ratio = {:.2T} will be used and the simulation continues.", HeatPartLoadRatio));
9286 0 : ShowContinueError(
9287 0 : state, format(" The estimated part-load ratio provides a heating sensible capacity = {:.2T}", ZoneSensLoadMet));
9288 0 : ShowContinueErrorTimeStamp(state, format(" Heating sensible load required = {:.2T}", TotalZoneSensLoad));
9289 : }
9290 0 : ShowRecurringWarningErrorAtEnd(state,
9291 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + " \"" +
9292 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
9293 : "\" - Heating sensible part-load ratio out of range error continues.",
9294 0 : state.dataFurnaces->Furnace(FurnaceNum).WSHPHeatRegulaFalsiFailedIndex,
9295 : TotalZoneSensLoad,
9296 : TotalZoneSensLoad);
9297 : }
9298 : }
9299 : }
9300 :
9301 : // CALL supplemental heater if required
9302 55203 : if ((TotalZoneSensLoad - ZoneSensLoadMet) > SmallLoad && HeatPartLoadRatio >= 1.0) {
9303 4228 : SuppHeatCoilLoad = TotalZoneSensLoad - ZoneSensLoadMet;
9304 4228 : CalcFurnaceOutput(state,
9305 : FurnaceNum,
9306 : FirstHVACIteration,
9307 : OpMode,
9308 : CompressorOp,
9309 : CoolPartLoadRatio,
9310 : HeatPartLoadRatio,
9311 : SuppHeatCoilLoad,
9312 : Dummy2,
9313 : ZoneSensLoadMet,
9314 : ZoneLatLoadMet,
9315 : OnOffAirFlowRatio,
9316 : false);
9317 : }
9318 :
9319 55203 : if (OpMode == CycFanCycCoil) {
9320 55203 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace *= HeatPartLoadRatio;
9321 : }
9322 :
9323 : //**********HVAC Scheduled ON, but no cooling, dehumidification or heating load*********
9324 26656 : } else if (GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0) {
9325 12412 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump = true; // initialization call to Calc Furnace
9326 12412 : HeatPartLoadRatio = 0.0;
9327 12412 : CoolPartLoadRatio = 0.0;
9328 12412 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; //! see 'Note' under INITIAL CALCULATIONS
9329 : // set report variables
9330 12412 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
9331 12412 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
9332 12412 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
9333 12412 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
9334 12412 : if (OpMode == CycFanCycCoil) {
9335 12412 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = 0.0;
9336 12412 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // see 'Note' under INITIAL CALCULATIONS
9337 12412 : CalcFurnaceOutput(state,
9338 : FurnaceNum,
9339 : FirstHVACIteration,
9340 : OpMode,
9341 : CompressorOp,
9342 : CoolPartLoadRatio,
9343 : HeatPartLoadRatio,
9344 : Dummy2,
9345 : Dummy2,
9346 : ZoneSensLoadMet,
9347 : ZoneLatLoadMet,
9348 : OnOffAirFlowRatio,
9349 : false);
9350 12412 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = 0.0;
9351 : } else { // continuous fan, cycling coil
9352 0 : CalcFurnaceOutput(state,
9353 : FurnaceNum,
9354 : FirstHVACIteration,
9355 : OpMode,
9356 : CompressorOp,
9357 : CoolPartLoadRatio,
9358 : HeatPartLoadRatio,
9359 : Dummy2,
9360 : Dummy2,
9361 : ZoneSensLoadMet,
9362 : ZoneLatLoadMet,
9363 : OnOffAirFlowRatio,
9364 : false);
9365 : }
9366 : //*********No heating or cooling or dehumidification*********
9367 : } else {
9368 14244 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump = true; // initialization call to Calc Furnace
9369 14244 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = 0.0;
9370 14244 : HeatPartLoadRatio = 0.0;
9371 14244 : CoolPartLoadRatio = 0.0;
9372 14244 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // see 'Note' under INITIAL CALCULATIONS
9373 14244 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = 0.0;
9374 14244 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
9375 14244 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = 0.0;
9376 14244 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
9377 14244 : CalcFurnaceOutput(state,
9378 : FurnaceNum,
9379 : FirstHVACIteration,
9380 : OpMode,
9381 : CompressorOp,
9382 : CoolPartLoadRatio,
9383 : HeatPartLoadRatio,
9384 : Dummy2,
9385 : Dummy2,
9386 : ZoneSensLoadMet,
9387 : ZoneLatLoadMet,
9388 : OnOffAirFlowRatio,
9389 : false);
9390 14244 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = 0.0;
9391 : }
9392 :
9393 : // Set the fan inlet node flow rates
9394 118555 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
9395 118555 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace;
9396 118555 : }
9397 :
9398 20662494 : void CalcFurnaceOutput(EnergyPlusData &state,
9399 : int const FurnaceNum,
9400 : bool const FirstHVACIteration,
9401 : int const FanOpMode, // Cycling fan or constant fan
9402 : CompressorOperation const CompressorOp, // Compressor on/off; 1=on, 0=off
9403 : Real64 const CoolPartLoadRatio, // DX cooling coil part load ratio
9404 : Real64 const HeatPartLoadRatio, // DX heating coil part load ratio (0 for other heating coil types)
9405 : Real64 const HeatCoilLoad, // Heating coil load for gas heater
9406 : Real64 const ReheatCoilLoad, // Reheating coil load for gas heater
9407 : Real64 &SensibleLoadMet, // Sensible cooling load met (furnace outlet with respect to control zone temp)
9408 : Real64 &LatentLoadMet, // Latent cooling load met (furnace outlet with respect to control zone humidity ratio)
9409 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON mass flow rate to AVERAGE
9410 : bool const HXUnitOn, // flag to enable HX based on zone moisture load
9411 : Optional<Real64 const> CoolingHeatingPLRRat // cooling PLR to heating PLR ratio, used for cycling fan RH control
9412 : )
9413 : {
9414 :
9415 : // SUBROUTINE INFORMATION:
9416 : // AUTHOR Richard Raustad
9417 : // DATE WRITTEN Sept 2001
9418 : // MODIFIED Dec 2001
9419 : // RE-ENGINEERED na
9420 :
9421 : // PURPOSE OF THIS SUBROUTINE:
9422 : // This subroutine calculates to sensible and latent loads met by the DX coils
9423 : // specified. Load met is the outlet node with respect to the control zone's
9424 : // temperature and humidity ratio.
9425 :
9426 : // METHODOLOGY EMPLOYED:
9427 : // Simulate each child object in the correct order for each system type. This routine is used in the
9428 : // RegulaFalsi function CALL. Air mass flow rate is set each iteration based on PLR.
9429 :
9430 : // REFERENCES:
9431 : // na
9432 :
9433 : // Using/Aliasing
9434 : using HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil;
9435 : using WaterToAirHeatPump::SimWatertoAirHP;
9436 : using WaterToAirHeatPumpSimple::SimWatertoAirHPSimple;
9437 :
9438 : // Locals
9439 : // SUBROUTINE ARGUMENT DEFINITIONS:
9440 :
9441 : // SUBROUTINE PARAMETER DEFINITIONS:
9442 : // na
9443 :
9444 : // INTERFACE BLOCK SPECIFICATIONS
9445 : // na
9446 :
9447 : // DERIVED TYPE DEFINITIONS
9448 : // na
9449 :
9450 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9451 : int FurnaceInletNode; // Furnace inlet node number
9452 : int FurnaceOutletNode; // Furnace outlet node number
9453 : Real64 AirMassFlow; // Furnace inlet node temperature
9454 : Real64 WSHPRuntimeFrac; // Compressor runtime fraction
9455 : Real64 CompPartLoadRatio; // Compressor part load ratio
9456 : Real64 Dummy; // dummy variable
9457 : Real64 Tout; // Temporary variable used when outlet temp > DesignMaxOutletTemp
9458 : Real64 Wout; // Temporary variable used when outlet temp > DesignMaxOutletTemp
9459 : int CoolingCoilType_Num; // Numeric Equivalent for CoolingCoilType
9460 : int HeatingCoilType_Num; // Numeric Equivalent for HeatingCoilType
9461 : Real64 QActual; // heating coil load met or delivered
9462 : bool SuppHeatingCoilFlag; // .TRUE. if supplemental heating coil
9463 :
9464 20662494 : FurnaceOutletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
9465 20662494 : FurnaceInletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
9466 20662494 : CoolingCoilType_Num = state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilType_Num;
9467 20662494 : HeatingCoilType_Num = state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num;
9468 20662494 : WSHPRuntimeFrac = state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac;
9469 20662494 : CompPartLoadRatio = state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio;
9470 20662494 : state.dataFurnaces->ModifiedHeatCoilLoad = 0.0;
9471 :
9472 20662494 : if (present(CoolingHeatingPLRRat)) {
9473 9522132 : state.dataFurnaces->CoolHeatPLRRat = CoolingHeatingPLRRat;
9474 : } else {
9475 11140362 : state.dataFurnaces->CoolHeatPLRRat = 1.0;
9476 : }
9477 :
9478 : // Cooling to Heating PLR Ratio (CoolHeatPLRRat) is used to track the air mass flow rate of both the heating
9479 : // and cooling coils when RH control is used and the heating coil operates longer than the cooling coil.
9480 : // When CoolPartLoadRatio/CoolHeatPLRRat is used, the PLR calculated is acutally the PLR for the heating
9481 : // coil (heating PLR is greater than cooling PLR), it is this PLR that determines the air mass flow rate.
9482 : // When MAX(HeatPartLoadRatio,CoolPartLoadRatio) is used, only one of these values is non-zero.
9483 20662494 : if (FanOpMode == CycFanCycCoil) {
9484 12795140 : if (state.dataFurnaces->CoolHeatPLRRat < 1.0) {
9485 2 : if (state.dataFurnaces->CoolHeatPLRRat > 0.0) {
9486 0 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate =
9487 0 : state.dataFurnaces->CompOnMassFlow * CoolPartLoadRatio / state.dataFurnaces->CoolHeatPLRRat;
9488 0 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatPump_WaterToAir) {
9489 0 : SetAverageAirFlow(state, FurnaceNum, CoolPartLoadRatio / state.dataFurnaces->CoolHeatPLRRat, OnOffAirFlowRatio);
9490 : }
9491 : } else {
9492 2 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow * CoolPartLoadRatio;
9493 2 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatPump_WaterToAir) {
9494 2 : SetAverageAirFlow(state, FurnaceNum, max(HeatPartLoadRatio, CoolPartLoadRatio), OnOffAirFlowRatio);
9495 : }
9496 : }
9497 : } else {
9498 12795138 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate =
9499 12795138 : state.dataFurnaces->CompOnMassFlow * max(HeatPartLoadRatio, CoolPartLoadRatio);
9500 12795138 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatPump_WaterToAir) {
9501 6022879 : SetAverageAirFlow(state, FurnaceNum, max(HeatPartLoadRatio, CoolPartLoadRatio), OnOffAirFlowRatio);
9502 : }
9503 : }
9504 : } else {
9505 7867354 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatPump_WaterToAir) {
9506 5333042 : SetAverageAirFlow(state, FurnaceNum, max(HeatPartLoadRatio, CoolPartLoadRatio), OnOffAirFlowRatio);
9507 : }
9508 : }
9509 :
9510 20662494 : AirMassFlow = state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate;
9511 20662494 : state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = AirMassFlow;
9512 :
9513 : // Simulate the air-to-air heat pump
9514 20662494 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir) {
9515 : // Simulate blow-thru fan and non-linear coils twice to update PLF used by the ONOFF Fan
9516 2375656 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
9517 7126968 : SimulateFanComponents(
9518 4751312 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9519 2375656 : if (CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
9520 0 : SimHXAssistedCoolingCoil(state,
9521 : BlankString,
9522 : FirstHVACIteration,
9523 : CompressorOp,
9524 : CoolPartLoadRatio,
9525 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9526 : FanOpMode,
9527 : HXUnitOn,
9528 : OnOffAirFlowRatio,
9529 0 : state.dataFurnaces->EconomizerFlag);
9530 : } else {
9531 4751312 : SimDXCoil(state,
9532 : BlankString,
9533 : CompressorOp,
9534 : FirstHVACIteration,
9535 2375656 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9536 : FanOpMode,
9537 : CoolPartLoadRatio,
9538 : OnOffAirFlowRatio);
9539 : }
9540 4751312 : SimDXCoil(state,
9541 : BlankString,
9542 : CompressorOp,
9543 : FirstHVACIteration,
9544 2375656 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
9545 : FanOpMode,
9546 : HeatPartLoadRatio,
9547 : OnOffAirFlowRatio);
9548 7126968 : SimulateFanComponents(
9549 4751312 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9550 : }
9551 : // Simulate cooling and heating coils
9552 2375656 : if (CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
9553 0 : SimHXAssistedCoolingCoil(state,
9554 : BlankString,
9555 : FirstHVACIteration,
9556 : CompressorOp,
9557 : CoolPartLoadRatio,
9558 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9559 : FanOpMode,
9560 : HXUnitOn,
9561 : OnOffAirFlowRatio,
9562 0 : state.dataFurnaces->EconomizerFlag);
9563 : } else {
9564 4751312 : SimDXCoil(state,
9565 : BlankString,
9566 : CompressorOp,
9567 : FirstHVACIteration,
9568 2375656 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9569 : FanOpMode,
9570 : CoolPartLoadRatio,
9571 : OnOffAirFlowRatio);
9572 : }
9573 4751312 : SimDXCoil(state,
9574 : BlankString,
9575 : CompressorOp,
9576 : FirstHVACIteration,
9577 2375656 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
9578 : FanOpMode,
9579 : HeatPartLoadRatio,
9580 : OnOffAirFlowRatio);
9581 : // Simulate the draw-thru fan
9582 2375656 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == DrawThru) {
9583 0 : SimulateFanComponents(
9584 0 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9585 : }
9586 : // Simulate the supplemental heating coil
9587 2375656 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat && ReheatCoilLoad > 0.0) {
9588 0 : SuppHeatingCoilFlag = true;
9589 0 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, FanOpMode, QActual);
9590 : } else {
9591 : // equivalent to QCoilReq=0.0d0 or ReHeatCoilLoad = 0.0d0
9592 2375656 : SuppHeatingCoilFlag = true;
9593 2375656 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, FanOpMode, QActual);
9594 : }
9595 : // Simulate the parameter estimate water-to-air heat pump
9596 27593409 : } else if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
9597 9306571 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_Simple) {
9598 : // Simulate blow-thru fan and non-linear coils twice to update PLF used by the ONOFF Fan
9599 8700028 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
9600 26100084 : SimulateFanComponents(
9601 17400056 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9602 : // COIL:WATERTOAIRHPSIMPLE:COOLING
9603 60900196 : SimWatertoAirHPSimple(state,
9604 : BlankString,
9605 8700028 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9606 8700028 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand,
9607 8700028 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand,
9608 : FanOpMode,
9609 : WSHPRuntimeFrac,
9610 8700028 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
9611 8700028 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
9612 8700028 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
9613 : CompressorOp,
9614 : CoolPartLoadRatio,
9615 : FirstHVACIteration); // CoolPartLoadRatio
9616 8700028 : Dummy = 0.0;
9617 : // COIL:WATERTOAIRHPSIMPLE:HEATING
9618 52200168 : SimWatertoAirHPSimple(state,
9619 : BlankString,
9620 8700028 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
9621 8700028 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand,
9622 : Dummy,
9623 : FanOpMode,
9624 : WSHPRuntimeFrac,
9625 8700028 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
9626 8700028 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
9627 8700028 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
9628 : CompressorOp,
9629 : HeatPartLoadRatio,
9630 : FirstHVACIteration); // HeatPartLoadRatio
9631 : // Simulate the whole thing a second time so that the correct PLF required by the coils is used by the Fan. *******
9632 26100084 : SimulateFanComponents(
9633 17400056 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9634 : }
9635 : // Simulate the cooling and heating coils
9636 : // COIL:WATERTOAIRHPSIMPLE:COOLING
9637 60900196 : SimWatertoAirHPSimple(state,
9638 : BlankString,
9639 8700028 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9640 8700028 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand,
9641 8700028 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand,
9642 : FanOpMode,
9643 : WSHPRuntimeFrac,
9644 8700028 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
9645 8700028 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
9646 8700028 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
9647 : CompressorOp,
9648 : CoolPartLoadRatio,
9649 : FirstHVACIteration); // CoolPartLoadRatio
9650 8700028 : Dummy = 0.0;
9651 : // COIL:WATERTOAIRHPSIMPLE:HEATING
9652 52200168 : SimWatertoAirHPSimple(state,
9653 : BlankString,
9654 8700028 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
9655 8700028 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand,
9656 : Dummy,
9657 : FanOpMode,
9658 : WSHPRuntimeFrac,
9659 8700028 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
9660 8700028 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
9661 8700028 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
9662 : CompressorOp,
9663 : HeatPartLoadRatio,
9664 : FirstHVACIteration); // HeatPartLoadRatio
9665 : // Simulate the draw-thru fan
9666 8700028 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
9667 26100084 : SimulateFanComponents(
9668 17400056 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9669 : }
9670 : // Simulate the supplemental heating coil
9671 8700028 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat && ReheatCoilLoad > 0.0) {
9672 0 : SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
9673 0 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, FanOpMode, QActual);
9674 : } else {
9675 8700028 : SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
9676 8700028 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
9677 : }
9678 : // Simulate the detailed water-to-air heat pump
9679 10193353 : } else if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir &&
9680 606543 : state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType == WatertoAir_ParEst) {
9681 : // Simulate the draw-thru fan
9682 606543 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
9683 1819629 : SimulateFanComponents(
9684 1213086 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9685 : }
9686 : // Simulate the cooling and heating coils
9687 5458887 : SimWatertoAirHP(state,
9688 : BlankString,
9689 606543 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9690 606543 : state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate,
9691 : FanOpMode,
9692 : FirstHVACIteration,
9693 : WSHPRuntimeFrac,
9694 606543 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
9695 606543 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
9696 606543 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
9697 606543 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump,
9698 606543 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand,
9699 606543 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand,
9700 : CompressorOp,
9701 : CoolPartLoadRatio);
9702 606543 : Dummy = 0.0;
9703 4852344 : SimWatertoAirHP(state,
9704 : BlankString,
9705 606543 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
9706 606543 : state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate,
9707 : FanOpMode,
9708 : FirstHVACIteration,
9709 : WSHPRuntimeFrac,
9710 606543 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
9711 606543 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
9712 606543 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
9713 606543 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump,
9714 606543 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand,
9715 : Dummy,
9716 : CompressorOp,
9717 : HeatPartLoadRatio);
9718 : // Simulate the draw-thru fan
9719 606543 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == DrawThru) {
9720 0 : SimulateFanComponents(
9721 0 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9722 : }
9723 : // Simulate the supplemental heating coil
9724 1213086 : HeatingCoils::SimulateHeatingCoilComponents(
9725 606543 : state, BlankString, FirstHVACIteration, HeatCoilLoad, state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex, _, true, FanOpMode);
9726 :
9727 : } else { // ELSE it's not a heat pump
9728 : // Simulate blow-thru fan
9729 8980267 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
9730 :
9731 26340972 : SimulateFanComponents(
9732 17560648 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9733 :
9734 : // For non-linear coils, simulate coil to update PLF used by the ONOFF Fan
9735 8780324 : if (state.dataFurnaces->Furnace(FurnaceNum).FanType_Num == FanType_SimpleOnOff) {
9736 13582342 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatOnly &&
9737 6790148 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != Furnace_HeatOnly) {
9738 :
9739 6774449 : if (!state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) {
9740 4170038 : SuppHeatingCoilFlag = false; // if false simulates heating coil
9741 4170038 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
9742 : }
9743 :
9744 6774449 : if (CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
9745 71364 : SimHXAssistedCoolingCoil(state,
9746 : BlankString,
9747 : FirstHVACIteration,
9748 : CompressorOp,
9749 : CoolPartLoadRatio,
9750 23788 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9751 : FanOpMode,
9752 : HXUnitOn,
9753 : OnOffAirFlowRatio,
9754 23788 : state.dataFurnaces->EconomizerFlag);
9755 : } else {
9756 20251983 : SimDXCoil(state,
9757 : BlankString,
9758 : CompressorOp,
9759 : FirstHVACIteration,
9760 6750661 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9761 : FanOpMode,
9762 : CoolPartLoadRatio,
9763 : OnOffAirFlowRatio,
9764 6750661 : state.dataFurnaces->CoolHeatPLRRat);
9765 : }
9766 : }
9767 :
9768 6792194 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) {
9769 2622156 : SuppHeatingCoilFlag = false; // if false simulates heating coil
9770 2622156 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
9771 : }
9772 20376582 : SimulateFanComponents(
9773 13584388 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9774 : } // Simple OnOff fan
9775 :
9776 : } // Blow thru fan
9777 :
9778 : // Simulate the cooling and heating coils
9779 17958488 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatOnly &&
9780 8978221 : state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != Furnace_HeatOnly) {
9781 :
9782 8962522 : if (!state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) {
9783 4232872 : SuppHeatingCoilFlag = false; // if false simulates heating coil
9784 4232872 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
9785 : }
9786 :
9787 8962522 : if (CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
9788 468906 : SimHXAssistedCoolingCoil(state,
9789 : BlankString,
9790 : FirstHVACIteration,
9791 : CompressorOp,
9792 : CoolPartLoadRatio,
9793 156302 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9794 : FanOpMode,
9795 : HXUnitOn,
9796 : OnOffAirFlowRatio,
9797 156302 : state.dataFurnaces->EconomizerFlag);
9798 : } else {
9799 26418660 : SimDXCoil(state,
9800 : BlankString,
9801 : CompressorOp,
9802 : FirstHVACIteration,
9803 8806220 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
9804 : FanOpMode,
9805 : CoolPartLoadRatio,
9806 : OnOffAirFlowRatio,
9807 8806220 : state.dataFurnaces->CoolHeatPLRRat);
9808 : }
9809 : }
9810 :
9811 8980267 : if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) {
9812 4747395 : SuppHeatingCoilFlag = false; // if false simulates heating coil
9813 4747395 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, FanOpMode, QActual);
9814 : }
9815 : // Simulate the draw-thru fan
9816 8980267 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == DrawThru) {
9817 599829 : SimulateFanComponents(
9818 399886 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
9819 : }
9820 14987424 : if (state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat ||
9821 6007157 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex > 0) {
9822 3110219 : SuppHeatingCoilFlag = true; // if truee simulates supplemental heating coil
9823 3110219 : CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, FanOpMode, QActual);
9824 : }
9825 : } // IF(Furnace(FurnaceNum)%FurnaceType_Num == UnitarySys_HeatPump_AirToAir)THEN
9826 :
9827 : // check the DesignMaxOutletTemp and reset if necessary (for Coil:Gas:Heating or Coil:Electric:Heating only)
9828 41324988 : if (state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).Temp >
9829 20662494 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp) {
9830 211699 : Wout = state.dataLoopNodes->Node(FurnaceOutletNode).HumRat;
9831 211699 : Tout = state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp;
9832 211699 : state.dataFurnaces->ModifiedHeatCoilLoad =
9833 211699 : HeatCoilLoad - (AirMassFlow * PsyCpAirFnW(Wout) * (state.dataLoopNodes->Node(FurnaceOutletNode).Temp - Tout));
9834 211699 : state.dataLoopNodes->Node(FurnaceOutletNode).Temp = Tout;
9835 : }
9836 :
9837 : // If the fan runs continually do not allow coils to set OnOffFanPartLoadRatio.
9838 20662494 : if (FanOpMode == ContFanCycCoil) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
9839 :
9840 20662494 : Real64 SensibleOutput(0.0); // sensible output rate, {W}
9841 20662494 : Real64 LatentOutput(0.0); // latent output rate, {W}
9842 20662494 : Real64 TotalOutput(0.0); // total output rate, {W}
9843 82649976 : CalcZoneSensibleLatentOutput(AirMassFlow,
9844 20662494 : state.dataLoopNodes->Node(FurnaceOutletNode).Temp,
9845 20662494 : state.dataLoopNodes->Node(FurnaceOutletNode).HumRat,
9846 20662494 : state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).Temp,
9847 20662494 : state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).HumRat,
9848 : SensibleOutput,
9849 : LatentOutput,
9850 : TotalOutput);
9851 20662494 : SensibleLoadMet = SensibleOutput - state.dataFurnaces->Furnace(FurnaceNum).SenLoadLoss;
9852 20662494 : state.dataFurnaces->Furnace(FurnaceNum).SensibleLoadMet = SensibleLoadMet;
9853 :
9854 20662494 : if (state.dataFurnaces->Furnace(FurnaceNum).Humidistat) {
9855 3793590 : LatentLoadMet = LatentOutput - state.dataFurnaces->Furnace(FurnaceNum).LatLoadLoss;
9856 : } else {
9857 16868904 : LatentLoadMet = 0.0;
9858 : }
9859 20662494 : state.dataFurnaces->Furnace(FurnaceNum).LatentLoadMet = LatentLoadMet;
9860 20662494 : }
9861 :
9862 : // End of Update subroutines for the Furnace Module
9863 : // *****************************************************************************
9864 :
9865 7781723 : Real64 CalcFurnaceResidual(EnergyPlusData &state,
9866 : Real64 const PartLoadRatio, // DX cooling coil part load ratio
9867 : int FurnaceNum,
9868 : bool FirstHVACIteration,
9869 : int FanOpMode,
9870 : CompressorOperation CompressorOp,
9871 : Real64 LoadToBeMet,
9872 : Real64 par6_loadFlag,
9873 : Real64 par7_sensLatentFlag,
9874 : Real64 par9_HXOnFlag,
9875 : Real64 par10_HeatingCoilPLR)
9876 : {
9877 :
9878 : // FUNCTION INFORMATION:
9879 : // AUTHOR Richard Raustad
9880 : // DATE WRITTEN Feb 2005
9881 : // MODIFIED na
9882 : // RE-ENGINEERED na
9883 :
9884 : // PURPOSE OF THIS SUBROUTINE:
9885 : // To calculate the part-load ratio for cooling and heating coils
9886 :
9887 : // Parameter description example:
9888 : // Par(1) = REAL(FurnaceNum,r64) ! Index to furnace
9889 : // Par(2) = 0.0 ! FirstHVACIteration FLAG, if 1.0 then TRUE, if 0.0 then FALSE
9890 : // Par(3) = REAL(OpMode,r64) ! Fan control, if 1.0 then cycling fan, if 0.0 then continuous fan
9891 : // Par(4) = REAL(CompressorOp,r64) ! Compressor control, if 1.0 then compressor ON, if 0.0 then compressor OFF
9892 : // Par(5) = CoolCoilLoad ! Sensible or Latent load to be met by furnace
9893 : // Par(6) = 1.0 ! Type of load FLAG, 0.0 if heating load, 1.0 if cooling or moisture load
9894 : // Par(7) = 1.0 ! Output calculation FLAG, 0.0 for latent capacity, 1.0 for sensible capacity
9895 : // Par(8) = OnOffAirFlowRatio ! Ratio of compressor ON air mass flow to AVERAGE air mass flow over time step
9896 : // Par(9) = HXUnitOn ! flag to enable HX, 1=ON and 2=OFF
9897 : // Par(10) = HeatingCoilPLR ! used to calculate latent degradation for cycling fan RH control
9898 :
9899 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
9900 : Real64 CoolPartLoadRatio; // DX cooling coil part load ratio
9901 : Real64 HeatPartLoadRatio; // DX heating coil part load ratio (0 for other heating coil types)
9902 : Real64 HeatCoilLoad; // Heating coil load for gas heater
9903 : Real64 SensibleLoadMet; // Sensible cooling load met (furnace outlet with respect to control zone temp)
9904 : Real64 LatentLoadMet; // Latent cooling load met (furnace outlet with respect to control zone humidity ratio)
9905 : Real64 OnOffAirFlowRatio; // Ratio of compressor ON air mass flow to AVERAGE air mass flow over time step
9906 : Real64 RuntimeFrac; // heat pump runtime fraction
9907 : Real64 CoolingHeatingPLRRatio; // ratio of cooling PLR to heating PLR, used for cycling fan RH control
9908 : bool HXUnitOn; // flag to enable HX based on zone moisture load
9909 : bool errFlag; // flag denoting error in runtime calculation
9910 :
9911 : // // Convert parameters to usable variables
9912 : // int FurnaceNum = int(Par(1));
9913 : // bool FirstHVACIteration = Par(2) == 1.0;
9914 : // int FanOpMode = int(Par(3));
9915 : // CompressorOperation CompressorOp = static_cast<CompressorOperation>(Par(4));
9916 : // Real64 LoadToBeMet = Par(5);
9917 : // Real64 par6_loadFlag = Par(6);
9918 : // Real64 par7_sensLatentFlag = Par(7);
9919 : // Real64 par9_HXOnFlag = Par(9);
9920 : // Real64 par10_HeatingCoilPLR = Par(10);
9921 :
9922 7781723 : if (par6_loadFlag == 1.0) {
9923 4852975 : CoolPartLoadRatio = PartLoadRatio;
9924 4852975 : HeatPartLoadRatio = 0.0;
9925 4852975 : HeatCoilLoad = 0.0;
9926 : } else {
9927 2928748 : CoolPartLoadRatio = 0.0;
9928 2928748 : HeatPartLoadRatio = PartLoadRatio;
9929 :
9930 2928748 : auto const HeatingCoilType_Num(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num);
9931 2928748 : if (HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel || HeatingCoilType_Num == Coil_HeatingElectric ||
9932 1638834 : HeatingCoilType_Num == Coil_HeatingWater || HeatingCoilType_Num == Coil_HeatingSteam) {
9933 1289914 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * PartLoadRatio;
9934 : } else {
9935 1638834 : HeatCoilLoad = 0.0;
9936 : }
9937 : }
9938 :
9939 : // OnOffAirFlowRatio = Par(8)
9940 7781723 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_WaterToAir) {
9941 3572932 : HeatPumpRunFrac(state, FurnaceNum, PartLoadRatio, errFlag, RuntimeFrac);
9942 3572932 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadRatio;
9943 3572932 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = RuntimeFrac;
9944 : }
9945 :
9946 7781723 : if (par9_HXOnFlag == 1.0) {
9947 4820033 : HXUnitOn = true;
9948 : } else {
9949 2961690 : HXUnitOn = false;
9950 : }
9951 :
9952 7781723 : if (par10_HeatingCoilPLR > 0.0) {
9953 : // Par(10) = Furnace(FurnaceNum)%HeatPartLoadRatio
9954 : // FanOpMode = CycFan and Furnace(FurnaceNum)%HeatPartLoadRatio must be > 0 for Part(10) to be greater than 0
9955 : // This variable used when in heating mode and dehumidification (cooling) is required.
9956 0 : CoolingHeatingPLRRatio = min(1.0, CoolPartLoadRatio / state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio);
9957 : } else {
9958 7781723 : CoolingHeatingPLRRatio = 1.0;
9959 : }
9960 :
9961 : // Subroutine arguments
9962 7781723 : CalcFurnaceOutput(state,
9963 : FurnaceNum,
9964 : FirstHVACIteration,
9965 : FanOpMode,
9966 : CompressorOp,
9967 : CoolPartLoadRatio,
9968 : HeatPartLoadRatio,
9969 : HeatCoilLoad,
9970 : 0.0,
9971 : SensibleLoadMet,
9972 : LatentLoadMet,
9973 : OnOffAirFlowRatio,
9974 : HXUnitOn,
9975 : CoolingHeatingPLRRatio);
9976 :
9977 : // Calculate residual based on output calculation flag
9978 7781723 : if (par7_sensLatentFlag == 1.0) {
9979 7308587 : if (LoadToBeMet == 0.0) {
9980 66408 : return (SensibleLoadMet - LoadToBeMet) / 100.0;
9981 : } else {
9982 7242179 : return (SensibleLoadMet - LoadToBeMet) / LoadToBeMet;
9983 : }
9984 : } else {
9985 473136 : if (LoadToBeMet == 0.0) {
9986 0 : return (LatentLoadMet - LoadToBeMet) / 100.0;
9987 : } else {
9988 473136 : return (LatentLoadMet - LoadToBeMet) / LoadToBeMet;
9989 : }
9990 : }
9991 : }
9992 :
9993 340886 : Real64 CalcWaterToAirResidual(EnergyPlusData &state,
9994 : Real64 const PartLoadRatio, // DX cooling coil part load ratio
9995 : int FurnaceNum,
9996 : bool FirstHVACIteration,
9997 : int FanOpMode,
9998 : CompressorOperation CompressorOp,
9999 : Real64 LoadToBeMet,
10000 : Real64 par6_loadTypeFlag,
10001 : Real64 par7_latentOrSensible,
10002 : Real64 ZoneSensLoadMetFanONCompOFF,
10003 : Real64 par9_HXUnitOne)
10004 : {
10005 :
10006 : // FUNCTION INFORMATION:
10007 : // AUTHOR Richard Raustad
10008 : // DATE WRITTEN October 2006
10009 : // MODIFIED na
10010 : // RE-ENGINEERED na
10011 :
10012 : // PURPOSE OF THIS SUBROUTINE:
10013 : // To calculate the part-load ratio for water to air HP's
10014 : // this is used for parameter estimation WAHPs but not equation fit WAHPs
10015 :
10016 : // Parameter description example:
10017 : // Par(1) = REAL(FurnaceNum,r64) ! Index to furnace
10018 : // Par(2) = 0.0 ! FirstHVACIteration FLAG, if 1.0 then TRUE, if 0.0 then FALSE
10019 : // Par(3) = REAL(OpMode,r64) ! Fan control, if 1.0 then cycling fan, if 0.0 then continuous fan
10020 : // Par(4) = REAL(CompressorOp,r64) ! Compressor control, if 1.0 then compressor ON, if 0.0 then compressor OFF
10021 : // Par(5) = CoolCoilLoad ! Sensible or Latent load to be met by furnace
10022 : // Par(6) = 1.0 ! Type of load FLAG, 0.0 if heating load, 1.0 if cooling or moisture load
10023 : // Par(7) = 1.0 ! Output calculation FLAG, 0.0 for latent capacity, 1.0 for sensible capacity
10024 : // Par(8) = ZoneSensLoadMetFanONCompOFF ! Output with fan ON compressor OFF
10025 :
10026 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10027 : Real64 CoolPartLoadRatio; // DX cooling coil part load ratio
10028 : Real64 HeatPartLoadRatio; // DX heating coil part load ratio (0 for other heating coil types)
10029 : Real64 HeatCoilLoad; // Heating coil load for gas heater
10030 : Real64 ZoneSensLoadMet; // Sensible cooling load met (furnace outlet with respect to control zone temp)
10031 : Real64 ZoneLatLoadMet; // Latent cooling load met (furnace outlet with respect to control zone humidity ratio)
10032 : bool errFlag;
10033 : Real64 RuntimeFrac;
10034 : Real64 Dummy;
10035 : Real64 HPCoilSensDemand;
10036 : Real64 OnOffAirFlowRatio;
10037 : bool HXUnitOn; // flag to enable HX based on zone moisture load (not valid for water-to-air HP's
10038 :
10039 : // Convert parameters to usable variables
10040 : // int FurnaceNum = int(Par[0]);
10041 : // bool FirstHVACIteration = Par[1] == 1.0;
10042 : // int FanOpMode = int(Par[2]);
10043 : // CompressorOperation CompressorOp = static_cast<CompressorOperation>(Par[3]);
10044 : // Real64 LoadToBeMet = Par[4];
10045 : // Real64 par6_loadTypeFlag = Par[5];
10046 : // Real64 par7_latentOrSensible = Par[6];
10047 : // Real64 ZoneSensLoadMetFanONCompOFF = Par[7];
10048 : // Real64 par9_HXUnitOne = Par[8];
10049 :
10050 340886 : if (par6_loadTypeFlag == 1.0) {
10051 137068 : CoolPartLoadRatio = PartLoadRatio;
10052 137068 : HeatPartLoadRatio = 0.0;
10053 137068 : HeatCoilLoad = 0.0;
10054 : } else {
10055 203818 : CoolPartLoadRatio = 0.0;
10056 203818 : HeatPartLoadRatio = PartLoadRatio;
10057 : }
10058 :
10059 : // calculate the run time fraction
10060 340886 : HeatPumpRunFrac(state, FurnaceNum, PartLoadRatio, errFlag, RuntimeFrac);
10061 :
10062 : // update the fan part load factor
10063 : // see 'Note' under INITIAL CALCULATIONS
10064 340886 : if (par6_loadTypeFlag == 1.0) {
10065 137068 : if (RuntimeFrac > 0.0) {
10066 102554 : state.dataHVACGlobal->OnOffFanPartLoadFraction = CoolPartLoadRatio / RuntimeFrac;
10067 : } else {
10068 34514 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
10069 : }
10070 : } else {
10071 203818 : if (RuntimeFrac > 0.0) {
10072 152843 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PartLoadRatio / RuntimeFrac;
10073 : // Else IF(RuntimeFrac == 0.0d0)THEN
10074 : // OnOffFanPartLoadFraction = 0.0
10075 : } else {
10076 50975 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
10077 : }
10078 : }
10079 340886 : state.dataFurnaces->OnOffFanPartLoadFractionSave = state.dataHVACGlobal->OnOffFanPartLoadFraction;
10080 : // update fan and compressor run times
10081 340886 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadRatio;
10082 340886 : state.dataFurnaces->Furnace(FurnaceNum).WSHPRuntimeFrac = RuntimeFrac;
10083 :
10084 : // Calculate the heating coil demand as (the zone sensible load - load met by fan heat and mixed air)
10085 : // Note; The load met by fan heat and mixed air is calculated as mdot(zoneinletenthalpy-zoneoutletenthalpy)
10086 : // This accounts for the negative sign in the equation.
10087 :
10088 : // Calculate the heat coil sensible capacity as the load met by the system with the fan and compressor on less
10089 : // the load met by the system with the compressor off.
10090 : // HPCoilSensCapacity = ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF
10091 :
10092 : // Set input parameters for heat pump coil model
10093 340886 : HPCoilSensDemand = LoadToBeMet - RuntimeFrac * ZoneSensLoadMetFanONCompOFF;
10094 : // HPCoilSensDemand = LoadToBeMet - PartLoadRatio*ZoneSensLoadMetFanONCompOFF
10095 340886 : if (par6_loadTypeFlag == 1.0) {
10096 137068 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
10097 137068 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = std::abs(HPCoilSensDemand);
10098 : } else {
10099 203818 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = HPCoilSensDemand;
10100 203818 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
10101 : }
10102 340886 : state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump = false; // initialization call to Calc Furnace
10103 :
10104 : // Calculate the zone loads met and the new part load ratio and for the specified run time
10105 340886 : Dummy = 0.0;
10106 340886 : OnOffAirFlowRatio = 1.0;
10107 340886 : if (par9_HXUnitOne == 1.0) {
10108 0 : HXUnitOn = true;
10109 : } else {
10110 340886 : HXUnitOn = false;
10111 : }
10112 :
10113 : // Subroutine arguments
10114 : // CALL CalcFurnaceOutput(FurnaceNum,FirstHVACIteration,FanOpMode,CompressorOp,CoolPartLoadRatio,&
10115 : // HeatPartLoadRatio, HeatCoilLoad, ReHeatCoilLoad, SensibleLoadMet, LatentLoadMet, HXUnitOn)
10116 340886 : CalcFurnaceOutput(state,
10117 : FurnaceNum,
10118 : FirstHVACIteration,
10119 : FanOpMode,
10120 : CompressorOp,
10121 : CoolPartLoadRatio,
10122 : HeatPartLoadRatio,
10123 : Dummy,
10124 : Dummy,
10125 : ZoneSensLoadMet,
10126 : ZoneLatLoadMet,
10127 : OnOffAirFlowRatio,
10128 : HXUnitOn);
10129 :
10130 : // Calculate residual based on output calculation flag
10131 340886 : if (par7_latentOrSensible == 1.0) {
10132 340886 : return (ZoneSensLoadMet - LoadToBeMet) / LoadToBeMet;
10133 : } else {
10134 0 : return (ZoneLatLoadMet - LoadToBeMet) / LoadToBeMet;
10135 : }
10136 : }
10137 :
10138 26112810 : void SetAverageAirFlow(EnergyPlusData &state,
10139 : int const FurnaceNum, // Unit index
10140 : Real64 const PartLoadRatio, // unit part load ratio
10141 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep
10142 : )
10143 : {
10144 :
10145 : // SUBROUTINE INFORMATION:
10146 : // AUTHOR Richard Raustad
10147 : // DATE WRITTEN July 2005
10148 : // MODIFIED na
10149 : // RE-ENGINEERED na
10150 :
10151 : // PURPOSE OF THIS SUBROUTINE:
10152 : // Set the average air mass flow rates using the part-load fraction of the HVAC system for this time step
10153 : // Set OnOffAirFlowRatio to be used by DX coils
10154 :
10155 : // METHODOLOGY EMPLOYED:
10156 : // The air flow rate in cooling, heating, and no cooling or heating can be different.
10157 : // Calculate the air flow rate based on initializations made in InitFurnace.
10158 :
10159 : // REFERENCES:
10160 : // na
10161 :
10162 : // Using/Aliasing
10163 : using namespace DataZoneEnergyDemands;
10164 :
10165 : // Locals
10166 : // SUBROUTINE ARGUMENT DEFINITIONS:
10167 :
10168 : // SUBROUTINE PARAMETER DEFINITIONS:
10169 : // na
10170 :
10171 : // INTERFACE BLOCK SPECIFICATIONS
10172 : // na
10173 :
10174 : // DERIVED TYPE DEFINITIONS
10175 : // na
10176 :
10177 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10178 : int InletNode; // inlet node number for furnace
10179 : Real64 AverageUnitMassFlow; // average supply air mass flow rate over time step
10180 :
10181 26112810 : InletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
10182 :
10183 26112810 : AverageUnitMassFlow = (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
10184 26112810 : if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
10185 12453602 : state.dataFurnaces->FanSpeedRatio =
10186 12453602 : (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
10187 : } else {
10188 13659208 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
10189 : }
10190 : // IF the furnace is scheduled on or nightime cycle overrides fan schedule. Uses same logic as fan.
10191 76252508 : if (GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0 &&
10192 51674744 : ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).FanAvailSchedPtr) > 0.0 || state.dataHVACGlobal->TurnFansOn) &&
10193 24732615 : !state.dataHVACGlobal->TurnFansOff)) {
10194 24732615 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
10195 24732615 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AverageUnitMassFlow;
10196 24732615 : if (AverageUnitMassFlow > 0.0) {
10197 20309180 : OnOffAirFlowRatio = state.dataFurnaces->CompOnMassFlow / AverageUnitMassFlow;
10198 : } else {
10199 4423435 : OnOffAirFlowRatio = 0.0;
10200 : }
10201 : } else {
10202 1380195 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
10203 1380195 : OnOffAirFlowRatio = 1.0;
10204 : }
10205 :
10206 26112810 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = state.dataFurnaces->CompOnMassFlow;
10207 26112810 : state.dataFurnaces->OnOffAirFlowRatioSave = OnOffAirFlowRatio;
10208 26112810 : }
10209 :
10210 3913818 : void HeatPumpRunFrac(EnergyPlusData &state,
10211 : int const FurnaceNum, // Furnace Index Number
10212 : Real64 const PLR, // part load ratio
10213 : bool &errFlag, // part load factor out of range flag
10214 : Real64 &RuntimeFrac // the required run time fraction to meet part load
10215 : )
10216 : {
10217 : // SUBROUTINE INFORMATION:
10218 : // AUTHOR Kenneth Tang
10219 : // DATE WRITTEN Apr 2004
10220 : // MODIFIED na
10221 : // RE-ENGINEERED na
10222 :
10223 : // PURPOSE OF THIS SUBROUTINE:
10224 : // This subroutine calculates the PLF based on the PLR. Parameters required are
10225 : // thermostat cycling rate (Nmax), heat pump time constant (tau), and the fraction
10226 : // of on-cycle power use (pr)
10227 :
10228 : // METHODOLOGY EMPLOYED:
10229 : // NA
10230 :
10231 : // REFERENCES:
10232 : // (1) Henderson, H. I., K. Rengarajan.1996. A Model to predict the latent capacity
10233 : // of air conditioners and heat pumps at part-load conditions with constant fan
10234 : // operation. ASHRAE Transactions 102 (1): 266-274
10235 :
10236 : // (2) Henderson, H.I. Jr., Y.J. Huang and Danny Parker. 1999. Residential Equipment
10237 : // Part Load Curves for Use in DOE-2. Environmental Energy Technologies Division,
10238 : // Ernest Orlando Lawrence Berkeley National Laboratory.
10239 :
10240 : // USE STATEMENTS:
10241 :
10242 : // Locals
10243 : // SUBROUTINE ARGUMENT DEFINITIONS:
10244 :
10245 : // SUBROUTINE PARAMETER DEFINITIONS:
10246 : // na
10247 :
10248 : // INTERFACE BLOCK SPECIFICATIONS
10249 : // na
10250 :
10251 : // DERIVED TYPE DEFINITIONS
10252 : // na
10253 :
10254 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10255 : Real64 PartLoadFactor; // Part load factor
10256 : Real64 Nmax; // Maximum cycling rate [cycles/hr]
10257 : Real64 tau; // Heat pump time constant [s]
10258 : Real64 pr; // On-cycle power use fraction [~]
10259 : Real64 error; // Calculation error
10260 : Real64 PLF1; // ith term of part load factor
10261 : Real64 PLF2; // (i+1)th term of part load factor
10262 : Real64 A; // Variable for simplify equation
10263 : int NumIteration; // Iteration Counter
10264 :
10265 3913818 : Nmax = state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour;
10266 3913818 : tau = state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant;
10267 3913818 : pr = state.dataFurnaces->Furnace(FurnaceNum).OnCyclePowerFraction;
10268 :
10269 : // Initialize
10270 3913818 : errFlag = false;
10271 3913818 : error = 1.0;
10272 3913818 : NumIteration = 0;
10273 :
10274 : // Initial guess for part load fraction
10275 3913818 : PLF1 = 1.0;
10276 :
10277 : // Calculate PLF using successive substitution until convergence is achieved
10278 : while (true) {
10279 23178122 : ++NumIteration;
10280 :
10281 13545970 : if (PLR == 1) {
10282 : // Set part load fraction, PLF1=1.0 if PLR=1.0 and exit loop
10283 1258521 : PLF1 = 1.0;
10284 1258521 : goto LOOPPLF_exit;
10285 : }
10286 :
10287 12287449 : if (NumIteration > 100) {
10288 : // Exit loop if interation exceed 100
10289 0 : errFlag = true;
10290 0 : PLF1 = 1.0;
10291 0 : goto LOOPPLF_exit;
10292 : }
10293 :
10294 12287449 : if (error < 0.00001) {
10295 : // Exit loop if convergence is achieved
10296 2655297 : goto LOOPPLF_exit;
10297 :
10298 : } else {
10299 : // Calculate PLF
10300 9632152 : A = 4.0 * tau * (Nmax / 3600.0) * (1 - PLR / PLF1);
10301 9632152 : if (A < 1.5e-3) {
10302 : // A safety check to prevent PLF2 = 1 - A * (1 - Exp(-1 / A))
10303 : // from "float underflow error". Occurs when PLR is very close to 1.0,
10304 : // small A value, thus Exp(-1/A) = 0
10305 28896 : PLF2 = 1 - A;
10306 : } else {
10307 9603256 : PLF2 = 1.0 - A * (1.0 - std::exp(-1.0 / A));
10308 : }
10309 9632152 : error = std::abs((PLF2 - PLF1) / PLF1);
10310 9632152 : PLF1 = PLF2;
10311 : }
10312 : }
10313 3913818 : LOOPPLF_exit:;
10314 :
10315 : // Adjust PLF for the off cycle power consumption if
10316 : // on-cycle power use is specified by the user
10317 3913818 : if (pr > 0.0) {
10318 3913818 : PartLoadFactor = PLR / ((PLR / PLF1) + (1 - PLR / PLF1) * pr);
10319 : } else {
10320 0 : PartLoadFactor = PLF1;
10321 : }
10322 :
10323 3913818 : if (PartLoadFactor <= 0.0) {
10324 1258521 : PartLoadFactor = 0.0;
10325 1258521 : RuntimeFrac = 0.0;
10326 1258521 : errFlag = true;
10327 : } else {
10328 2655297 : RuntimeFrac = PLR / PartLoadFactor;
10329 : }
10330 :
10331 3913818 : if (RuntimeFrac > 1.0) {
10332 0 : RuntimeFrac = 1.0;
10333 : }
10334 3913818 : }
10335 :
10336 : // Beginning of Reporting subroutines for the Furnace Module
10337 : // *****************************************************************************
10338 :
10339 6396161 : void ReportFurnace(EnergyPlusData &state, int const FurnaceNum, int const AirLoopNum)
10340 : {
10341 :
10342 : // SUBROUTINE INFORMATION:
10343 : // AUTHOR Richard Liesen
10344 : // DATE WRITTEN Feb 2001
10345 : // MODIFIED na
10346 : // RE-ENGINEERED na
10347 :
10348 : // PURPOSE OF THIS SUBROUTINE:
10349 : // This subroutine updates the report variable for the coils.
10350 :
10351 : // METHODOLOGY EMPLOYED:
10352 : // Update fan part-load ratio based on mass flow rate ratio.
10353 : // Update global variables used by AirflowNetwork module.
10354 :
10355 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10356 : Real64 ratio;
10357 : Real64 OnOffRatio;
10358 :
10359 : // Report the Furnace Fan Part Load Ratio
10360 6396161 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling < 1) {
10361 4897761 : if (state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate > 0.0) {
10362 4897761 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio =
10363 4897761 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace / state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate;
10364 : } else {
10365 0 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = 0.0;
10366 : }
10367 : }
10368 :
10369 : // Set mass flow rates during on and off cylce using an OnOff fan
10370 6396161 : if (state.afn->distribution_simulated) {
10371 328068 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate = state.dataFurnaces->CompOnMassFlow;
10372 328068 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate = state.dataFurnaces->CompOffMassFlow;
10373 328068 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode = state.dataFurnaces->Furnace(FurnaceNum).OpMode;
10374 328068 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio = state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio;
10375 328068 : OnOffRatio = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
10376 328068 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatPump_AirToAir) {
10377 263778 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio =
10378 527556 : max(state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio,
10379 263778 : state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio,
10380 263778 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio);
10381 263778 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio =
10382 263778 : min(1.0, state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio);
10383 : }
10384 328068 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool) {
10385 74622 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio == 0.0 &&
10386 32468 : state.dataFurnaces->Furnace(FurnaceNum).CoolPartLoadRatio == 0.0 &&
10387 7594 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio > 0.0) {
10388 22224 : if (state.dataFurnaces->CompOnMassFlow < max(state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow,
10389 14816 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow) &&
10390 0 : state.dataFurnaces->CompOnMassFlow > 0.0) {
10391 0 : ratio = max(state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow,
10392 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow) /
10393 0 : state.dataFurnaces->CompOnMassFlow;
10394 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio =
10395 0 : state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio * ratio;
10396 : }
10397 : }
10398 : }
10399 : }
10400 6396161 : if (state.dataFurnaces->Furnace(FurnaceNum).FirstPass) {
10401 356 : if (!state.dataGlobal->SysSizingCalc) {
10402 356 : DataSizing::resetHVACSizingGlobals(state, 0, state.dataSize->CurSysNum, state.dataFurnaces->Furnace(FurnaceNum).FirstPass);
10403 : }
10404 : }
10405 6396161 : state.dataHVACGlobal->OnOffFanPartLoadFraction =
10406 : 1.0; // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
10407 6396161 : }
10408 :
10409 68650180 : void CalcNonDXHeatingCoils(EnergyPlusData &state,
10410 : int const FurnaceNum, // Furnace Index
10411 : bool const SuppHeatingCoilFlag, // .TRUE. if supplemental heating coil
10412 : bool const FirstHVACIteration, // flag for first HVAC iteration in the time step
10413 : Real64 const QCoilLoad, // load met by unit (watts)
10414 : int const FanMode, // fan operation mode
10415 : Real64 &HeatCoilLoadmet // Heating Load Met
10416 : )
10417 : {
10418 : // SUBROUTINE INFORMATION:
10419 : // AUTHOR Bereket Nigusse, FSEC/UCF
10420 : // DATE WRITTEN January 2012
10421 : // MODIFIED na
10422 : // RE-ENGINEERED na
10423 :
10424 : // PURPOSE OF THIS SUBROUTINE:
10425 : // This subroutine simulates the four non dx heating coil types: Gas, Electric, hot water and steam.
10426 :
10427 : // METHODOLOGY EMPLOYED:
10428 : // Simply calls the different heating coil component. The hot water flow rate matching the coil load
10429 : // is calculated iteratively.
10430 :
10431 : // Using/Aliasing
10432 : using DataHVACGlobals::SmallLoad;
10433 : using PlantUtilities::SetComponentFlowRate;
10434 : using SteamCoils::SimulateSteamCoilComponents;
10435 : using WaterCoils::SimulateWaterCoilComponents;
10436 :
10437 : // Locals
10438 : // SUBROUTINE ARGUMENT DEFINITIONS:
10439 :
10440 : // SUBROUTINE PARAMETER DEFINITIONS:
10441 68650180 : Real64 constexpr ErrTolerance(0.001); // convergence limit for hotwater coil
10442 68650180 : int constexpr SolveMaxIter(50);
10443 :
10444 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10445 : Real64 QActual; // actual heating load
10446 : Real64 mdot; // heating coil steam or hot water mass flow rate
10447 : Real64 MinWaterFlow; // coil minimum hot water mass flow rate, kg/s
10448 : Real64 MaxHotWaterFlow; // coil maximum hot water mass flow rate, kg/s
10449 : Real64 HotWaterMdot; // actual hot water mass flow rate
10450 : std::array<Real64, 4> Par;
10451 : int SolFlag;
10452 68650180 : auto &HeatingCoilName = state.dataFurnaces->HeatingCoilName; // name of heating coil
10453 68650180 : int CoilTypeNum(0); // heating coil type number
10454 68650180 : int HeatingCoilIndex(0); // heating coil index
10455 68650180 : int CoilControlNode(0); // control node for hot water and steam heating coils
10456 68650180 : int CoilOutletNode(0); // air outlet node of the heatiing coils
10457 68650180 : PlantLocation plantLoc{}; // plant loop location
10458 :
10459 68650180 : QActual = 0.0;
10460 :
10461 68650180 : if (SuppHeatingCoilFlag) {
10462 19592255 : HeatingCoilName = state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName;
10463 19592255 : HeatingCoilIndex = state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex;
10464 19592255 : CoilControlNode = state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode;
10465 19592255 : CoilOutletNode = state.dataFurnaces->Furnace(FurnaceNum).SuppCoilOutletNode;
10466 19592255 : CoilTypeNum = state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilType_Num;
10467 19592255 : plantLoc = state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc;
10468 19592255 : MaxHotWaterFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxSuppCoilFluidFlow;
10469 : } else {
10470 49057925 : HeatingCoilName = state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName;
10471 49057925 : HeatingCoilIndex = state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex;
10472 49057925 : CoilControlNode = state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode;
10473 49057925 : CoilOutletNode = state.dataFurnaces->Furnace(FurnaceNum).CoilOutletNode;
10474 49057925 : CoilTypeNum = state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num;
10475 49057925 : plantLoc = state.dataFurnaces->Furnace(FurnaceNum).plantLoc;
10476 49057925 : MaxHotWaterFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxHeatCoilFluidFlow;
10477 : }
10478 :
10479 68650180 : switch (CoilTypeNum) {
10480 68557286 : case Coil_HeatingGasOrOtherFuel:
10481 : case Coil_HeatingElectric:
10482 : case Coil_HeatingDesuperheater: {
10483 68557286 : HeatingCoils::SimulateHeatingCoilComponents(
10484 : state, HeatingCoilName, FirstHVACIteration, QCoilLoad, HeatingCoilIndex, QActual, SuppHeatingCoilFlag, FanMode);
10485 68557286 : } break;
10486 92894 : case Coil_HeatingWater: {
10487 92894 : if (QCoilLoad > SmallLoad) {
10488 1540 : SetComponentFlowRate(state, MaxHotWaterFlow, CoilControlNode, CoilOutletNode, plantLoc);
10489 1540 : SimulateWaterCoilComponents(state, HeatingCoilName, FirstHVACIteration, HeatingCoilIndex, QActual, FanMode);
10490 :
10491 1540 : if (QActual > (QCoilLoad + SmallLoad)) {
10492 : // control water flow to obtain output matching QCoilLoad
10493 1440 : MinWaterFlow = 0.0;
10494 1440 : Par[0] = double(FurnaceNum);
10495 1440 : if (FirstHVACIteration) {
10496 0 : Par[1] = 1.0;
10497 : } else {
10498 1440 : Par[1] = 0.0;
10499 : }
10500 1440 : Par[2] = QCoilLoad;
10501 1440 : if (SuppHeatingCoilFlag) {
10502 1440 : Par[3] = 1.0;
10503 : } else {
10504 0 : Par[3] = 0.0;
10505 : }
10506 379304 : auto f = [&state, FurnaceNum, FirstHVACIteration, QCoilLoad, SuppHeatingCoilFlag](Real64 const HWFlow) {
10507 22312 : Real64 QCoilRequested = QCoilLoad;
10508 :
10509 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
10510 : Real64 QCoilActual; // delivered coil load, W
10511 22312 : Real64 mdot = HWFlow; // to get non-const argument
10512 22312 : QCoilActual = QCoilRequested;
10513 22312 : if (!SuppHeatingCoilFlag) {
10514 0 : PlantUtilities::SetComponentFlowRate(state,
10515 : mdot,
10516 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode,
10517 0 : state.dataFurnaces->Furnace(FurnaceNum).CoilOutletNode,
10518 0 : state.dataFurnaces->Furnace(FurnaceNum).plantLoc);
10519 0 : WaterCoils::SimulateWaterCoilComponents(state,
10520 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
10521 : FirstHVACIteration,
10522 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
10523 : QCoilActual,
10524 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode);
10525 : } else {
10526 : // supplemental coil
10527 89248 : PlantUtilities::SetComponentFlowRate(state,
10528 : mdot,
10529 44624 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode,
10530 44624 : state.dataFurnaces->Furnace(FurnaceNum).SuppCoilOutletNode,
10531 44624 : state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc);
10532 : // simulate the hot water supplemental heating coil
10533 133872 : WaterCoils::SimulateWaterCoilComponents(state,
10534 44624 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
10535 : FirstHVACIteration,
10536 44624 : state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex,
10537 : QCoilActual,
10538 44624 : state.dataFurnaces->Furnace(FurnaceNum).OpMode);
10539 : }
10540 22312 : return QCoilRequested != 0.0 ? (QCoilActual - QCoilRequested) / QCoilRequested : 0.0;
10541 1440 : };
10542 1440 : General::SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, HotWaterMdot, f, MinWaterFlow, MaxHotWaterFlow);
10543 1440 : if (SolFlag == -1) {
10544 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HotWaterCoilMaxIterIndex == 0) {
10545 0 : ShowWarningMessage(state,
10546 0 : "CalcNonDXHeatingCoils: Hot water coil control failed for " +
10547 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + "=\"" +
10548 0 : state.dataFurnaces->Furnace(FurnaceNum).Name + "\"");
10549 0 : ShowContinueErrorTimeStamp(state, "");
10550 0 : ShowContinueError(state, format(" Iteration limit [{}] exceeded in calculating hot water mass flow rate", SolveMaxIter));
10551 : }
10552 0 : ShowRecurringWarningErrorAtEnd(
10553 : state,
10554 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed (iteration limit [{}]) for {}=\"{}",
10555 : SolveMaxIter,
10556 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num),
10557 0 : state.dataFurnaces->Furnace(FurnaceNum).Name),
10558 0 : state.dataFurnaces->Furnace(FurnaceNum).HotWaterCoilMaxIterIndex);
10559 1440 : } else if (SolFlag == -2) {
10560 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HotWaterCoilMaxIterIndex2 == 0) {
10561 0 : ShowWarningMessage(state,
10562 0 : "CalcNonDXHeatingCoils: Hot water coil control failed (maximum flow limits) for " +
10563 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + "=\"" +
10564 0 : state.dataFurnaces->Furnace(FurnaceNum).Name + "\"");
10565 0 : ShowContinueErrorTimeStamp(state, "");
10566 0 : ShowContinueError(state, "...Bad hot water maximum flow rate limits");
10567 0 : ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinWaterFlow));
10568 0 : ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxHotWaterFlow));
10569 : }
10570 0 : ShowRecurringWarningErrorAtEnd(state,
10571 0 : "CalcNonDXHeatingCoils: Hot water coil control failed (flow limits) for " +
10572 0 : cFurnaceTypes(state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num) + "=\"" +
10573 0 : state.dataFurnaces->Furnace(FurnaceNum).Name + "\"",
10574 0 : state.dataFurnaces->Furnace(FurnaceNum).HotWaterCoilMaxIterIndex2,
10575 : MaxHotWaterFlow,
10576 : MinWaterFlow,
10577 : _,
10578 : "[kg/s]",
10579 : "[kg/s]");
10580 : }
10581 : }
10582 : } else {
10583 91354 : mdot = 0.0;
10584 91354 : SetComponentFlowRate(state, mdot, CoilControlNode, CoilOutletNode, plantLoc);
10585 : }
10586 : // simulate the hot water heating coil
10587 92894 : SimulateWaterCoilComponents(state, HeatingCoilName, FirstHVACIteration, HeatingCoilIndex, QActual, FanMode);
10588 92894 : } break;
10589 0 : case Coil_HeatingSteam: {
10590 0 : if (QCoilLoad > SmallLoad) {
10591 0 : SetComponentFlowRate(state, MaxHotWaterFlow, CoilControlNode, CoilOutletNode, plantLoc);
10592 : // simulate the steam heating coil
10593 0 : SimulateSteamCoilComponents(state, HeatingCoilName, FirstHVACIteration, HeatingCoilIndex, QCoilLoad, QActual, FanMode);
10594 : } else {
10595 0 : mdot = 0.0;
10596 0 : SetComponentFlowRate(state, mdot, CoilControlNode, CoilOutletNode, plantLoc);
10597 : // simulate the steam heating coil
10598 0 : SimulateSteamCoilComponents(state, HeatingCoilName, FirstHVACIteration, HeatingCoilIndex, QCoilLoad, QActual, FanMode);
10599 : }
10600 0 : } break;
10601 0 : default:
10602 0 : break;
10603 : }
10604 :
10605 68650180 : HeatCoilLoadmet = QActual;
10606 68650180 : }
10607 :
10608 : // End of Reporting subroutines for the Furnace Module
10609 :
10610 : //******************************************************************************
10611 :
10612 1498400 : void SimVariableSpeedHP(EnergyPlusData &state,
10613 : int const FurnaceNum, // number of the current engine driven Heat Pump being simulated
10614 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
10615 : int const AirLoopNum, // index to air loop
10616 : Real64 const QZnReq, // required zone load
10617 : Real64 const QLatReq, // required latent load
10618 : Real64 &OnOffAirFlowRatio // ratio of compressor ON airflow to AVERAGE airflow over timestep
10619 : )
10620 : {
10621 :
10622 : // SUBROUTINE INFORMATION:
10623 : // AUTHOR Bo Shen, based on HVACMultiSpeedHeatPump:CalcMSHeatPump
10624 : // DATE WRITTEN March, 2012
10625 :
10626 : // PURPOSE OF THIS SUBROUTINE:
10627 : // Simulate a multispeed heat pump; adjust its output to match the
10628 : // required system load.
10629 :
10630 : // METHODOLOGY EMPLOYED:
10631 : // Calls ControlMSHPOutput to obtain the desired unit output
10632 :
10633 : using namespace DataZoneEnergyDemands;
10634 : using DataHVACGlobals::SmallLoad;
10635 : using DataHVACGlobals::SmallMassFlow;
10636 : using IntegratedHeatPump::DecideWorkMode;
10637 :
10638 : Real64 PartLoadFrac; // compressor part load fraction
10639 : Real64 SpeedRatio; // compressor speed ratio
10640 : bool UnitOn; // TRUE if unit is on
10641 : int OutletNode; // MSHP air outlet node
10642 : int InletNode; // MSHP air inlet node
10643 : Real64 AirMassFlow; // air mass flow rate [kg/s]
10644 : int OpMode; // operating mode (fan cycling or continious; DX coil always cycles)
10645 : int ZoneNum; // Controlled zone number
10646 : Real64 QTotUnitOut; // capacity output
10647 1498400 : auto &SpeedNum = state.dataFurnaces->SpeedNum;
10648 1498400 : auto &SupHeaterLoad = state.dataFurnaces->SupHeaterLoad;
10649 : Real64 TotalZoneLatentLoad; // Total ZONE latent load
10650 : Real64 TotalZoneSensibleLoad; // Total ZONE sensible load
10651 : Real64 SystemSensibleLoad; // Positive value means heating required
10652 : CompressorOperation CompressorOp; // compressor operation; 1=on, 0=off
10653 : Real64 SaveMassFlowRate; // saved inlet air mass flow rate [kg/s]
10654 : Real64 QSensUnitOut; // sensible capacity output
10655 : Real64 QLatUnitOut; // latent capacity output
10656 : Real64 ActualSensibleOutput; // Actual furnace sensible capacity
10657 : Real64 ReheatCoilLoad; // reheat coil load due to dehumidification
10658 : Real64 QToHeatSetPt; // Load required to meet heating setpoint temp (>0 is a heating load)
10659 : Real64 NoCompOutput; // output when no active compressor [W]
10660 : int TotBranchNum; // total exit branch number
10661 : int ZoneSideNodeNum; // zone equip supply node
10662 : bool EconoActive; // TRUE if Economizer is active
10663 :
10664 : // to be removed by furnace/unitary system
10665 :
10666 : // zero DX coils, and supplemental electric heater electricity consumption
10667 1498400 : state.dataHVACGlobal->DXElecHeatingPower = 0.0;
10668 1498400 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
10669 1498400 : state.dataFurnaces->SaveCompressorPLR = 0.0;
10670 1498400 : state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
10671 1498400 : state.dataHVACGlobal->SuppHeatingCoilPower = 0.0;
10672 :
10673 1498400 : SystemSensibleLoad = QZnReq;
10674 1498400 : TotalZoneSensibleLoad = QZnReq;
10675 1498400 : TotalZoneLatentLoad = QLatReq;
10676 :
10677 : // initialize local variables
10678 1498400 : UnitOn = true;
10679 1498400 : OutletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
10680 1498400 : InletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
10681 1498400 : AirMassFlow = state.dataFurnaces->Furnace(FurnaceNum).DesignMassFlowRate;
10682 1498400 : OpMode = state.dataFurnaces->Furnace(FurnaceNum).OpMode;
10683 1498400 : ZoneNum = state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum;
10684 1498400 : CompressorOp = CompressorOperation::On;
10685 :
10686 : // Set latent load for heating
10687 1498400 : if (state.dataFurnaces->HeatingLoad) {
10688 100583 : state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode = Furnaces::ModeOfOperation::HeatingMode;
10689 : // Set latent load for cooling and no sensible load condition
10690 1397817 : } else if (state.dataFurnaces->CoolingLoad) {
10691 1299577 : state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode = Furnaces::ModeOfOperation::CoolingMode;
10692 : } else {
10693 98240 : state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode = Furnaces::ModeOfOperation::NoCoolHeat;
10694 : }
10695 :
10696 : // set the on/off flags
10697 1498400 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == CycFanCycCoil) {
10698 : // cycling unit only runs if there is a cooling or heating load.
10699 20262 : if (std::abs(QZnReq) < SmallLoad || AirMassFlow < SmallMassFlow || state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
10700 3168 : UnitOn = false;
10701 : }
10702 1478138 : } else if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == ContFanCycCoil) {
10703 : // continuous unit: fan runs if scheduled on; coil runs only if there is a cooling or heating load
10704 1478138 : if (AirMassFlow < SmallMassFlow) {
10705 0 : UnitOn = false;
10706 : }
10707 : }
10708 :
10709 1498400 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
10710 :
10711 1498400 : if (AirLoopNum != 0) {
10712 1498400 : EconoActive = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
10713 : } else {
10714 0 : EconoActive = false;
10715 : }
10716 :
10717 1498400 : SaveMassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRate;
10718 : // decide current working mode for IHP
10719 1498400 : if ((FirstHVACIteration) && (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP))
10720 5050 : DecideWorkMode(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, TotalZoneSensibleLoad, TotalZoneLatentLoad);
10721 :
10722 4409226 : if (!FirstHVACIteration && state.dataFurnaces->Furnace(FurnaceNum).OpMode == CycFanCycCoil &&
10723 1504702 : (QZnReq < (-1.0 * SmallLoad) || TotalZoneLatentLoad < (-1.0 * SmallLoad)) && EconoActive) {
10724 : // for cycling fan, cooling load, check whether furnace can meet load with compressor off
10725 0 : CompressorOp = CompressorOperation::Off;
10726 0 : ControlVSHPOutput(state,
10727 : FurnaceNum,
10728 : FirstHVACIteration,
10729 : CompressorOp,
10730 : OpMode,
10731 : TotalZoneSensibleLoad,
10732 : TotalZoneLatentLoad,
10733 : ZoneNum,
10734 : SpeedNum,
10735 : SpeedRatio,
10736 : PartLoadFrac,
10737 : OnOffAirFlowRatio,
10738 : SupHeaterLoad);
10739 :
10740 0 : TotalZoneSensibleLoad = QZnReq;
10741 0 : TotalZoneLatentLoad = QLatReq;
10742 :
10743 0 : if (SpeedNum == state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling && SpeedRatio == 1.0) {
10744 : // compressor on (reset inlet air mass flow rate to starting value)
10745 0 : state.dataLoopNodes->Node(InletNode).MassFlowRate = SaveMassFlowRate;
10746 0 : CompressorOp = CompressorOperation::On;
10747 0 : ControlVSHPOutput(state,
10748 : FurnaceNum,
10749 : FirstHVACIteration,
10750 : CompressorOp,
10751 : OpMode,
10752 : TotalZoneSensibleLoad,
10753 : TotalZoneLatentLoad,
10754 : ZoneNum,
10755 : SpeedNum,
10756 : SpeedRatio,
10757 : PartLoadFrac,
10758 : OnOffAirFlowRatio,
10759 : SupHeaterLoad);
10760 : }
10761 : } else {
10762 : // compressor on
10763 1498400 : CompressorOp = CompressorOperation::On;
10764 :
10765 : // if ( QZnReq < -1000.0 .AND. FurnaceNum == 1 ) then
10766 : // CompressorOp = On
10767 : // end if
10768 1498400 : ControlVSHPOutput(state,
10769 : FurnaceNum,
10770 : FirstHVACIteration,
10771 : CompressorOp,
10772 : OpMode,
10773 : TotalZoneSensibleLoad,
10774 : TotalZoneLatentLoad,
10775 : ZoneNum,
10776 : SpeedNum,
10777 : SpeedRatio,
10778 : PartLoadFrac,
10779 : OnOffAirFlowRatio,
10780 : SupHeaterLoad);
10781 : }
10782 :
10783 1498400 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool) {
10784 1247328 : state.dataFurnaces->SaveCompressorPLR = PartLoadFrac;
10785 : } else {
10786 251072 : if (SpeedNum > 1) {
10787 102612 : state.dataFurnaces->SaveCompressorPLR = 1.0;
10788 : }
10789 :
10790 251072 : if (PartLoadFrac == 1.0 && state.dataFurnaces->SaveCompressorPLR < 1.0) {
10791 6 : PartLoadFrac = state.dataFurnaces->SaveCompressorPLR;
10792 : }
10793 : }
10794 :
10795 1498400 : ReheatCoilLoad = 0.0;
10796 1498400 : TotalZoneSensibleLoad = QZnReq;
10797 1498400 : TotalZoneLatentLoad = QLatReq;
10798 : // Calculate the reheat coil output
10799 3061002 : if ((GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) > 0.0) &&
10800 1579634 : (state.dataFurnaces->Furnace(FurnaceNum).Humidistat &&
10801 187500 : state.dataFurnaces->Furnace(FurnaceNum).DehumidControlType_Num == DehumidificationControlMode::CoolReheat &&
10802 : (QLatReq < 0.0))) { // if a Humidistat is installed and dehumdification control type is CoolReheat
10803 76718 : CalcVarSpeedHeatPump(state,
10804 : FurnaceNum,
10805 : FirstHVACIteration,
10806 : CompressorOp,
10807 : SpeedNum,
10808 : SpeedRatio,
10809 : PartLoadFrac,
10810 : ActualSensibleOutput,
10811 : QLatUnitOut,
10812 : TotalZoneSensibleLoad,
10813 : TotalZoneLatentLoad,
10814 : OnOffAirFlowRatio,
10815 : ReheatCoilLoad);
10816 76718 : if (state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum > 0) {
10817 153436 : QToHeatSetPt = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
10818 76718 : .SequencedOutputRequiredToHeatingSP(state.dataFurnaces->Furnace(FurnaceNum).ZoneSequenceHeatingNum) /
10819 76718 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac);
10820 : } else {
10821 0 : QToHeatSetPt = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum)
10822 0 : .OutputRequiredToHeatingSP /
10823 0 : state.dataFurnaces->Furnace(FurnaceNum).ControlZoneMassFlowFrac);
10824 : }
10825 : // Cooling mode or floating condition and dehumidification is required
10826 76718 : if (QToHeatSetPt < 0.0) {
10827 : // Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
10828 : // the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
10829 52244 : ReheatCoilLoad = max(0.0, (QToHeatSetPt - ActualSensibleOutput));
10830 52244 : state.dataFurnaces->Furnace(FurnaceNum).DehumidInducedHeatingDemandRate = ReheatCoilLoad;
10831 : // Heating mode and dehumidification is required
10832 24474 : } else if (QToHeatSetPt >= 0.0) {
10833 24474 : ReheatCoilLoad = max(QToHeatSetPt, QToHeatSetPt - ActualSensibleOutput);
10834 24474 : state.dataFurnaces->Furnace(FurnaceNum).DehumidInducedHeatingDemandRate = max(0.0, ActualSensibleOutput * (-1.0));
10835 : } else {
10836 0 : ReheatCoilLoad = 0.0;
10837 : }
10838 :
10839 76718 : SupHeaterLoad = 0.0;
10840 76718 : CalcVarSpeedHeatPump(state,
10841 : FurnaceNum,
10842 : FirstHVACIteration,
10843 : CompressorOp,
10844 : 1,
10845 : 0.0,
10846 : 0.0,
10847 : NoCompOutput,
10848 : QLatUnitOut,
10849 : 0.0,
10850 : 0.0,
10851 : OnOffAirFlowRatio,
10852 : SupHeaterLoad);
10853 :
10854 76718 : if (NoCompOutput > SystemSensibleLoad && SystemSensibleLoad > 0.0 && ReheatCoilLoad > 0.0) {
10855 : // Reduce reheat coil load if you are controlling high humidity but outside air
10856 : // and/or the supply air fan is providing enough heat to meet the system sensible load.
10857 : // This will bring the zone temp closer to the heating setpoint temp.
10858 4671 : ReheatCoilLoad = max(0.0, ReheatCoilLoad - (NoCompOutput - SystemSensibleLoad));
10859 : }
10860 : } else {
10861 : // No humidistat installed
10862 1421682 : ReheatCoilLoad = 0.0;
10863 : }
10864 :
10865 1498400 : TotalZoneSensibleLoad = QZnReq;
10866 1498400 : TotalZoneLatentLoad = QLatReq;
10867 1498400 : if (ReheatCoilLoad > 0.0) {
10868 67349 : CalcVarSpeedHeatPump(state,
10869 : FurnaceNum,
10870 : FirstHVACIteration,
10871 : CompressorOp,
10872 : SpeedNum,
10873 : SpeedRatio,
10874 : PartLoadFrac,
10875 : QSensUnitOut,
10876 : QLatUnitOut,
10877 : TotalZoneSensibleLoad,
10878 : TotalZoneLatentLoad,
10879 : OnOffAirFlowRatio,
10880 : ReheatCoilLoad);
10881 : } else {
10882 1431051 : CalcVarSpeedHeatPump(state,
10883 : FurnaceNum,
10884 : FirstHVACIteration,
10885 : CompressorOp,
10886 : SpeedNum,
10887 : SpeedRatio,
10888 : PartLoadFrac,
10889 : QSensUnitOut,
10890 : QLatUnitOut,
10891 : TotalZoneSensibleLoad,
10892 : TotalZoneLatentLoad,
10893 : OnOffAirFlowRatio,
10894 : SupHeaterLoad);
10895 : }
10896 :
10897 : // calculate delivered capacity
10898 1498400 : AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
10899 :
10900 1498400 : state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = AirMassFlow;
10901 :
10902 2996800 : QTotUnitOut = AirMassFlow * (state.dataLoopNodes->Node(OutletNode).Enthalpy -
10903 1498400 : state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone).Enthalpy);
10904 :
10905 1498400 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
10906 1498400 : state.dataLoopNodes->Node(OutletNode).MassFlowRateMaxAvail = AirMassFlow;
10907 :
10908 1498400 : if (!FirstHVACIteration && AirMassFlow > 0.0 && AirLoopNum > 0) {
10909 1404678 : TotBranchNum = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumOutletBranches;
10910 1404678 : if (TotBranchNum == 1) {
10911 1404678 : ZoneSideNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(1);
10912 : // THE MASS FLOW PRECISION of the system solver is not enough for some small air flow rate iterations , BY DEBUGGING
10913 : // it may cause mass flow rate occilations between airloop and zoneequip
10914 : // specify the air flow rate directly for one-to-one system, when the iteration deviation is closing the solver precision level
10915 : // 0.02 is 2 * HVACFlowRateToler, in order to accomodate the system solver precision level
10916 1404678 : if (std::abs(AirMassFlow - state.dataLoopNodes->Node(ZoneSideNodeNum).MassFlowRate) < 0.02)
10917 795522 : state.dataLoopNodes->Node(ZoneSideNodeNum).MassFlowRateMaxAvail = AirMassFlow;
10918 1404678 : state.dataLoopNodes->Node(ZoneSideNodeNum).MassFlowRate = AirMassFlow;
10919 : }
10920 :
10921 : // the below might be useful if more divergences occur
10922 : // Node(PrimaryAirSystem(AirLoopNumber)%Branch(1)%NodeNumIn)%MassFlowRateMaxAvail = AirMassFlow
10923 : // Node(PrimaryAirSystem(AirLoopNumber)%Branch(1)%NodeNumIn)%MassFlowRate = AirMassFlow
10924 : }
10925 :
10926 : // report variables
10927 1498400 : state.dataFurnaces->Furnace(FurnaceNum).DehumidInducedHeatingDemandRate = ReheatCoilLoad;
10928 1498400 : if (QZnReq > SmallLoad) { // HEATING LOAD
10929 120012 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
10930 120012 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = QZnReq;
10931 : } else {
10932 1378388 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = std::abs(QZnReq);
10933 1378388 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
10934 : }
10935 :
10936 1498400 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = state.dataFurnaces->SaveCompressorPLR;
10937 1498400 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == CycFanCycCoil) {
10938 20262 : if (SupHeaterLoad > 0.0) {
10939 9372 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = 1.0;
10940 : } else {
10941 10890 : if (SpeedNum < 2) {
10942 6149 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = PartLoadFrac;
10943 : } else {
10944 4741 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = 1.0;
10945 : }
10946 : }
10947 : } else {
10948 1478138 : if (UnitOn) {
10949 1478138 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = 1.0;
10950 : } else {
10951 0 : if (SpeedNum < 2) {
10952 0 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = PartLoadFrac;
10953 : } else {
10954 0 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = 1.0;
10955 : }
10956 : }
10957 : }
10958 1498400 : }
10959 :
10960 : //******************************************************************************
10961 :
10962 1498400 : void ControlVSHPOutput(EnergyPlusData &state,
10963 : int const FurnaceNum, // Unit index of engine driven heat pump
10964 : bool const FirstHVACIteration, // flag for 1st HVAC iteration in the time step
10965 : CompressorOperation const CompressorOp, // compressor operation; 1=on, 0=off
10966 : int const OpMode, // operating mode: CycFanCycCoil | ContFanCycCoil
10967 : Real64 &QZnReq, // cooling or heating output needed by zone [W]
10968 : Real64 &QLatReq, // latent cooling output needed by zone [W]
10969 : int const ZoneNum, // Index to zone number
10970 : int &SpeedNum, // Speed number
10971 : Real64 &SpeedRatio, // unit speed ratio for DX coils
10972 : Real64 &PartLoadFrac, // unit part load fraction
10973 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to AVERAGE airflow over timestep
10974 : Real64 &SupHeaterLoad // Supplemental heater load [W]
10975 : )
10976 : {
10977 :
10978 : // SUBROUTINE INFORMATION:
10979 : // AUTHOR Bo Shen, based on HVACMultiSpeedHeatPump:ControlMSHPOutput
10980 : // DATE WRITTEN March, 2012
10981 :
10982 : // PURPOSE OF THIS SUBROUTINE:
10983 : // Determine the part load fraction at low speed, and speed ratio at high speed for this time step.
10984 :
10985 : // METHODOLOGY EMPLOYED:
10986 : // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
10987 :
10988 : // Using/Aliasing
10989 : using IntegratedHeatPump::GetCurWorkMode;
10990 : using IntegratedHeatPump::GetMaxSpeedNumIHP;
10991 : using IntegratedHeatPump::IHPOperationMode;
10992 : using Psychrometrics::PsyCpAirFnW;
10993 :
10994 : // SUBROUTINE PARAMETER DEFINITIONS:
10995 1498400 : int constexpr MaxIte(500); // maximum number of iterations
10996 :
10997 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
10998 : Real64 FullOutput; // unit full output when compressor is operating [W]
10999 : Real64 LowOutput; // unit full output at low speed [W]
11000 : Real64 TempOutput; // unit output when iteration limit exceeded [W]
11001 : Real64 NoCompOutput; // output when no active compressor [W]
11002 : Real64 LatOutput; // latent capacity output
11003 : Real64 ErrorToler; // error tolerance
11004 : int SolFla; // Flag of RegulaFalsi solver
11005 : std::array<Real64, 10> Par; // Parameters passed to RegulaFalsi
11006 : Real64 QCoilActual; // coil load actually delivered returned to calling component
11007 : int i; // Speed index
11008 1498400 : int ErrCountCyc(0); // Counter used to minimize the occurrence of output warnings
11009 1498400 : int ErrCountVar(0); // Counter used to minimize the occurrence of output warnings
11010 1498400 : IHPOperationMode IHPMode(IHPOperationMode::Idle);
11011 :
11012 1498400 : SupHeaterLoad = 0.0;
11013 1498400 : PartLoadFrac = 0.0;
11014 1498400 : SpeedRatio = 0.0;
11015 1498400 : SpeedNum = 1;
11016 1498400 : LatOutput = 0.0;
11017 1498400 : Real64 noLatOutput = 0.0;
11018 1498400 : ErrorToler = 0.001; // Error tolerance for convergence from input deck
11019 :
11020 1545292 : if (GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) == 0.0) return;
11021 :
11022 : // Get result when DX coil is off
11023 1485884 : SupHeaterLoad = 0.0;
11024 1485884 : CalcVarSpeedHeatPump(state,
11025 : FurnaceNum,
11026 : FirstHVACIteration,
11027 : CompressorOp,
11028 : SpeedNum,
11029 : SpeedRatio,
11030 : PartLoadFrac,
11031 : NoCompOutput,
11032 : noLatOutput,
11033 : 0.0,
11034 : 0.0,
11035 : OnOffAirFlowRatio,
11036 : SupHeaterLoad);
11037 :
11038 1485884 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11039 10146 : IHPMode = GetCurWorkMode(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex);
11040 10146 : if ((IHPOperationMode::DedicatedWaterHtg == IHPMode) || (IHPOperationMode::SCWHMatchWH == IHPMode)) { // cooling capacity is a resultant
11041 280 : return;
11042 : }
11043 : }
11044 :
11045 : // If cooling and NoCompOutput < QZnReq, the coil needs to be off
11046 : // If heating and NoCompOutput > QZnReq, the coil needs to be off
11047 : // If no cooling or heating and no latent load, the coil needs to be off
11048 1485604 : if (QZnReq < -SmallLoad) {
11049 1280537 : if (NoCompOutput < QZnReq && QLatReq >= -SmallLoad) return;
11050 205067 : } else if (QZnReq > SmallLoad) {
11051 120012 : if (NoCompOutput > QZnReq && QLatReq >= -SmallLoad) return;
11052 118370 : if (QLatReq <= -SmallLoad) QZnReq = 0.0; // Zero heating load to allow dehumidification
11053 : } else {
11054 85055 : if (QLatReq >= -SmallLoad) return;
11055 : }
11056 :
11057 : // Get full load result
11058 1453961 : PartLoadFrac = 1.0;
11059 1453961 : SpeedRatio = 1.0;
11060 1453961 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode == Furnaces::ModeOfOperation::HeatingMode) {
11061 100236 : SpeedNum = state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating;
11062 1353725 : } else if (state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode == Furnaces::ModeOfOperation::CoolingMode) {
11063 1297954 : SpeedNum = state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling;
11064 55771 : } else if (QLatReq < -SmallLoad) {
11065 55444 : SpeedNum = state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling;
11066 : } else {
11067 327 : SpeedNum = 1;
11068 327 : PartLoadFrac = 0.0;
11069 : }
11070 :
11071 1453961 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP)
11072 8539 : SpeedNum = GetMaxSpeedNumIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex);
11073 :
11074 1453961 : CalcVarSpeedHeatPump(state,
11075 : FurnaceNum,
11076 : FirstHVACIteration,
11077 : CompressorOp,
11078 : SpeedNum,
11079 : SpeedRatio,
11080 : PartLoadFrac,
11081 : FullOutput,
11082 : LatOutput,
11083 : QZnReq,
11084 : QLatReq,
11085 : OnOffAirFlowRatio,
11086 : SupHeaterLoad);
11087 :
11088 1453961 : if (QLatReq < (-1.0 * SmallLoad)) { // dehumidification mode
11089 76718 : if (QLatReq <= LatOutput || (QZnReq < -SmallLoad && QZnReq <= FullOutput) || (QZnReq > SmallLoad && QZnReq >= FullOutput)) {
11090 152 : PartLoadFrac = 1.0;
11091 152 : SpeedRatio = 1.0;
11092 152 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadFrac;
11093 152 : state.dataFurnaces->Furnace(FurnaceNum).CompSpeedRatio = SpeedRatio;
11094 152 : state.dataFurnaces->Furnace(FurnaceNum).CompSpeedNum = SpeedNum;
11095 152 : return;
11096 : }
11097 76566 : ErrorToler = 0.001; // Error tolerance for convergence from input deck
11098 1377243 : } else if (QZnReq < (-1.0 * SmallLoad)) {
11099 1277007 : if (QZnReq <= FullOutput) {
11100 2301 : PartLoadFrac = 1.0;
11101 2301 : SpeedRatio = 1.0;
11102 2301 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadFrac;
11103 2301 : state.dataFurnaces->Furnace(FurnaceNum).CompSpeedRatio = SpeedRatio;
11104 2301 : state.dataFurnaces->Furnace(FurnaceNum).CompSpeedNum = SpeedNum;
11105 2301 : return;
11106 : }
11107 1274706 : ErrorToler = 0.001; // Error tolerance for convergence from input deck
11108 : } else {
11109 100236 : if (QZnReq >= FullOutput) {
11110 41704 : PartLoadFrac = 1.0;
11111 41704 : SpeedRatio = 1.0;
11112 : // may need supplemental heating so don't return in heating mode
11113 : }
11114 100236 : ErrorToler = 0.001; // Error tolerance for convergence from input deck
11115 : }
11116 :
11117 1451508 : if ((QZnReq < -SmallLoad && NoCompOutput - QZnReq > SmallLoad) || (QZnReq > SmallLoad && QZnReq - NoCompOutput > SmallLoad)) {
11118 1378082 : if ((QZnReq > SmallLoad && QZnReq < FullOutput) || (QZnReq < (-1.0 * SmallLoad) && QZnReq > FullOutput)) {
11119 :
11120 1336378 : Par[0] = FurnaceNum;
11121 1336378 : Par[1] = ZoneNum;
11122 1336378 : if (FirstHVACIteration) {
11123 37323 : Par[2] = 1.0;
11124 : } else {
11125 1299055 : Par[2] = 0.0;
11126 : }
11127 1336378 : Par[3] = OpMode;
11128 1336378 : Par[4] = QZnReq;
11129 1336378 : Par[5] = OnOffAirFlowRatio;
11130 1336378 : Par[6] = SupHeaterLoad;
11131 1336378 : Par[8] = static_cast<int>(CompressorOp);
11132 1336378 : Par[9] = 1.0;
11133 : // Check whether the low speed coil can meet the load or not
11134 1336378 : CalcVarSpeedHeatPump(state,
11135 : FurnaceNum,
11136 : FirstHVACIteration,
11137 : CompressorOp,
11138 : 1,
11139 : 0.0,
11140 : 1.0,
11141 : LowOutput,
11142 : LatOutput,
11143 : QZnReq,
11144 : QLatReq,
11145 : OnOffAirFlowRatio,
11146 : SupHeaterLoad);
11147 1336378 : if ((QZnReq > SmallLoad && QZnReq <= LowOutput) || (QZnReq < (-1.0 * SmallLoad) && QZnReq >= LowOutput)) {
11148 : // Calculate the part load fraction
11149 333421 : SpeedRatio = 0.0;
11150 333421 : SpeedNum = 1;
11151 : auto f =
11152 3373524 : [&state, FurnaceNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, CompressorOp](Real64 const PartLoadFrac) {
11153 1686762 : return VSHPCyclingResidual(
11154 : state, PartLoadFrac, FurnaceNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, CompressorOp, 1.0);
11155 2020183 : };
11156 333421 : General::SolveRoot(state, ErrorToler, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
11157 333421 : if (SolFla == -1) {
11158 0 : if (!state.dataGlobal->WarmupFlag) {
11159 0 : if (ErrCountCyc == 0) {
11160 0 : ++ErrCountCyc;
11161 0 : ShowWarningError(state,
11162 0 : "Iteration limit exceeded calculating VS WSHP unit cycling ratio, for unit=" +
11163 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
11164 0 : ShowContinueErrorTimeStamp(state, format("Cycling ratio returned={:.2R}", PartLoadFrac));
11165 : } else {
11166 0 : ++ErrCountCyc;
11167 0 : ShowRecurringWarningErrorAtEnd(
11168 : state,
11169 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
11170 : "\": Iteration limit warning exceeding calculating DX unit cycling ratio continues...",
11171 0 : state.dataFurnaces->Furnace(FurnaceNum).ErrIndexCyc,
11172 : PartLoadFrac,
11173 : PartLoadFrac);
11174 : }
11175 : }
11176 333421 : } else if (SolFla == -2) {
11177 0 : ShowFatalError(state,
11178 0 : "VS WSHP unit cycling ratio calculation failed: cycling limits exceeded, for unit=" +
11179 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
11180 333421 : }
11181 : } else {
11182 : // Check to see which speed to meet the load
11183 1002957 : PartLoadFrac = 1.0;
11184 1002957 : SpeedRatio = 1.0;
11185 1002957 : if (QZnReq < (-1.0 * SmallLoad)) { // Cooling
11186 4416863 : for (i = 2; i <= state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling; ++i) {
11187 4416863 : CalcVarSpeedHeatPump(state,
11188 : FurnaceNum,
11189 : FirstHVACIteration,
11190 : CompressorOp,
11191 : i,
11192 : SpeedRatio,
11193 : PartLoadFrac,
11194 : TempOutput,
11195 : LatOutput,
11196 : QZnReq,
11197 : QLatReq,
11198 : OnOffAirFlowRatio,
11199 : SupHeaterLoad);
11200 :
11201 4416863 : if (QZnReq >= TempOutput) {
11202 963056 : SpeedNum = i;
11203 963056 : break;
11204 : }
11205 : }
11206 : } else {
11207 189443 : for (i = 2; i <= state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating; ++i) {
11208 189443 : CalcVarSpeedHeatPump(state,
11209 : FurnaceNum,
11210 : FirstHVACIteration,
11211 : CompressorOp,
11212 : i,
11213 : SpeedRatio,
11214 : PartLoadFrac,
11215 : TempOutput,
11216 : LatOutput,
11217 : QZnReq,
11218 : QLatReq,
11219 : OnOffAirFlowRatio,
11220 : SupHeaterLoad);
11221 189443 : if (QZnReq <= TempOutput) {
11222 39901 : SpeedNum = i;
11223 39901 : break;
11224 : }
11225 : }
11226 : }
11227 1002957 : Par[7] = SpeedNum;
11228 : auto f = [&state, FurnaceNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, SpeedNum, CompressorOp](
11229 6839780 : Real64 const SpeedRatio) {
11230 3419890 : return VSHPSpeedResidual(
11231 : state, SpeedRatio, FurnaceNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, SpeedNum, CompressorOp, 1.0);
11232 4422847 : };
11233 1002957 : General::SolveRoot(state, ErrorToler, MaxIte, SolFla, SpeedRatio, f, 1.0e-10, 1.0);
11234 1002957 : if (SolFla == -1) {
11235 0 : if (!state.dataGlobal->WarmupFlag) {
11236 0 : if (ErrCountVar == 0) {
11237 0 : ++ErrCountVar;
11238 0 : ShowWarningError(state,
11239 0 : "Iteration limit exceeded calculating VS WSHP unit speed ratio, for unit=" +
11240 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
11241 0 : ShowContinueErrorTimeStamp(state, format("Speed ratio returned=[{:.2R}], Speed number ={}", SpeedRatio, SpeedNum));
11242 : } else {
11243 0 : ++ErrCountVar;
11244 0 : ShowRecurringWarningErrorAtEnd(
11245 : state,
11246 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
11247 : "\": Iteration limit warning exceeding calculating DX unit speed ratio continues...",
11248 0 : state.dataFurnaces->Furnace(FurnaceNum).ErrIndexVar,
11249 : SpeedRatio,
11250 : SpeedRatio);
11251 : }
11252 : }
11253 1002957 : } else if (SolFla == -2) {
11254 0 : ShowFatalError(state,
11255 0 : "VS WSHP unit compressor speed calculation failed: speed limits exceeded, for unit=" +
11256 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
11257 : }
11258 1336378 : }
11259 : } else {
11260 41704 : LatOutput = noLatOutput; // reset full output if not needed for sensible load
11261 41704 : SpeedNum = 1; // reset speed from full output test
11262 1378082 : }
11263 : } else {
11264 73426 : LatOutput = noLatOutput; // reset full output if not needed for sensible load
11265 73426 : SpeedNum = 1; // reset speed from full output test
11266 : }
11267 : // meet the latent load
11268 1451508 : if (QLatReq < -SmallLoad && QLatReq < LatOutput) {
11269 73442 : PartLoadFrac = 1.0;
11270 73442 : SpeedRatio = 1.0;
11271 115149 : for (i = SpeedNum; i <= state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling; ++i) {
11272 115149 : CalcVarSpeedHeatPump(state,
11273 : FurnaceNum,
11274 : FirstHVACIteration,
11275 : CompressorOp,
11276 : i,
11277 : SpeedRatio,
11278 : PartLoadFrac,
11279 : TempOutput,
11280 : LatOutput,
11281 : QZnReq,
11282 : QLatReq,
11283 : OnOffAirFlowRatio,
11284 : SupHeaterLoad);
11285 :
11286 115149 : if (QLatReq > LatOutput) {
11287 73442 : SpeedNum = i;
11288 73442 : break;
11289 : }
11290 : }
11291 73442 : if (QLatReq - LatOutput > SmallLoad) {
11292 73373 : Par[0] = FurnaceNum;
11293 73373 : Par[1] = ZoneNum;
11294 73373 : if (FirstHVACIteration) {
11295 17874 : Par[2] = 1.0;
11296 : } else {
11297 55499 : Par[2] = 0.0;
11298 : }
11299 73373 : Par[3] = OpMode;
11300 73373 : Par[4] = QLatReq;
11301 73373 : Par[5] = OnOffAirFlowRatio;
11302 73373 : Par[6] = SupHeaterLoad;
11303 73373 : Par[7] = SpeedNum;
11304 73373 : Par[8] = static_cast<int>(CompressorOp);
11305 73373 : Par[9] = 0.0;
11306 73373 : if (SpeedNum < 2) {
11307 : auto f =
11308 564076 : [&state, FurnaceNum, FirstHVACIteration, QLatReq, OnOffAirFlowRatio, SupHeaterLoad, CompressorOp](Real64 const PartLoadFrac) {
11309 282038 : return VSHPCyclingResidual(
11310 : state, PartLoadFrac, FurnaceNum, FirstHVACIteration, QLatReq, OnOffAirFlowRatio, SupHeaterLoad, CompressorOp, 0.0);
11311 331293 : };
11312 49255 : General::SolveRoot(state, ErrorToler, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
11313 : } else {
11314 : auto f = [&state, FurnaceNum, FirstHVACIteration, QLatReq, OnOffAirFlowRatio, SupHeaterLoad, SpeedNum, CompressorOp](
11315 211050 : Real64 const SpeedRatio) {
11316 105525 : return VSHPSpeedResidual(state,
11317 : SpeedRatio,
11318 : FurnaceNum,
11319 : FirstHVACIteration,
11320 : QLatReq,
11321 : OnOffAirFlowRatio,
11322 : SupHeaterLoad,
11323 : SpeedNum,
11324 : CompressorOp,
11325 : 0.0);
11326 129643 : };
11327 24118 : General::SolveRoot(state, ErrorToler, MaxIte, SolFla, SpeedRatio, f, 1.0e-10, 1.0);
11328 : }
11329 73373 : if (SolFla == -1) {
11330 0 : if (!state.dataGlobal->WarmupFlag) {
11331 0 : if (ErrCountVar == 0) {
11332 0 : ++ErrCountVar;
11333 0 : ShowWarningError(state,
11334 0 : "Iteration limit exceeded calculating VS WSHP unit speed ratio, for unit=" +
11335 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
11336 0 : ShowContinueErrorTimeStamp(state, format("Speed ratio returned=[{:.2R}], Speed number ={}", SpeedRatio, SpeedNum));
11337 : } else {
11338 0 : ++ErrCountVar;
11339 0 : ShowRecurringWarningErrorAtEnd(state,
11340 0 : state.dataFurnaces->Furnace(FurnaceNum).Name +
11341 : "\": Iteration limit warning exceeding calculating DX unit speed ratio continues...",
11342 0 : state.dataFurnaces->Furnace(FurnaceNum).ErrIndexVar,
11343 : SpeedRatio,
11344 : SpeedRatio);
11345 : }
11346 : }
11347 73373 : } else if (SolFla == -2) {
11348 0 : ShowFatalError(state,
11349 0 : "VS WSHP unit compressor speed calculation failed: speed limits exceeded, for unit=" +
11350 0 : state.dataFurnaces->Furnace(FurnaceNum).Name);
11351 : }
11352 : }
11353 : }
11354 : // end meet the latent load
11355 :
11356 : // if the heating coil cannot meet the load, trim with supplemental heater
11357 : // occurs with constant fan mode when compressor is on or off
11358 : // occurs with cycling fan mode when compressor PLR is equal to 1
11359 1451508 : if ((QZnReq > SmallLoad && QZnReq > FullOutput) && (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex != 0)) {
11360 21367 : PartLoadFrac = 1.0;
11361 21367 : SpeedRatio = 1.0;
11362 21367 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating > 0)
11363 21367 : SpeedNum = state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating; // maximum heating speed, avoid zero for cooling only mode
11364 :
11365 21367 : if (state.dataEnvrn->OutDryBulbTemp <= state.dataFurnaces->Furnace(FurnaceNum).MaxOATSuppHeat) {
11366 21367 : SupHeaterLoad = QZnReq - FullOutput;
11367 : } else {
11368 0 : SupHeaterLoad = 0.0;
11369 : }
11370 21367 : CalcVarSpeedHeatPump(state,
11371 : FurnaceNum,
11372 : FirstHVACIteration,
11373 : CompressorOp,
11374 : SpeedNum,
11375 : SpeedRatio,
11376 : PartLoadFrac,
11377 : TempOutput,
11378 : LatOutput,
11379 : QZnReq,
11380 : QLatReq,
11381 : OnOffAirFlowRatio,
11382 : SupHeaterLoad);
11383 : }
11384 :
11385 : // check the outlet of the supplemental heater to be lower than the maximum supplemental heater supply air temperature
11386 2903016 : if (state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).Temp >
11387 1451604 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp &&
11388 96 : SupHeaterLoad > 0.0) {
11389 :
11390 : // If the supply air temperature is to high, turn off the supplemental heater to recalculate the outlet temperature
11391 96 : CalcNonDXHeatingCoils(state, FurnaceNum, true, FirstHVACIteration, 0.0, OpMode, QCoilActual);
11392 : // If the outlet temperature is below the maximum supplemental heater supply air temperature, reduce the load passed to
11393 : // the supplemental heater, otherwise leave the supplemental heater off. If the supplemental heater is to be turned on,
11394 : // use the outlet conditions when the supplemental heater was off (CALL above) as the inlet conditions for the calculation
11395 : // of supplemental heater load to just meet the maximum supply air temperature from the supplemental heater.
11396 192 : if (state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).Temp <
11397 96 : state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp) {
11398 96 : Real64 CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).HumRat);
11399 192 : SupHeaterLoad = state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum).MassFlowRate * CpAir *
11400 192 : (state.dataFurnaces->Furnace(FurnaceNum).DesignMaxOutletTemp -
11401 96 : state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum).Temp);
11402 :
11403 : } else {
11404 0 : SupHeaterLoad = 0.0;
11405 : }
11406 : }
11407 :
11408 : // prepare module level output
11409 1451508 : state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadFrac;
11410 1451508 : state.dataFurnaces->Furnace(FurnaceNum).CompSpeedRatio = SpeedRatio;
11411 1451508 : state.dataFurnaces->Furnace(FurnaceNum).CompSpeedNum = SpeedNum;
11412 1451508 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilLatentDemand = std::abs(QLatReq);
11413 :
11414 1451508 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == ContFanCycCoil) {
11415 1434514 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = 1.0;
11416 : } else {
11417 16994 : state.dataFurnaces->Furnace(FurnaceNum).FanPartLoadRatio = PartLoadFrac;
11418 : }
11419 : }
11420 :
11421 : //******************************************************************************
11422 :
11423 17638252 : void CalcVarSpeedHeatPump(EnergyPlusData &state,
11424 : int const FurnaceNum, // Variable speed heat pump number
11425 : bool const FirstHVACIteration, // Flag for 1st HVAC iteration
11426 : CompressorOperation const CompressorOp, // Compressor on/off; 1=on, 0=off
11427 : int const SpeedNum, // Speed number
11428 : Real64 const SpeedRatio, // Compressor speed ratio
11429 : Real64 const PartLoadFrac, // Compressor part load fraction
11430 : Real64 &SensibleLoadMet, // Sensible cooling load met (furnace outlet with respect to control zone temp)
11431 : Real64 &LatentLoadMet, // Latent cooling load met (furnace outlet with respect to control zone humidity ratio)
11432 : Real64 const QZnReq, // Zone load (W)
11433 : Real64 const QLatReq, // Zone latent load []
11434 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to AVERAGE airflow over timestep
11435 : Real64 &SupHeaterLoad // supplemental heater load (W)
11436 : )
11437 : {
11438 : // SUBROUTINE INFORMATION:
11439 : // AUTHOR: Bo Shen, based on HVACMultiSpeedHeatPump:CalcMSHeatPump
11440 : // DATE WRITTEN: March 2012
11441 :
11442 : // PURPOSE OF THIS SUBROUTINE:
11443 : // This routine will calcultes MSHP performance based on given system load
11444 :
11445 : // Using/Aliasing
11446 : using Fans::SimulateFanComponents;
11447 : using IntegratedHeatPump::SimIHP;
11448 : using VariableSpeedCoils::SimVariableSpeedCoils;
11449 :
11450 : // Locals
11451 : // SUBROUTINE ARGUMENT DEFINITIONS:
11452 :
11453 : // SUBROUTINE PARAMETER DEFINITIONS:
11454 : // INTEGER, PARAMETER :: On = 1 ! Compressor on flag
11455 : // INTEGER, PARAMETER :: Off = 2 ! Compressor off flag
11456 :
11457 : // INTERFACE BLOCK SPECIFICATIONS
11458 : // na
11459 :
11460 : // DERIVMS TYPE DEFINITIONS
11461 : // na
11462 :
11463 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
11464 : int OutletNode; // MSHP air outlet node
11465 : int InletNode; // MSHP air inlet node
11466 : Real64 AirMassFlow; // Air mass flow rate [kg/s]
11467 : Real64 SavePartloadRatio; // part-load ratio
11468 : Real64 SaveSpeedRatio; // speed ratio
11469 : Real64 QCoilActual; // coil load actually delivered returned to calling component
11470 : Real64 ErrorToler; // supplemental heating coil convergence tollerance
11471 : bool SuppHeatingCoilFlag; // whether to turn on the supplemental heater
11472 : Real64 HeatCoilLoad; // REQUIRED HEAT COIL LOAD
11473 :
11474 17638252 : InletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
11475 17638252 : OutletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
11476 :
11477 17638252 : HeatCoilLoad = 0.0;
11478 17638252 : state.dataFurnaces->SaveCompressorPLR = 0.0;
11479 17638252 : SavePartloadRatio = 0.0;
11480 17638252 : ErrorToler = 0.001;
11481 :
11482 : // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
11483 17638252 : SetVSHPAirFlow(state, FurnaceNum, PartLoadFrac, OnOffAirFlowRatio, SpeedNum, SpeedRatio);
11484 :
11485 17638252 : if ((SupHeaterLoad > 1.0e-10) && (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool) &&
11486 0 : (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex == 0)) {
11487 : // ONLY HEATING COIL, NO SUPPLEMENTAL COIL, USED FOR REHEAT DURING DUHMI
11488 0 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * PartLoadFrac; // REHEAT IN FAN ON TIME
11489 :
11490 0 : if (HeatCoilLoad > SupHeaterLoad) HeatCoilLoad = SupHeaterLoad; // HEATING COIL RUN TIME < FAN ON TIME
11491 :
11492 17638252 : } else if ((QZnReq > SmallLoad) && (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
11493 63344 : HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * PartLoadFrac;
11494 : } else {
11495 17574908 : HeatCoilLoad = 0.0;
11496 : }
11497 :
11498 17638252 : AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
11499 : // if blow through, simulate fan then coils
11500 17638252 : if (state.dataFurnaces->Furnace(FurnaceNum).FanPlace == BlowThru) {
11501 52914756 : SimulateFanComponents(
11502 35276504 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
11503 :
11504 17638252 : if ((!state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) &&
11505 0 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
11506 : // simulate furnace heating coil
11507 0 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
11508 0 : CalcNonDXHeatingCoils(state,
11509 : FurnaceNum,
11510 : SuppHeatingCoilFlag,
11511 : FirstHVACIteration,
11512 : HeatCoilLoad,
11513 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11514 : QCoilActual);
11515 : }
11516 :
11517 31551287 : if ((QZnReq < (-1.0 * SmallLoad) || (QLatReq < (-1.0 * SmallLoad))) &&
11518 13913035 : (state.dataEnvrn->OutDryBulbTemp >=
11519 13913035 : state.dataFurnaces->Furnace(FurnaceNum).MinOATCompressorCooling)) { // COOLING MODE or dehumidification mode
11520 :
11521 13913035 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11522 219426 : SimIHP(state,
11523 : BlankString,
11524 36571 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11525 36571 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11526 36571 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11527 36571 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11528 36571 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11529 : CompressorOp,
11530 : PartLoadFrac,
11531 : SpeedNum,
11532 : SpeedRatio,
11533 : QZnReq,
11534 : QLatReq,
11535 : false,
11536 : false,
11537 : OnOffAirFlowRatio);
11538 : } else {
11539 83258784 : SimVariableSpeedCoils(state,
11540 : BlankString,
11541 13876464 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11542 13876464 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11543 13876464 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11544 13876464 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11545 13876464 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11546 : CompressorOp,
11547 : PartLoadFrac,
11548 : SpeedNum,
11549 : SpeedRatio,
11550 : QZnReq,
11551 : QLatReq,
11552 : OnOffAirFlowRatio);
11553 : }
11554 :
11555 13913035 : SavePartloadRatio = PartLoadFrac;
11556 13913035 : SaveSpeedRatio = SpeedRatio;
11557 :
11558 13913035 : state.dataFurnaces->SaveCompressorPLR =
11559 13913035 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).PartLoadRatio;
11560 : } else {
11561 3725217 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11562 155130 : SimIHP(state,
11563 : BlankString,
11564 25855 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11565 25855 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11566 25855 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11567 25855 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11568 25855 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11569 : CompressorOp,
11570 : PartLoadFrac,
11571 : SpeedNum,
11572 : SpeedRatio,
11573 : QZnReq,
11574 : QLatReq,
11575 : false,
11576 : false,
11577 : OnOffAirFlowRatio);
11578 : } else {
11579 22196172 : SimVariableSpeedCoils(state,
11580 : BlankString,
11581 3699362 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11582 3699362 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11583 3699362 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11584 3699362 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11585 3699362 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11586 : CompressorOp,
11587 : 0.0,
11588 : 1,
11589 : 0.0,
11590 : 0.0,
11591 : 0.0,
11592 : OnOffAirFlowRatio);
11593 : }
11594 : }
11595 :
11596 17638252 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatCool) {
11597 2286376 : if ((QZnReq > SmallLoad) && state.dataFurnaces->HeatingLoad) {
11598 582074 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11599 84540 : SimIHP(state,
11600 : BlankString,
11601 14090 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
11602 14090 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11603 14090 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11604 14090 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11605 14090 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11606 : CompressorOp,
11607 : PartLoadFrac,
11608 : SpeedNum,
11609 : SpeedRatio,
11610 : QZnReq,
11611 : QLatReq,
11612 : false,
11613 : false,
11614 : OnOffAirFlowRatio);
11615 : } else {
11616 3407904 : SimVariableSpeedCoils(state,
11617 : BlankString,
11618 567984 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
11619 567984 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11620 567984 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11621 567984 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11622 567984 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11623 : CompressorOp,
11624 : PartLoadFrac,
11625 : SpeedNum,
11626 : SpeedRatio,
11627 : QZnReq,
11628 : QLatReq,
11629 : OnOffAirFlowRatio);
11630 : }
11631 :
11632 582074 : SavePartloadRatio = PartLoadFrac;
11633 582074 : SaveSpeedRatio = SpeedRatio;
11634 :
11635 582074 : state.dataFurnaces->SaveCompressorPLR =
11636 582074 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).PartLoadRatio;
11637 : } else {
11638 1704302 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11639 290016 : SimIHP(state,
11640 : BlankString,
11641 48336 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11642 48336 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11643 48336 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11644 48336 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11645 48336 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11646 : CompressorOp,
11647 : PartLoadFrac,
11648 : SpeedNum,
11649 : SpeedRatio,
11650 : QZnReq,
11651 : QLatReq,
11652 : false,
11653 : false,
11654 : OnOffAirFlowRatio);
11655 : } else {
11656 9935796 : SimVariableSpeedCoils(state,
11657 : BlankString,
11658 1655966 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
11659 1655966 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11660 1655966 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11661 1655966 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11662 1655966 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11663 : CompressorOp,
11664 : 0.0,
11665 : 1,
11666 : 0.0,
11667 : 0.0,
11668 : 0.0,
11669 : OnOffAirFlowRatio);
11670 : }
11671 : }
11672 30703752 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream &&
11673 15351876 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
11674 : // simulate furnace heating coil
11675 15351876 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
11676 15351876 : CalcNonDXHeatingCoils(state,
11677 : FurnaceNum,
11678 : SuppHeatingCoilFlag,
11679 : FirstHVACIteration,
11680 : HeatCoilLoad,
11681 15351876 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11682 : QCoilActual);
11683 : }
11684 :
11685 : // Call twice to ensure the fan outlet conditions are updated
11686 52914756 : SimulateFanComponents(
11687 35276504 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
11688 :
11689 17638252 : if ((!state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) &&
11690 0 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
11691 : // simulate furnace heating coil
11692 0 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
11693 0 : CalcNonDXHeatingCoils(state,
11694 : FurnaceNum,
11695 : SuppHeatingCoilFlag,
11696 : FirstHVACIteration,
11697 : HeatCoilLoad,
11698 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11699 : QCoilActual);
11700 : }
11701 :
11702 31551287 : if ((QZnReq < (-1.0 * SmallLoad) || (QLatReq < (-1.0 * SmallLoad))) &&
11703 13913035 : (state.dataEnvrn->OutDryBulbTemp >= state.dataFurnaces->Furnace(FurnaceNum).MinOATCompressorCooling)) {
11704 :
11705 13913035 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11706 219426 : SimIHP(state,
11707 : BlankString,
11708 36571 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11709 36571 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11710 36571 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11711 36571 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11712 36571 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11713 : CompressorOp,
11714 : PartLoadFrac,
11715 : SpeedNum,
11716 : SpeedRatio,
11717 : QZnReq,
11718 : QLatReq,
11719 : false,
11720 : false,
11721 : OnOffAirFlowRatio);
11722 : } else {
11723 83258784 : SimVariableSpeedCoils(state,
11724 : BlankString,
11725 13876464 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11726 13876464 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11727 13876464 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11728 13876464 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11729 13876464 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11730 : CompressorOp,
11731 : PartLoadFrac,
11732 : SpeedNum,
11733 : SpeedRatio,
11734 : QZnReq,
11735 : QLatReq,
11736 : OnOffAirFlowRatio);
11737 : }
11738 :
11739 13913035 : SavePartloadRatio = PartLoadFrac;
11740 13913035 : SaveSpeedRatio = SpeedRatio;
11741 13913035 : state.dataFurnaces->SaveCompressorPLR =
11742 13913035 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).PartLoadRatio;
11743 : } else {
11744 :
11745 3725217 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11746 155130 : SimIHP(state,
11747 : BlankString,
11748 25855 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11749 25855 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11750 25855 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11751 25855 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11752 25855 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11753 : CompressorOp,
11754 : PartLoadFrac,
11755 : SpeedNum,
11756 : SpeedRatio,
11757 : QZnReq,
11758 : QLatReq,
11759 : false,
11760 : false,
11761 : OnOffAirFlowRatio);
11762 : } else {
11763 22196172 : SimVariableSpeedCoils(state,
11764 : BlankString,
11765 3699362 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11766 3699362 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11767 3699362 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11768 3699362 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11769 3699362 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11770 : CompressorOp,
11771 : 0.0,
11772 : 1,
11773 : 0.0,
11774 : 0.0,
11775 : 0.0,
11776 : OnOffAirFlowRatio);
11777 : }
11778 : }
11779 :
11780 17638252 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatCool) {
11781 2286376 : if ((QZnReq > SmallLoad) && state.dataFurnaces->HeatingLoad) {
11782 582074 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11783 84540 : SimIHP(state,
11784 : BlankString,
11785 14090 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
11786 14090 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11787 14090 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11788 14090 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11789 14090 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11790 : CompressorOp,
11791 : PartLoadFrac,
11792 : SpeedNum,
11793 : SpeedRatio,
11794 : QZnReq,
11795 : QLatReq,
11796 : false,
11797 : false,
11798 : OnOffAirFlowRatio);
11799 : } else {
11800 3407904 : SimVariableSpeedCoils(state,
11801 : BlankString,
11802 567984 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
11803 567984 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11804 567984 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11805 567984 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11806 567984 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11807 : CompressorOp,
11808 : PartLoadFrac,
11809 : SpeedNum,
11810 : SpeedRatio,
11811 : QZnReq,
11812 : QLatReq,
11813 : OnOffAirFlowRatio);
11814 : }
11815 :
11816 582074 : SavePartloadRatio = PartLoadFrac;
11817 582074 : SaveSpeedRatio = SpeedRatio;
11818 582074 : state.dataFurnaces->SaveCompressorPLR =
11819 582074 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).PartLoadRatio;
11820 : } else {
11821 1704302 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11822 290016 : SimIHP(state,
11823 : BlankString,
11824 48336 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11825 48336 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11826 48336 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11827 48336 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11828 48336 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11829 : CompressorOp,
11830 : PartLoadFrac,
11831 : SpeedNum,
11832 : SpeedRatio,
11833 : QZnReq,
11834 : QLatReq,
11835 : false,
11836 : false,
11837 : OnOffAirFlowRatio);
11838 : } else {
11839 9935796 : SimVariableSpeedCoils(state,
11840 : BlankString,
11841 1655966 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
11842 1655966 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11843 1655966 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11844 1655966 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11845 1655966 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11846 : CompressorOp,
11847 : 0.0,
11848 : 1,
11849 : 0.0,
11850 : 0.0,
11851 : 0.0,
11852 : OnOffAirFlowRatio);
11853 : }
11854 : }
11855 30703752 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream &&
11856 15351876 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
11857 : // simulate furnace heating coil
11858 15351876 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
11859 15351876 : CalcNonDXHeatingCoils(state,
11860 : FurnaceNum,
11861 : SuppHeatingCoilFlag,
11862 : FirstHVACIteration,
11863 : HeatCoilLoad,
11864 15351876 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11865 : QCoilActual);
11866 : }
11867 :
11868 : // Simulate supplemental heating coil for blow through fan
11869 17638252 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex > 0) {
11870 2286376 : SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
11871 2286376 : CalcNonDXHeatingCoils(state,
11872 : FurnaceNum,
11873 : SuppHeatingCoilFlag,
11874 : FirstHVACIteration,
11875 : SupHeaterLoad,
11876 2286376 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11877 : QCoilActual);
11878 : }
11879 : } else { // otherwise simulate DX coils then fan then supplemental heater
11880 :
11881 0 : if ((!state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream) &&
11882 0 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
11883 : // simulate furnace heating coil
11884 0 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
11885 0 : CalcNonDXHeatingCoils(state,
11886 : FurnaceNum,
11887 : SuppHeatingCoilFlag,
11888 : FirstHVACIteration,
11889 : HeatCoilLoad,
11890 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11891 : QCoilActual);
11892 : }
11893 :
11894 0 : if ((QZnReq < (-1.0 * SmallLoad) || (QLatReq < (-1.0 * SmallLoad))) &&
11895 0 : (state.dataEnvrn->OutDryBulbTemp >= state.dataFurnaces->Furnace(FurnaceNum).MinOATCompressorCooling)) {
11896 :
11897 0 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11898 0 : SimIHP(state,
11899 : BlankString,
11900 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11901 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11902 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11903 0 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11904 0 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11905 : CompressorOp,
11906 : PartLoadFrac,
11907 : SpeedNum,
11908 : SpeedRatio,
11909 : QZnReq,
11910 : QLatReq,
11911 : false,
11912 : false,
11913 : OnOffAirFlowRatio);
11914 : } else {
11915 0 : SimVariableSpeedCoils(state,
11916 : BlankString,
11917 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11918 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11919 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11920 0 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11921 0 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11922 : CompressorOp,
11923 : PartLoadFrac,
11924 : SpeedNum,
11925 : SpeedRatio,
11926 : QZnReq,
11927 : QLatReq,
11928 : OnOffAirFlowRatio);
11929 : }
11930 :
11931 0 : SavePartloadRatio = PartLoadFrac;
11932 0 : SaveSpeedRatio = SpeedRatio;
11933 :
11934 0 : state.dataFurnaces->SaveCompressorPLR =
11935 0 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).PartLoadRatio;
11936 : } else {
11937 0 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11938 0 : SimIHP(state,
11939 : BlankString,
11940 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11941 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11942 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11943 0 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11944 0 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11945 : CompressorOp,
11946 : PartLoadFrac,
11947 : SpeedNum,
11948 : SpeedRatio,
11949 : QZnReq,
11950 : QLatReq,
11951 : false,
11952 : false,
11953 : OnOffAirFlowRatio);
11954 : } else {
11955 0 : SimVariableSpeedCoils(state,
11956 : BlankString,
11957 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
11958 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11959 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11960 0 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11961 0 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11962 : CompressorOp,
11963 : 0.0,
11964 : 1,
11965 : 0.0,
11966 : 0.0,
11967 : 0.0,
11968 : OnOffAirFlowRatio);
11969 : }
11970 : }
11971 :
11972 0 : if (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num != UnitarySys_HeatCool) {
11973 0 : if (QZnReq > SmallLoad && (state.dataEnvrn->OutDryBulbTemp >= state.dataFurnaces->Furnace(FurnaceNum).MinOATCompressorCooling)) {
11974 :
11975 0 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
11976 0 : SimIHP(state,
11977 : BlankString,
11978 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
11979 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11980 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11981 0 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11982 0 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
11983 : CompressorOp,
11984 : PartLoadFrac,
11985 : SpeedNum,
11986 : SpeedRatio,
11987 : QZnReq,
11988 : QLatReq,
11989 : false,
11990 : false,
11991 : OnOffAirFlowRatio);
11992 : } else {
11993 0 : SimVariableSpeedCoils(state,
11994 : BlankString,
11995 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
11996 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
11997 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
11998 0 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
11999 0 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
12000 : CompressorOp,
12001 : PartLoadFrac,
12002 : SpeedNum,
12003 : SpeedRatio,
12004 : QZnReq,
12005 : QLatReq,
12006 : OnOffAirFlowRatio);
12007 : }
12008 :
12009 0 : SavePartloadRatio = PartLoadFrac;
12010 0 : SaveSpeedRatio = SpeedRatio;
12011 0 : state.dataFurnaces->SaveCompressorPLR =
12012 0 : state.dataVariableSpeedCoils->VarSpeedCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).PartLoadRatio;
12013 : } else {
12014 0 : if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
12015 0 : SimIHP(state,
12016 : BlankString,
12017 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
12018 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
12019 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
12020 0 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
12021 0 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
12022 : CompressorOp,
12023 : PartLoadFrac,
12024 : SpeedNum,
12025 : SpeedRatio,
12026 : QZnReq,
12027 : QLatReq,
12028 : false,
12029 : false,
12030 : OnOffAirFlowRatio);
12031 : } else {
12032 0 : SimVariableSpeedCoils(state,
12033 : BlankString,
12034 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
12035 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
12036 0 : state.dataFurnaces->Furnace(FurnaceNum).MaxONOFFCyclesperHour,
12037 0 : state.dataFurnaces->Furnace(FurnaceNum).HPTimeConstant,
12038 0 : state.dataFurnaces->Furnace(FurnaceNum).FanDelayTime,
12039 : CompressorOp,
12040 : 0.0,
12041 : 1,
12042 : 0.0,
12043 : 0.0,
12044 : 0.0,
12045 : OnOffAirFlowRatio);
12046 : }
12047 : }
12048 0 : } else if (state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilUpstream &&
12049 0 : (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
12050 : // simulate furnace heating coil
12051 0 : SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
12052 0 : CalcNonDXHeatingCoils(state,
12053 : FurnaceNum,
12054 : SuppHeatingCoilFlag,
12055 : FirstHVACIteration,
12056 : HeatCoilLoad,
12057 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
12058 : QCoilActual);
12059 : }
12060 :
12061 0 : SimulateFanComponents(
12062 0 : state, BlankString, FirstHVACIteration, state.dataFurnaces->Furnace(FurnaceNum).FanIndex, state.dataFurnaces->FanSpeedRatio);
12063 : // Simulate supplemental heating coil for draw through fan
12064 0 : if (state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex > 0) {
12065 0 : SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
12066 0 : CalcNonDXHeatingCoils(state,
12067 : FurnaceNum,
12068 : SuppHeatingCoilFlag,
12069 : FirstHVACIteration,
12070 : SupHeaterLoad,
12071 0 : state.dataFurnaces->Furnace(FurnaceNum).OpMode,
12072 : QCoilActual);
12073 : }
12074 : }
12075 :
12076 : // If the fan runs continually do not allow coils to set OnOffFanPartLoadRatio.
12077 17638252 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == ContFanCycCoil) state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
12078 :
12079 17638252 : auto &outNode = state.dataLoopNodes->Node(OutletNode);
12080 17638252 : auto &zoneNode = state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).NodeNumOfControlledZone);
12081 17638252 : Real64 zoneEnthalpy = PsyHFnTdbW(zoneNode.Temp, zoneNode.HumRat);
12082 17638252 : Real64 outletEnthalpy = PsyHFnTdbW(outNode.Temp, outNode.HumRat);
12083 17638252 : Real64 totalLoadMet = AirMassFlow * (outletEnthalpy - zoneEnthalpy);
12084 17638252 : SensibleLoadMet =
12085 17638252 : AirMassFlow * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(outNode.Temp, outNode.HumRat, zoneNode.Temp, zoneNode.HumRat); // sensible {W};
12086 17638252 : LatentLoadMet = totalLoadMet - SensibleLoadMet;
12087 17638252 : state.dataFurnaces->Furnace(FurnaceNum).LatentLoadMet = LatentLoadMet;
12088 17638252 : }
12089 :
12090 : //******************************************************************************
12091 :
12092 1968800 : Real64 VSHPCyclingResidual(EnergyPlusData &state,
12093 : Real64 const PartLoadFrac, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
12094 : int FurnaceNum,
12095 : // int ZoneNum,
12096 : bool FirstHVACIteration,
12097 : // int OpMode,
12098 : Real64 LoadToBeMet,
12099 : Real64 OnOffAirFlowRatio,
12100 : Real64 SupHeaterLoad,
12101 : CompressorOperation CompressorOp,
12102 : Real64 par9_SensLatFlag)
12103 : {
12104 : // FUNCTION INFORMATION:
12105 : // AUTHOR Bo Shen, based on HVACMultiSpeedHeatPump:MSHPCyclingResidual
12106 : // DATE WRITTEN March, 2012
12107 : // MODIFIED na
12108 : // RE-ENGINEERED na
12109 :
12110 : // PURPOSE OF THIS FUNCTION:
12111 : // Calculates residual function ((ActualOutput - QZnReq)/QZnReq)
12112 : // MSHP output depends on the part load ratio which is being varied to zero the residual.
12113 :
12114 : // METHODOLOGY EMPLOYED:
12115 : // Calls CalcMSHeatPump to get ActualOutput at the given part load ratio
12116 : // and calculates the residual as defined above
12117 :
12118 : // Locals
12119 : // SUBROUTINE ARGUMENT DEFINITIONS:
12120 : // par[0] = FurnaceNum
12121 : // par[1] = Zone Num
12122 : // par[2] = FirstHVACIteration
12123 : // par[3] = OpMode
12124 : // par[4] = QZnReq, load to be met
12125 : // par[5] = OnOffAirFlowRatio
12126 : // par[6] = SupHeaterLoad
12127 : // par[7] = NOT USED
12128 : // par[8] = CompressorOp
12129 : // par[9] = 1.0 to meet sensible load
12130 : // int FurnaceNum = int(Par[0]);
12131 : // int ZoneNum = int(Par[1]);
12132 : // bool FirstHVACIteration = (Par[2] == 1.0);
12133 : // int OpMode = int(Par[3]);
12134 : // Real64 LoadToBeMet = Par[4];
12135 : // Real64 OnOffAirFlowRatio = Par[5];
12136 : // Real64 SupHeaterLoad = Par[6];
12137 : // CompressorOperation CompressorOp = static_cast<CompressorOperation>(Par[8]);
12138 : // Real64 par9_SensLatFlag = Par[9];
12139 :
12140 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
12141 : Real64 QZnReq; // zone sensible load (W)
12142 : Real64 QZnLat; // zone latent load (W)
12143 : Real64 ZoneSensLoadMet; // delivered sensible capacity of MSHP
12144 : Real64 ZoneLatLoadMet; // delivered latent capacity of MSHP
12145 : Real64 ResScale; // Residual scale
12146 :
12147 1968800 : QZnReq = 0.0;
12148 1968800 : QZnLat = 0.0;
12149 1968800 : if (par9_SensLatFlag == 1.0) {
12150 1686762 : QZnReq = LoadToBeMet;
12151 : } else {
12152 282038 : QZnLat = LoadToBeMet;
12153 : }
12154 :
12155 1968800 : CalcVarSpeedHeatPump(state,
12156 : FurnaceNum,
12157 : FirstHVACIteration,
12158 : CompressorOp,
12159 : 1,
12160 : 0.0,
12161 : PartLoadFrac,
12162 : ZoneSensLoadMet,
12163 : ZoneLatLoadMet,
12164 : QZnReq,
12165 : QZnLat,
12166 : OnOffAirFlowRatio,
12167 : SupHeaterLoad);
12168 :
12169 1968800 : ResScale = std::abs(LoadToBeMet);
12170 1968800 : if (ResScale < 100.0) {
12171 5464 : ResScale = 100.0;
12172 : } else {
12173 1963336 : ResScale = LoadToBeMet;
12174 : }
12175 :
12176 : // Calculate residual based on output calculation flag
12177 1968800 : if (par9_SensLatFlag == 1.0) {
12178 1686762 : return (ZoneSensLoadMet - LoadToBeMet) / ResScale;
12179 : } else {
12180 282038 : return (ZoneLatLoadMet - LoadToBeMet) / ResScale;
12181 : }
12182 : }
12183 :
12184 : //******************************************************************************
12185 :
12186 3525415 : Real64 VSHPSpeedResidual(EnergyPlusData &state,
12187 : Real64 const SpeedRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
12188 : int FurnaceNum,
12189 : // int ZoneNum,
12190 : bool FirstHVACIteration,
12191 : // int OpMode
12192 : Real64 LoadToBeMet,
12193 : Real64 OnOffAirFlowRatio,
12194 : Real64 SupHeaterLoad,
12195 : int SpeedNum,
12196 : CompressorOperation CompressorOp,
12197 : Real64 par9_SensLatFlag)
12198 : {
12199 : // FUNCTION INFORMATION:
12200 : // AUTHOR Bo Shen, , based on HVACMultiSpeedHeatPump:MSHPVarSpeedgResidual
12201 : // DATE WRITTEN March, 2012
12202 : // MODIFIED na
12203 : // RE-ENGINEERED na
12204 :
12205 : // PURPOSE OF THIS FUNCTION:
12206 : // Calculates residual function ((ActualOutput - QZnReq)/QZnReq)
12207 : // MSHP output depends on the part load ratio which is being varied to zero the residual.
12208 :
12209 : // METHODOLOGY EMPLOYED:
12210 : // Calls CalcMSHeatPump to get ActualOutput at the given speed ratio (partload ratio for high speed)
12211 : // and calculates the residual as defined above
12212 :
12213 3525415 : Real64 QZnReq = 0.0;
12214 3525415 : Real64 QZnLat = 0.0;
12215 3525415 : if (par9_SensLatFlag == 1.0) {
12216 3419890 : QZnReq = LoadToBeMet;
12217 : } else {
12218 105525 : QZnLat = LoadToBeMet;
12219 : }
12220 :
12221 : Real64 ZoneSensLoadMet; // delivered sensible capacity of MSHP
12222 : Real64 ZoneLatLoadMet; // delivered latent capacity of MSHP
12223 3525415 : CalcVarSpeedHeatPump(state,
12224 : FurnaceNum,
12225 : FirstHVACIteration,
12226 : CompressorOp,
12227 : SpeedNum,
12228 : SpeedRatio,
12229 : 1.0,
12230 : ZoneSensLoadMet,
12231 : ZoneLatLoadMet,
12232 : QZnReq,
12233 : QZnLat,
12234 : OnOffAirFlowRatio,
12235 : SupHeaterLoad);
12236 :
12237 3525415 : Real64 ResScale = std::abs(LoadToBeMet);
12238 3525415 : if (ResScale < 100.0) {
12239 0 : ResScale = 100.0;
12240 : } else {
12241 3525415 : ResScale = LoadToBeMet;
12242 : }
12243 :
12244 : // Calculate residual based on output calculation flag
12245 3525415 : if (par9_SensLatFlag == 1.0) {
12246 3419890 : return (ZoneSensLoadMet - LoadToBeMet) / ResScale;
12247 : } else {
12248 105525 : return (ZoneLatLoadMet - LoadToBeMet) / ResScale;
12249 : }
12250 : }
12251 :
12252 17638252 : void SetVSHPAirFlow(EnergyPlusData &state,
12253 : int const FurnaceNum, // Unit index
12254 : Real64 const PartLoadRatio, // unit part load ratio
12255 : Real64 &OnOffAirFlowRatio, // ratio of compressor ON airflow to average airflow over timestep
12256 : Optional_int_const SpeedNum, // Speed number
12257 : Optional<Real64 const> SpeedRatio // Speed ratio
12258 : )
12259 : {
12260 :
12261 : // SUBROUTINE INFORMATION:
12262 : // AUTHOR Bo Shen, based on HVACMultiSpeedHeatPump:SetAverageAirFlow
12263 : // DATE WRITTEN March, 2012
12264 : // MODIFIED na
12265 : // RE-ENGINEERED na
12266 : // PURPOSE OF THIS SUBROUTINE:
12267 : // Set the average air mass flow rates using the part load fraction of the heat pump for this time step
12268 : // Set OnOffAirFlowRatio to be used by DX coils
12269 :
12270 : // METHODOLOGY EMPLOYED:
12271 : // na
12272 :
12273 : // REFERENCES:
12274 : // na
12275 :
12276 : // Using/Aliasing
12277 17638252 : auto &MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
12278 17638252 : auto &MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
12279 : using IntegratedHeatPump::GetAirMassFlowRateIHP;
12280 : using IntegratedHeatPump::GetMaxSpeedNumIHP;
12281 : using IntegratedHeatPump::IHPOperationMode;
12282 :
12283 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12284 : int InletNode; // inlet node number for PTHPNum
12285 : Real64 AverageUnitMassFlow; // average supply air mass flow rate over time step
12286 : int OutNode; // Outlet node number in MSHP loop
12287 :
12288 17638252 : InletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
12289 17638252 : OutNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
12290 :
12291 17638252 : MSHPMassFlowRateLow = 0.0; // Mass flow rate at low speed
12292 17638252 : MSHPMassFlowRateHigh = 0.0; // Mass flow rate at high speed
12293 :
12294 17638252 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == ContFanCycCoil) {
12295 17513215 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).IdleMassFlowRate;
12296 17513215 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).IdleSpeedRatio;
12297 : } else {
12298 125037 : state.dataFurnaces->CompOffMassFlow = 0.0;
12299 125037 : state.dataFurnaces->CompOffFlowRatio = 0.0;
12300 : }
12301 :
12302 17638252 : if (state.dataFurnaces->CoolingLoad && (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
12303 15238428 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling > 0) {
12304 15238428 : state.dataFurnaces->CompOnMassFlow =
12305 15238428 : state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling);
12306 15238428 : state.dataFurnaces->CompOnFlowRatio =
12307 15238428 : state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling);
12308 15238428 : MSHPMassFlowRateLow =
12309 15238428 : state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling);
12310 15238428 : MSHPMassFlowRateHigh =
12311 15238428 : state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedCooling);
12312 : } else {
12313 0 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxCoolAirMassFlow;
12314 0 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).CoolingSpeedRatio;
12315 : }
12316 15238428 : AverageUnitMassFlow = (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
12317 15238428 : if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
12318 15238428 : state.dataFurnaces->FanSpeedRatio =
12319 15238428 : (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
12320 : } else {
12321 0 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
12322 : }
12323 2399824 : } else if (state.dataFurnaces->HeatingLoad && (state.dataFurnaces->Furnace(FurnaceNum).FurnaceType_Num == UnitarySys_HeatCool)) {
12324 111816 : if (state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating > 0) {
12325 0 : state.dataFurnaces->CompOnMassFlow =
12326 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating);
12327 0 : state.dataFurnaces->CompOnFlowRatio =
12328 0 : state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating);
12329 0 : MSHPMassFlowRateLow =
12330 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating);
12331 0 : MSHPMassFlowRateHigh =
12332 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(state.dataFurnaces->Furnace(FurnaceNum).NumOfSpeedHeating);
12333 : } else {
12334 111816 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).MaxHeatAirMassFlow;
12335 111816 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).HeatingSpeedRatio;
12336 : }
12337 111816 : AverageUnitMassFlow = (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
12338 111816 : if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
12339 111816 : state.dataFurnaces->FanSpeedRatio =
12340 111816 : (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
12341 : } else {
12342 0 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
12343 : }
12344 2288008 : } else if (state.dataFurnaces->Furnace(FurnaceNum).bIsIHP) {
12345 62426 : if (!state.dataZoneEnergyDemand->CurDeadBandOrSetback(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) && present(SpeedNum)) {
12346 : // if(present(SpeedNum)) {
12347 59205 : state.dataFurnaces->CompOnMassFlow =
12348 59205 : GetAirMassFlowRateIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, SpeedNum, SpeedRatio, false);
12349 59205 : state.dataFurnaces->CompOnFlowRatio =
12350 118410 : state.dataFurnaces->CompOnMassFlow /
12351 118410 : GetAirMassFlowRateIHP(state,
12352 59205 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
12353 59205 : GetMaxSpeedNumIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex),
12354 : 1.0,
12355 : false);
12356 59205 : MSHPMassFlowRateLow = GetAirMassFlowRateIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, SpeedNum, 0.0, false);
12357 59205 : MSHPMassFlowRateHigh = GetAirMassFlowRateIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, SpeedNum, 1.0, false);
12358 : }
12359 :
12360 : // Set up fan flow rate during compressor off time
12361 62426 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == ContFanCycCoil && present(SpeedNum)) {
12362 0 : if (state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl == AirFlowControlConstFan::UseCompressorOnFlow &&
12363 0 : state.dataFurnaces->CompOnMassFlow > 0.0) {
12364 0 : state.dataFurnaces->CompOffMassFlow =
12365 0 : GetAirMassFlowRateIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, SpeedNum, 1.0, false);
12366 0 : state.dataFurnaces->CompOffFlowRatio =
12367 0 : state.dataFurnaces->CompOffMassFlow /
12368 0 : GetAirMassFlowRateIHP(state,
12369 0 : state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex,
12370 0 : GetMaxSpeedNumIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex),
12371 : 1.0,
12372 : false);
12373 : }
12374 : }
12375 :
12376 62426 : if (present(SpeedNum)) {
12377 62426 : if (SpeedNum > 1) {
12378 39564 : AverageUnitMassFlow = state.dataFurnaces->CompOnMassFlow;
12379 39564 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
12380 : } else {
12381 22862 : AverageUnitMassFlow =
12382 22862 : (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
12383 22862 : if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
12384 0 : state.dataFurnaces->FanSpeedRatio =
12385 0 : (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
12386 : } else {
12387 22862 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
12388 : }
12389 : }
12390 : } else {
12391 0 : AverageUnitMassFlow =
12392 0 : (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
12393 0 : if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
12394 0 : state.dataFurnaces->FanSpeedRatio =
12395 0 : (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
12396 : } else {
12397 0 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
12398 : }
12399 : }
12400 :
12401 62426 : if (IHPOperationMode::SCWHMatchWH ==
12402 62426 : state.dataIntegratedHP->IntegratedHeatPumps(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).CurMode) {
12403 336 : state.dataFurnaces->CompOnMassFlow =
12404 336 : GetAirMassFlowRateIHP(state, state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex, SpeedNum, SpeedRatio, false);
12405 336 : AverageUnitMassFlow = state.dataFurnaces->CompOnMassFlow;
12406 : }
12407 : } else {
12408 2225582 : if (!state.dataZoneEnergyDemand->CurDeadBandOrSetback(state.dataFurnaces->Furnace(FurnaceNum).ControlZoneNum) && present(SpeedNum)) {
12409 1463062 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode == Furnaces::ModeOfOperation::HeatingMode) {
12410 706089 : if (SpeedNum == 1) {
12411 252272 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(SpeedNum);
12412 252272 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(SpeedNum);
12413 252272 : MSHPMassFlowRateLow = state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(1);
12414 252272 : MSHPMassFlowRateHigh = state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(1);
12415 453817 : } else if (SpeedNum > 1) {
12416 453817 : state.dataFurnaces->CompOnMassFlow =
12417 907634 : SpeedRatio * state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(SpeedNum) +
12418 453817 : (1.0 - SpeedRatio) * state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(SpeedNum - 1);
12419 453817 : state.dataFurnaces->CompOnFlowRatio =
12420 907634 : SpeedRatio * state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(SpeedNum) +
12421 453817 : (1.0 - SpeedRatio) * state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(SpeedNum - 1);
12422 453817 : MSHPMassFlowRateLow = state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(SpeedNum - 1);
12423 453817 : MSHPMassFlowRateHigh = state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(SpeedNum);
12424 : }
12425 756973 : } else if (state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode == Furnaces::ModeOfOperation::CoolingMode) {
12426 592126 : if (SpeedNum == 1) {
12427 434119 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(SpeedNum);
12428 434119 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(SpeedNum);
12429 434119 : MSHPMassFlowRateLow = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(1);
12430 434119 : MSHPMassFlowRateHigh = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(1);
12431 158007 : } else if (SpeedNum > 1) {
12432 158007 : state.dataFurnaces->CompOnMassFlow =
12433 316014 : SpeedRatio * state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(SpeedNum) +
12434 158007 : (1.0 - SpeedRatio) * state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(SpeedNum - 1);
12435 158007 : state.dataFurnaces->CompOnFlowRatio =
12436 316014 : SpeedRatio * state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(SpeedNum) +
12437 158007 : (1.0 - SpeedRatio) * state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(SpeedNum - 1);
12438 158007 : MSHPMassFlowRateLow = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(SpeedNum - 1);
12439 158007 : MSHPMassFlowRateHigh = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(SpeedNum);
12440 : }
12441 : }
12442 : }
12443 :
12444 : // Set up fan flow rate during compressor off time
12445 2225582 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == ContFanCycCoil && present(SpeedNum)) {
12446 4324310 : if (state.dataFurnaces->Furnace(FurnaceNum).AirFlowControl == AirFlowControlConstFan::UseCompressorOnFlow &&
12447 2161339 : state.dataFurnaces->CompOnMassFlow > 0.0) {
12448 2161339 : if (SpeedNum == 1) { // LOWEST SPEED USE IDLE FLOW
12449 1333946 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).IdleMassFlowRate;
12450 1333946 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).IdleSpeedRatio;
12451 827393 : } else if (state.dataFurnaces->Furnace(FurnaceNum).LastMode == Furnaces::ModeOfOperation::HeatingMode) {
12452 439721 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(SpeedNum);
12453 439721 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(SpeedNum);
12454 : } else {
12455 387672 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(SpeedNum);
12456 387672 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(SpeedNum);
12457 : }
12458 : }
12459 : }
12460 :
12461 2225582 : if (present(SpeedNum)) {
12462 2225582 : if (SpeedNum > 1) {
12463 867301 : AverageUnitMassFlow = state.dataFurnaces->CompOnMassFlow;
12464 867301 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
12465 : } else {
12466 1358281 : AverageUnitMassFlow =
12467 1358281 : (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
12468 1358281 : if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
12469 1335578 : state.dataFurnaces->FanSpeedRatio =
12470 1335578 : (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
12471 : } else {
12472 22703 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
12473 : }
12474 : }
12475 : } else {
12476 0 : AverageUnitMassFlow =
12477 0 : (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
12478 0 : if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
12479 0 : state.dataFurnaces->FanSpeedRatio =
12480 0 : (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
12481 : } else {
12482 0 : state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
12483 : }
12484 : }
12485 : }
12486 :
12487 17638252 : if (GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).SchedPtr) == 0.0) {
12488 12516 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
12489 12516 : OnOffAirFlowRatio = 0.0;
12490 : } else {
12491 17625736 : state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
12492 17625736 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AverageUnitMassFlow;
12493 17625736 : if (AverageUnitMassFlow > 0.0) {
12494 17599694 : OnOffAirFlowRatio = state.dataFurnaces->CompOnMassFlow / AverageUnitMassFlow;
12495 : } else {
12496 26042 : OnOffAirFlowRatio = 0.0;
12497 : }
12498 : }
12499 :
12500 17638252 : state.dataLoopNodes->Node(OutNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRate;
12501 :
12502 : // IF(ABS(Node(OutNode)%MassFlowRate - 0.435) < 0.001) THEN
12503 : // Node(OutNode)%MassFlowRate = Node(InletNode)%MassFlowRate
12504 : // END IF
12505 17638252 : }
12506 :
12507 0 : void SetOnOffMassFlowRateVSCoil(EnergyPlusData &state,
12508 : int const FurnaceNum, // index to furnace
12509 : int const ZoneNum, // index to zone
12510 : bool const FirstHVACIteration, // Flag for 1st HVAC iteration
12511 : [[maybe_unused]] int const AirLoopNum, // index to air loop !unused1208
12512 : Real64 &OnOffAirFlowRatio, // ratio of coil on to coil off air flow rate
12513 : [[maybe_unused]] int const OpMode, // fan operating mode
12514 : [[maybe_unused]] Real64 const QZnReq, // sensible load to be met (W) !unused1208
12515 : [[maybe_unused]] Real64 const MoistureLoad, // moisture load to be met (W)
12516 : Real64 &PartLoadRatio // coil part-load ratio
12517 : )
12518 : {
12519 :
12520 : // SUBROUTINE INFORMATION:
12521 : // AUTHOR Bo Shen
12522 : // DATE WRITTEN March 2012
12523 : // MODIFIED na
12524 : // RE-ENGINEERED na
12525 :
12526 : // PURPOSE OF THIS SUBROUTINE:
12527 : // This subroutine is for initializations of the Furnace Components.
12528 :
12529 : // METHODOLOGY EMPLOYED:
12530 : // The HeatCool furnace/unitarysystem and air-to-air heat pump may have alternate air flow rates
12531 : // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
12532 : // air flow rates. Use these flow rates during the Calc routines to set the average mass flow rates
12533 : // based on PLR.
12534 :
12535 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
12536 : int InNode; // Inlet node number in MSHP loop
12537 : int OutNode; // Outlet node number in MSHP loop
12538 :
12539 0 : InNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
12540 0 : OutNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceOutletNodeNum;
12541 :
12542 0 : if (state.dataFurnaces->CoolingLoad) {
12543 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode = Furnaces::ModeOfOperation::CoolingMode;
12544 0 : } else if (state.dataFurnaces->HeatingLoad) {
12545 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode = Furnaces::ModeOfOperation::HeatingMode;
12546 : } else {
12547 0 : state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode = Furnaces::ModeOfOperation::NoCoolHeat;
12548 : }
12549 :
12550 : // Set the inlet node mass flow rate
12551 0 : if (state.dataFurnaces->Furnace(FurnaceNum).OpMode == ContFanCycCoil) {
12552 : // constant fan mode
12553 0 : if ((state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode == Furnaces::ModeOfOperation::HeatingMode) &&
12554 0 : !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
12555 0 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(1);
12556 0 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(1);
12557 0 : state.dataFurnaces->Furnace(FurnaceNum).LastMode = Furnaces::ModeOfOperation::HeatingMode;
12558 0 : } else if ((state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode == Furnaces::ModeOfOperation::CoolingMode) &&
12559 0 : !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
12560 0 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(1);
12561 0 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(1);
12562 0 : state.dataFurnaces->Furnace(FurnaceNum).LastMode = Furnaces::ModeOfOperation::CoolingMode;
12563 : } else {
12564 0 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).IdleMassFlowRate;
12565 0 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).IdleSpeedRatio;
12566 : }
12567 0 : state.dataFurnaces->CompOffMassFlow = state.dataFurnaces->Furnace(FurnaceNum).IdleMassFlowRate;
12568 0 : state.dataFurnaces->CompOffFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).IdleSpeedRatio;
12569 : } else {
12570 : // cycling fan mode
12571 0 : if ((state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode == Furnaces::ModeOfOperation::HeatingMode) &&
12572 0 : !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
12573 0 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).HeatMassFlowRate(1);
12574 0 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).MSHeatingSpeedRatio(1);
12575 0 : } else if ((state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode == Furnaces::ModeOfOperation::CoolingMode) &&
12576 0 : !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
12577 0 : state.dataFurnaces->CompOnMassFlow = state.dataFurnaces->Furnace(FurnaceNum).CoolMassFlowRate(1);
12578 0 : state.dataFurnaces->CompOnFlowRatio = state.dataFurnaces->Furnace(FurnaceNum).MSCoolingSpeedRatio(1);
12579 : } else {
12580 0 : state.dataFurnaces->CompOnMassFlow = 0.0;
12581 0 : state.dataFurnaces->CompOnFlowRatio = 0.0;
12582 : }
12583 0 : state.dataFurnaces->CompOffMassFlow = 0.0;
12584 0 : state.dataFurnaces->CompOffFlowRatio = 0.0;
12585 : }
12586 :
12587 : // Set the inlet node mass flow rate
12588 0 : if (GetCurrentScheduleValue(state, state.dataFurnaces->Furnace(FurnaceNum).FanAvailSchedPtr) > 0.0 &&
12589 0 : state.dataFurnaces->CompOnMassFlow != 0.0) {
12590 0 : OnOffAirFlowRatio = 1.0;
12591 0 : if (FirstHVACIteration) {
12592 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
12593 0 : PartLoadRatio = 0.0;
12594 : } else {
12595 0 : if (state.dataFurnaces->Furnace(FurnaceNum).HeatCoolMode != Furnaces::ModeOfOperation::NoCoolHeat) {
12596 0 : PartLoadRatio = 1.0;
12597 : } else {
12598 0 : PartLoadRatio = 0.0;
12599 : }
12600 : }
12601 : } else {
12602 0 : PartLoadRatio = 0.0;
12603 0 : state.dataLoopNodes->Node(InNode).MassFlowRate = 0.0;
12604 0 : state.dataLoopNodes->Node(OutNode).MassFlowRate = 0.0;
12605 0 : state.dataLoopNodes->Node(OutNode).MassFlowRateMaxAvail = 0.0;
12606 0 : OnOffAirFlowRatio = 1.0;
12607 : }
12608 :
12609 : // Set the system mass flow rates
12610 0 : SetVSHPAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
12611 0 : }
12612 :
12613 356 : void SetMinOATCompressor(EnergyPlusData &state,
12614 : int const FurnaceNum, // index to furnace
12615 : std::string const &cCurrentModuleObject, // type of furnace
12616 : bool &ErrorsFound // GetInput logical that errors were found
12617 : )
12618 : {
12619 356 : bool errFlag = false;
12620 356 : auto &furnace = state.dataFurnaces->Furnace(FurnaceNum);
12621 :
12622 : // Set minimum OAT for heat pump compressor operation in heating mode
12623 356 : if (furnace.CoolingCoilType_Num == CoilDX_CoolingSingleSpeed) {
12624 204 : furnace.MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, furnace.CoolingCoilIndex, errFlag);
12625 152 : } else if (furnace.CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
12626 6 : std::string ChildCoolingCoilType = state.dataHVACAssistedCC->HXAssistedCoil(furnace.CoolingCoilIndex).CoolingCoilType;
12627 6 : std::string ChildCoolingCoilName = state.dataHVACAssistedCC->HXAssistedCoil(furnace.CoolingCoilIndex).CoolingCoilName;
12628 :
12629 3 : if (UtilityRoutines::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
12630 1 : int childCCIndex_DX = CoilCoolingDX::factory(state, ChildCoolingCoilName);
12631 1 : if (childCCIndex_DX < 0) {
12632 0 : ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, furnace.Name));
12633 0 : errFlag = true;
12634 0 : ErrorsFound = true;
12635 : }
12636 1 : auto &newCoil = state.dataCoilCooingDX->coilCoolingDXs[childCCIndex_DX];
12637 1 : furnace.MinOATCompressorCooling = newCoil.performance.minOutdoorDrybulb;
12638 2 : } else if (UtilityRoutines::SameString(ChildCoolingCoilType, "Coil:Cooling:DX:VariableSpeed")) {
12639 0 : int childCCIndex_VS = state.dataHVACAssistedCC->HXAssistedCoil(furnace.CoolingCoilIndex).CoolingCoilIndex;
12640 0 : furnace.MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, childCCIndex_VS, errFlag);
12641 : } else { // Single speed
12642 2 : int childCCIndex_SP = state.dataHVACAssistedCC->HXAssistedCoil(furnace.CoolingCoilIndex).CoolingCoilIndex;
12643 2 : furnace.MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, childCCIndex_SP, errFlag);
12644 : }
12645 149 : } else if (furnace.CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
12646 6 : furnace.MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, furnace.CoolingCoilIndex, errFlag);
12647 : } else {
12648 143 : furnace.MinOATCompressorCooling = -1000.0;
12649 : }
12650 356 : if (errFlag) {
12651 0 : ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, furnace.Name));
12652 0 : ErrorsFound = true;
12653 : }
12654 :
12655 : // Set minimum OAT for heat pump compressor operation in heating mode
12656 356 : errFlag = false;
12657 356 : if (furnace.HeatingCoilType_Num == Coil_HeatingAirToAirVariableSpeed) {
12658 2 : furnace.MinOATCompressorHeating = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, furnace.HeatingCoilIndex, errFlag);
12659 354 : } else if (furnace.HeatingCoilType_Num == CoilDX_HeatingEmpirical) {
12660 30 : furnace.MinOATCompressorHeating = DXCoils::GetMinOATCompressor(state, furnace.HeatingCoilIndex, errFlag);
12661 : } else {
12662 324 : furnace.MinOATCompressorHeating = -1000.0;
12663 : }
12664 356 : if (errFlag) {
12665 0 : ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, furnace.Name));
12666 0 : ErrorsFound = true;
12667 : }
12668 356 : }
12669 :
12670 : } // namespace Furnaces
12671 :
12672 2313 : } // namespace EnergyPlus
|