LCOV - code coverage report
Current view: top level - EnergyPlus - Furnaces.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 20.9 % 5306 1110
Test Date: 2025-06-02 12:03:30 Functions: 44.1 % 34 15

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <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/OutputReportPredefined.hh>
      88              : #include <EnergyPlus/PlantUtilities.hh>
      89              : #include <EnergyPlus/Psychrometrics.hh>
      90              : #include <EnergyPlus/ScheduleManager.hh>
      91              : #include <EnergyPlus/SteamCoils.hh>
      92              : #include <EnergyPlus/WaterCoils.hh>
      93              : #include <EnergyPlus/WaterToAirHeatPump.hh>
      94              : #include <EnergyPlus/WaterToAirHeatPumpSimple.hh>
      95              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      96              : 
      97              : namespace EnergyPlus {
      98              : 
      99              : namespace Furnaces {
     100              :     // Module containing the Furnace and Unitary System simulation routines
     101              : 
     102              :     // MODULE INFORMATION:
     103              :     //       AUTHOR         Dan Fisher
     104              :     //       DATE WRITTEN   Jan 2001
     105              :     //       MODIFIED       Richard Liesen, Feb 2001; Don Shirey, Mar/Oct 2001, Oct 2003
     106              :     //                      Richard Raustad, Nov 2006 - allow draw through fan and alternate air flow in cooling,
     107              :     //                      heating, and when no cooling or heating is required.
     108              :     //                      Bereket Nigusse, FSEC, June 2010 - deprecated supply air flow fraction through controlled
     109              :     //                      zone from the furnace object input field. Now, the flow fraction is calculated internally
     110              :     //                      B. Nigusse, FSEC, Jan 2012 - added steam and hot water heating coils as an option
     111              :     //                      Bo Shen, ORNL, March 2012 - added variable-speed water source heat pump cooling and heating coils, using curve-fits
     112              :     //                      Bo Shen, ORNL, July 2012 - added variable-speed air source heat pump cooling and heating coils, using curve-fits
     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 dehumidification 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 dehumidification 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              :     // Dehumidification 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              : 
     165              :     // MODULE PARAMETER DEFINITIONS
     166              :     static constexpr std::string_view BlankString;
     167              : 
     168              :     // Functions
     169              : 
     170        15222 :     void SimFurnace(EnergyPlusData &state,
     171              :                     std::string_view FurnaceName,
     172              :                     bool const FirstHVACIteration,
     173              :                     int const AirLoopNum, // Primary air loop number
     174              :                     int &CompIndex        // Pointer to which furnace
     175              :     )
     176              :     {
     177              : 
     178              :         // SUBROUTINE INFORMATION:
     179              :         //       AUTHOR         Dan Fisher
     180              :         //       DATE WRITTEN   Jan 2001
     181              :         //       MODIFIED       Richard Liesen, Oct 2001 - Richard Raustad; Bo Shen, March 2012, for VS WSHP
     182              :         //       RE-ENGINEERED  Feb 2001
     183              : 
     184              :         // PURPOSE OF THIS SUBROUTINE:
     185              :         // This subroutine manages Furnace component simulation.
     186              : 
     187              :         // METHODOLOGY EMPLOYED:
     188              :         // Call the calc routine to determine an operating PLR. Resimulate child components at this PLR.
     189              :         // A supplemental heater augments the heating capacity for both air-to-air and water-to-air heat pump systems.
     190              :         // A reheat coil is used for the HeatCool furnace/unitarysystem to offset the sensible cooling when the
     191              :         // dehumidification control type is COOLREHEAT. Both the supplemental and reheat heating coil load is calculated
     192              :         // in the Calc routines and returned here through subroutine arguments. The actual simulation of these coils is
     193              :         // performed here (i.e. the supplemental and reheat coil loads are passed as 0 to CalcFurnaceOutput).
     194              : 
     195              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     196              :         int FurnaceNum;           // Furnace number
     197        15222 :         Real64 HeatCoilLoad(0.0); // Zone heating coil load
     198              :         Real64 ReheatCoilLoad;    // Load to be met by the reheat coil (if high humidity control)
     199              :         Real64 MoistureLoad;      // Control zone latent load
     200        15222 :         Real64 Dummy(0.0);
     201        15222 :         HVAC::FanOp fanOp = HVAC::FanOp::Invalid; // Fan operating mode (1=FanOp::Cycling, 2=FanOp::Continuous)
     202              : 
     203              :         Real64 QActual;           // actual heating coil output (W)
     204              :         bool SuppHeatingCoilFlag; // true if supplemental heating coil
     205              : 
     206              :         // Obtains and Allocates Furnace related parameters from input file
     207        15222 :         if (state.dataFurnaces->GetFurnaceInputFlag) { // First time subroutine has been entered
     208              :             // Get the furnace input
     209            2 :             GetFurnaceInput(state);
     210            2 :             state.dataFurnaces->GetFurnaceInputFlag = false;
     211              :         }
     212              : 
     213              :         // Find the correct Furnace
     214        15222 :         if (CompIndex == 0) {
     215            3 :             FurnaceNum = Util::FindItemInList(FurnaceName, state.dataFurnaces->Furnace);
     216            3 :             if (FurnaceNum == 0) {
     217            0 :                 ShowFatalError(state, format("SimFurnace: Unit not found={}", FurnaceName));
     218              :             }
     219            3 :             CompIndex = FurnaceNum;
     220              :         } else {
     221        15219 :             FurnaceNum = CompIndex;
     222        15219 :             if (FurnaceNum > state.dataFurnaces->NumFurnaces || FurnaceNum < 1) {
     223            0 :                 ShowFatalError(state,
     224            0 :                                format("SimFurnace:  Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
     225              :                                       FurnaceNum,
     226            0 :                                       state.dataFurnaces->NumFurnaces,
     227              :                                       FurnaceName));
     228              :             }
     229        15219 :             if (state.dataFurnaces->CheckEquipName(FurnaceNum)) {
     230            2 :                 if (FurnaceName != state.dataFurnaces->Furnace(FurnaceNum).Name) {
     231            0 :                     ShowFatalError(state,
     232            0 :                                    format("SimFurnace: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
     233              :                                           FurnaceNum,
     234              :                                           FurnaceName,
     235            0 :                                           state.dataFurnaces->Furnace(FurnaceNum).Name));
     236              :                 }
     237            2 :                 state.dataFurnaces->CheckEquipName(FurnaceNum) = false;
     238              :             }
     239              :         }
     240              : 
     241        15222 :         bool HXUnitOn = false;          // flag to control HX assisted cooling coil
     242        15222 :         Real64 OnOffAirFlowRatio = 0.0; // Ratio of compressor ON air flow to AVERAGE air flow over time step
     243              :         // here we need to deal with sequenced zone equip sensible load in control zone
     244        15222 :         Real64 ZoneLoad = 0.0;
     245              : 
     246        15222 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
     247        15222 :         auto &zoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum);
     248        15222 :         if (thisFurnace.ZoneSequenceCoolingNum > 0 && thisFurnace.ZoneSequenceHeatingNum > 0) {
     249        15220 :             Real64 ZoneLoadToCoolSPSequenced = zoneSysEnergyDemand.SequencedOutputRequiredToCoolingSP(thisFurnace.ZoneSequenceCoolingNum);
     250        15220 :             Real64 ZoneLoadToHeatSPSequenced = zoneSysEnergyDemand.SequencedOutputRequiredToHeatingSP(thisFurnace.ZoneSequenceHeatingNum);
     251        15220 :             auto const &tempControlType = state.dataHeatBalFanSys->TempControlType(thisFurnace.ControlZoneNum);
     252        15220 :             if (ZoneLoadToHeatSPSequenced > 0.0 && ZoneLoadToCoolSPSequenced > 0.0 && tempControlType != HVAC::SetptType::SingleCool) {
     253         8360 :                 ZoneLoad = ZoneLoadToHeatSPSequenced;
     254         6860 :             } else if (ZoneLoadToHeatSPSequenced > 0.0 && ZoneLoadToCoolSPSequenced > 0.0 && tempControlType == HVAC::SetptType::SingleCool) {
     255            0 :                 ZoneLoad = 0.0;
     256         6860 :             } else if (ZoneLoadToHeatSPSequenced < 0.0 && ZoneLoadToCoolSPSequenced < 0.0 && tempControlType != HVAC::SetptType::SingleHeat) {
     257         6748 :                 ZoneLoad = ZoneLoadToCoolSPSequenced;
     258          112 :             } else if (ZoneLoadToHeatSPSequenced < 0.0 && ZoneLoadToCoolSPSequenced < 0.0 && tempControlType == HVAC::SetptType::SingleHeat) {
     259            0 :                 ZoneLoad = 0.0;
     260          112 :             } else if (ZoneLoadToHeatSPSequenced <= 0.0 && ZoneLoadToCoolSPSequenced >= 0.0) {
     261          112 :                 ZoneLoad = 0.0;
     262              :             }
     263        15220 :             MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(thisFurnace.ControlZoneNum)
     264        15220 :                                .SequencedOutputRequiredToDehumidSP(thisFurnace.ZoneSequenceCoolingNum);
     265        15220 :         } else {
     266            2 :             ZoneLoad = zoneSysEnergyDemand.RemainingOutputRequired;
     267            2 :             MoistureLoad = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(thisFurnace.ControlZoneNum).OutputRequiredToDehumidifyingSP;
     268              :         }
     269              : 
     270              :         // H2OHtOfVap
     271        15222 :         MoistureLoad *= Psychrometrics::PsyHfgAirFnWTdb(state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).HumRat,
     272        15222 :                                                         state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).Temp);
     273              : 
     274              :         // Initialize Furnace Flows
     275        15222 :         InitFurnace(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, ZoneLoad, MoistureLoad, FirstHVACIteration);
     276              : 
     277        15222 :         int FurnaceInletNode = thisFurnace.FurnaceInletNodeNum;
     278              : 
     279              :         // MassFlowRateMaxAvail issues are impeding non-VAV air loop equipment by limiting air flow
     280              :         // temporarily open up flow limits while simulating, and then set this same value at the INLET after this parent has simulated
     281        15222 :         Real64 TempMassFlowRateMaxAvail = state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail;
     282        15222 :         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = thisFurnace.DesignMassFlowRate;
     283              : 
     284        15222 :         Real64 FurnaceSavMdot = state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate;
     285        15222 :         HVAC::CompressorOp compressorOp = HVAC::CompressorOp::On;
     286        15222 :         state.dataFurnaces->CoolHeatPLRRat = 1.0;
     287              : 
     288              :         // Simulate correct system type (1 of 4 choices)
     289        15222 :         switch (thisFurnace.type) {
     290              :             // Simulate HeatOnly systems:
     291            0 :         case HVAC::UnitarySysType::Furnace_HeatOnly:
     292              :         case HVAC::UnitarySysType::Unitary_HeatOnly: {
     293              :             // Update the furnace flow rates
     294            0 :             CalcNewZoneHeatOnlyFlowRates(state, FurnaceNum, FirstHVACIteration, ZoneLoad, HeatCoilLoad, OnOffAirFlowRatio);
     295              : 
     296            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
     297              :                 // simulate fan
     298            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
     299              :             }
     300              : 
     301              :             // simulate furnace heating coil
     302            0 :             SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
     303            0 :             CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
     304              : 
     305            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::DrawThru) {
     306              :                 // simulate fan
     307            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
     308              :             }
     309            0 :         } break;
     310              :             // Simulate HeatCool systems:
     311            0 :         case HVAC::UnitarySysType::Furnace_HeatCool:
     312              :         case HVAC::UnitarySysType::Unitary_HeatCool: {
     313            0 :             if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
     314              :                 // variable speed cooling coil
     315            0 :                 HeatCoilLoad = 0.0;
     316            0 :                 if (thisFurnace.bIsIHP) {
     317            0 :                     state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).ControlledZoneTemp =
     318            0 :                         state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).Temp;
     319              :                 }
     320            0 :                 SimVariableSpeedHP(state, FurnaceNum, FirstHVACIteration, AirLoopNum, ZoneLoad, MoistureLoad, OnOffAirFlowRatio);
     321              :             } else {
     322              :                 // calculate the system flow rate
     323            0 :                 if (!FirstHVACIteration && thisFurnace.fanOp == HVAC::FanOp::Cycling && state.dataFurnaces->CoolingLoad &&
     324            0 :                     state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
     325              :                     // for cycling fan, cooling load, check whether furnace can meet load with compressor off
     326            0 :                     compressorOp = HVAC::CompressorOp::Off;
     327            0 :                     CalcNewZoneHeatCoolFlowRates(state,
     328              :                                                  FurnaceNum,
     329              :                                                  FirstHVACIteration,
     330              :                                                  compressorOp,
     331              :                                                  ZoneLoad,
     332              :                                                  MoistureLoad,
     333              :                                                  HeatCoilLoad,
     334              :                                                  ReheatCoilLoad,
     335              :                                                  OnOffAirFlowRatio,
     336              :                                                  HXUnitOn);
     337            0 :                     if (thisFurnace.CoolPartLoadRatio >= 1.0 || thisFurnace.HeatPartLoadRatio >= 1.0 ||
     338            0 :                         (thisFurnace.CoolPartLoadRatio <= 0.0 && thisFurnace.HeatPartLoadRatio <= 0.0)) {
     339              :                         // compressor on (reset inlet air mass flow rate to starting value)
     340            0 :                         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = FurnaceSavMdot;
     341            0 :                         compressorOp = HVAC::CompressorOp::On;
     342            0 :                         CalcNewZoneHeatCoolFlowRates(state,
     343              :                                                      FurnaceNum,
     344              :                                                      FirstHVACIteration,
     345              :                                                      compressorOp,
     346              :                                                      ZoneLoad,
     347              :                                                      MoistureLoad,
     348              :                                                      HeatCoilLoad,
     349              :                                                      ReheatCoilLoad,
     350              :                                                      OnOffAirFlowRatio,
     351              :                                                      HXUnitOn);
     352              :                     }
     353              :                 } else {
     354              :                     // compressor on
     355            0 :                     CalcNewZoneHeatCoolFlowRates(state,
     356              :                                                  FurnaceNum,
     357              :                                                  FirstHVACIteration,
     358              :                                                  compressorOp,
     359              :                                                  ZoneLoad,
     360              :                                                  MoistureLoad,
     361              :                                                  HeatCoilLoad,
     362              :                                                  ReheatCoilLoad,
     363              :                                                  OnOffAirFlowRatio,
     364              :                                                  HXUnitOn);
     365              :                 }
     366              : 
     367            0 :                 if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
     368              :                     // simulate fan
     369            0 :                     state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
     370              :                 }
     371              : 
     372            0 :                 if (!thisFurnace.CoolingCoilUpstream) {
     373              :                     // simulate furnace heating coil
     374            0 :                     SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
     375            0 :                     CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
     376              :                 }
     377              : 
     378              :                 // simulate furnace DX cooling coil
     379            0 :                 if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
     380            0 :                     HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
     381              :                                                                         BlankString,
     382              :                                                                         FirstHVACIteration,
     383              :                                                                         compressorOp,
     384              :                                                                         thisFurnace.CoolPartLoadRatio,
     385            0 :                                                                         thisFurnace.CoolingCoilIndex,
     386              :                                                                         fanOp,
     387              :                                                                         HXUnitOn,
     388              :                                                                         OnOffAirFlowRatio,
     389            0 :                                                                         state.dataFurnaces->EconomizerFlag);
     390              :                 } else {
     391            0 :                     DXCoils::SimDXCoil(state,
     392              :                                        BlankString,
     393              :                                        compressorOp,
     394              :                                        FirstHVACIteration,
     395            0 :                                        thisFurnace.CoolingCoilIndex,
     396              :                                        fanOp,
     397            0 :                                        thisFurnace.CoolPartLoadRatio,
     398              :                                        OnOffAirFlowRatio,
     399            0 :                                        state.dataFurnaces->CoolHeatPLRRat);
     400              :                 }
     401              : 
     402            0 :                 if (thisFurnace.CoolingCoilUpstream) {
     403              :                     // simulate furnace heating coil
     404            0 :                     SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
     405            0 :                     CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
     406              :                 }
     407              : 
     408            0 :                 if (thisFurnace.fanPlace == HVAC::FanPlace::DrawThru) {
     409              :                     // simulate fan
     410            0 :                     state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
     411              :                 }
     412              : 
     413              :                 // Simulate furnace reheat coil if a humidistat is used or if the reheat coil is present
     414            0 :                 if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat || thisFurnace.SuppHeatCoilIndex > 0) {
     415            0 :                     SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
     416            0 :                     CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, fanOp, QActual);
     417              :                 }
     418              :             }
     419            0 :         } break;
     420              :             // Simulate air-to-air heat pumps:
     421        15222 :         case HVAC::UnitarySysType::Unitary_HeatPump_AirToAir: {
     422        15222 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
     423              :                 // variable speed heat pump
     424            0 :                 HeatCoilLoad = 0.0;
     425            0 :                 if (thisFurnace.bIsIHP) {
     426            0 :                     auto &integratedHP = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex);
     427            0 :                     integratedHP.ControlledZoneTemp = state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).Temp;
     428            0 :                     integratedHP.IDFanID = thisFurnace.FanIndex; // why do this every time?
     429            0 :                     integratedHP.IDFanName = BlankString;
     430            0 :                     integratedHP.fanPlace = thisFurnace.fanPlace;
     431              :                 }
     432              : 
     433            0 :                 SimVariableSpeedHP(state, FurnaceNum, FirstHVACIteration, AirLoopNum, ZoneLoad, MoistureLoad, OnOffAirFlowRatio);
     434              :             } else {
     435              :                 // Update the furnace flow rates
     436        20283 :                 if (!FirstHVACIteration && thisFurnace.fanOp == HVAC::FanOp::Cycling && state.dataFurnaces->CoolingLoad &&
     437         5061 :                     state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
     438              :                     // for cycling fan, cooling load, check whether furnace can meet load with compressor off
     439            0 :                     compressorOp = HVAC::CompressorOp::Off;
     440            0 :                     CalcNewZoneHeatCoolFlowRates(state,
     441              :                                                  FurnaceNum,
     442              :                                                  FirstHVACIteration,
     443              :                                                  compressorOp,
     444              :                                                  ZoneLoad,
     445              :                                                  MoistureLoad,
     446              :                                                  HeatCoilLoad,
     447              :                                                  ReheatCoilLoad,
     448              :                                                  OnOffAirFlowRatio,
     449              :                                                  HXUnitOn);
     450            0 :                     if (thisFurnace.CoolPartLoadRatio >= 1.0 || thisFurnace.HeatPartLoadRatio >= 1.0 ||
     451            0 :                         (thisFurnace.CoolPartLoadRatio <= 0.0 && thisFurnace.HeatPartLoadRatio <= 0.0)) {
     452              :                         // compressor on (reset inlet air mass flow rate to starting value)
     453            0 :                         compressorOp = HVAC::CompressorOp::On;
     454            0 :                         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = FurnaceSavMdot;
     455            0 :                         CalcNewZoneHeatCoolFlowRates(state,
     456              :                                                      FurnaceNum,
     457              :                                                      FirstHVACIteration,
     458              :                                                      compressorOp,
     459              :                                                      ZoneLoad,
     460              :                                                      MoistureLoad,
     461              :                                                      HeatCoilLoad,
     462              :                                                      ReheatCoilLoad,
     463              :                                                      OnOffAirFlowRatio,
     464              :                                                      HXUnitOn);
     465              :                     }
     466              :                 } else {
     467              :                     // compressor on
     468        15222 :                     CalcNewZoneHeatCoolFlowRates(state,
     469              :                                                  FurnaceNum,
     470              :                                                  FirstHVACIteration,
     471              :                                                  compressorOp,
     472              :                                                  ZoneLoad,
     473              :                                                  MoistureLoad,
     474              :                                                  HeatCoilLoad,
     475              :                                                  ReheatCoilLoad,
     476              :                                                  OnOffAirFlowRatio,
     477              :                                                  HXUnitOn);
     478              :                 }
     479              : 
     480        15222 :                 if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
     481        15222 :                     state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
     482              :                 }
     483              : 
     484        15222 :                 if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
     485            0 :                     HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
     486              :                                                                         BlankString,
     487              :                                                                         FirstHVACIteration,
     488              :                                                                         compressorOp,
     489              :                                                                         thisFurnace.CoolPartLoadRatio,
     490            0 :                                                                         thisFurnace.CoolingCoilIndex,
     491              :                                                                         fanOp,
     492              :                                                                         HXUnitOn,
     493              :                                                                         OnOffAirFlowRatio,
     494            0 :                                                                         state.dataFurnaces->EconomizerFlag);
     495              :                 } else {
     496        30444 :                     DXCoils::SimDXCoil(state,
     497              :                                        BlankString,
     498              :                                        compressorOp,
     499              :                                        FirstHVACIteration,
     500        15222 :                                        thisFurnace.CoolingCoilIndex,
     501              :                                        fanOp,
     502        15222 :                                        thisFurnace.CoolPartLoadRatio,
     503              :                                        OnOffAirFlowRatio);
     504              :                 }
     505        30444 :                 DXCoils::SimDXCoil(state,
     506              :                                    BlankString,
     507              :                                    compressorOp,
     508              :                                    FirstHVACIteration,
     509        15222 :                                    thisFurnace.HeatingCoilIndex,
     510              :                                    fanOp,
     511        15222 :                                    thisFurnace.HeatPartLoadRatio,
     512              :                                    OnOffAirFlowRatio);
     513        15222 :                 if (thisFurnace.fanPlace == HVAC::FanPlace::DrawThru) {
     514            0 :                     state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
     515              :                 }
     516              : 
     517              :                 // Simulate furnace reheat coil if a humidistat is present, the dehumidification type of coolreheat and
     518              :                 // reheat coil load exists
     519        15222 :                 if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat && ReheatCoilLoad > 0.0) {
     520            0 :                     SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
     521            0 :                     CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, fanOp, QActual);
     522              :                 } else {
     523        15222 :                     SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
     524        15222 :                     CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
     525              :                 }
     526              :             }
     527        15222 :         } break;
     528              :         // Simulate water-to-air systems:
     529            0 :         case HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir: {
     530            0 :             if (thisFurnace.WatertoAirHPType == WAHPCoilType::Simple) {
     531              :                 // Update the furnace flow rates
     532              :                 //   When CompressorOp logic is added to the child cooling coil (COIL:WaterToAirHP:EquationFit:Cooling), then this logic
     533              :                 //   needs to be reinstated... to align with Unitary/Furnace HeatCool and Unitary Air-to-Air Heat Pump (see above).
     534            0 :                 if (!FirstHVACIteration && thisFurnace.fanOp == HVAC::FanOp::Cycling && state.dataFurnaces->CoolingLoad &&
     535            0 :                     state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive) {
     536              :                     // for cycling fan, cooling load, check whether furnace can meet load with compressor off
     537            0 :                     compressorOp = HVAC::CompressorOp::Off;
     538            0 :                     CalcNewZoneHeatCoolFlowRates(state,
     539              :                                                  FurnaceNum,
     540              :                                                  FirstHVACIteration,
     541              :                                                  compressorOp,
     542              :                                                  ZoneLoad,
     543              :                                                  MoistureLoad,
     544              :                                                  HeatCoilLoad,
     545              :                                                  ReheatCoilLoad,
     546              :                                                  OnOffAirFlowRatio,
     547              :                                                  HXUnitOn);
     548            0 :                     if (thisFurnace.CoolPartLoadRatio >= 1.0 || thisFurnace.HeatPartLoadRatio >= 1.0 ||
     549            0 :                         (thisFurnace.CoolPartLoadRatio <= 0.0 && thisFurnace.HeatPartLoadRatio <= 0.0)) {
     550              :                         // compressor on (reset inlet air mass flow rate to starting value)
     551            0 :                         compressorOp = HVAC::CompressorOp::On;
     552            0 :                         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = FurnaceSavMdot;
     553            0 :                         CalcNewZoneHeatCoolFlowRates(state,
     554              :                                                      FurnaceNum,
     555              :                                                      FirstHVACIteration,
     556              :                                                      compressorOp,
     557              :                                                      ZoneLoad,
     558              :                                                      MoistureLoad,
     559              :                                                      HeatCoilLoad,
     560              :                                                      ReheatCoilLoad,
     561              :                                                      OnOffAirFlowRatio,
     562              :                                                      HXUnitOn);
     563              :                     }
     564              :                 } else {
     565              :                     // compressor on
     566            0 :                     CalcNewZoneHeatCoolFlowRates(state,
     567              :                                                  FurnaceNum,
     568              :                                                  FirstHVACIteration,
     569              :                                                  compressorOp,
     570              :                                                  ZoneLoad,
     571              :                                                  MoistureLoad,
     572              :                                                  HeatCoilLoad,
     573              :                                                  ReheatCoilLoad,
     574              :                                                  OnOffAirFlowRatio,
     575              :                                                  HXUnitOn);
     576              :                 }
     577            0 :                 if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
     578            0 :                     state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
     579              :                 }
     580              : 
     581            0 :                 WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
     582              :                                                                 BlankString,
     583            0 :                                                                 thisFurnace.CoolingCoilIndex,
     584              :                                                                 thisFurnace.CoolingCoilSensDemand,
     585              :                                                                 thisFurnace.CoolingCoilLatentDemand,
     586              :                                                                 thisFurnace.fanOp,
     587              :                                                                 compressorOp,
     588              :                                                                 thisFurnace.CoolPartLoadRatio,
     589              :                                                                 FirstHVACIteration);
     590            0 :                 WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
     591              :                                                                 BlankString,
     592            0 :                                                                 thisFurnace.HeatingCoilIndex,
     593              :                                                                 thisFurnace.HeatingCoilSensDemand,
     594              :                                                                 Dummy,
     595              :                                                                 thisFurnace.fanOp,
     596              :                                                                 compressorOp,
     597              :                                                                 thisFurnace.HeatPartLoadRatio,
     598              :                                                                 FirstHVACIteration);
     599              : 
     600            0 :                 if (thisFurnace.fanPlace == HVAC::FanPlace::DrawThru) {
     601            0 :                     state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
     602              :                 }
     603            0 :                 if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat && ReheatCoilLoad > 0.0) {
     604            0 :                     SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
     605            0 :                     CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, fanOp, QActual);
     606              :                 } else {
     607            0 :                     SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
     608            0 :                     CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
     609              :                 }
     610            0 :             } else if (thisFurnace.WatertoAirHPType == WAHPCoilType::ParEst) {
     611              : 
     612              :                 // simulate the heat pump
     613            0 :                 HeatCoilLoad = 0.0;
     614            0 :                 CalcWaterToAirHeatPump(state, FurnaceNum, FirstHVACIteration, compressorOp, ZoneLoad, MoistureLoad);
     615            0 :             } else if (thisFurnace.WatertoAirHPType == WAHPCoilType::VarSpeedEquationFit) {
     616              :                 // simulate the heat pump
     617            0 :                 HeatCoilLoad = 0.0;
     618            0 :                 if (thisFurnace.bIsIHP) {
     619            0 :                     state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).ControlledZoneTemp =
     620            0 :                         state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).Temp;
     621              :                 }
     622            0 :                 SimVariableSpeedHP(state, FurnaceNum, FirstHVACIteration, AirLoopNum, ZoneLoad, MoistureLoad, OnOffAirFlowRatio);
     623              : 
     624            0 :             } else if (thisFurnace.WatertoAirHPType == WAHPCoilType::VarSpeedLookupTable) {
     625            0 :                 HeatCoilLoad = 0.0; // Added: Used below
     626              :             } else {
     627            0 :                 assert(false); //? If all possible states covered by if conditions change to HeatCoilLoad = 0.0;
     628              :             }
     629            0 :         } break;
     630            0 :         default: {
     631              :             // will never get here, all system types are simulated above
     632            0 :             assert(false);
     633              :         } break;
     634              :         }
     635              : 
     636              :         // set the econo lockout flags
     637        15222 :         auto &airLoopControlInfo = state.dataAirLoop->AirLoopControlInfo(AirLoopNum);
     638        15222 :         if (thisFurnace.CompPartLoadRatio > 0.0 && airLoopControlInfo.CanLockoutEconoWithCompressor) {
     639            0 :             airLoopControlInfo.ReqstEconoLockoutWithCompressor = true;
     640              :         } else {
     641        15222 :             airLoopControlInfo.ReqstEconoLockoutWithCompressor = false;
     642              :         }
     643              : 
     644        15222 :         if ((HeatCoilLoad > 0.0 || thisFurnace.HeatPartLoadRatio > 0.0) &&
     645         8361 :             (airLoopControlInfo.CanLockoutEconoWithCompressor || airLoopControlInfo.CanLockoutEconoWithHeating)) {
     646            0 :             airLoopControlInfo.ReqstEconoLockoutWithHeating = true;
     647              :         } else {
     648        15222 :             airLoopControlInfo.ReqstEconoLockoutWithHeating = false;
     649              :         }
     650              : 
     651        15222 :         if (thisFurnace.fanOp == HVAC::FanOp::Cycling) {
     652        15222 :             state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = thisFurnace.FanPartLoadRatio;
     653              :         } else {
     654            0 :             state.dataAirLoop->AirLoopFlow(AirLoopNum).FanPLR = 1.0; // 1 means constant fan does not cycle.
     655              :         }
     656              : 
     657              :         // Report the current Furnace output
     658        15222 :         ReportFurnace(state, FurnaceNum, AirLoopNum);
     659              : 
     660              :         // Reset OnOffFanPartLoadFraction to 1 in case another on/off fan is called without a part-load curve
     661        15222 :         state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
     662              : 
     663        15222 :         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = TempMassFlowRateMaxAvail;
     664        15222 :     }
     665              : 
     666              :     // Get Input Section of the Module
     667              :     //******************************************************************************
     668              : 
     669            2 :     void GetFurnaceInput(EnergyPlusData &state)
     670              :     {
     671              : 
     672              :         // SUBROUTINE INFORMATION:
     673              :         //       AUTHOR         Richard Liesen
     674              :         //       DATE WRITTEN   Feb 2001
     675              :         //       MODIFIED       Don Shirey and Rich Raustad, Mar/Oct 2001, Mar 2003
     676              :         //                      Bereket Nigusse, April 2010 - deprecated supply air flow fraction through
     677              :         //                      controlled zone from the input field.
     678              :         //                      Bo Shen, March 2012, add inputs for VS WSHP,
     679              :         //                      Bo Shen, ORNL, July 2012 - added variable-speed air source heat pump cooling and heating coils, using curve-fits
     680              : 
     681              :         // PURPOSE OF THIS SUBROUTINE:
     682              :         // Obtains input data for fans and coils and stores it in the Furnace data structures
     683              : 
     684              :         // METHODOLOGY EMPLOYED:
     685              :         // Uses "Get" routines to read in data.
     686              : 
     687              :         // SUBROUTINE PARAMETER DEFINITIONS:
     688            2 :         std::string_view constexpr getUnitaryHeatOnly("GetUnitaryHeatOnly");
     689            2 :         std::string_view constexpr getAirLoopHVACHeatCoolInput("GetAirLoopHVACHeatCoolInput");
     690            2 :         std::string_view constexpr routineName = "GetFurnaceInput";
     691              : 
     692              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     693              :         int FurnaceNum;                // The Furnace that you are currently loading input into
     694              :         int GetObjectNum;              // The index to each specific object name
     695              :         int NumFields;                 // Total number of fields in object
     696              :         int NumAlphas;                 // Total number of alpha fields in object
     697              :         int NumNumbers;                // Total number of numeric fields in object
     698              :         int IOStatus;                  // Function call status
     699            2 :         Array1D<Real64> Numbers;       // Numeric data
     700            2 :         Array1D_string Alphas;         // Alpha data
     701            2 :         Array1D_string cAlphaFields;   // Alpha field names
     702            2 :         Array1D_string cNumericFields; // Numeric field names
     703            2 :         Array1D_bool lAlphaBlanks;     // Logical array, alpha field input BLANK = .TRUE.
     704            2 :         Array1D_bool lNumericBlanks;   // Logical array, numeric field input BLANK = .TRUE.
     705            2 :         std::string CompSetFanInlet;
     706            2 :         std::string CompSetFanOutlet;
     707            2 :         std::string CompSetCoolInlet;
     708            2 :         std::string CompSetHeatInlet;
     709            2 :         std::string CompSetHeatOutlet;
     710            2 :         bool ErrorsFound(false);       // If errors detected in input
     711              :         bool IsNotOK;                  // Flag to verify name
     712              :         bool AirNodeFound;             // Used to determine if control zone is valid
     713              :         bool AirLoopFound;             // Used to determine if control zone is served by furnace air loop
     714              :         int TstatZoneNum;              // Used to determine if control zone has a thermostat object
     715              :         int HStatZoneNum;              // Used to determine if control zone has a humidistat object
     716              :         bool errFlag;                  // Mining function error flag
     717              :         int FanInletNode;              // Used for node checking warning messages
     718              :         int FanOutletNode;             // Used for node checking warning messages
     719              :         int CoolingCoilInletNode;      // Used for node checking warning messages
     720              :         int CoolingCoilOutletNode;     // Used for node checking warning messages
     721              :         int HeatingCoilInletNode;      // Used for node checking warning messages
     722              :         int HeatingCoilOutletNode;     // Used for node checking warning messages
     723              :         int SupHeatCoilInletNode;      // Used for node checking warning messages
     724              :         int SupHeatCoilOutletNode;     // Used for node checking warning messages
     725            2 :         std::string CoolingCoilType;   // Used in mining function CALLS
     726            2 :         std::string CoolingCoilName;   // Used in mining function CALLS
     727            2 :         std::string HeatingCoilType;   // Used in mining function CALLS
     728            2 :         std::string HeatingCoilName;   // Used in mining function CALLS
     729            2 :         std::string ReheatingCoilType; // Used in mining function CALLS
     730            2 :         std::string ReheatingCoilName; // Used in mining function CALLS
     731            2 :         std::string SuppHeatCoilType;  // Used in mining function CALLS
     732            2 :         std::string SuppHeatCoilName;  // Used in mining function CALLS
     733            2 :         std::string FanName;           // Used in mining function CALLS
     734              :         bool PrintMessage;             // Used in mining function CALLS
     735              :         int HeatingCoilPLFCurveIndex;  // index of heating coil PLF curve
     736              :         Real64 SteamDensity;           // density of steam at 100C
     737              :         int DXCoilIndex;               // Index to DX coil in HXAssited object
     738            2 :         std::string IHPCoilName;       // IHP cooling coil name
     739            2 :         auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     740              :         DataLoopNode::ConnectionObjectType currentModuleObjectType;
     741              : 
     742            2 :         state.dataFurnaces->GetFurnaceInputFlag = false;
     743            2 :         int MaxNumbers = 0;
     744            2 :         int MaxAlphas = 0;
     745              : 
     746            2 :         std::string_view CurrentModuleObject = "AirLoopHVAC:Unitary:Furnace:HeatOnly";
     747            2 :         int NumHeatOnly = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     748            2 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
     749            2 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     750            2 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     751              : 
     752            2 :         CurrentModuleObject = "AirLoopHVAC:Unitary:Furnace:HeatCool";
     753            2 :         int NumHeatCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     754            2 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
     755            2 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     756            2 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     757              : 
     758            2 :         CurrentModuleObject = "AirLoopHVAC:UnitaryHeatOnly";
     759            2 :         int NumUnitaryHeatOnly = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     760            2 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
     761            2 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     762            2 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     763              : 
     764            2 :         CurrentModuleObject = "AirLoopHVAC:UnitaryHeatCool";
     765            2 :         int NumUnitaryHeatCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     766            2 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
     767            2 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     768            2 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     769              : 
     770            2 :         CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:AirToAir";
     771            2 :         int NumHeatPump = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     772            2 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
     773            2 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     774            2 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     775              : 
     776            2 :         CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:WaterToAir";
     777            2 :         int NumWaterToAirHeatPump = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     778            2 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
     779            2 :         MaxNumbers = max(MaxNumbers, NumNumbers);
     780            2 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     781              : 
     782            2 :         Alphas.allocate(MaxAlphas);
     783            2 :         Numbers.dimension(MaxNumbers, 0.0);
     784            2 :         cAlphaFields.allocate(MaxAlphas);
     785            2 :         cNumericFields.allocate(MaxNumbers);
     786            2 :         lAlphaBlanks.dimension(MaxAlphas, true);
     787            2 :         lNumericBlanks.dimension(MaxNumbers, true);
     788              : 
     789            2 :         state.dataFurnaces->NumFurnaces = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + NumHeatPump + NumWaterToAirHeatPump;
     790              : 
     791            2 :         if (state.dataFurnaces->NumFurnaces > 0) {
     792            2 :             state.dataFurnaces->Furnace.allocate(state.dataFurnaces->NumFurnaces);
     793            2 :             state.dataFurnaces->UniqueFurnaceNames.reserve(state.dataFurnaces->NumFurnaces);
     794              :         }
     795            2 :         state.dataFurnaces->CheckEquipName.dimension(state.dataFurnaces->NumFurnaces, true);
     796              : 
     797            2 :         int IHPCoilIndex = 0;
     798              : 
     799              :         // Get the data for the HeatOnly Furnace
     800            2 :         for (int HeatOnlyNum = 1; HeatOnlyNum <= NumHeatOnly + NumUnitaryHeatOnly; ++HeatOnlyNum) {
     801              : 
     802            0 :             FanInletNode = 0;
     803            0 :             FanOutletNode = 0;
     804            0 :             HeatingCoilInletNode = 0;
     805            0 :             HeatingCoilOutletNode = 0;
     806            0 :             CoolingCoilType = ' ';
     807            0 :             CoolingCoilName = ' ';
     808            0 :             HeatingCoilType = ' ';
     809            0 :             HeatingCoilName = ' ';
     810              : 
     811            0 :             FurnaceNum = HeatOnlyNum;
     812            0 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
     813              : 
     814              :             //       Furnace and UnitarySystem objects are both read in here.
     815              :             //       Will still have 2 differently named objects for the user, but read in with 1 DO loop.
     816            0 :             if (HeatOnlyNum <= NumHeatOnly) {
     817            0 :                 CurrentModuleObject = "AirLoopHVAC:Unitary:Furnace:HeatOnly";
     818            0 :                 currentModuleObjectType = DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryFurnaceHeatOnly;
     819            0 :                 thisFurnace.type = HVAC::UnitarySysType::Furnace_HeatOnly;
     820            0 :                 GetObjectNum = HeatOnlyNum;
     821              :             } else {
     822            0 :                 CurrentModuleObject = "AirLoopHVAC:UnitaryHeatOnly";
     823            0 :                 currentModuleObjectType = DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatOnly;
     824            0 :                 thisFurnace.type = HVAC::UnitarySysType::Unitary_HeatOnly;
     825            0 :                 GetObjectNum = HeatOnlyNum - NumHeatOnly;
     826              :             }
     827              : 
     828            0 :             thisFurnace.iterationMode.allocate(3);
     829              : 
     830            0 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     831              :                                                                      CurrentModuleObject,
     832              :                                                                      GetObjectNum,
     833              :                                                                      Alphas,
     834              :                                                                      NumAlphas,
     835              :                                                                      Numbers,
     836              :                                                                      NumNumbers,
     837              :                                                                      IOStatus,
     838              :                                                                      lNumericBlanks,
     839              :                                                                      lAlphaBlanks,
     840              :                                                                      cAlphaFields,
     841              :                                                                      cNumericFields);
     842              : 
     843            0 :             GlobalNames::VerifyUniqueInterObjectName(
     844            0 :                 state, state.dataFurnaces->UniqueFurnaceNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
     845              : 
     846            0 :             thisFurnace.Name = Alphas(1);
     847            0 :             ErrorObjectHeader eoh{routineName, cAlphaFields(1), thisFurnace.Name};
     848              : 
     849            0 :             if (lAlphaBlanks(2)) {
     850            0 :                 thisFurnace.availSched = Sched::GetScheduleAlwaysOn(state);
     851            0 :             } else if ((thisFurnace.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
     852            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
     853            0 :                 ErrorsFound = true;
     854              :             }
     855              : 
     856            0 :             thisFurnace.FurnaceInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     857            0 :                                                                                   Alphas(3),
     858              :                                                                                   ErrorsFound,
     859              :                                                                                   currentModuleObjectType,
     860            0 :                                                                                   Alphas(1),
     861              :                                                                                   DataLoopNode::NodeFluidType::Air,
     862              :                                                                                   DataLoopNode::ConnectionType::Inlet,
     863              :                                                                                   NodeInputManager::CompFluidStream::Primary,
     864              :                                                                                   DataLoopNode::ObjectIsParent);
     865            0 :             thisFurnace.FurnaceOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     866            0 :                                                                                    Alphas(4),
     867              :                                                                                    ErrorsFound,
     868              :                                                                                    currentModuleObjectType,
     869            0 :                                                                                    Alphas(1),
     870              :                                                                                    DataLoopNode::NodeFluidType::Air,
     871              :                                                                                    DataLoopNode::ConnectionType::Outlet,
     872              :                                                                                    NodeInputManager::CompFluidStream::Primary,
     873              :                                                                                    DataLoopNode::ObjectIsParent);
     874              : 
     875            0 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
     876              : 
     877            0 :             if (lAlphaBlanks(5)) {
     878            0 :                 thisFurnace.fanOp = HVAC::FanOp::Cycling;
     879            0 :             } else if ((thisFurnace.fanOpModeSched = Sched::GetSchedule(state, Alphas(5))) == nullptr) {
     880            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(5), Alphas(5));
     881            0 :                 ErrorsFound = true;
     882              :             }
     883              : 
     884              :             // Get the Controlling Zone or Location of the Furnace Thermostat
     885              : 
     886            0 :             thisFurnace.ControlZoneNum = Util::FindItemInList(Alphas(6), state.dataHeatBal->Zone);
     887            0 :             if (thisFurnace.ControlZoneNum == 0) {
     888            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     889            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(6), Alphas(6)));
     890            0 :                 ErrorsFound = true;
     891              :             }
     892              : 
     893              :             // Get the node number for the zone with the thermostat
     894            0 :             if (thisFurnace.ControlZoneNum > 0) {
     895            0 :                 AirNodeFound = false;
     896            0 :                 AirLoopFound = false;
     897            0 :                 int ControlledZoneNum = thisFurnace.ControlZoneNum;
     898              :                 //             Find the controlled zone number for the specified thermostat location
     899            0 :                 thisFurnace.NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
     900              :                 //             Determine if furnace is on air loop served by the thermostat location specified
     901            0 :                 for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
     902            0 :                     int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
     903            0 :                     if (AirLoopNumber > 0) {
     904            0 :                         for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
     905            0 :                             for (int CompNum = 1;
     906            0 :                                  CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
     907              :                                  ++CompNum) {
     908            0 :                                 if (!Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name,
     909            0 :                                                       thisFurnace.Name) ||
     910            0 :                                     !Util::SameString(
     911            0 :                                         state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
     912              :                                         CurrentModuleObject)) {
     913            0 :                                     continue;
     914              :                                 }
     915            0 :                                 AirLoopFound = true;
     916            0 :                                 thisFurnace.ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
     917            0 :                                 break;
     918              :                             }
     919            0 :                             if (AirLoopFound) {
     920            0 :                                 break;
     921              :                             }
     922              :                         }
     923            0 :                         for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
     924            0 :                             if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
     925            0 :                                 continue;
     926              :                             }
     927            0 :                             AirNodeFound = true;
     928              :                         }
     929            0 :                         for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
     930            0 :                             if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
     931            0 :                                 continue;
     932              :                             }
     933            0 :                             AirNodeFound = true;
     934              :                         }
     935              :                     }
     936            0 :                     if (AirLoopFound) {
     937            0 :                         break;
     938              :                     }
     939              :                 }
     940            0 :                 if (!AirNodeFound) {
     941            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     942            0 :                     ShowContinueError(state, "Did not find Air Node (Zone with Thermostat).");
     943            0 :                     ShowContinueError(state, format("Specified {} = {}", cAlphaFields(6), Alphas(6)));
     944            0 :                     ShowContinueError(
     945              :                         state, "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
     946            0 :                     ErrorsFound = true;
     947              :                 }
     948            0 :                 if (!AirLoopFound) {
     949            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     950            0 :                     ShowContinueError(state, "Did not find correct Primary Air Loop.");
     951            0 :                     ShowContinueError(state, format("Specified {} = {} is not served by this AirLoopHVAC equipment.", cAlphaFields(6), Alphas(6)));
     952            0 :                     ErrorsFound = true;
     953              :                 }
     954              :             }
     955              : 
     956              :             // Get fan data
     957            0 :             FanName = Alphas(8);
     958            0 :             errFlag = false;
     959              : 
     960            0 :             thisFurnace.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(7)));
     961            0 :             if (thisFurnace.fanType != HVAC::FanType::OnOff && thisFurnace.fanType != HVAC::FanType::Constant) {
     962            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     963            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(7), Alphas(7)));
     964            0 :                 ErrorsFound = true;
     965              : 
     966            0 :             } else if ((thisFurnace.FanIndex = Fans::GetFanIndex(state, FanName)) == 0) {
     967            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(8), FanName);
     968            0 :                 ErrorsFound = true;
     969              : 
     970              :             } else {
     971            0 :                 auto *fan = state.dataFans->fans(thisFurnace.FanIndex);
     972            0 :                 thisFurnace.ActualFanVolFlowRate = fan->maxAirFlowRate;
     973            0 :                 FanInletNode = fan->inletNodeNum;
     974            0 :                 FanOutletNode = fan->outletNodeNum;
     975            0 :                 thisFurnace.fanAvailSched = fan->availSched;
     976              : 
     977              :                 // Check fan's schedule for cycling fan operation if constant volume fan is used
     978            0 :                 if (thisFurnace.fanOpModeSched != nullptr && thisFurnace.fanType == HVAC::FanType::Constant) {
     979            0 :                     if (!thisFurnace.fanOpModeSched->checkMinMaxVals(state, Clusive::Ex, 0.0, Clusive::In, 1.0)) {
     980            0 :                         Sched::ShowSevereBadMinMax(
     981              :                             state,
     982              :                             eoh,
     983            0 :                             cAlphaFields(5),
     984            0 :                             Alphas(5),
     985              :                             Clusive::Ex,
     986              :                             0.0,
     987              :                             Clusive::In,
     988              :                             1.0,
     989            0 :                             format("For {} = {}, Fan operating mode must be continuous (schedule values > 0)", cAlphaFields(7), Alphas(7)));
     990            0 :                         ErrorsFound = true;
     991              :                     }
     992            0 :                 } else if (lAlphaBlanks(5) && thisFurnace.fanType != HVAC::FanType::OnOff) {
     993            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisFurnace.Name));
     994            0 :                     ShowContinueError(state, format("{} = {}", cAlphaFields(7), Alphas(7)));
     995            0 :                     ShowContinueError(state, format("Fan type must be Fan:OnOff when {} = Blank.", cAlphaFields(5)));
     996            0 :                     ErrorsFound = true;
     997              :                 }
     998              :             }
     999              : 
    1000            0 :             thisFurnace.fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Alphas(9)));
    1001            0 :             assert(thisFurnace.fanPlace != HVAC::FanPlace::Invalid);
    1002              : 
    1003              :             // Get coil data
    1004            0 :             HeatingCoilType = Alphas(10);
    1005            0 :             HeatingCoilName = Alphas(11);
    1006            0 :             thisFurnace.HeatingCoilType = HeatingCoilType;
    1007            0 :             thisFurnace.HeatingCoilName = HeatingCoilName;
    1008            0 :             if (Util::SameString(HeatingCoilType, "Coil:Heating:Fuel") || Util::SameString(HeatingCoilType, "Coil:Heating:Electric")) {
    1009            0 :                 errFlag = false;
    1010            0 :                 thisFurnace.HeatingCoilType_Num = HeatingCoils::GetHeatingCoilTypeNum(state, HeatingCoilType, HeatingCoilName, errFlag);
    1011            0 :                 if (errFlag) {
    1012            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1013            0 :                     ErrorsFound = true;
    1014              :                 } else {
    1015            0 :                     ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    1016            0 :                     if (IsNotOK) {
    1017            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1018            0 :                         ErrorsFound = true;
    1019              : 
    1020              :                     } else { // mine data from heating coil object
    1021              : 
    1022              :                         // Get index to Heating Coil
    1023            0 :                         errFlag = false;
    1024            0 :                         HeatingCoils::GetCoilIndex(state, HeatingCoilName, thisFurnace.HeatingCoilIndex, errFlag);
    1025            0 :                         if (errFlag) {
    1026            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1027            0 :                             ErrorsFound = true;
    1028              :                         }
    1029              : 
    1030              :                         // Get the furnace design capacity
    1031            0 :                         errFlag = false;
    1032            0 :                         thisFurnace.DesignHeatingCapacity = HeatingCoils::GetCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
    1033            0 :                         if (errFlag) {
    1034            0 :                             ShowContinueError(state, format("...occurs in {} ={}", CurrentModuleObject, Alphas(1)));
    1035            0 :                             ErrorsFound = true;
    1036              :                         }
    1037              : 
    1038              :                         // Get the Heating Coil Inlet Node
    1039            0 :                         errFlag = false;
    1040            0 :                         HeatingCoilInletNode = HeatingCoils::GetCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    1041            0 :                         thisFurnace.HWCoilAirInletNode = HeatingCoilInletNode;
    1042            0 :                         if (errFlag) {
    1043            0 :                             ShowContinueError(state, format("...occurs in {} ={}", CurrentModuleObject, Alphas(1)));
    1044            0 :                             ErrorsFound = true;
    1045              :                         }
    1046              : 
    1047              :                         // Get the Heating Coil Outlet Node
    1048            0 :                         errFlag = false;
    1049            0 :                         HeatingCoilOutletNode = HeatingCoils::GetCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    1050            0 :                         if (errFlag) {
    1051            0 :                             ShowContinueError(state, format("...occurs in {} ={}", CurrentModuleObject, Alphas(1)));
    1052            0 :                             ErrorsFound = true;
    1053              :                         }
    1054              : 
    1055              :                     } // IF (IsNotOK) THEN
    1056              :                 }
    1057              : 
    1058            0 :             } else if (Util::SameString(HeatingCoilType, "Coil:Heating:Water")) {
    1059            0 :                 thisFurnace.HeatingCoilType_Num = HVAC::Coil_HeatingWater;
    1060            0 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    1061            0 :                 if (IsNotOK) {
    1062            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1063            0 :                     ErrorsFound = true;
    1064              :                 } else { // mine data from heating coil object
    1065              : 
    1066              :                     // Get the Heating Coil water Inlet or control Node number
    1067            0 :                     errFlag = false;
    1068            0 :                     thisFurnace.CoilControlNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
    1069            0 :                     if (errFlag) {
    1070            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1071            0 :                         ErrorsFound = true;
    1072              :                     }
    1073              : 
    1074              :                     // Get the Heating Coil hot water max volume flow rate
    1075            0 :                     errFlag = false;
    1076            0 :                     thisFurnace.MaxHeatCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
    1077            0 :                     if (errFlag) {
    1078            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1079            0 :                         ErrorsFound = true;
    1080              :                     }
    1081              : 
    1082              :                     // Get the Heating Coil Inlet Node
    1083            0 :                     errFlag = false;
    1084            0 :                     HeatingCoilInletNode = WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
    1085            0 :                     thisFurnace.HWCoilAirInletNode = HeatingCoilInletNode;
    1086            0 :                     if (errFlag) {
    1087            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1088            0 :                         ErrorsFound = true;
    1089              :                     }
    1090              : 
    1091              :                     // Get the Heating Coil Outlet Node
    1092            0 :                     errFlag = false;
    1093            0 :                     HeatingCoilOutletNode = WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
    1094            0 :                     thisFurnace.HWCoilAirOutletNode = HeatingCoilOutletNode;
    1095            0 :                     if (errFlag) {
    1096            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1097            0 :                         ErrorsFound = true;
    1098              :                     }
    1099              : 
    1100              :                     // check if user has also used a water coil controller, which they should not do
    1101            0 :                     errFlag = false;
    1102            0 :                     HVACControllers::CheckCoilWaterInletNode(state, thisFurnace.CoilControlNode, errFlag);
    1103            0 :                     if (!errFlag) { // then did find a controller so that is bad
    1104            0 :                         ShowSevereError(state,
    1105            0 :                                         format("{} = {} has a conflicting Controller:WaterCoil object", CurrentModuleObject, thisFurnace.Name));
    1106            0 :                         ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
    1107            0 :                         ShowContinueError(state, "No water coil controller should be input for the coil.");
    1108            0 :                         ErrorsFound = true;
    1109              :                     }
    1110              :                 }
    1111              : 
    1112            0 :             } else if (Util::SameString(HeatingCoilType, "Coil:Heating:Steam")) {
    1113            0 :                 thisFurnace.HeatingCoilType_Num = HVAC::Coil_HeatingSteam;
    1114            0 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    1115            0 :                 if (IsNotOK) {
    1116            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1117            0 :                     ErrorsFound = true;
    1118              :                 } else { // mine data from heating coil object
    1119              : 
    1120            0 :                     errFlag = false;
    1121            0 :                     thisFurnace.HeatingCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", HeatingCoilName, errFlag);
    1122            0 :                     if (thisFurnace.HeatingCoilIndex == 0) {
    1123            0 :                         ShowSevereError(state, format("{} illegal {} = {}", CurrentModuleObject, cAlphaFields(11), HeatingCoilName));
    1124            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1125            0 :                         ErrorsFound = true;
    1126              :                     }
    1127              : 
    1128              :                     // Get the Heating Coil steam inlet node number
    1129            0 :                     errFlag = false;
    1130            0 :                     thisFurnace.CoilControlNode = SteamCoils::GetCoilSteamInletNode(state, "COIL:HEATING:STEAM", HeatingCoilName, errFlag);
    1131            0 :                     if (errFlag) {
    1132            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1133            0 :                         ErrorsFound = true;
    1134              :                     }
    1135              : 
    1136              :                     // Get the Heating Coil steam max volume flow rate
    1137            0 :                     thisFurnace.MaxHeatCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.HeatingCoilIndex, errFlag);
    1138            0 :                     if (thisFurnace.MaxHeatCoilFluidFlow > 0.0) {
    1139            0 :                         SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, getUnitaryHeatOnly);
    1140            0 :                         thisFurnace.MaxHeatCoilFluidFlow *= SteamDensity;
    1141              :                     }
    1142              : 
    1143              :                     // Get the Heating Coil Inlet Node
    1144            0 :                     errFlag = false;
    1145            0 :                     HeatingCoilInletNode = SteamCoils::GetCoilAirInletNode(state, thisFurnace.HeatingCoilIndex, HeatingCoilName, errFlag);
    1146            0 :                     thisFurnace.HWCoilAirInletNode = HeatingCoilInletNode;
    1147            0 :                     if (errFlag) {
    1148            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1149            0 :                         ErrorsFound = true;
    1150              :                     }
    1151              : 
    1152              :                     // Get the Heating Coil Outlet Node
    1153            0 :                     errFlag = false;
    1154            0 :                     HeatingCoilOutletNode = SteamCoils::GetCoilAirOutletNode(state, thisFurnace.HeatingCoilIndex, HeatingCoilName, errFlag);
    1155            0 :                     thisFurnace.HWCoilAirOutletNode = HeatingCoilOutletNode;
    1156            0 :                     if (errFlag) {
    1157            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1158            0 :                         ErrorsFound = true;
    1159              :                     }
    1160              :                 }
    1161              : 
    1162              :             } else {
    1163            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1164            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(11), Alphas(11)));
    1165            0 :                 ErrorsFound = true;
    1166              :             } // IF (Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
    1167              : 
    1168              :             // Add component sets array
    1169            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    1170            0 :                 CompSetFanInlet = Alphas(3);
    1171            0 :                 CompSetFanOutlet = state.dataLoopNodes->NodeID(FanOutletNode);
    1172            0 :                 CompSetHeatInlet = state.dataLoopNodes->NodeID(FanOutletNode);
    1173            0 :                 CompSetHeatOutlet = Alphas(4);
    1174              :                 // Fan inlet node name must not be the same as the furnace inlet node name
    1175            0 :                 if (FanInletNode != thisFurnace.FurnaceInletNodeNum) {
    1176            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1177            0 :                     if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatOnly) {
    1178            0 :                         ShowContinueError(
    1179              :                             state, "When a blow through fan is specified, the fan inlet node name must be the same as the furnace inlet node name.");
    1180            0 :                         ShowContinueError(state, format("...Fan inlet node name     = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    1181            0 :                         ShowContinueError(state,
    1182            0 :                                           format("...Furnace inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    1183              :                     } else {
    1184            0 :                         ShowContinueError(
    1185              :                             state,
    1186              :                             "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system inlet node name.");
    1187            0 :                         ShowContinueError(state, format("...Fan inlet node name            = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    1188            0 :                         ShowContinueError(
    1189            0 :                             state, format("...Unitary System inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    1190              :                     }
    1191            0 :                     ErrorsFound = true;
    1192              :                 }
    1193              :                 // Fan outlet node name must be the same as the heating coil inlet node name
    1194            0 :                 if (FanOutletNode != HeatingCoilInletNode) {
    1195            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1196            0 :                     ShowContinueError(
    1197              :                         state,
    1198              :                         "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil inlet node name.");
    1199            0 :                     ShowContinueError(state, format("...Fan outlet node name         = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    1200            0 :                     ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    1201            0 :                     ErrorsFound = true;
    1202              :                 }
    1203              :                 // Heating coil outlet node name must be the same as the furnace outlet node name
    1204            0 :                 if (HeatingCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    1205            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1206            0 :                     if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatOnly) {
    1207            0 :                         ShowContinueError(state,
    1208              :                                           "When a blow through fan is specified, the heating coil outlet node name must be the same as the furnace "
    1209              :                                           "outlet node name.");
    1210            0 :                         ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    1211            0 :                         ShowContinueError(
    1212            0 :                             state, format("...Furnace outlet node name      = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    1213              :                     } else {
    1214            0 :                         ShowContinueError(state,
    1215              :                                           "When a blow through fan is specified, the heating coil outlet node name must be the same as the unitary "
    1216              :                                           "system outlet node name.");
    1217            0 :                         ShowContinueError(state,
    1218            0 :                                           format("...Heating coil outlet node name  = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    1219            0 :                         ShowContinueError(
    1220            0 :                             state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    1221              :                     }
    1222            0 :                     ErrorsFound = true;
    1223              :                 }
    1224              :             } else { // draw through fan
    1225            0 :                 CompSetHeatInlet = Alphas(3);
    1226            0 :                 CompSetHeatOutlet = state.dataLoopNodes->NodeID(FanInletNode);
    1227            0 :                 CompSetFanInlet = state.dataLoopNodes->NodeID(FanInletNode);
    1228            0 :                 CompSetFanOutlet = Alphas(4);
    1229              :                 // Heating coil inlet node name must not be the same as the furnace inlet node name
    1230            0 :                 if (HeatingCoilInletNode != thisFurnace.FurnaceInletNodeNum) {
    1231            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1232            0 :                     if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatOnly) {
    1233            0 :                         ShowContinueError(state,
    1234              :                                           "When a draw through fan is specified, the heating coil inlet node name must be the same as the furnace "
    1235              :                                           "inlet node name.");
    1236            0 :                         ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    1237            0 :                         ShowContinueError(
    1238            0 :                             state, format("...Furnace inlet node name      = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    1239              :                     } else {
    1240            0 :                         ShowContinueError(state,
    1241              :                                           "When a draw through fan is specified, the heating coil inlet node name must be the same as the unitary "
    1242              :                                           "system inlet node name.");
    1243            0 :                         ShowContinueError(state, format("...Heating coil inlet node name  = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    1244            0 :                         ShowContinueError(
    1245            0 :                             state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    1246              :                     }
    1247            0 :                     ErrorsFound = true;
    1248              :                 }
    1249              :                 // Heating coil outlet node name must be the same as the fan inlet node name
    1250            0 :                 if (HeatingCoilOutletNode != FanInletNode) {
    1251            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1252            0 :                     ShowContinueError(
    1253              :                         state,
    1254              :                         "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan inlet node name.");
    1255            0 :                     ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    1256            0 :                     ShowContinueError(state, format("...Fan inlet node name           = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    1257            0 :                     ErrorsFound = true;
    1258              :                 }
    1259              :                 // Fan coil outlet node name must be the same as the furnace outlet node name
    1260            0 :                 if (FanOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    1261            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1262            0 :                     if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatOnly) {
    1263            0 :                         ShowContinueError(
    1264              :                             state,
    1265              :                             "When a draw through fan is specified, the fan outlet node name must be the same as the furnace outlet node name.");
    1266            0 :                         ShowContinueError(state, format("...Fan outlet node name     = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    1267            0 :                         ShowContinueError(state,
    1268            0 :                                           format("...Furnace outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    1269              :                     } else {
    1270            0 :                         ShowContinueError(state,
    1271              :                                           "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
    1272              :                                           "outlet node name.");
    1273            0 :                         ShowContinueError(state, format("...Fan outlet node name           = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    1274            0 :                         ShowContinueError(
    1275            0 :                             state, format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    1276              :                     }
    1277            0 :                     ErrorsFound = true;
    1278              :                 }
    1279              :             }
    1280              : 
    1281              :             // Add fan to component sets array
    1282            0 :             BranchNodeConnections::SetUpCompSets(
    1283            0 :                 state, CurrentModuleObject, thisFurnace.Name, Alphas(7), Alphas(8), CompSetFanInlet, CompSetFanOutlet);
    1284              :             // Add heating coil to component sets array
    1285            0 :             BranchNodeConnections::SetUpCompSets(
    1286            0 :                 state, CurrentModuleObject, thisFurnace.Name, Alphas(10), Alphas(11), CompSetHeatInlet, CompSetHeatOutlet);
    1287              : 
    1288              :             // Set the furnace max outlet temperature
    1289            0 :             thisFurnace.DesignMaxOutletTemp = Numbers(1);
    1290              : 
    1291              :             // Set the furnace design fan volumetric flow rate
    1292            0 :             thisFurnace.DesignFanVolFlowRate = Numbers(2);
    1293              : 
    1294              :             // Compare the flow rates.
    1295            0 :             if (thisFurnace.ActualFanVolFlowRate != DataSizing::AutoSize && thisFurnace.DesignFanVolFlowRate != DataSizing::AutoSize) {
    1296            0 :                 if (thisFurnace.DesignFanVolFlowRate > thisFurnace.ActualFanVolFlowRate) {
    1297            0 :                     ShowWarningError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1298            0 :                     ShowContinueError(
    1299            0 :                         state, format("... The {} > Max Volume Flow Rate defined in the associated fan object, should be <=.", cNumericFields(2)));
    1300            0 :                     ShowContinueError(state,
    1301            0 :                                       format("... Entered value = {:.4R}... Fan [{} = {}] Max Value = {:.4R}",
    1302            0 :                                              thisFurnace.DesignFanVolFlowRate,
    1303            0 :                                              HVAC::fanTypeNames[(int)thisFurnace.fanType],
    1304              :                                              FanName,
    1305            0 :                                              thisFurnace.ActualFanVolFlowRate));
    1306            0 :                     ShowContinueError(state, " The HVAC system  flow rate is reset to the fan flow rate and the simulation continues.");
    1307            0 :                     thisFurnace.DesignFanVolFlowRate = thisFurnace.ActualFanVolFlowRate;
    1308              :                 }
    1309              :             }
    1310            0 :             if (thisFurnace.DesignFanVolFlowRate != DataSizing::AutoSize) {
    1311            0 :                 if (thisFurnace.DesignFanVolFlowRate <= 0.0) {
    1312            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1313            0 :                     ShowContinueError(state, format("... The {} <= 0.0, it must be > 0.0.", cNumericFields(2)));
    1314            0 :                     ShowContinueError(state, format("... Entered value = {:.2R}", thisFurnace.DesignFanVolFlowRate));
    1315            0 :                     ErrorsFound = true;
    1316              :                 }
    1317              :             }
    1318              : 
    1319              :             //       HeatOnly furnace has only 1 flow rate, initialize other variables used in this module
    1320            0 :             thisFurnace.MaxHeatAirVolFlow = thisFurnace.DesignFanVolFlowRate;
    1321            0 :             thisFurnace.MaxCoolAirVolFlow = thisFurnace.DesignFanVolFlowRate;
    1322            0 :             thisFurnace.MaxNoCoolHeatAirVolFlow = thisFurnace.DesignFanVolFlowRate;
    1323            0 :             thisFurnace.AirFlowControl = AirFlowControlConstFan::UseCompressorOnFlow;
    1324              : 
    1325              :             // Set heating convergence tolerance
    1326            0 :             thisFurnace.HeatingConvergenceTolerance = 0.001;
    1327              : 
    1328              :             // set minimum outdoor temperature for compressor operation
    1329            0 :             SetMinOATCompressor(state, FurnaceNum, cCurrentModuleObject, ErrorsFound);
    1330              : 
    1331              :         } // End of the HeatOnly Furnace Loop
    1332              : 
    1333              :         // Get the data for the HeatCool Furnace or UnitarySystem
    1334            2 :         for (int HeatCoolNum = 1; HeatCoolNum <= NumHeatCool + NumUnitaryHeatCool; ++HeatCoolNum) {
    1335              : 
    1336            0 :             FanInletNode = 0;
    1337            0 :             FanOutletNode = 0;
    1338            0 :             CoolingCoilInletNode = 0;
    1339            0 :             CoolingCoilOutletNode = 0;
    1340            0 :             HeatingCoilInletNode = 0;
    1341            0 :             HeatingCoilOutletNode = 0;
    1342            0 :             int ReheatCoilInletNode = 0;
    1343            0 :             int ReheatCoilOutletNode = 0;
    1344            0 :             CoolingCoilType = ' ';
    1345            0 :             CoolingCoilName = ' ';
    1346            0 :             HeatingCoilType = ' ';
    1347            0 :             HeatingCoilName = ' ';
    1348              : 
    1349            0 :             FurnaceNum = HeatCoolNum + NumHeatOnly + NumUnitaryHeatOnly;
    1350            0 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    1351              : 
    1352              :             //      Furnace and UnitarySystem objects are both read in here.
    1353              :             //      Will still have 2 differently named objects for the user, but read in with 1 DO loop.
    1354            0 :             if (HeatCoolNum <= NumHeatCool) {
    1355            0 :                 CurrentModuleObject = "AirLoopHVAC:Unitary:Furnace:HeatCool";
    1356            0 :                 currentModuleObjectType = DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryFurnaceHeatCool;
    1357            0 :                 thisFurnace.type = HVAC::UnitarySysType::Furnace_HeatCool;
    1358            0 :                 GetObjectNum = HeatCoolNum;
    1359              :             } else {
    1360            0 :                 CurrentModuleObject = "AirLoopHVAC:UnitaryHeatCool";
    1361            0 :                 currentModuleObjectType = DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCool;
    1362            0 :                 thisFurnace.type = HVAC::UnitarySysType::Unitary_HeatCool;
    1363            0 :                 GetObjectNum = HeatCoolNum - NumHeatCool;
    1364              :             }
    1365              : 
    1366            0 :             thisFurnace.iterationMode.allocate(3);
    1367              : 
    1368            0 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1369              :                                                                      CurrentModuleObject,
    1370              :                                                                      GetObjectNum,
    1371              :                                                                      Alphas,
    1372              :                                                                      NumAlphas,
    1373              :                                                                      Numbers,
    1374              :                                                                      NumNumbers,
    1375              :                                                                      IOStatus,
    1376              :                                                                      lNumericBlanks,
    1377              :                                                                      lAlphaBlanks,
    1378              :                                                                      cAlphaFields,
    1379              :                                                                      cNumericFields);
    1380              : 
    1381            0 :             GlobalNames::VerifyUniqueInterObjectName(
    1382            0 :                 state, state.dataFurnaces->UniqueFurnaceNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    1383              : 
    1384            0 :             thisFurnace.Name = Alphas(1);
    1385              : 
    1386            0 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, thisFurnace.Name};
    1387              : 
    1388            0 :             if (lAlphaBlanks(2)) {
    1389            0 :                 thisFurnace.availSched = Sched::GetScheduleAlwaysOn(state);
    1390            0 :             } else if ((thisFurnace.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    1391            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    1392            0 :                 ErrorsFound = true;
    1393              :             }
    1394              : 
    1395            0 :             thisFurnace.FurnaceInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
    1396            0 :                                                                                   Alphas(3),
    1397              :                                                                                   ErrorsFound,
    1398              :                                                                                   currentModuleObjectType,
    1399            0 :                                                                                   Alphas(1),
    1400              :                                                                                   DataLoopNode::NodeFluidType::Air,
    1401              :                                                                                   DataLoopNode::ConnectionType::Inlet,
    1402              :                                                                                   NodeInputManager::CompFluidStream::Primary,
    1403              :                                                                                   DataLoopNode::ObjectIsParent);
    1404            0 :             thisFurnace.FurnaceOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
    1405            0 :                                                                                    Alphas(4),
    1406              :                                                                                    ErrorsFound,
    1407              :                                                                                    currentModuleObjectType,
    1408            0 :                                                                                    Alphas(1),
    1409              :                                                                                    DataLoopNode::NodeFluidType::Air,
    1410              :                                                                                    DataLoopNode::ConnectionType::Outlet,
    1411              :                                                                                    NodeInputManager::CompFluidStream::Primary,
    1412              :                                                                                    DataLoopNode::ObjectIsParent);
    1413              : 
    1414            0 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    1415              : 
    1416            0 :             if (lAlphaBlanks(5)) {
    1417            0 :                 thisFurnace.fanOp = HVAC::FanOp::Cycling;
    1418            0 :             } else if ((thisFurnace.fanOpModeSched = Sched::GetSchedule(state, Alphas(5))) == nullptr) {
    1419            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(5), Alphas(5));
    1420            0 :                 ErrorsFound = true;
    1421              :             }
    1422              : 
    1423              :             // Get the Controlling Zone or Location of the Furnace Thermostat
    1424            0 :             thisFurnace.ControlZoneNum = Util::FindItemInList(Alphas(6), state.dataHeatBal->Zone);
    1425            0 :             if (thisFurnace.ControlZoneNum == 0) {
    1426            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1427            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(6), Alphas(6)));
    1428            0 :                 ErrorsFound = true;
    1429              :             }
    1430              : 
    1431              :             // Get the node number for the zone with the thermostat
    1432            0 :             if (thisFurnace.ControlZoneNum > 0) {
    1433            0 :                 AirNodeFound = false;
    1434            0 :                 AirLoopFound = false;
    1435            0 :                 int ControlledZoneNum = thisFurnace.ControlZoneNum;
    1436              :                 //             Find the controlled zone number for the specified thermostat location
    1437            0 :                 thisFurnace.NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
    1438              :                 //             Determine if system is on air loop served by the thermostat location specified
    1439            0 :                 for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    1440            0 :                     int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
    1441            0 :                     if (AirLoopNumber > 0) {
    1442            0 :                         for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
    1443            0 :                             for (int CompNum = 1;
    1444            0 :                                  CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
    1445              :                                  ++CompNum) {
    1446            0 :                                 if (!Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name,
    1447            0 :                                                       Alphas(1)) ||
    1448            0 :                                     !Util::SameString(
    1449            0 :                                         state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
    1450              :                                         CurrentModuleObject)) {
    1451            0 :                                     continue;
    1452              :                                 }
    1453            0 :                                 AirLoopFound = true;
    1454            0 :                                 thisFurnace.ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
    1455            0 :                                 break;
    1456              :                             }
    1457            0 :                             if (AirLoopFound) {
    1458            0 :                                 break;
    1459              :                             }
    1460              :                         }
    1461            0 :                         for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
    1462            0 :                             if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    1463            0 :                                 continue;
    1464              :                             }
    1465            0 :                             AirNodeFound = true;
    1466              :                         }
    1467            0 :                         for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
    1468            0 :                             if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    1469            0 :                                 continue;
    1470              :                             }
    1471            0 :                             AirNodeFound = true;
    1472              :                         }
    1473              :                     }
    1474            0 :                     if (AirLoopFound) {
    1475            0 :                         break;
    1476              :                     }
    1477              :                 }
    1478            0 :                 if (!AirNodeFound) {
    1479            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1480            0 :                     ShowContinueError(state, "Did not find air node (zone with thermostat).");
    1481            0 :                     ShowContinueError(state, format("Specified {} = {}", cAlphaFields(6), Alphas(6)));
    1482            0 :                     ShowContinueError(
    1483              :                         state, "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
    1484            0 :                     ErrorsFound = true;
    1485              :                 }
    1486            0 :                 if (!AirLoopFound) {
    1487            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1488            0 :                     ShowContinueError(state, "Did not find correct AirLoopHVAC.");
    1489            0 :                     ShowContinueError(state, format("Specified {} = {}", cAlphaFields(6), Alphas(6)));
    1490            0 :                     ErrorsFound = true;
    1491              :                 }
    1492              :             }
    1493              : 
    1494              :             // Get fan data
    1495            0 :             FanName = Alphas(8);
    1496              : 
    1497            0 :             thisFurnace.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(7)));
    1498              : 
    1499            0 :             if (thisFurnace.fanType != HVAC::FanType::OnOff && thisFurnace.fanType != HVAC::FanType::Constant) {
    1500            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1501            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(7), Alphas(7)));
    1502            0 :                 ErrorsFound = true;
    1503              : 
    1504            0 :             } else if ((thisFurnace.FanIndex = Fans::GetFanIndex(state, FanName)) == 0) {
    1505            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(8), FanName);
    1506            0 :                 ErrorsFound = true;
    1507              : 
    1508              :             } else {
    1509            0 :                 auto *fan = state.dataFans->fans(thisFurnace.FanIndex);
    1510            0 :                 thisFurnace.ActualFanVolFlowRate = fan->maxAirFlowRate;
    1511            0 :                 FanInletNode = fan->inletNodeNum;
    1512            0 :                 FanOutletNode = fan->outletNodeNum;
    1513            0 :                 thisFurnace.fanAvailSched = fan->availSched;
    1514              : 
    1515              :                 // Check fan's schedule for cycling fan operation if constant volume fan is used
    1516            0 :                 if (thisFurnace.fanOpModeSched != nullptr && thisFurnace.fanType == HVAC::FanType::Constant) {
    1517            0 :                     if (!thisFurnace.fanOpModeSched->checkMinMaxVals(state, Clusive::Ex, 0.0, Clusive::In, 1.0)) {
    1518            0 :                         Sched::ShowSevereBadMinMax(
    1519              :                             state,
    1520              :                             eoh,
    1521            0 :                             cAlphaFields(5),
    1522            0 :                             Alphas(5),
    1523              :                             Clusive::In,
    1524              :                             0.0,
    1525              :                             Clusive::In,
    1526              :                             1.0,
    1527            0 :                             format("For {} = {}, fan operating mode must be continuous (schedule values > 0)", cAlphaFields(7), Alphas(7)));
    1528            0 :                         ErrorsFound = true;
    1529              :                     }
    1530            0 :                 } else if (lAlphaBlanks(5) && thisFurnace.fanType != HVAC::FanType::OnOff) {
    1531            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisFurnace.Name));
    1532            0 :                     ShowContinueError(state, format("{} = {}", cAlphaFields(7), Alphas(7)));
    1533            0 :                     ShowContinueError(state, format("Fan type must be Fan:OnOff when {} = Blank.", cAlphaFields(5)));
    1534            0 :                     ErrorsFound = true;
    1535              :                 }
    1536              :             }
    1537              : 
    1538            0 :             thisFurnace.fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Alphas(9)));
    1539            0 :             assert(thisFurnace.fanPlace != HVAC::FanPlace::Invalid);
    1540              : 
    1541              :             // Get coil data
    1542            0 :             HeatingCoilType = Alphas(10);
    1543            0 :             HeatingCoilName = Alphas(11);
    1544            0 :             HeatingCoilPLFCurveIndex = 0;
    1545            0 :             thisFurnace.HeatingCoilType = HeatingCoilType;
    1546            0 :             thisFurnace.HeatingCoilName = HeatingCoilName;
    1547            0 :             if (Util::SameString(HeatingCoilType, "Coil:Heating:Fuel") || Util::SameString(HeatingCoilType, "Coil:Heating:Electric")) {
    1548            0 :                 errFlag = false;
    1549            0 :                 thisFurnace.HeatingCoilType_Num = HeatingCoils::GetHeatingCoilTypeNum(state, HeatingCoilType, HeatingCoilName, errFlag);
    1550            0 :                 if (errFlag) {
    1551            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1552            0 :                     ErrorsFound = true;
    1553              :                 } else {
    1554              : 
    1555            0 :                     ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    1556            0 :                     if (IsNotOK) {
    1557            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1558            0 :                         ErrorsFound = true;
    1559              : 
    1560              :                     } else { // mine data from heating coil
    1561              : 
    1562              :                         // Get heating coil index
    1563            0 :                         errFlag = false;
    1564            0 :                         HeatingCoils::GetCoilIndex(state, HeatingCoilName, thisFurnace.HeatingCoilIndex, errFlag);
    1565            0 :                         if (errFlag) {
    1566            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1567            0 :                             ErrorsFound = true;
    1568              :                         }
    1569              : 
    1570              :                         // Get the design heating capacity
    1571            0 :                         errFlag = false;
    1572            0 :                         thisFurnace.DesignHeatingCapacity = HeatingCoils::GetCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
    1573            0 :                         if (errFlag) {
    1574            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1575            0 :                             ErrorsFound = true;
    1576              :                         }
    1577              : 
    1578              :                         // Get the Heating Coil Inlet Node
    1579            0 :                         errFlag = false;
    1580            0 :                         HeatingCoilInletNode = HeatingCoils::GetCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    1581            0 :                         if (errFlag) {
    1582            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1583            0 :                             ErrorsFound = true;
    1584              :                         }
    1585              : 
    1586              :                         // Get the Heating Coil Outlet Node
    1587            0 :                         errFlag = false;
    1588            0 :                         HeatingCoilOutletNode = HeatingCoils::GetCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    1589            0 :                         if (errFlag) {
    1590            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1591            0 :                             ErrorsFound = true;
    1592              :                         }
    1593              : 
    1594              :                         // Get the Heating Coil PLF Curve Index
    1595            0 :                         errFlag = false;
    1596            0 :                         HeatingCoilPLFCurveIndex = HeatingCoils::GetHeatingCoilPLFCurveIndex(state, HeatingCoilType, HeatingCoilName, errFlag);
    1597            0 :                         if (errFlag) {
    1598            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1599            0 :                             ErrorsFound = true;
    1600              :                         }
    1601              : 
    1602              :                     } // IF (IsNotOK) THEN
    1603              :                 }
    1604              : 
    1605            0 :             } else if (Util::SameString(HeatingCoilType, "Coil:Heating:Water")) {
    1606            0 :                 thisFurnace.HeatingCoilType_Num = HVAC::Coil_HeatingWater;
    1607            0 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    1608            0 :                 if (IsNotOK) {
    1609            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1610            0 :                     ErrorsFound = true;
    1611              :                 } else { // mine data from heating coil object
    1612              : 
    1613              :                     // Get the Heating Coil water Inlet or control Node number
    1614            0 :                     errFlag = false;
    1615            0 :                     thisFurnace.CoilControlNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
    1616            0 :                     if (errFlag) {
    1617            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1618            0 :                         ErrorsFound = true;
    1619              :                     }
    1620              : 
    1621              :                     // Get the Heating Coil hot water max volume flow rate
    1622            0 :                     errFlag = false;
    1623            0 :                     thisFurnace.MaxHeatCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
    1624            0 :                     if (errFlag) {
    1625            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1626            0 :                         ErrorsFound = true;
    1627              :                     }
    1628              : 
    1629              :                     // Get the Heating Coil Inlet Node
    1630            0 :                     errFlag = false;
    1631            0 :                     HeatingCoilInletNode = WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
    1632            0 :                     thisFurnace.HWCoilAirInletNode = HeatingCoilInletNode;
    1633            0 :                     if (errFlag) {
    1634            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1635            0 :                         ErrorsFound = true;
    1636              :                     }
    1637              : 
    1638              :                     // Get the Heating Coil Outlet Node
    1639            0 :                     errFlag = false;
    1640            0 :                     HeatingCoilOutletNode = WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", HeatingCoilName, errFlag);
    1641            0 :                     thisFurnace.HWCoilAirOutletNode = HeatingCoilOutletNode;
    1642            0 :                     if (errFlag) {
    1643            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1644            0 :                         ErrorsFound = true;
    1645              :                     }
    1646              : 
    1647              :                     // check if user has also used a water coil controller, which they should not do
    1648            0 :                     errFlag = false;
    1649            0 :                     HVACControllers::CheckCoilWaterInletNode(state, thisFurnace.CoilControlNode, errFlag);
    1650            0 :                     if (!errFlag) { // then did find a controller so that is bad
    1651            0 :                         ShowSevereError(state,
    1652            0 :                                         format("{} = {} has a conflicting Controller:WaterCoil object", CurrentModuleObject, thisFurnace.Name));
    1653            0 :                         ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
    1654            0 :                         ShowContinueError(state, "No water coil controller should be input for the coil.");
    1655            0 :                         ErrorsFound = true;
    1656              :                     }
    1657              :                 }
    1658              : 
    1659            0 :             } else if (Util::SameString(HeatingCoilType, "Coil:Heating:Steam")) {
    1660            0 :                 thisFurnace.HeatingCoilType_Num = HVAC::Coil_HeatingSteam;
    1661            0 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    1662            0 :                 if (IsNotOK) {
    1663            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1664            0 :                     ErrorsFound = true;
    1665              :                 } else { // mine data from heating coil object
    1666              : 
    1667            0 :                     errFlag = false;
    1668            0 :                     thisFurnace.HeatingCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", HeatingCoilName, errFlag);
    1669            0 :                     if (thisFurnace.HeatingCoilIndex == 0) {
    1670            0 :                         ShowSevereError(state, format("{} illegal {} = {}", CurrentModuleObject, cAlphaFields(11), HeatingCoilName));
    1671            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1672            0 :                         ErrorsFound = true;
    1673              :                     }
    1674              : 
    1675              :                     // Get the Heating Coil steam inlet node number
    1676            0 :                     errFlag = false;
    1677            0 :                     thisFurnace.CoilControlNode = SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", HeatingCoilName, errFlag);
    1678            0 :                     if (errFlag) {
    1679            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1680            0 :                         ErrorsFound = true;
    1681              :                     }
    1682              : 
    1683              :                     // Get the Heating Coil steam max volume flow rate
    1684            0 :                     thisFurnace.MaxHeatCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.HeatingCoilIndex, errFlag);
    1685            0 :                     if (thisFurnace.MaxHeatCoilFluidFlow > 0.0) {
    1686              :                         SteamDensity =
    1687            0 :                             Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, getAirLoopHVACHeatCoolInput);
    1688            0 :                         thisFurnace.MaxHeatCoilFluidFlow *= SteamDensity;
    1689              :                     }
    1690              : 
    1691              :                     // Get the Heating Coil Inlet Node
    1692            0 :                     errFlag = false;
    1693            0 :                     HeatingCoilInletNode = SteamCoils::GetCoilAirInletNode(state, thisFurnace.HeatingCoilIndex, HeatingCoilName, errFlag);
    1694            0 :                     thisFurnace.HWCoilAirInletNode = HeatingCoilInletNode;
    1695            0 :                     if (errFlag) {
    1696            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1697            0 :                         ErrorsFound = true;
    1698              :                     }
    1699              : 
    1700              :                     // Get the Heating Coil Outlet Node
    1701            0 :                     errFlag = false;
    1702            0 :                     HeatingCoilOutletNode = SteamCoils::GetCoilAirOutletNode(state, thisFurnace.HeatingCoilIndex, HeatingCoilName, errFlag);
    1703            0 :                     thisFurnace.HWCoilAirOutletNode = HeatingCoilOutletNode;
    1704            0 :                     if (errFlag) {
    1705            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    1706            0 :                         ErrorsFound = true;
    1707              :                     }
    1708              :                 }
    1709              : 
    1710              :             } else {
    1711            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1712            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(11), Alphas(11)));
    1713            0 :                 ErrorsFound = true;
    1714              :             } // IF (Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
    1715              : 
    1716              :             // Get Cooling Coil Information if available
    1717            0 :             CoolingCoilType = Alphas(12);
    1718            0 :             CoolingCoilName = Alphas(13);
    1719              :             //       Find the type of coil. Do not print message since this may not be the correct coil type.
    1720            0 :             errFlag = false;
    1721            0 :             PrintMessage = false;
    1722              : 
    1723            0 :             if (Util::SameString(CoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED") ||
    1724            0 :                 Util::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
    1725            0 :                 thisFurnace.CoolingCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
    1726            0 :                 if (Util::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
    1727            0 :                     thisFurnace.bIsIHP = true;
    1728              :                 }
    1729              :             } else {
    1730            0 :                 thisFurnace.CoolingCoilType_Num = DXCoils::GetCoilTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, PrintMessage);
    1731              :             }
    1732              : 
    1733              :             // If coil type not found, check to see if a HX assisted cooling coil is used.
    1734            0 :             if (thisFurnace.CoolingCoilType_Num == 0) {
    1735            0 :                 errFlag = false;
    1736            0 :                 thisFurnace.CoolingCoilType_Num =
    1737            0 :                     HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, PrintMessage);
    1738              :             }
    1739              : 
    1740            0 :             if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
    1741            0 :                 ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
    1742            0 :                 if (IsNotOK) {
    1743            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1744            0 :                     ErrorsFound = true;
    1745              : 
    1746              :                 } else { // mine data from DX cooling coil
    1747              : 
    1748              :                     // Get DX cooling coil index
    1749            0 :                     DXCoils::GetDXCoilIndex(state, CoolingCoilName, thisFurnace.CoolingCoilIndex, IsNotOK);
    1750            0 :                     if (IsNotOK) {
    1751            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1752            0 :                         ErrorsFound = true;
    1753              :                     }
    1754              : 
    1755              :                     // Get DX cooling coil capacity
    1756            0 :                     errFlag = false;
    1757            0 :                     thisFurnace.DesignCoolingCapacity = DXCoils::GetCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
    1758            0 :                     if (errFlag) {
    1759            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1760            0 :                         ErrorsFound = true;
    1761              :                     }
    1762              : 
    1763              :                     // Get the Cooling Coil Nodes
    1764            0 :                     errFlag = false;
    1765            0 :                     CoolingCoilInletNode = DXCoils::GetCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    1766            0 :                     CoolingCoilOutletNode = DXCoils::GetCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    1767            0 :                     if (errFlag) {
    1768            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1769            0 :                         ErrorsFound = true;
    1770              :                     }
    1771              : 
    1772              :                     // Get outdoor condenser node from DX coil object
    1773            0 :                     errFlag = false;
    1774            0 :                     if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    1775            0 :                         if (thisFurnace.bIsIHP) {
    1776            0 :                             IHPCoilIndex = IntegratedHeatPump::GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
    1777            0 :                             IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(IHPCoilIndex).SCCoilName;
    1778            0 :                             thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
    1779              :                         } else {
    1780            0 :                             thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
    1781              :                         }
    1782              :                     } else {
    1783            0 :                         thisFurnace.CondenserNodeNum = DXCoils::GetCoilCondenserInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    1784              :                     }
    1785            0 :                     if (errFlag) {
    1786            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1787            0 :                         ErrorsFound = true;
    1788              :                     }
    1789              : 
    1790              :                 } // IF (IsNotOK) THEN
    1791              : 
    1792              :                 // Push heating coil PLF curve index to DX coil
    1793            0 :                 if (HeatingCoilPLFCurveIndex > 0) {
    1794            0 :                     DXCoils::SetDXCoolingCoilData(state, thisFurnace.CoolingCoilIndex, ErrorsFound, HeatingCoilPLFCurveIndex);
    1795              :                 }
    1796              : 
    1797            0 :             } else if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
    1798            0 :                 ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
    1799            0 :                 if (IsNotOK) {
    1800            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1801            0 :                     ErrorsFound = true;
    1802              : 
    1803              :                 } else { // mine data from heat exchanger assisted cooling coil
    1804              : 
    1805              :                     // Get DX heat exchanger assisted cooling coil index
    1806            0 :                     HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, CoolingCoilName, thisFurnace.CoolingCoilIndex, IsNotOK);
    1807            0 :                     if (IsNotOK) {
    1808            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1809            0 :                         ErrorsFound = true;
    1810              :                     }
    1811              : 
    1812              :                     // Get DX cooling coil capacity
    1813            0 :                     errFlag = false;
    1814            0 :                     thisFurnace.DesignCoolingCapacity = HVACHXAssistedCoolingCoil::GetCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
    1815            0 :                     if (errFlag) {
    1816            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1817            0 :                         ErrorsFound = true;
    1818              :                     }
    1819              : 
    1820              :                     // Get the Cooling Coil Nodes
    1821            0 :                     errFlag = false;
    1822            0 :                     CoolingCoilInletNode = HVACHXAssistedCoolingCoil::GetCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    1823            0 :                     CoolingCoilOutletNode = HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    1824            0 :                     if (errFlag) {
    1825            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1826            0 :                         ErrorsFound = true;
    1827              :                     }
    1828              : 
    1829              :                     // Get outdoor condenser node from heat exchanger assisted DX coil object
    1830            0 :                     errFlag = false;
    1831            0 :                     std::string ChildCoolingCoilName = HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, CoolingCoilType, CoolingCoilName, IsNotOK);
    1832            0 :                     std::string ChildCoolingCoilType = HVACHXAssistedCoolingCoil::GetHXDXCoilType(state, CoolingCoilType, CoolingCoilName, IsNotOK);
    1833            0 :                     if (IsNotOK) {
    1834            0 :                         ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, Alphas(1)));
    1835            0 :                         ErrorsFound = true;
    1836              :                     }
    1837              : 
    1838              :                     // if (thisFurnace.CoolingCoilType_Num == CoilDX_CoolingHXAssisted) {
    1839            0 :                     if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
    1840              : 
    1841            0 :                         int childCCIndex = CoilCoolingDX::factory(state, ChildCoolingCoilName);
    1842            0 :                         if (childCCIndex < 0) {
    1843            0 :                             ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, Alphas(1)));
    1844            0 :                             errFlag = true;
    1845            0 :                             ErrorsFound = true;
    1846              :                         }
    1847            0 :                         auto const &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
    1848              : 
    1849            0 :                         thisFurnace.CondenserNodeNum = newCoil.condInletNodeIndex;
    1850              : 
    1851              :                     }
    1852              :                     // else if (thisFurnace.CoolingCoilType_Num == Coil_CoolingAirToAirVariableSpeed) {
    1853            0 :                     else if (Util::SameString(ChildCoolingCoilType, "Coil:Cooling:DX:VariableSpeed")) {
    1854            0 :                         if (thisFurnace.bIsIHP) {
    1855            0 :                             IHPCoilIndex = IntegratedHeatPump::GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
    1856            0 :                             IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(IHPCoilIndex).SCCoilName;
    1857            0 :                             thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
    1858              :                         } else {
    1859            0 :                             thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
    1860              :                         }
    1861              :                     } else {
    1862            0 :                         thisFurnace.CondenserNodeNum = DXCoils::GetCoilCondenserInletNode(
    1863              :                             state,
    1864              :                             "COIL:COOLING:DX:SINGLESPEED",
    1865            0 :                             HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, CoolingCoilType, CoolingCoilName, errFlag),
    1866              :                             errFlag);
    1867              :                     }
    1868              : 
    1869            0 :                     if (errFlag) {
    1870            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1871            0 :                         ErrorsFound = true;
    1872              :                     }
    1873              : 
    1874              :                     // Push heating coil PLF curve index to DX coil
    1875            0 :                     if (HeatingCoilPLFCurveIndex > 0) {
    1876              :                         // get the actual index to the DX cooling coil object
    1877            0 :                         DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
    1878            0 :                         thisFurnace.ActualDXCoilIndexForHXAssisted = DXCoilIndex;
    1879              :                         int ActualCoolCoilType =
    1880            0 :                             HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, true);
    1881            0 :                         if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
    1882            0 :                             DXCoils::SetDXCoolingCoilData(state, DXCoilIndex, ErrorsFound, HeatingCoilPLFCurveIndex);
    1883              :                         }
    1884              :                         // what could we do for VS coil here? odd thing here
    1885              :                     }
    1886              : 
    1887            0 :                 } // IF (IsNotOK) THEN
    1888            0 :             } else if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    1889              :                 // BOS ADDED, AUG/2012, VARIIABLE SPEED DX COOLING COIL
    1890              :                 //  Furnace(FurnaceNum)%DXCoolCoilType = 'COIL:COOLING:DX:VARIABLESPEED'
    1891              :                 //  Furnace(FurnaceNum)%DXCoolCoilName = CoolingCoilName
    1892            0 :                 if (Util::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
    1893            0 :                     thisFurnace.bIsIHP = true;
    1894              :                 }
    1895            0 :                 ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
    1896              : 
    1897            0 :                 if (IsNotOK) {
    1898            0 :                     ShowContinueError(state, format("...specified in {}=\"{}\".", CurrentModuleObject, Alphas(1)));
    1899            0 :                     ErrorsFound = true;
    1900              :                 } else {
    1901            0 :                     errFlag = false;
    1902            0 :                     if (thisFurnace.bIsIHP) {
    1903            0 :                         thisFurnace.CoolingCoilIndex = IntegratedHeatPump::GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
    1904            0 :                         IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilName;
    1905              :                     } else {
    1906            0 :                         thisFurnace.CoolingCoilIndex =
    1907            0 :                             VariableSpeedCoils::GetCoilIndexVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    1908            0 :                         IHPCoilName = CoolingCoilName;
    1909              :                     }
    1910              : 
    1911            0 :                     if (errFlag) {
    1912            0 :                         ShowContinueError(state, format("...specified in {}=\"{}\".", CurrentModuleObject, Alphas(1)));
    1913            0 :                         ErrorsFound = true;
    1914              :                     }
    1915              : 
    1916            0 :                     if (thisFurnace.bIsIHP) {
    1917              :                         CoolingCoilInletNode =
    1918            0 :                             VariableSpeedCoils::GetCoilInletNodeVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    1919              :                         CoolingCoilOutletNode =
    1920            0 :                             VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    1921            0 :                         thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
    1922              :                     } else {
    1923            0 :                         CoolingCoilInletNode = VariableSpeedCoils::GetCoilInletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    1924            0 :                         CoolingCoilOutletNode = VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    1925            0 :                         thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
    1926              :                     }
    1927              : 
    1928            0 :                     if (errFlag) {
    1929            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    1930            0 :                         ErrorsFound = true;
    1931              :                     }
    1932              :                 }
    1933              :             } else {
    1934            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1935            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(12), Alphas(12)));
    1936            0 :                 ErrorsFound = true;
    1937              :             }
    1938              : 
    1939            0 :             if (Util::SameString(Alphas(14), "None") || Util::SameString(Alphas(14), "Multimode") || Util::SameString(Alphas(14), "CoolReheat")) {
    1940            0 :                 AirNodeFound = false;
    1941            0 :                 if (Util::SameString(Alphas(14), "Multimode")) {
    1942            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::Multimode;
    1943            0 :                     thisFurnace.Humidistat = true;
    1944            0 :                     if (thisFurnace.CoolingCoilType_Num != HVAC::CoilDX_CoolingHXAssisted) {
    1945            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1946            0 :                         ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(14), Alphas(14)));
    1947            0 :                         ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted Cooling Coil.");
    1948            0 :                         if (lAlphaBlanks(15)) {
    1949            0 :                             ShowContinueError(state,
    1950              :                                               "Dehumidification control type is assumed to be None since a reheat coil has not been specified and "
    1951              :                                               "the simulation continues.");
    1952            0 :                             thisFurnace.Humidistat = false;
    1953            0 :                             thisFurnace.DehumidControlType_Num = DehumidificationControlMode::None;
    1954              :                         } else {
    1955            0 :                             ShowContinueError(state, "Dehumidification control type is assumed to be CoolReheat and the simulation continues.");
    1956            0 :                             thisFurnace.DehumidControlType_Num = DehumidificationControlMode::CoolReheat;
    1957              :                         }
    1958              :                     }
    1959              :                 }
    1960            0 :                 if (Util::SameString(Alphas(14), "CoolReheat")) {
    1961            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::CoolReheat;
    1962            0 :                     thisFurnace.Humidistat = true;
    1963            0 :                     if (lAlphaBlanks(15)) {
    1964            0 :                         ShowWarningError(state, format("{} \"{}\"", CurrentModuleObject, Alphas(1)));
    1965            0 :                         ShowContinueError(state,
    1966              :                                           "Dehumidification control type is assumed to be None since a reheat coil has not been specified and the "
    1967              :                                           "simulation continues.");
    1968            0 :                         thisFurnace.Humidistat = false;
    1969            0 :                         thisFurnace.DehumidControlType_Num = DehumidificationControlMode::None;
    1970              :                     }
    1971              :                 }
    1972            0 :                 if (Util::SameString(Alphas(14), "None")) {
    1973            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::None;
    1974            0 :                     thisFurnace.Humidistat = false;
    1975              :                 }
    1976            0 :                 if (thisFurnace.Humidistat) {
    1977            0 :                     for (HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
    1978            0 :                         if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    1979            0 :                             continue;
    1980              :                         }
    1981            0 :                         AirNodeFound = true;
    1982              :                     }
    1983            0 :                     if (!AirNodeFound) {
    1984            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1985            0 :                         ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
    1986            0 :                         ShowContinueError(state, format("Specified {} = {}", cAlphaFields(6), Alphas(6)));
    1987            0 :                         ErrorsFound = true;
    1988              :                     }
    1989              :                 }
    1990              :             } else { // invalid input
    1991            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    1992            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(14), Alphas(14)));
    1993            0 :                 thisFurnace.Humidistat = false;
    1994            0 :                 ErrorsFound = true;
    1995              :             }
    1996              : 
    1997              :             //       Check placement of cooling coil with respect to fan placement and dehumidification control type
    1998            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    1999            0 :                 if (FanOutletNode == HeatingCoilInletNode && thisFurnace.DehumidControlType_Num != DehumidificationControlMode::CoolReheat) {
    2000            0 :                     thisFurnace.CoolingCoilUpstream = false;
    2001              :                 }
    2002              :             } else {
    2003            0 :                 if (HeatingCoilOutletNode == CoolingCoilInletNode && thisFurnace.DehumidControlType_Num != DehumidificationControlMode::CoolReheat) {
    2004            0 :                     thisFurnace.CoolingCoilUpstream = false;
    2005              :                 }
    2006              :             }
    2007              : 
    2008              :             // Get reheat coil data if humidistat is used
    2009            0 :             ReheatingCoilType = Alphas(15);
    2010            0 :             ReheatingCoilName = Alphas(16);
    2011            0 :             thisFurnace.SuppHeatCoilType = ReheatingCoilType;
    2012            0 :             thisFurnace.SuppHeatCoilName = ReheatingCoilName;
    2013            0 :             errFlag = false;
    2014            0 :             if (!lAlphaBlanks(15)) {
    2015            0 :                 if (Util::SameString(ReheatingCoilType, "Coil:Heating:Fuel") || Util::SameString(ReheatingCoilType, "Coil:Heating:Electric") ||
    2016            0 :                     Util::SameString(ReheatingCoilType, "Coil:Heating:Desuperheater")) {
    2017              : 
    2018            0 :                     thisFurnace.SuppHeatCoilType_Num = HeatingCoils::GetHeatingCoilTypeNum(state, ReheatingCoilType, ReheatingCoilName, errFlag);
    2019            0 :                     if (errFlag) {
    2020            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2021            0 :                         ErrorsFound = true;
    2022              :                     } else {
    2023              : 
    2024            0 :                         ValidateComponent(state, ReheatingCoilType, ReheatingCoilName, IsNotOK, CurrentModuleObject);
    2025            0 :                         if (IsNotOK) {
    2026            0 :                             ShowContinueError(state, format("In {} \"{}\"", CurrentModuleObject, Alphas(1)));
    2027            0 :                             ErrorsFound = true;
    2028              : 
    2029              :                         } else { // mine data from reheat coil
    2030              : 
    2031              :                             // Get the heating coil index
    2032            0 :                             HeatingCoils::GetCoilIndex(state, ReheatingCoilName, thisFurnace.SuppHeatCoilIndex, IsNotOK);
    2033            0 :                             if (IsNotOK) {
    2034            0 :                                 ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2035            0 :                                 ErrorsFound = true;
    2036              :                             }
    2037              : 
    2038              :                             // Get the design supplemental heating capacity
    2039            0 :                             errFlag = false;
    2040            0 :                             thisFurnace.DesignSuppHeatingCapacity =
    2041            0 :                                 HeatingCoils::GetCoilCapacity(state, ReheatingCoilType, ReheatingCoilName, errFlag);
    2042            0 :                             if (errFlag) {
    2043            0 :                                 ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2044            0 :                                 ErrorsFound = true;
    2045              :                             }
    2046              : 
    2047              :                             // Get the Reheat Coil Inlet Node
    2048            0 :                             errFlag = false;
    2049            0 :                             ReheatCoilInletNode = HeatingCoils::GetCoilInletNode(state, ReheatingCoilType, ReheatingCoilName, errFlag);
    2050            0 :                             if (errFlag) {
    2051            0 :                                 ShowContinueError(state, format("...occurs in {} \"{}\"", CurrentModuleObject, Alphas(1)));
    2052            0 :                                 ErrorsFound = true;
    2053              :                             }
    2054              : 
    2055              :                             // Get the Reheat Coil Outlet Node
    2056            0 :                             errFlag = false;
    2057            0 :                             ReheatCoilOutletNode = HeatingCoils::GetCoilOutletNode(state, ReheatingCoilType, ReheatingCoilName, errFlag);
    2058            0 :                             if (errFlag) {
    2059            0 :                                 ShowContinueError(state, format("...occurs in {} \"{}\"", CurrentModuleObject, Alphas(1)));
    2060            0 :                                 ErrorsFound = true;
    2061              :                             }
    2062              : 
    2063              :                         } // IF (IsNotOK) THEN
    2064              :                     }
    2065              : 
    2066            0 :                 } else if (Util::SameString(ReheatingCoilType, "Coil:Heating:Water")) {
    2067            0 :                     thisFurnace.SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
    2068            0 :                     ValidateComponent(state, ReheatingCoilType, ReheatingCoilName, IsNotOK, CurrentModuleObject);
    2069            0 :                     if (IsNotOK) {
    2070            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2071            0 :                         ErrorsFound = true;
    2072              :                     } else { // mine data from heating coil object
    2073              : 
    2074              :                         // Get the Heating Coil water Inlet or control Node number
    2075            0 :                         errFlag = false;
    2076            0 :                         thisFurnace.SuppCoilControlNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", ReheatingCoilName, errFlag);
    2077            0 :                         if (errFlag) {
    2078            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    2079            0 :                             ErrorsFound = true;
    2080              :                         }
    2081              : 
    2082              :                         // Get the ReHeat Coil hot water max volume flow rate
    2083            0 :                         errFlag = false;
    2084            0 :                         thisFurnace.MaxSuppCoilFluidFlow =
    2085            0 :                             WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", ReheatingCoilName, errFlag);
    2086            0 :                         if (errFlag) {
    2087            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    2088            0 :                             ErrorsFound = true;
    2089              :                         }
    2090              : 
    2091              :                         // Get the ReHeat Coil Inlet Node
    2092            0 :                         errFlag = false;
    2093            0 :                         ReheatCoilInletNode = WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", ReheatingCoilName, errFlag);
    2094            0 :                         thisFurnace.SuppCoilAirInletNode = ReheatCoilInletNode;
    2095            0 :                         if (errFlag) {
    2096            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    2097            0 :                             ErrorsFound = true;
    2098              :                         }
    2099              : 
    2100              :                         // Get the ReHeat Coil Outlet Node
    2101            0 :                         errFlag = false;
    2102            0 :                         ReheatCoilOutletNode = WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", ReheatingCoilName, errFlag);
    2103            0 :                         thisFurnace.SuppCoilAirOutletNode = ReheatCoilOutletNode;
    2104            0 :                         if (errFlag) {
    2105            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    2106            0 :                             ErrorsFound = true;
    2107              :                         }
    2108              : 
    2109              :                         // check if user has also used a water coil controller, which they should not do
    2110            0 :                         errFlag = false;
    2111            0 :                         HVACControllers::CheckCoilWaterInletNode(state, thisFurnace.CoilControlNode, errFlag);
    2112            0 :                         if (!errFlag) { // then did find a controller so that is bad
    2113            0 :                             ShowSevereError(state,
    2114            0 :                                             format("{} = {} has a conflicting Controller:WaterCoil object", CurrentModuleObject, thisFurnace.Name));
    2115            0 :                             ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
    2116            0 :                             ShowContinueError(state, "No water coil controller should be input for the coil.");
    2117            0 :                             ErrorsFound = true;
    2118              :                         }
    2119              :                     }
    2120              : 
    2121            0 :                 } else if (Util::SameString(ReheatingCoilType, "Coil:Heating:Steam")) {
    2122            0 :                     thisFurnace.SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
    2123            0 :                     ValidateComponent(state, ReheatingCoilType, ReheatingCoilName, IsNotOK, CurrentModuleObject);
    2124            0 :                     if (IsNotOK) {
    2125            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2126            0 :                         ErrorsFound = true;
    2127              :                     } else { // mine data from heating coil object
    2128              : 
    2129            0 :                         errFlag = false;
    2130            0 :                         thisFurnace.SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", ReheatingCoilName, errFlag);
    2131            0 :                         if (thisFurnace.SuppHeatCoilIndex == 0) {
    2132            0 :                             ShowSevereError(state, format("{} illegal {} = {}", CurrentModuleObject, cAlphaFields(11), ReheatingCoilName));
    2133            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    2134            0 :                             ErrorsFound = true;
    2135              :                         }
    2136              : 
    2137              :                         // Get the Heating Coil steam inlet node number
    2138            0 :                         errFlag = false;
    2139            0 :                         thisFurnace.SuppCoilControlNode = SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", ReheatingCoilName, errFlag);
    2140            0 :                         if (errFlag) {
    2141            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    2142            0 :                             ErrorsFound = true;
    2143              :                         }
    2144              : 
    2145              :                         // Get the Heating Coil steam max volume flow rate
    2146            0 :                         thisFurnace.MaxSuppCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.SuppHeatCoilIndex, errFlag);
    2147            0 :                         if (thisFurnace.MaxSuppCoilFluidFlow > 0.0) {
    2148              :                             SteamDensity =
    2149            0 :                                 Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, getAirLoopHVACHeatCoolInput);
    2150            0 :                             thisFurnace.MaxSuppCoilFluidFlow =
    2151            0 :                                 SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.SuppHeatCoilIndex, errFlag) * SteamDensity;
    2152              :                         }
    2153              : 
    2154              :                         // Get the Heating Coil Inlet Node
    2155            0 :                         errFlag = false;
    2156            0 :                         ReheatCoilInletNode = SteamCoils::GetCoilAirInletNode(state, thisFurnace.SuppHeatCoilIndex, ReheatingCoilName, errFlag);
    2157            0 :                         thisFurnace.SuppCoilAirInletNode = ReheatCoilInletNode;
    2158            0 :                         if (errFlag) {
    2159            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    2160            0 :                             ErrorsFound = true;
    2161              :                         }
    2162              : 
    2163              :                         // Get the Heating Coil Outlet Node
    2164            0 :                         errFlag = false;
    2165            0 :                         ReheatCoilOutletNode = SteamCoils::GetCoilAirOutletNode(state, thisFurnace.SuppHeatCoilIndex, ReheatingCoilName, errFlag);
    2166            0 :                         thisFurnace.SuppCoilAirOutletNode = ReheatCoilOutletNode;
    2167            0 :                         if (errFlag) {
    2168            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    2169            0 :                             ErrorsFound = true;
    2170              :                         }
    2171              :                     }
    2172              : 
    2173              :                 } else { // Illegal heating coil
    2174            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2175            0 :                     ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(15), Alphas(15)));
    2176            0 :                     ErrorsFound = true;
    2177              :                 } // IF (Furnace(FurnaceNum)%SuppHeatCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
    2178              : 
    2179              :             } // IF(.NOT. lAlphaBlanks(15))THEN
    2180              : 
    2181            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    2182              : 
    2183            0 :                 if (FanInletNode != thisFurnace.FurnaceInletNodeNum) {
    2184            0 :                     ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2185            0 :                     if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatCool) {
    2186            0 :                         ShowContinueError(
    2187              :                             state, "When a blow through fan is specified, the fan inlet node name must be the same as the furnace inlet node name.");
    2188            0 :                         ShowContinueError(state, format("...Fan inlet node name     = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    2189            0 :                         ShowContinueError(state,
    2190            0 :                                           format("...Furnace inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    2191              :                     } else {
    2192            0 :                         ShowContinueError(
    2193              :                             state,
    2194              :                             "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system inlet node name.");
    2195            0 :                         ShowContinueError(state, format("...Fan inlet node name           = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    2196            0 :                         ShowContinueError(
    2197            0 :                             state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    2198              :                     }
    2199            0 :                     ErrorsFound = true;
    2200              :                 }
    2201            0 :                 if (thisFurnace.CoolingCoilUpstream) {
    2202            0 :                     if (FanOutletNode != CoolingCoilInletNode) {
    2203            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2204            0 :                         ShowContinueError(
    2205              :                             state,
    2206              :                             "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil inlet node name.");
    2207            0 :                         ShowContinueError(state, format("...Fan outlet node name         = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    2208            0 :                         ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    2209            0 :                         ErrorsFound = true;
    2210              :                     }
    2211            0 :                     if (CoolingCoilOutletNode != HeatingCoilInletNode) {
    2212            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2213            0 :                         ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
    2214            0 :                         ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    2215            0 :                         ShowContinueError(state, format("...Heating coil inlet node name  = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    2216            0 :                         ErrorsFound = true;
    2217              :                     }
    2218            0 :                     if ((thisFurnace.Humidistat && thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) ||
    2219              :                         ReheatCoilInletNode > 0) {
    2220            0 :                         if (HeatingCoilOutletNode != ReheatCoilInletNode) {
    2221            0 :                             ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2222            0 :                             ShowContinueError(state,
    2223              :                                               "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
    2224              :                                               "reheat coil inlet node name.");
    2225            0 :                             ShowContinueError(state,
    2226            0 :                                               format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    2227            0 :                             ShowContinueError(state,
    2228            0 :                                               format("...Reheat coil inlet node name   = {}", state.dataLoopNodes->NodeID(ReheatCoilInletNode)));
    2229            0 :                             ErrorsFound = true;
    2230              :                         }
    2231            0 :                         if (ReheatCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    2232            0 :                             ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2233            0 :                             if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatCool) {
    2234            0 :                                 ShowContinueError(state, "The reheat coil outlet node name must be the same as the furnace outlet node name.");
    2235            0 :                                 ShowContinueError(state,
    2236            0 :                                                   format("...Reheat coil outlet node name = {}", state.dataLoopNodes->NodeID(ReheatCoilOutletNode)));
    2237            0 :                                 ShowContinueError(
    2238              :                                     state,
    2239            0 :                                     format("...Furnace outlet node name     = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2240              :                             } else {
    2241            0 :                                 ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
    2242            0 :                                 ShowContinueError(
    2243            0 :                                     state, format("...Reheat coil outlet node name   = {}", state.dataLoopNodes->NodeID(ReheatCoilOutletNode)));
    2244            0 :                                 ShowContinueError(
    2245              :                                     state,
    2246            0 :                                     format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2247              :                             }
    2248            0 :                             ErrorsFound = true;
    2249              :                         }
    2250              :                     } else { // IF((Furnace(FurnaceNum)%Humidistat ...
    2251              :                         // Heating coil outlet node name must be the same as the furnace outlet node name
    2252            0 :                         if (HeatingCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    2253            0 :                             ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2254            0 :                             if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatOnly) {
    2255            0 :                                 ShowContinueError(state,
    2256              :                                                   "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
    2257              :                                                   "furnace outlet node name.");
    2258            0 :                                 ShowContinueError(
    2259            0 :                                     state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    2260            0 :                                 ShowContinueError(
    2261              :                                     state,
    2262            0 :                                     format("...Furnace outlet node name      = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2263              :                             } else {
    2264            0 :                                 ShowContinueError(state,
    2265              :                                                   "When a blow through fan is specified, the heating coil outlet node name must be the same as the "
    2266              :                                                   "unitary system outlet node name.");
    2267            0 :                                 ShowContinueError(
    2268            0 :                                     state, format("...Heating coil outlet node name  = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    2269            0 :                                 ShowContinueError(
    2270              :                                     state,
    2271            0 :                                     format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2272              :                             }
    2273            0 :                             ErrorsFound = true;
    2274              :                         }
    2275              :                     }
    2276              :                 } else { // IF(Furnace(FurnaceNum)%CoolingCoilUpstream)THEN
    2277            0 :                     if (FanOutletNode != HeatingCoilInletNode) {
    2278            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2279            0 :                         ShowContinueError(
    2280              :                             state,
    2281              :                             "When a blow through fan is specified, the fan outlet node name must be the same as the heating coil inlet node name.");
    2282            0 :                         ShowContinueError(state, format("...Fan outlet node name         = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    2283            0 :                         ShowContinueError(state, format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    2284            0 :                         ErrorsFound = true;
    2285              :                     }
    2286            0 :                     if (HeatingCoilOutletNode != CoolingCoilInletNode) {
    2287            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2288            0 :                         ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
    2289            0 :                         ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    2290            0 :                         ShowContinueError(state, format("...Cooling coil inlet node name  = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    2291            0 :                         ErrorsFound = true;
    2292              :                     }
    2293            0 :                     if (CoolingCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    2294            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2295            0 :                         if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatCool) {
    2296            0 :                             ShowContinueError(state,
    2297              :                                               "When a blow through fan is specified, the cooling coil outlet node name must be the same as the "
    2298              :                                               "furnace outlet node name.");
    2299            0 :                             ShowContinueError(state,
    2300            0 :                                               format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    2301            0 :                             ShowContinueError(
    2302              :                                 state,
    2303            0 :                                 format("...Furnace outlet node name      = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2304              :                         } else {
    2305            0 :                             ShowContinueError(state,
    2306              :                                               "When a blow through fan is specified, the cooling coil outlet node name must be the same as the "
    2307              :                                               "unitary system outlet node name.");
    2308            0 :                             ShowContinueError(state,
    2309            0 :                                               format("...Cooling coil outlet node name   = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    2310            0 :                             ShowContinueError(
    2311              :                                 state,
    2312            0 :                                 format("...UnitarySystem outlet node name  = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2313              :                         }
    2314            0 :                         ErrorsFound = true;
    2315              :                     }
    2316              :                 }
    2317              : 
    2318              :             } else { // ELSE from IF(Furnace(FurnaceNum)%FanPlace .EQ. BlowThru)THEN
    2319              : 
    2320            0 :                 if (thisFurnace.CoolingCoilUpstream) {
    2321            0 :                     if (CoolingCoilInletNode != thisFurnace.FurnaceInletNodeNum) {
    2322            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2323            0 :                         if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatCool) {
    2324            0 :                             ShowContinueError(state,
    2325              :                                               "When a draw through fan is specified, the cooling coil inlet node name must be the same as the "
    2326              :                                               "furnace inlet node name.");
    2327            0 :                             ShowContinueError(state,
    2328            0 :                                               format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    2329            0 :                             ShowContinueError(
    2330            0 :                                 state, format("...Furnace inlet node name      = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    2331              :                         } else {
    2332            0 :                             ShowContinueError(state,
    2333              :                                               "When a draw through fan is specified, the cooling coil inlet node name must be the same as the "
    2334              :                                               "unitary system inlet node name.");
    2335            0 :                             ShowContinueError(state,
    2336            0 :                                               format("...Cooling coil inlet node name  = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    2337            0 :                             ShowContinueError(
    2338            0 :                                 state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    2339              :                         }
    2340            0 :                         ErrorsFound = true;
    2341              :                     }
    2342            0 :                     if (CoolingCoilOutletNode != HeatingCoilInletNode) {
    2343            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2344            0 :                         ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
    2345            0 :                         ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    2346            0 :                         ShowContinueError(state, format("...Heating coil inlet node name  = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    2347            0 :                         ErrorsFound = true;
    2348              :                     }
    2349            0 :                     if (HeatingCoilOutletNode != FanInletNode) {
    2350            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2351            0 :                         ShowContinueError(
    2352              :                             state,
    2353              :                             "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan inlet node name.");
    2354            0 :                         ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    2355            0 :                         ShowContinueError(state, format("...Fan inlet node name           = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    2356            0 :                         ErrorsFound = true;
    2357              :                     }
    2358            0 :                     if ((thisFurnace.Humidistat && thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) ||
    2359              :                         ReheatCoilInletNode > 0) {
    2360            0 :                         if (FanOutletNode != ReheatCoilInletNode) {
    2361            0 :                             ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2362            0 :                             ShowContinueError(state,
    2363              :                                               "When a draw through fan is specified, the fan outlet node name must be the same as the reheat coil "
    2364              :                                               "inlet node name.");
    2365            0 :                             ShowContinueError(state, format("...Fan outlet node name        = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    2366            0 :                             ShowContinueError(state, format("...Reheat coil inlet node name = {}", state.dataLoopNodes->NodeID(ReheatCoilInletNode)));
    2367            0 :                             ErrorsFound = true;
    2368              :                         }
    2369            0 :                         if (ReheatCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    2370            0 :                             ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2371            0 :                             if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatCool) {
    2372            0 :                                 ShowContinueError(state, "The reheat coil outlet node name must be the same as the furnace outlet node name.");
    2373            0 :                                 ShowContinueError(state,
    2374            0 :                                                   format("...Reheat coil outlet node name = {}", state.dataLoopNodes->NodeID(ReheatCoilOutletNode)));
    2375            0 :                                 ShowContinueError(
    2376              :                                     state,
    2377            0 :                                     format("...Furnace outlet node name     = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2378              :                             } else {
    2379            0 :                                 ShowContinueError(state, "The reheat coil outlet node name must be the same as the unitary system outlet node name.");
    2380            0 :                                 ShowContinueError(
    2381            0 :                                     state, format("...Reheat coil outlet node name   = {}", state.dataLoopNodes->NodeID(ReheatCoilOutletNode)));
    2382            0 :                                 ShowContinueError(
    2383              :                                     state,
    2384            0 :                                     format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2385              :                             }
    2386            0 :                             ErrorsFound = true;
    2387              :                         }
    2388              :                     } else {
    2389            0 :                         if (FanOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    2390            0 :                             ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2391            0 :                             ShowContinueError(state,
    2392              :                                               "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
    2393              :                                               "outlet node name.");
    2394            0 :                             ShowContinueError(state, format("...Fan outlet node name        = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    2395            0 :                             ShowContinueError(
    2396              :                                 state,
    2397            0 :                                 format("...Unitary system outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2398            0 :                             ErrorsFound = true;
    2399              :                         }
    2400              :                     }
    2401              :                 } else { // IF(Furnace(FurnaceNum)%CoolingCoilUpstream)THEN
    2402            0 :                     if (HeatingCoilInletNode != thisFurnace.FurnaceInletNodeNum) {
    2403            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2404            0 :                         if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatCool) {
    2405            0 :                             ShowContinueError(state,
    2406              :                                               "When a draw through fan is specified, the heating coil inlet node name must be the same as the "
    2407              :                                               "furnace inlet node name.");
    2408            0 :                             ShowContinueError(state,
    2409            0 :                                               format("...Heating coil inlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    2410            0 :                             ShowContinueError(
    2411            0 :                                 state, format("...Furnace inlet node name      = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    2412              :                         } else {
    2413            0 :                             ShowContinueError(state,
    2414              :                                               "When a draw through fan is specified, the heating coil inlet node name must be the same as the "
    2415              :                                               "unitary system inlet node name.");
    2416            0 :                             ShowContinueError(state,
    2417            0 :                                               format("...Heating coil inlet node name  = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    2418            0 :                             ShowContinueError(
    2419            0 :                                 state, format("...UnitarySystem inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    2420              :                         }
    2421            0 :                         ErrorsFound = true;
    2422              :                     }
    2423            0 :                     if (HeatingCoilOutletNode != CoolingCoilInletNode) {
    2424            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2425            0 :                         ShowContinueError(state, "The heating coil outlet node name must be the same as the cooling coil inlet node name.");
    2426            0 :                         ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    2427            0 :                         ShowContinueError(state, format("...Cooling coil inlet node name  = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    2428            0 :                         ErrorsFound = true;
    2429              :                     }
    2430            0 :                     if (CoolingCoilOutletNode != FanInletNode) {
    2431            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2432            0 :                         ShowContinueError(
    2433              :                             state,
    2434              :                             "When a draw through fan is specified, the cooling coil outlet node name must be the same as the fan inlet node name.");
    2435            0 :                         ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    2436            0 :                         ShowContinueError(state, format("...Fan inlet node name           = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    2437            0 :                         ErrorsFound = true;
    2438              :                     }
    2439            0 :                     if (FanOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    2440            0 :                         ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    2441            0 :                         if (thisFurnace.type == HVAC::UnitarySysType::Furnace_HeatCool) {
    2442            0 :                             ShowContinueError(
    2443              :                                 state,
    2444              :                                 "When a draw through fan is specified, the fan outlet node name must be the same as the furnace outlet node name.");
    2445            0 :                             ShowContinueError(state, format("...Fan outlet node name     = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    2446            0 :                             ShowContinueError(
    2447            0 :                                 state, format("...Furnace outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2448              :                         } else {
    2449            0 :                             ShowContinueError(state,
    2450              :                                               "When a draw through fan is specified, the fan outlet node name must be the same as the unitary system "
    2451              :                                               "outlet node name.");
    2452            0 :                             ShowContinueError(state, format("...Fan outlet node name           = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    2453            0 :                             ShowContinueError(
    2454              :                                 state,
    2455            0 :                                 format("...UnitarySystem outlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    2456              :                         }
    2457            0 :                         ErrorsFound = true;
    2458              :                     }
    2459              :                 }
    2460              :             } // ELSE from IF(Furnace(FurnaceNum)%FanPlace .EQ. BlowThru)THEN
    2461              : 
    2462              :             // Add fan to component sets array
    2463            0 :             BranchNodeConnections::SetUpCompSets(state,
    2464              :                                                  CurrentModuleObject,
    2465            0 :                                                  Alphas(1),
    2466            0 :                                                  Alphas(7),
    2467            0 :                                                  Alphas(8),
    2468            0 :                                                  state.dataLoopNodes->NodeID(FanInletNode),
    2469            0 :                                                  state.dataLoopNodes->NodeID(FanOutletNode));
    2470              : 
    2471              :             // Add DX cooling coil to component sets array
    2472            0 :             if (thisFurnace.bIsIHP) {
    2473            0 :                 BranchNodeConnections::SetUpCompSets(state,
    2474              :                                                      CurrentModuleObject,
    2475            0 :                                                      Alphas(1),
    2476            0 :                                                      Alphas(12),
    2477            0 :                                                      Alphas(13) + " Cooling Coil",
    2478            0 :                                                      state.dataLoopNodes->NodeID(CoolingCoilInletNode),
    2479            0 :                                                      state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
    2480              :             } else {
    2481            0 :                 BranchNodeConnections::SetUpCompSets(state,
    2482              :                                                      CurrentModuleObject,
    2483            0 :                                                      Alphas(1),
    2484            0 :                                                      Alphas(12),
    2485            0 :                                                      Alphas(13),
    2486            0 :                                                      state.dataLoopNodes->NodeID(CoolingCoilInletNode),
    2487            0 :                                                      state.dataLoopNodes->NodeID(CoolingCoilOutletNode));
    2488              :             }
    2489              : 
    2490              :             // Add heating coil to component sets array
    2491            0 :             if (thisFurnace.bIsIHP) {
    2492            0 :                 BranchNodeConnections::SetUpCompSets(state,
    2493              :                                                      CurrentModuleObject,
    2494            0 :                                                      Alphas(1),
    2495            0 :                                                      Alphas(10),
    2496            0 :                                                      Alphas(11) + " Heating Coil",
    2497            0 :                                                      state.dataLoopNodes->NodeID(HeatingCoilInletNode),
    2498            0 :                                                      state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
    2499              :             } else {
    2500            0 :                 BranchNodeConnections::SetUpCompSets(state,
    2501              :                                                      CurrentModuleObject,
    2502            0 :                                                      Alphas(1),
    2503            0 :                                                      Alphas(10),
    2504            0 :                                                      Alphas(11),
    2505            0 :                                                      state.dataLoopNodes->NodeID(HeatingCoilInletNode),
    2506            0 :                                                      state.dataLoopNodes->NodeID(HeatingCoilOutletNode));
    2507              :             }
    2508              : 
    2509            0 :             if (ReheatCoilInletNode > 0) {
    2510              : 
    2511              :                 // Add reheating coil to component sets array
    2512            0 :                 BranchNodeConnections::SetUpCompSets(state,
    2513              :                                                      CurrentModuleObject,
    2514            0 :                                                      Alphas(1),
    2515            0 :                                                      Alphas(15),
    2516            0 :                                                      Alphas(16),
    2517            0 :                                                      state.dataLoopNodes->NodeID(ReheatCoilInletNode),
    2518            0 :                                                      state.dataLoopNodes->NodeID(ReheatCoilOutletNode));
    2519              :             }
    2520              : 
    2521              :             // Set the furnace max outlet temperature
    2522            0 :             thisFurnace.DesignMaxOutletTemp = Numbers(1);
    2523              : 
    2524            0 :             thisFurnace.MaxCoolAirVolFlow = Numbers(2);
    2525            0 :             if (thisFurnace.MaxCoolAirVolFlow <= 0 && thisFurnace.MaxCoolAirVolFlow != DataSizing::AutoSize) {
    2526            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2527            0 :                 ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(2), Numbers(2)));
    2528            0 :                 ErrorsFound = true;
    2529              :             }
    2530              : 
    2531            0 :             thisFurnace.MaxHeatAirVolFlow = Numbers(3);
    2532            0 :             if (thisFurnace.MaxHeatAirVolFlow <= 0 && thisFurnace.MaxHeatAirVolFlow != DataSizing::AutoSize) {
    2533            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2534            0 :                 ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(3), Numbers(3)));
    2535            0 :                 ErrorsFound = true;
    2536              :             }
    2537              : 
    2538            0 :             thisFurnace.MaxNoCoolHeatAirVolFlow = Numbers(4);
    2539            0 :             if (thisFurnace.MaxNoCoolHeatAirVolFlow < 0 && thisFurnace.MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
    2540            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2541            0 :                 ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(4), Numbers(4)));
    2542            0 :                 ErrorsFound = true;
    2543              :             }
    2544              : 
    2545            0 :             if (Numbers(2) != DataSizing::AutoSize && Numbers(3) != DataSizing::AutoSize && Numbers(4) != DataSizing::AutoSize) {
    2546            0 :                 thisFurnace.DesignFanVolFlowRate = max(Numbers(2), Numbers(3), Numbers(4));
    2547              :             } else {
    2548            0 :                 thisFurnace.DesignFanVolFlowRate = DataSizing::AutoSize;
    2549              :             }
    2550              : 
    2551            0 :             if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2552            0 :                 errFlag = false;
    2553            0 :                 if (thisFurnace.bIsIHP) {
    2554            0 :                     thisFurnace.CoolingCoilIndex = IntegratedHeatPump::GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
    2555            0 :                     IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilName;
    2556            0 :                     thisFurnace.MaxCoolAirVolFlow =
    2557            0 :                         VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    2558              :                 } else {
    2559            0 :                     thisFurnace.MaxCoolAirVolFlow =
    2560            0 :                         VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    2561              :                 }
    2562              : 
    2563            0 :                 if (errFlag) {
    2564            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2565            0 :                     ErrorsFound = true;
    2566              :                 }
    2567              : 
    2568            0 :                 thisFurnace.MaxNoCoolHeatAirVolFlow = min(thisFurnace.MaxHeatAirVolFlow, thisFurnace.MaxCoolAirVolFlow);
    2569            0 :                 if (thisFurnace.MaxHeatAirVolFlow != DataSizing::AutoSize && thisFurnace.MaxCoolAirVolFlow != DataSizing::AutoSize) {
    2570            0 :                     thisFurnace.DesignFanVolFlowRate = max(thisFurnace.MaxHeatAirVolFlow, thisFurnace.MaxCoolAirVolFlow);
    2571              :                 } else {
    2572            0 :                     thisFurnace.DesignFanVolFlowRate = DataSizing::AutoSize;
    2573              :                 }
    2574              :             }
    2575              : 
    2576            0 :             if (thisFurnace.ActualFanVolFlowRate != DataSizing::AutoSize) {
    2577            0 :                 if (thisFurnace.ActualFanVolFlowRate < thisFurnace.MaxCoolAirVolFlow && thisFurnace.MaxCoolAirVolFlow != DataSizing::AutoSize) {
    2578            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2579            0 :                     ShowContinueError(
    2580              :                         state,
    2581            0 :                         format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
    2582            0 :                                thisFurnace.ActualFanVolFlowRate,
    2583              :                                FanName));
    2584            0 :                     ShowContinueError(state, format(" The {} is reset to the fan flow rate and the simulation continues.", cNumericFields(2)));
    2585            0 :                     thisFurnace.MaxCoolAirVolFlow = thisFurnace.ActualFanVolFlowRate;
    2586            0 :                     thisFurnace.DesignFanVolFlowRate = thisFurnace.ActualFanVolFlowRate;
    2587              :                 }
    2588            0 :                 if (thisFurnace.ActualFanVolFlowRate < thisFurnace.MaxHeatAirVolFlow && thisFurnace.MaxHeatAirVolFlow != DataSizing::AutoSize) {
    2589            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2590            0 :                     ShowContinueError(
    2591              :                         state,
    2592            0 :                         format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
    2593            0 :                                thisFurnace.ActualFanVolFlowRate,
    2594              :                                FanName));
    2595            0 :                     ShowContinueError(state, format(" The {} is reset to the fan flow rate and the simulation continues.", cNumericFields(3)));
    2596            0 :                     thisFurnace.MaxHeatAirVolFlow = thisFurnace.ActualFanVolFlowRate;
    2597            0 :                     thisFurnace.DesignFanVolFlowRate = thisFurnace.ActualFanVolFlowRate;
    2598              :                 }
    2599              :             }
    2600              : 
    2601            0 :             if (thisFurnace.fanOpModeSched != nullptr) {
    2602              :                 // Is this correct? 0.0 for max also?
    2603            0 :                 if (!thisFurnace.fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) {
    2604              :                     //           set air flow control mode:
    2605              :                     //             UseCompressorOnFlow = operate at last cooling or heating air flow requested when compressor is off
    2606              :                     //             UseCompressorOffFlow = operate at value specified by user
    2607              :                     //           AirFlowControl only valid if fan opmode = ContFanCycComp
    2608            0 :                     if (thisFurnace.MaxNoCoolHeatAirVolFlow == 0.0) {
    2609            0 :                         thisFurnace.AirFlowControl = AirFlowControlConstFan::UseCompressorOnFlow;
    2610              :                     } else {
    2611            0 :                         thisFurnace.AirFlowControl = AirFlowControlConstFan::UseCompressorOffFlow;
    2612              :                     }
    2613              :                 }
    2614              :             }
    2615              : 
    2616            0 :             if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2617            0 :                 errFlag = false;
    2618            0 :                 if (thisFurnace.bIsIHP) {
    2619            0 :                     thisFurnace.CoolingCoilIndex = IntegratedHeatPump::GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
    2620            0 :                     IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilName;
    2621            0 :                     thisFurnace.DesignCoolingCapacity =
    2622            0 :                         VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    2623              :                 } else {
    2624            0 :                     thisFurnace.DesignCoolingCapacity =
    2625            0 :                         VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    2626              :                 }
    2627              : 
    2628            0 :                 if (errFlag) {
    2629            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2630            0 :                     ErrorsFound = true;
    2631              :                 }
    2632              :             }
    2633              : 
    2634              :             // Set heating convergence tolerance
    2635            0 :             thisFurnace.HeatingConvergenceTolerance = 0.001;
    2636              : 
    2637              :             // Set cooling convergence tolerance
    2638            0 :             thisFurnace.CoolingConvergenceTolerance = 0.001;
    2639              : 
    2640              :             // set minimum outdoor temperature for compressor operation
    2641            0 :             SetMinOATCompressor(state, FurnaceNum, cCurrentModuleObject, ErrorsFound);
    2642              : 
    2643              :         } // End of the HeatCool Furnace Loop
    2644              : 
    2645              :         // Get the data for the Unitary System HeatPump AirToAir (UnitarySystem:HeatPump:AirToAir)
    2646            4 :         for (int HeatPumpNum = 1; HeatPumpNum <= NumHeatPump; ++HeatPumpNum) {
    2647              : 
    2648            2 :             CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:AirToAir";
    2649            2 :             FanInletNode = 0;
    2650            2 :             FanOutletNode = 0;
    2651            2 :             CoolingCoilInletNode = 0;
    2652            2 :             CoolingCoilOutletNode = 0;
    2653            2 :             HeatingCoilInletNode = 0;
    2654            2 :             HeatingCoilOutletNode = 0;
    2655            2 :             SupHeatCoilInletNode = 0;
    2656            2 :             SupHeatCoilOutletNode = 0;
    2657            2 :             CoolingCoilType = ' ';
    2658            2 :             CoolingCoilName = ' ';
    2659            2 :             HeatingCoilType = ' ';
    2660            2 :             HeatingCoilName = ' ';
    2661              : 
    2662            2 :             FurnaceNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + HeatPumpNum;
    2663            2 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    2664            2 :             thisFurnace.iterationMode.allocate(3);
    2665              : 
    2666            2 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    2667              :                                                                      CurrentModuleObject,
    2668              :                                                                      HeatPumpNum,
    2669              :                                                                      Alphas,
    2670              :                                                                      NumAlphas,
    2671              :                                                                      Numbers,
    2672              :                                                                      NumNumbers,
    2673              :                                                                      IOStatus,
    2674              :                                                                      lNumericBlanks,
    2675              :                                                                      lAlphaBlanks,
    2676              :                                                                      cAlphaFields,
    2677              :                                                                      cNumericFields);
    2678              : 
    2679            4 :             GlobalNames::VerifyUniqueInterObjectName(
    2680            2 :                 state, state.dataFurnaces->UniqueFurnaceNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    2681              : 
    2682            2 :             thisFurnace.type = HVAC::UnitarySysType::Unitary_HeatPump_AirToAir;
    2683            2 :             thisFurnace.Name = Alphas(1);
    2684              : 
    2685            2 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, thisFurnace.Name};
    2686              : 
    2687            2 :             if (lAlphaBlanks(2)) {
    2688            0 :                 thisFurnace.availSched = Sched::GetScheduleAlwaysOn(state);
    2689            2 :             } else if ((thisFurnace.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    2690            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    2691            0 :                 ErrorsFound = true;
    2692              :             }
    2693              : 
    2694            2 :             thisFurnace.FurnaceInletNodeNum =
    2695            2 :                 NodeInputManager::GetOnlySingleNode(state,
    2696            2 :                                                     Alphas(3),
    2697              :                                                     ErrorsFound,
    2698              :                                                     DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir,
    2699            2 :                                                     Alphas(1),
    2700              :                                                     DataLoopNode::NodeFluidType::Air,
    2701              :                                                     DataLoopNode::ConnectionType::Inlet,
    2702              :                                                     NodeInputManager::CompFluidStream::Primary,
    2703              :                                                     DataLoopNode::ObjectIsParent);
    2704              : 
    2705            2 :             thisFurnace.FurnaceOutletNodeNum =
    2706            4 :                 NodeInputManager::GetOnlySingleNode(state,
    2707            2 :                                                     Alphas(4),
    2708              :                                                     ErrorsFound,
    2709              :                                                     DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpAirToAir,
    2710            2 :                                                     Alphas(1),
    2711              :                                                     DataLoopNode::NodeFluidType::Air,
    2712              :                                                     DataLoopNode::ConnectionType::Outlet,
    2713              :                                                     NodeInputManager::CompFluidStream::Primary,
    2714              :                                                     DataLoopNode::ObjectIsParent);
    2715              : 
    2716            2 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    2717              : 
    2718              :             // Get the Controlling Zone or Location of the Furnace Thermostat
    2719            2 :             thisFurnace.ControlZoneNum = Util::FindItemInList(Alphas(5), state.dataHeatBal->Zone);
    2720            2 :             if (thisFurnace.ControlZoneNum == 0) {
    2721            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2722            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(5), Alphas(5)));
    2723            0 :                 ErrorsFound = true;
    2724              :             }
    2725              : 
    2726              :             // Get the node number for the zone with the thermostat
    2727            2 :             if (thisFurnace.ControlZoneNum > 0) {
    2728            2 :                 AirNodeFound = false;
    2729            2 :                 AirLoopFound = false;
    2730            2 :                 int ControlledZoneNum = thisFurnace.ControlZoneNum;
    2731              :                 //             Find the controlled zone number for the specified thermostat location
    2732            2 :                 thisFurnace.NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
    2733              :                 //             Determine if furnace is on air loop served by the thermostat location specified
    2734            3 :                 for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    2735            3 :                     int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
    2736            3 :                     if (AirLoopNumber > 0) {
    2737            2 :                         for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
    2738            3 :                             for (int CompNum = 1;
    2739            3 :                                  CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
    2740              :                                  ++CompNum) {
    2741            3 :                                 if (!Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name,
    2742            8 :                                                       Alphas(1)) ||
    2743            2 :                                     !Util::SameString(
    2744            2 :                                         state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
    2745              :                                         CurrentModuleObject)) {
    2746            1 :                                     continue;
    2747              :                                 }
    2748            2 :                                 AirLoopFound = true;
    2749            2 :                                 thisFurnace.ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
    2750            2 :                                 break;
    2751              :                             }
    2752            2 :                             if (AirLoopFound) {
    2753            2 :                                 break;
    2754              :                             }
    2755              :                         }
    2756            4 :                         for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
    2757            2 :                             if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    2758            0 :                                 continue;
    2759              :                             }
    2760            2 :                             AirNodeFound = true;
    2761              :                         }
    2762            2 :                         for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
    2763            0 :                             if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    2764            0 :                                 continue;
    2765              :                             }
    2766            0 :                             AirNodeFound = true;
    2767              :                         }
    2768              :                     }
    2769            3 :                     if (AirLoopFound) {
    2770            2 :                         break;
    2771              :                     }
    2772              :                 }
    2773            2 :                 if (!AirNodeFound) {
    2774            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2775            0 :                     ShowContinueError(state, "Did not find air node (zone with thermostat).");
    2776            0 :                     ShowContinueError(state, format("Specified {} = {}", cAlphaFields(5), Alphas(5)));
    2777            0 :                     ShowContinueError(
    2778              :                         state, "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
    2779            0 :                     ErrorsFound = true;
    2780              :                 }
    2781            2 :                 if (!AirLoopFound) {
    2782            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2783            0 :                     ShowContinueError(state, "Did not find correct AirLoopHVAC.");
    2784            0 :                     ShowContinueError(state, format("Specified {} = {}", cAlphaFields(5), Alphas(5)));
    2785            0 :                     ErrorsFound = true;
    2786              :                 }
    2787              :             }
    2788              : 
    2789              :             // Get fan data
    2790            2 :             FanName = Alphas(7);
    2791              : 
    2792            2 :             thisFurnace.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(6)));
    2793              : 
    2794            2 :             if (thisFurnace.fanType == HVAC::FanType::OnOff || thisFurnace.fanType == HVAC::FanType::Constant) {
    2795              : 
    2796            2 :                 if ((thisFurnace.FanIndex = Fans::GetFanIndex(state, FanName)) == 0) {
    2797            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFields(7), FanName);
    2798            0 :                     ErrorsFound = true;
    2799              :                 } else {
    2800            2 :                     auto *fan = state.dataFans->fans(thisFurnace.FanIndex);
    2801            2 :                     FanInletNode = fan->inletNodeNum;
    2802            2 :                     FanOutletNode = fan->outletNodeNum;
    2803            2 :                     thisFurnace.fanAvailSched = fan->availSched;
    2804            2 :                     thisFurnace.ActualFanVolFlowRate = fan->maxAirFlowRate;
    2805              :                 }
    2806              :             }
    2807              : 
    2808              :             // Get heating coil type and name data
    2809            2 :             HeatingCoilType = Alphas(8);
    2810            2 :             HeatingCoilName = Alphas(9);
    2811              : 
    2812            2 :             errFlag = false;
    2813              : 
    2814            4 :             if (Util::SameString(HeatingCoilType, "COIL:HEATING:DX:VARIABLESPEED") ||
    2815            4 :                 Util::SameString(HeatingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
    2816            0 :                 thisFurnace.HeatingCoilType_Num = HVAC::Coil_HeatingAirToAirVariableSpeed;
    2817            0 :                 if (Util::SameString(HeatingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
    2818            0 :                     thisFurnace.bIsIHP = true;
    2819              :                 }
    2820              :             } else {
    2821            2 :                 thisFurnace.HeatingCoilType_Num = DXCoils::GetCoilTypeNum(state, HeatingCoilType, HeatingCoilName, errFlag);
    2822              :             }
    2823              : 
    2824            2 :             if (errFlag) {
    2825            0 :                 ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2826            0 :                 ErrorsFound = true;
    2827              :             }
    2828              : 
    2829            2 :             if (thisFurnace.HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
    2830            2 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    2831            2 :                 if (IsNotOK) {
    2832            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2833            0 :                     ErrorsFound = true;
    2834              : 
    2835              :                 } else { // mine data from DX heating coil
    2836              : 
    2837            2 :                     DXCoils::GetDXCoilIndex(state, HeatingCoilName, thisFurnace.HeatingCoilIndex, IsNotOK);
    2838            2 :                     if (IsNotOK) {
    2839            0 :                         ShowContinueError(state, format("...occurs {} = {}", CurrentModuleObject, Alphas(1)));
    2840            0 :                         ErrorsFound = true;
    2841              :                     }
    2842              : 
    2843              :                     // Get the Heating Coil Node Names
    2844            2 :                     errFlag = false;
    2845            2 :                     HeatingCoilInletNode = DXCoils::GetCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    2846            2 :                     HeatingCoilOutletNode = DXCoils::GetCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    2847            2 :                     if (errFlag) {
    2848            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2849            0 :                         ErrorsFound = true;
    2850              :                     }
    2851              : 
    2852              :                     // Get the design heating capacity
    2853            2 :                     errFlag = false;
    2854            2 :                     thisFurnace.DesignHeatingCapacity = DXCoils::GetCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
    2855            2 :                     if (errFlag) {
    2856            0 :                         ShowContinueError(state, format("...occurs in {} ={}", CurrentModuleObject, Alphas(1)));
    2857            0 :                         ErrorsFound = true;
    2858              :                     }
    2859              : 
    2860              :                 } // IF (IsNotOK) THEN
    2861            0 :             } else if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
    2862            0 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    2863            0 :                 if (IsNotOK) {
    2864            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2865            0 :                     ErrorsFound = true;
    2866              :                 } else {
    2867            0 :                     if (thisFurnace.bIsIHP) {
    2868            0 :                         thisFurnace.HeatingCoilIndex = IntegratedHeatPump::GetCoilIndexIHP(state, HeatingCoilType, HeatingCoilName, errFlag);
    2869            0 :                         IHPCoilIndex = thisFurnace.HeatingCoilIndex;
    2870            0 :                         IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(IHPCoilIndex).SHCoilName;
    2871              :                         HeatingCoilInletNode =
    2872            0 :                             VariableSpeedCoils::GetCoilInletNodeVariableSpeed(state, "COIL:HEATING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    2873              :                         HeatingCoilOutletNode =
    2874            0 :                             VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(state, "COIL:HEATING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    2875              :                     } else {
    2876            0 :                         thisFurnace.HeatingCoilIndex =
    2877            0 :                             VariableSpeedCoils::GetCoilIndexVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    2878            0 :                         HeatingCoilInletNode = VariableSpeedCoils::GetCoilInletNodeVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    2879            0 :                         HeatingCoilOutletNode = VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    2880              :                     }
    2881              :                 }
    2882              :             } else {
    2883            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    2884            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(8), Alphas(8)));
    2885            0 :                 ErrorsFound = true;
    2886              :             }
    2887              : 
    2888              :             // Get Cooling Coil Information if available
    2889            2 :             CoolingCoilType = Alphas(10);
    2890            2 :             CoolingCoilName = Alphas(11);
    2891              : 
    2892            4 :             if (Util::SameString(CoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED") ||
    2893            4 :                 Util::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
    2894            0 :                 thisFurnace.CoolingCoilType_Num = HVAC::Coil_CoolingAirToAirVariableSpeed;
    2895            0 :                 if (Util::SameString(CoolingCoilType, "COILSYSTEM:INTEGRATEDHEATPUMP:AIRSOURCE")) {
    2896            0 :                     thisFurnace.bIsIHP = true;
    2897              :                 }
    2898              :             }
    2899              : 
    2900            2 :             ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
    2901              : 
    2902            2 :             if (IsNotOK) {
    2903            0 :                 ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2904            0 :                 ErrorsFound = true;
    2905              : 
    2906              :             } else { // mine data from DX cooling coil
    2907              : 
    2908            2 :                 errFlag = false;
    2909            2 :                 PrintMessage = false;
    2910              : 
    2911            2 :                 if (thisFurnace.CoolingCoilType_Num != HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2912            2 :                     thisFurnace.CoolingCoilType_Num = DXCoils::GetCoilTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, PrintMessage);
    2913              :                 }
    2914              : 
    2915              :                 // If coil type not found, check to see if a HX assisted cooling coil is used.
    2916            2 :                 if (thisFurnace.CoolingCoilType_Num == 0) {
    2917            0 :                     errFlag = false;
    2918            0 :                     PrintMessage = false;
    2919            0 :                     thisFurnace.CoolingCoilType_Num =
    2920            0 :                         HVACHXAssistedCoolingCoil::GetCoilGroupTypeNum(state, CoolingCoilType, CoolingCoilName, errFlag, PrintMessage);
    2921              :                 }
    2922              : 
    2923            2 :                 if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
    2924              : 
    2925              :                     // Get the cooling coil node numbers
    2926            2 :                     errFlag = false;
    2927            2 :                     DXCoils::GetDXCoilIndex(state, CoolingCoilName, thisFurnace.CoolingCoilIndex, errFlag);
    2928            2 :                     CoolingCoilInletNode = DXCoils::GetCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    2929            2 :                     CoolingCoilOutletNode = DXCoils::GetCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    2930            2 :                     if (errFlag) {
    2931            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2932            0 :                         ErrorsFound = true;
    2933              :                     }
    2934              : 
    2935              :                     // Get the DX cooling coil design capacity
    2936            2 :                     errFlag = false;
    2937            2 :                     thisFurnace.DesignCoolingCapacity = DXCoils::GetCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
    2938            2 :                     if (errFlag) {
    2939            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2940            0 :                         ErrorsFound = true;
    2941              :                     }
    2942              : 
    2943            0 :                 } else if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
    2944              : 
    2945              :                     // Get the cooling coil node numbers
    2946            0 :                     errFlag = false;
    2947            0 :                     HVACHXAssistedCoolingCoil::GetHXDXCoilIndex(state, CoolingCoilName, thisFurnace.CoolingCoilIndex, errFlag);
    2948            0 :                     CoolingCoilInletNode = HVACHXAssistedCoolingCoil::GetCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    2949            0 :                     CoolingCoilOutletNode = HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    2950            0 :                     if (errFlag) {
    2951            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2952            0 :                         ErrorsFound = true;
    2953              :                     }
    2954              : 
    2955              :                     // Get the heat exchanger assisted cooling coil design capacity
    2956            0 :                     errFlag = false;
    2957            0 :                     thisFurnace.DesignCoolingCapacity = HVACHXAssistedCoolingCoil::GetCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
    2958            0 :                     if (errFlag) {
    2959            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    2960            0 :                         ErrorsFound = true;
    2961              :                     }
    2962              : 
    2963              :                     // get the actual index to the DX cooling coil object
    2964            0 :                     DXCoilIndex = HVACHXAssistedCoolingCoil::GetActualDXCoilIndex(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
    2965            0 :                     thisFurnace.ActualDXCoilIndexForHXAssisted = DXCoilIndex;
    2966              : 
    2967            0 :                 } else if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2968              :                     // BOS ADDED, AUG/2012, VARIIABLE SPEED DX COOLING COIL
    2969              :                     //  Furnace(FurnaceNum)%DXCoolCoilType = 'COIL:COOLING:DX:VARIABLESPEED'
    2970              :                     //  Furnace(FurnaceNum)%DXCoolCoilName = CoolingCoilName
    2971            0 :                     ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
    2972            0 :                     if (IsNotOK) {
    2973            0 :                         ShowContinueError(state, format("...specified in {}=\"{}\".", CurrentModuleObject, Alphas(1)));
    2974            0 :                         ErrorsFound = true;
    2975              :                     } else {
    2976            0 :                         errFlag = false;
    2977            0 :                         if (thisFurnace.bIsIHP) {
    2978            0 :                             thisFurnace.CoolingCoilIndex = IntegratedHeatPump::GetCoilIndexIHP(state, CoolingCoilType, CoolingCoilName, errFlag);
    2979            0 :                             IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilName;
    2980              :                         } else {
    2981            0 :                             thisFurnace.CoolingCoilIndex =
    2982            0 :                                 VariableSpeedCoils::GetCoilIndexVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    2983            0 :                             IHPCoilName = CoolingCoilName;
    2984              :                         }
    2985              : 
    2986            0 :                         if (errFlag) {
    2987            0 :                             ShowContinueError(state, format("...specified in {}=\"{}\".", CurrentModuleObject, Alphas(1)));
    2988            0 :                             ErrorsFound = true;
    2989              :                         }
    2990              : 
    2991            0 :                         if (thisFurnace.bIsIHP) {
    2992              :                             CoolingCoilInletNode =
    2993            0 :                                 VariableSpeedCoils::GetCoilInletNodeVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    2994              :                             CoolingCoilOutletNode =
    2995            0 :                                 VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    2996            0 :                             thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
    2997              :                         } else {
    2998              :                             CoolingCoilInletNode =
    2999            0 :                                 VariableSpeedCoils::GetCoilInletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    3000              :                             CoolingCoilOutletNode =
    3001            0 :                                 VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    3002            0 :                             thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
    3003              :                         }
    3004              : 
    3005            0 :                         if (errFlag) {
    3006            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3007            0 :                             ErrorsFound = true;
    3008              :                         }
    3009              :                     }
    3010              :                 } else {
    3011            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3012            0 :                     ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(10), Alphas(10)));
    3013            0 :                     ErrorsFound = true;
    3014              :                 }
    3015              :             }
    3016              : 
    3017            2 :             if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed &&
    3018            0 :                 thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
    3019              :                 // Furnace(FurnaceNum)%WatertoAirHPType = WatertoAir_VarSpeedEquationFit
    3020            0 :                 if (thisFurnace.bIsIHP) {
    3021            0 :                     VariableSpeedCoils::SetVarSpeedCoilData(state,
    3022            0 :                                                             state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilIndex,
    3023              :                                                             ErrorsFound,
    3024              :                                                             _,
    3025            0 :                                                             state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SHCoilIndex);
    3026              :                 } else {
    3027            0 :                     VariableSpeedCoils::SetVarSpeedCoilData(state, thisFurnace.CoolingCoilIndex, ErrorsFound, _, thisFurnace.HeatingCoilIndex);
    3028              :                 }
    3029              :             }
    3030              : 
    3031              :             // Get supplemental heating coil information
    3032            2 :             SuppHeatCoilType = Alphas(12);
    3033            2 :             SuppHeatCoilName = Alphas(13);
    3034            2 :             thisFurnace.SuppHeatCoilType = SuppHeatCoilType;
    3035            2 :             thisFurnace.SuppHeatCoilName = SuppHeatCoilName;
    3036            2 :             errFlag = false;
    3037            2 :             if (Util::SameString(SuppHeatCoilType, "Coil:Heating:Fuel") || Util::SameString(SuppHeatCoilType, "Coil:Heating:Electric")) {
    3038              : 
    3039            2 :                 thisFurnace.SuppHeatCoilType_Num = HeatingCoils::GetHeatingCoilTypeNum(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3040            2 :                 if (errFlag) {
    3041            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3042            0 :                     ErrorsFound = true;
    3043              :                 } else {
    3044            2 :                     IsNotOK = false;
    3045            2 :                     ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
    3046            2 :                     if (IsNotOK) {
    3047            0 :                         ShowContinueError(state, format("In {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3048            0 :                         ErrorsFound = true;
    3049              : 
    3050              :                     } else { // mine data from the supplemental heating coil
    3051              : 
    3052            2 :                         HeatingCoils::GetCoilIndex(state, SuppHeatCoilName, thisFurnace.SuppHeatCoilIndex, IsNotOK);
    3053            2 :                         if (IsNotOK) {
    3054            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3055            0 :                             ErrorsFound = true;
    3056              :                         }
    3057              : 
    3058              :                         // Get the Supplemental Heating Coil Inlet Node Number
    3059            2 :                         errFlag = false;
    3060            2 :                         SupHeatCoilInletNode = HeatingCoils::GetCoilInletNode(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3061            2 :                         if (errFlag) {
    3062            0 :                             ShowContinueError(state, format("...occurs in {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3063            0 :                             ErrorsFound = true;
    3064              :                         }
    3065              : 
    3066              :                         // Get the Supplemental Heating Coil Outlet Node Number
    3067            2 :                         errFlag = false;
    3068            2 :                         SupHeatCoilOutletNode = HeatingCoils::GetCoilOutletNode(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3069              : 
    3070            2 :                         if (errFlag) {
    3071            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3072            0 :                             ErrorsFound = true;
    3073              :                         }
    3074              : 
    3075              :                         // Get the supplemental heating coil design capacity
    3076            2 :                         errFlag = false;
    3077            2 :                         thisFurnace.DesignSuppHeatingCapacity = HeatingCoils::GetCoilCapacity(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3078            2 :                         if (errFlag) {
    3079            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3080            0 :                             ErrorsFound = true;
    3081              :                         }
    3082              : 
    3083              :                     } // IF (IsNotOK) THEN
    3084              :                 }
    3085            0 :             } else if (Util::SameString(SuppHeatCoilType, "Coil:Heating:Water")) {
    3086            0 :                 thisFurnace.SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
    3087            0 :                 ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
    3088            0 :                 if (IsNotOK) {
    3089            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3090            0 :                     ErrorsFound = true;
    3091              :                 } else { // mine data from heating coil object
    3092              : 
    3093              :                     // Get the Heating Coil water Inlet or control Node number
    3094            0 :                     errFlag = false;
    3095            0 :                     thisFurnace.SuppCoilControlNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
    3096            0 :                     if (errFlag) {
    3097            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3098            0 :                         ErrorsFound = true;
    3099              :                     }
    3100              : 
    3101              :                     // Get the ReHeat Coil hot water max volume flow rate
    3102            0 :                     errFlag = false;
    3103            0 :                     thisFurnace.MaxSuppCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
    3104            0 :                     if (errFlag) {
    3105            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3106            0 :                         ErrorsFound = true;
    3107              :                     }
    3108              : 
    3109              :                     // Get the ReHeat Coil Inlet Node
    3110            0 :                     errFlag = false;
    3111            0 :                     SupHeatCoilInletNode = WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
    3112            0 :                     thisFurnace.SuppCoilAirInletNode = SupHeatCoilInletNode;
    3113            0 :                     if (errFlag) {
    3114            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3115            0 :                         ErrorsFound = true;
    3116              :                     }
    3117              : 
    3118              :                     // Get the ReHeat Coil Outlet Node
    3119            0 :                     errFlag = false;
    3120            0 :                     SupHeatCoilOutletNode = WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
    3121            0 :                     thisFurnace.SuppCoilAirOutletNode = SupHeatCoilOutletNode;
    3122            0 :                     if (errFlag) {
    3123            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3124            0 :                         ErrorsFound = true;
    3125              :                     }
    3126            0 :                     errFlag = false;
    3127            0 :                     HVACControllers::CheckCoilWaterInletNode(state, thisFurnace.CoilControlNode, errFlag);
    3128            0 :                     if (!errFlag) { // then did find a controller so that is bad
    3129            0 :                         ShowSevereError(state,
    3130            0 :                                         format("{} = {} has a conflicting Controller:WaterCoil object", CurrentModuleObject, thisFurnace.Name));
    3131            0 :                         ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
    3132            0 :                         ShowContinueError(state, "No water coil controller should be input for the coil.");
    3133            0 :                         ErrorsFound = true;
    3134              :                     }
    3135              :                 }
    3136              : 
    3137            0 :             } else if (Util::SameString(SuppHeatCoilType, "Coil:Heating:Steam")) {
    3138            0 :                 thisFurnace.SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
    3139            0 :                 ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
    3140            0 :                 if (IsNotOK) {
    3141            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3142            0 :                     ErrorsFound = true;
    3143              :                 } else { // mine data from heating coil object
    3144              : 
    3145            0 :                     errFlag = false;
    3146            0 :                     thisFurnace.SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", SuppHeatCoilName, errFlag);
    3147            0 :                     if (thisFurnace.SuppHeatCoilIndex == 0) {
    3148            0 :                         ShowSevereError(state, format("{} illegal {} = {}", CurrentModuleObject, cAlphaFields(12), SuppHeatCoilName));
    3149            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3150            0 :                         ErrorsFound = true;
    3151              :                     }
    3152              : 
    3153              :                     // Get the Heating Coil steam inlet node number
    3154            0 :                     errFlag = false;
    3155            0 :                     thisFurnace.SuppCoilControlNode = SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", SuppHeatCoilName, errFlag);
    3156            0 :                     if (errFlag) {
    3157            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3158            0 :                         ErrorsFound = true;
    3159              :                     }
    3160              : 
    3161              :                     // Get the Heating Coil steam max volume flow rate
    3162            0 :                     thisFurnace.MaxSuppCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.SuppHeatCoilIndex, errFlag);
    3163            0 :                     if (thisFurnace.MaxSuppCoilFluidFlow > 0.0) {
    3164              :                         SteamDensity =
    3165            0 :                             Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, getAirLoopHVACHeatCoolInput);
    3166            0 :                         thisFurnace.MaxSuppCoilFluidFlow =
    3167            0 :                             SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.SuppHeatCoilIndex, errFlag) * SteamDensity;
    3168              :                     }
    3169              : 
    3170              :                     // Get the Heating Coil Inlet Node
    3171            0 :                     errFlag = false;
    3172            0 :                     SupHeatCoilInletNode = SteamCoils::GetCoilAirInletNode(state, thisFurnace.SuppHeatCoilIndex, SuppHeatCoilName, errFlag);
    3173            0 :                     thisFurnace.SuppCoilAirInletNode = SupHeatCoilInletNode;
    3174            0 :                     if (errFlag) {
    3175            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3176            0 :                         ErrorsFound = true;
    3177              :                     }
    3178              : 
    3179              :                     // Get the Heating Coil Outlet Node
    3180            0 :                     errFlag = false;
    3181            0 :                     SupHeatCoilOutletNode = SteamCoils::GetCoilAirOutletNode(state, thisFurnace.SuppHeatCoilIndex, SuppHeatCoilName, errFlag);
    3182            0 :                     thisFurnace.SuppCoilAirOutletNode = SupHeatCoilOutletNode;
    3183            0 :                     if (errFlag) {
    3184            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3185            0 :                         ErrorsFound = true;
    3186              :                     }
    3187              :                 }
    3188              : 
    3189              :             } else {
    3190            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3191            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(12), Alphas(12)));
    3192            0 :                 ErrorsFound = true;
    3193              :             } // IF (Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
    3194              : 
    3195            2 :             thisFurnace.fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Alphas(14)));
    3196            2 :             assert(thisFurnace.fanPlace != HVAC::FanPlace::Invalid);
    3197              : 
    3198            2 :             if (lAlphaBlanks(15)) {
    3199            0 :                 thisFurnace.fanOp = HVAC::FanOp::Cycling;
    3200            0 :                 if (thisFurnace.fanType != HVAC::FanType::OnOff) {
    3201            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisFurnace.Name));
    3202            0 :                     ShowContinueError(state, format("{} = {}", cAlphaFields(6), Alphas(6)));
    3203            0 :                     ShowContinueError(state, format("Fan type must be Fan:OnOff when {} = Blank.", cAlphaFields(15)));
    3204            0 :                     ErrorsFound = true;
    3205              :                 }
    3206            2 :             } else if ((thisFurnace.fanOpModeSched = Sched::GetSchedule(state, Alphas(15))) == nullptr) {
    3207            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(15), Alphas(15));
    3208            0 :                 ErrorsFound = true;
    3209              :             }
    3210              : 
    3211            2 :             if (thisFurnace.fanType == HVAC::FanType::Constant && thisFurnace.fanOpModeSched != nullptr &&
    3212            0 :                 !thisFurnace.fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 1.0)) {
    3213            0 :                 Sched::ShowSevereBadMinMax(
    3214              :                     state,
    3215              :                     eoh,
    3216            0 :                     cAlphaFields(15),
    3217            0 :                     Alphas(15),
    3218              :                     Clusive::In,
    3219              :                     0.0,
    3220              :                     Clusive::In,
    3221              :                     1.0,
    3222            0 :                     format("For {} = {}, fan operating mode must be continuous (schedule values > 0)", cAlphaFields(7), Alphas(7)));
    3223            0 :                 ErrorsFound = true;
    3224              :             }
    3225              : 
    3226              :             // Dehumidification Control Type
    3227            2 :             if (Util::SameString(Alphas(16), "None") || Util::SameString(Alphas(16), "Multimode") || Util::SameString(Alphas(16), "CoolReheat")) {
    3228            2 :                 AirNodeFound = false;
    3229            2 :                 if (Util::SameString(Alphas(16), "Multimode")) {
    3230            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::Multimode;
    3231            0 :                     thisFurnace.Humidistat = true;
    3232            0 :                     if (thisFurnace.CoolingCoilType_Num != HVAC::CoilDX_CoolingHXAssisted) {
    3233            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3234            0 :                         ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(16), Alphas(16)));
    3235            0 :                         ShowContinueError(state, "Multimode control must be used with a Heat Exchanger Assisted Cooling Coil.");
    3236            0 :                         ErrorsFound = true;
    3237              :                     }
    3238              :                 }
    3239            2 :                 if (Util::SameString(Alphas(16), "CoolReheat")) {
    3240            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::CoolReheat;
    3241            0 :                     thisFurnace.Humidistat = true;
    3242              :                 }
    3243            2 :                 if (Util::SameString(Alphas(16), "None")) {
    3244            2 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::None;
    3245            2 :                     thisFurnace.Humidistat = false;
    3246              :                 }
    3247            2 :                 if (thisFurnace.Humidistat) {
    3248            0 :                     for (HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
    3249            0 :                         if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    3250            0 :                             continue;
    3251              :                         }
    3252            0 :                         AirNodeFound = true;
    3253              :                     }
    3254            0 :                     if (!AirNodeFound) {
    3255            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3256            0 :                         ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
    3257            0 :                         ShowContinueError(state, format("Specified {} = {}", cAlphaFields(5), Alphas(5)));
    3258            0 :                         ErrorsFound = true;
    3259              :                     }
    3260              :                 }
    3261              :             } else { // invalid input or blank
    3262            0 :                 if (!lAlphaBlanks(16)) {
    3263            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3264            0 :                     ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(16), Alphas(16)));
    3265            0 :                     ErrorsFound = true;
    3266              :                 } else {
    3267            0 :                     thisFurnace.Humidistat = false;
    3268            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::None;
    3269              :                 }
    3270              :             }
    3271              : 
    3272              :             // Check node names for child components
    3273            2 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    3274            2 :                 if (FanInletNode != thisFurnace.FurnaceInletNodeNum) {
    3275            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3276            0 :                     ShowContinueError(
    3277              :                         state,
    3278              :                         "When a blow through fan is specified, the fan inlet node name must be the same as the unitary system inlet node name.");
    3279            0 :                     ShowContinueError(state, format("...Fan inlet node name            = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    3280            0 :                     ShowContinueError(state,
    3281            0 :                                       format("...Unitary system inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    3282            0 :                     ErrorsFound = true;
    3283              :                 }
    3284            2 :                 if (FanOutletNode != CoolingCoilInletNode) {
    3285            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3286            0 :                     ShowContinueError(
    3287              :                         state,
    3288              :                         "When a blow through fan is specified, the fan outlet node name must be the same as the cooling coil inlet node name.");
    3289            0 :                     ShowContinueError(state, format("...Fan outlet node name         = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    3290            0 :                     ShowContinueError(state, format("...Cooling coil inlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    3291            0 :                     ErrorsFound = true;
    3292              :                 }
    3293            2 :                 if (CoolingCoilOutletNode != HeatingCoilInletNode) {
    3294            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3295            0 :                     ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
    3296            0 :                     ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    3297            0 :                     ShowContinueError(state, format("...Heating coil inlet node name  = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    3298            0 :                     ErrorsFound = true;
    3299              :                 }
    3300            2 :                 if (HeatingCoilOutletNode != SupHeatCoilInletNode) {
    3301            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3302            0 :                     ShowContinueError(state,
    3303              :                                       "When a blow through fan is specified, the heating coil outlet node name must be the same as the supplemental "
    3304              :                                       "heating coil inlet node name.");
    3305            0 :                     ShowContinueError(
    3306            0 :                         state, format("...Heating coil outlet node name              = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    3307            0 :                     ShowContinueError(
    3308            0 :                         state, format("...Supplemental heating coil inlet node name  = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
    3309            0 :                     ErrorsFound = true;
    3310              :                 }
    3311            2 :                 if (SupHeatCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    3312            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3313            0 :                     ShowContinueError(state,
    3314              :                                       "The supplemental heating coil outlet node name must be the same as the unitary system outlet node name.");
    3315            0 :                     ShowContinueError(
    3316            0 :                         state, format("...Supplemental heating coil outlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
    3317            0 :                     ShowContinueError(
    3318              :                         state,
    3319            0 :                         format("...Unitary system outlet node name            = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    3320            0 :                     ErrorsFound = true;
    3321              :                 }
    3322              :             } else {
    3323            0 :                 if (CoolingCoilInletNode != thisFurnace.FurnaceInletNodeNum) {
    3324            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3325            0 :                     ShowContinueError(state,
    3326              :                                       "When a draw through fan is specified, the cooling coil inlet node name must be the same as the unitary system "
    3327              :                                       "inlet node name.");
    3328            0 :                     ShowContinueError(state, format("...Cooling coil inlet node name   = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    3329            0 :                     ShowContinueError(state,
    3330            0 :                                       format("...Unitary system inlet node name = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    3331            0 :                     ErrorsFound = true;
    3332              :                 }
    3333            0 :                 if (CoolingCoilOutletNode != HeatingCoilInletNode) {
    3334            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3335            0 :                     ShowContinueError(state, "The cooling coil outlet node name must be the same as the heating coil inlet node name.");
    3336            0 :                     ShowContinueError(state, format("...Cooling coil outlet node name = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    3337            0 :                     ShowContinueError(state, format("...Heating coil inlet node name  = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    3338            0 :                     ErrorsFound = true;
    3339              :                 }
    3340            0 :                 if (HeatingCoilOutletNode != FanInletNode) {
    3341            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3342            0 :                     ShowContinueError(
    3343              :                         state,
    3344              :                         "When a draw through fan is specified, the heating coil outlet node name must be the same as the fan inlet node name.");
    3345            0 :                     ShowContinueError(state, format("...Heating coil outlet node name = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    3346            0 :                     ShowContinueError(state, format("...Fan inlet node name           = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    3347            0 :                     ErrorsFound = true;
    3348              :                 }
    3349            0 :                 if (FanOutletNode != SupHeatCoilInletNode) {
    3350            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3351            0 :                     ShowContinueError(state,
    3352              :                                       "When a draw through fan is specified, the fan outlet node name must be the same as the supplemental heating "
    3353              :                                       "coil inlet node name.");
    3354            0 :                     ShowContinueError(state,
    3355            0 :                                       format("...Fan outlet node name                       = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    3356            0 :                     ShowContinueError(
    3357            0 :                         state, format("...Supplemental heating coil inlet node name  = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
    3358            0 :                     ErrorsFound = true;
    3359              :                 }
    3360            0 :                 if (SupHeatCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    3361            0 :                     ShowSevereError(state, format("For {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3362            0 :                     ShowContinueError(state,
    3363              :                                       "The supplemental heating coil outlet node name must be the same as the unitary system outlet node name.");
    3364            0 :                     ShowContinueError(
    3365            0 :                         state, format("...Supplemental heating coil outlet node name = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
    3366            0 :                     ShowContinueError(
    3367              :                         state,
    3368            0 :                         format("...Unitary system outlet node name            = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    3369            0 :                     ErrorsFound = true;
    3370              :                 }
    3371              :             }
    3372              : 
    3373              :             // Add component sets array
    3374            2 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    3375            2 :                 CompSetFanInlet = Alphas(3);
    3376            2 :                 CompSetCoolInlet = "UNDEFINED";
    3377              :             } else {
    3378            0 :                 CompSetFanInlet = "UNDEFINED";
    3379            0 :                 CompSetCoolInlet = Alphas(3);
    3380              :             }
    3381            2 :             BranchNodeConnections::SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(6), Alphas(7), CompSetFanInlet, "UNDEFINED");
    3382              : 
    3383              :             // Add DX cooling coil to component sets array
    3384            2 :             if (thisFurnace.bIsIHP) {
    3385            0 :                 BranchNodeConnections::SetUpCompSets(
    3386            0 :                     state, CurrentModuleObject, Alphas(1), Alphas(10), Alphas(11) + " Cooling Coil", CompSetCoolInlet, "UNDEFINED");
    3387              :             } else {
    3388            2 :                 BranchNodeConnections::SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(10), Alphas(11), CompSetCoolInlet, "UNDEFINED");
    3389              :             }
    3390              :             // Add DX heating coil to component sets array
    3391            2 :             if (thisFurnace.bIsIHP) {
    3392            0 :                 BranchNodeConnections::SetUpCompSets(
    3393            0 :                     state, CurrentModuleObject, Alphas(1), Alphas(8), Alphas(9) + " Heating Coil", "UNDEFINED", "UNDEFINED");
    3394              :             } else {
    3395            2 :                 BranchNodeConnections::SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(8), Alphas(9), "UNDEFINED", "UNDEFINED");
    3396              :             }
    3397              : 
    3398              :             // Add supplemental heating coil to component sets array
    3399            2 :             BranchNodeConnections::SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(12), Alphas(13), "UNDEFINED", Alphas(4));
    3400              : 
    3401            2 :             thisFurnace.MaxCoolAirVolFlow = Numbers(1);
    3402            2 :             if (thisFurnace.MaxCoolAirVolFlow <= 0 && thisFurnace.MaxCoolAirVolFlow != DataSizing::AutoSize) {
    3403            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3404            0 :                 ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(1), Numbers(1)));
    3405            0 :                 ErrorsFound = true;
    3406              :             }
    3407              : 
    3408            2 :             thisFurnace.MaxHeatAirVolFlow = Numbers(2);
    3409            2 :             if (thisFurnace.MaxHeatAirVolFlow <= 0 && thisFurnace.MaxHeatAirVolFlow != DataSizing::AutoSize) {
    3410            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3411            0 :                 ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(2), Numbers(2)));
    3412            0 :                 ErrorsFound = true;
    3413              :             }
    3414              : 
    3415            2 :             thisFurnace.MaxNoCoolHeatAirVolFlow = Numbers(3);
    3416            2 :             if (thisFurnace.MaxNoCoolHeatAirVolFlow < 0 && thisFurnace.MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
    3417            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3418            0 :                 ShowContinueError(state, format("Illegal {} = {:.7T}", cNumericFields(3), Numbers(3)));
    3419            0 :                 ErrorsFound = true;
    3420              :             }
    3421              : 
    3422            2 :             if (thisFurnace.fanOpModeSched != nullptr) {
    3423            2 :                 if (!thisFurnace.fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) { // Autodesk:Note Range is 0 to 0?
    3424              :                     //           set air flow control mode:
    3425              :                     //             UseCompressorOnFlow = operate at last cooling or heating air flow requested when compressor is off
    3426              :                     //             UseCompressorOffFlow = operate at value specified by user
    3427              :                     //           AirFlowControl only valid if fan opmode = ContFanCycComp
    3428            0 :                     if (thisFurnace.MaxNoCoolHeatAirVolFlow == 0.0) {
    3429            0 :                         thisFurnace.AirFlowControl = AirFlowControlConstFan::UseCompressorOnFlow;
    3430              :                     } else {
    3431            0 :                         thisFurnace.AirFlowControl = AirFlowControlConstFan::UseCompressorOffFlow;
    3432              :                     }
    3433              :                 }
    3434              :             }
    3435              : 
    3436            2 :             if (Numbers(1) != DataSizing::AutoSize && Numbers(2) != DataSizing::AutoSize && Numbers(3) != DataSizing::AutoSize) {
    3437            0 :                 thisFurnace.DesignFanVolFlowRate = max(Numbers(1), Numbers(2), Numbers(3));
    3438              :             } else {
    3439            2 :                 thisFurnace.DesignFanVolFlowRate = DataSizing::AutoSize;
    3440              :             }
    3441              : 
    3442            2 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
    3443            0 :                 errFlag = false;
    3444              : 
    3445            0 :                 if (thisFurnace.bIsIHP) {
    3446            0 :                     IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SHCoilName;
    3447            0 :                     thisFurnace.MaxHeatAirVolFlow =
    3448            0 :                         VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, "COIL:HEATING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    3449            0 :                     IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilName;
    3450            0 :                     thisFurnace.MaxCoolAirVolFlow =
    3451            0 :                         VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    3452              :                 } else {
    3453            0 :                     thisFurnace.MaxHeatAirVolFlow =
    3454            0 :                         VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    3455            0 :                     thisFurnace.MaxCoolAirVolFlow =
    3456            0 :                         VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    3457              :                 }
    3458              : 
    3459            0 :                 if (errFlag) {
    3460            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3461            0 :                     ErrorsFound = true;
    3462              :                 }
    3463              : 
    3464            0 :                 thisFurnace.MaxNoCoolHeatAirVolFlow = min(thisFurnace.MaxHeatAirVolFlow, thisFurnace.MaxCoolAirVolFlow);
    3465            0 :                 if (thisFurnace.MaxHeatAirVolFlow != DataSizing::AutoSize && thisFurnace.MaxCoolAirVolFlow != DataSizing::AutoSize) {
    3466            0 :                     thisFurnace.DesignFanVolFlowRate = max(thisFurnace.MaxHeatAirVolFlow, thisFurnace.MaxCoolAirVolFlow);
    3467              :                 } else {
    3468            0 :                     thisFurnace.DesignFanVolFlowRate = DataSizing::AutoSize;
    3469              :                 }
    3470              :             }
    3471              : 
    3472            2 :             if (thisFurnace.ActualFanVolFlowRate != DataSizing::AutoSize) {
    3473            0 :                 if (thisFurnace.ActualFanVolFlowRate < thisFurnace.MaxCoolAirVolFlow && thisFurnace.MaxCoolAirVolFlow != DataSizing::AutoSize) {
    3474            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3475            0 :                     ShowContinueError(
    3476              :                         state,
    3477            0 :                         format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in cooling mode.",
    3478            0 :                                thisFurnace.ActualFanVolFlowRate,
    3479              :                                FanName));
    3480            0 :                     ShowContinueError(state, format(" The {} is reset to the fan flow rate and the simulation continues.", cNumericFields(1)));
    3481            0 :                     thisFurnace.MaxCoolAirVolFlow = thisFurnace.ActualFanVolFlowRate;
    3482            0 :                     thisFurnace.DesignFanVolFlowRate = thisFurnace.ActualFanVolFlowRate;
    3483              :                 }
    3484            0 :                 if (thisFurnace.ActualFanVolFlowRate < thisFurnace.MaxHeatAirVolFlow && thisFurnace.MaxHeatAirVolFlow != DataSizing::AutoSize) {
    3485            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3486            0 :                     ShowContinueError(
    3487              :                         state,
    3488            0 :                         format("... air flow rate = {:.7T} in fan object {} is less than the maximum HVAC system air flow rate in heating mode.",
    3489            0 :                                thisFurnace.ActualFanVolFlowRate,
    3490              :                                FanName));
    3491            0 :                     ShowContinueError(state, format(" The {} is reset to the fan flow rate and the simulation continues.", cNumericFields(2)));
    3492            0 :                     thisFurnace.MaxHeatAirVolFlow = thisFurnace.ActualFanVolFlowRate;
    3493            0 :                     thisFurnace.DesignFanVolFlowRate = thisFurnace.ActualFanVolFlowRate;
    3494              :                 }
    3495              :             }
    3496              : 
    3497              :             // Set heating convergence tolerance
    3498            2 :             thisFurnace.HeatingConvergenceTolerance = 0.001;
    3499              : 
    3500              :             //       Mine heatpump outdoor condenser node from DX coil object
    3501            2 :             errFlag = false;
    3502            2 :             if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
    3503            2 :                 thisFurnace.CondenserNodeNum = DXCoils::GetCoilCondenserInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    3504            0 :             } else if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    3505            0 :                 if (thisFurnace.bIsIHP) {
    3506            0 :                     IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilName;
    3507            0 :                     thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, IHPCoilName, errFlag);
    3508              :                 } else {
    3509            0 :                     thisFurnace.CondenserNodeNum = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, CoolingCoilName, errFlag);
    3510              :                 }
    3511              :             } else {
    3512            0 :                 thisFurnace.CondenserNodeNum =
    3513            0 :                     DXCoils::GetCoilCondenserInletNode(state,
    3514              :                                                        "Coil:Cooling:DX:SingleSpeed",
    3515            0 :                                                        HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, CoolingCoilType, CoolingCoilName, errFlag),
    3516              :                                                        errFlag);
    3517              :             }
    3518            2 :             if (errFlag) {
    3519            0 :                 ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3520            0 :                 ErrorsFound = true;
    3521              :             }
    3522              : 
    3523            2 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
    3524            0 :                 errFlag = false;
    3525            0 :                 if (thisFurnace.bIsIHP) {
    3526            0 :                     IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SHCoilName;
    3527            0 :                     thisFurnace.DesignHeatingCapacity =
    3528            0 :                         VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, "Coil:Heating:DX:VariableSpeed", IHPCoilName, errFlag);
    3529              :                 } else {
    3530            0 :                     thisFurnace.DesignHeatingCapacity =
    3531            0 :                         VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    3532              :                 }
    3533              : 
    3534            0 :                 if (errFlag) {
    3535            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3536            0 :                     ErrorsFound = true;
    3537              :                 }
    3538              :             }
    3539              : 
    3540            2 :             if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    3541            0 :                 errFlag = false;
    3542            0 :                 if (thisFurnace.bIsIHP) {
    3543            0 :                     IHPCoilName = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilName;
    3544            0 :                     thisFurnace.DesignCoolingCapacity =
    3545            0 :                         VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, "COIL:COOLING:DX:VARIABLESPEED", IHPCoilName, errFlag);
    3546              :                 } else {
    3547            0 :                     thisFurnace.DesignCoolingCapacity =
    3548            0 :                         VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    3549              :                 }
    3550              : 
    3551            0 :                 if (errFlag) {
    3552            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3553            0 :                     ErrorsFound = true;
    3554              :                 }
    3555              :             }
    3556              : 
    3557              :             // Set cooling convergence tolerance
    3558            2 :             thisFurnace.CoolingConvergenceTolerance = 0.001;
    3559              : 
    3560              :             // Set the furnace max outlet temperature
    3561            2 :             thisFurnace.DesignMaxOutletTemp = Numbers(4);
    3562              : 
    3563              :             // Set maximum supply air temperature for supplemental heating coil
    3564            2 :             thisFurnace.MaxOATSuppHeat = Numbers(5);
    3565            4 :             OutputReportPredefined::PreDefTableEntry(
    3566            2 :                 state, state.dataOutRptPredefined->pdchDXHeatCoilSuppHiT, HeatingCoilName, thisFurnace.MaxOATSuppHeat);
    3567              : 
    3568              :             // set minimum outdoor temperature for compressor operation
    3569            2 :             SetMinOATCompressor(state, FurnaceNum, cCurrentModuleObject, ErrorsFound);
    3570              : 
    3571              :         } // End of the Unitary System HeatPump Loop
    3572              : 
    3573              :         // Get the Input for the Water to Air Heat Pump (UnitarySystem:HeatPump:WaterToAir)
    3574            2 :         for (int HeatPumpNum = 1; HeatPumpNum <= NumWaterToAirHeatPump; ++HeatPumpNum) {
    3575              : 
    3576            0 :             CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:WaterToAir";
    3577            0 :             FanInletNode = 0;
    3578            0 :             FanOutletNode = 0;
    3579            0 :             CoolingCoilInletNode = 0;
    3580            0 :             CoolingCoilOutletNode = 0;
    3581            0 :             HeatingCoilInletNode = 0;
    3582            0 :             HeatingCoilOutletNode = 0;
    3583            0 :             SupHeatCoilInletNode = 0;
    3584            0 :             SupHeatCoilOutletNode = 0;
    3585            0 :             CoolingCoilType = ' ';
    3586            0 :             CoolingCoilName = ' ';
    3587            0 :             HeatingCoilType = ' ';
    3588            0 :             HeatingCoilName = ' ';
    3589              : 
    3590            0 :             FurnaceNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + NumHeatPump + HeatPumpNum;
    3591            0 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    3592            0 :             thisFurnace.iterationMode.allocate(3);
    3593              : 
    3594            0 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    3595              :                                                                      CurrentModuleObject,
    3596              :                                                                      HeatPumpNum,
    3597              :                                                                      Alphas,
    3598              :                                                                      NumAlphas,
    3599              :                                                                      Numbers,
    3600              :                                                                      NumNumbers,
    3601              :                                                                      IOStatus,
    3602              :                                                                      lNumericBlanks,
    3603              :                                                                      lAlphaBlanks,
    3604              :                                                                      cAlphaFields,
    3605              :                                                                      cNumericFields);
    3606              : 
    3607            0 :             GlobalNames::VerifyUniqueInterObjectName(
    3608            0 :                 state, state.dataFurnaces->UniqueFurnaceNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    3609              : 
    3610            0 :             thisFurnace.type = HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir;
    3611            0 :             thisFurnace.Name = Alphas(1);
    3612              : 
    3613            0 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, thisFurnace.Name};
    3614              : 
    3615            0 :             if (lAlphaBlanks(2)) {
    3616            0 :                 thisFurnace.availSched = Sched::GetScheduleAlwaysOn(state);
    3617            0 :             } else if ((thisFurnace.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
    3618            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
    3619            0 :                 ErrorsFound = true;
    3620              :             }
    3621              : 
    3622            0 :             thisFurnace.FurnaceInletNodeNum =
    3623            0 :                 NodeInputManager::GetOnlySingleNode(state,
    3624            0 :                                                     Alphas(3),
    3625              :                                                     ErrorsFound,
    3626              :                                                     DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpWaterToAir,
    3627            0 :                                                     Alphas(1),
    3628              :                                                     DataLoopNode::NodeFluidType::Air,
    3629              :                                                     DataLoopNode::ConnectionType::Inlet,
    3630              :                                                     NodeInputManager::CompFluidStream::Primary,
    3631              :                                                     DataLoopNode::ObjectIsParent);
    3632              : 
    3633            0 :             thisFurnace.FurnaceOutletNodeNum =
    3634            0 :                 NodeInputManager::GetOnlySingleNode(state,
    3635            0 :                                                     Alphas(4),
    3636              :                                                     ErrorsFound,
    3637              :                                                     DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpWaterToAir,
    3638            0 :                                                     Alphas(1),
    3639              :                                                     DataLoopNode::NodeFluidType::Air,
    3640              :                                                     DataLoopNode::ConnectionType::Outlet,
    3641              :                                                     NodeInputManager::CompFluidStream::Primary,
    3642              :                                                     DataLoopNode::ObjectIsParent);
    3643              : 
    3644            0 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    3645              : 
    3646              :             // Get the Controlling Zone or Location of the Furnace Thermostat
    3647            0 :             thisFurnace.ControlZoneNum = Util::FindItemInList(Alphas(5), state.dataHeatBal->Zone);
    3648            0 :             if (thisFurnace.ControlZoneNum == 0) {
    3649            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3650            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(5), Alphas(5)));
    3651            0 :                 ErrorsFound = true;
    3652              :             }
    3653              : 
    3654              :             // Get the node number for the zone with the thermostat
    3655            0 :             if (thisFurnace.ControlZoneNum > 0) {
    3656            0 :                 AirNodeFound = false;
    3657            0 :                 AirLoopFound = false;
    3658            0 :                 int ControlledZoneNum = thisFurnace.ControlZoneNum;
    3659              :                 //             Find the controlled zone number for the specified thermostat location
    3660            0 :                 thisFurnace.NodeNumOfControlledZone = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
    3661              :                 //             Determine if furnace is on air loop served by the thermostat location specified
    3662            0 :                 for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    3663            0 :                     int AirLoopNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode);
    3664            0 :                     if (AirLoopNumber > 0) {
    3665            0 :                         for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).NumBranches; ++BranchNum) {
    3666            0 :                             for (int CompNum = 1;
    3667            0 :                                  CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).TotalComponents;
    3668              :                                  ++CompNum) {
    3669            0 :                                 if (!Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).Name,
    3670            0 :                                                       Alphas(1)) ||
    3671            0 :                                     !Util::SameString(
    3672            0 :                                         state.dataAirSystemsData->PrimaryAirSystems(AirLoopNumber).Branch(BranchNum).Comp(CompNum).TypeOf,
    3673              :                                         CurrentModuleObject)) {
    3674            0 :                                     continue;
    3675              :                                 }
    3676            0 :                                 AirLoopFound = true;
    3677            0 :                                 thisFurnace.ZoneInletNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNode(zoneInNode);
    3678            0 :                                 break;
    3679              :                             }
    3680            0 :                             if (AirLoopFound) {
    3681            0 :                                 break;
    3682              :                             }
    3683              :                         }
    3684            0 :                         for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
    3685            0 :                             if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    3686            0 :                                 continue;
    3687              :                             }
    3688            0 :                             AirNodeFound = true;
    3689              :                         }
    3690            0 :                         for (TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumComfortControlledZones; ++TstatZoneNum) {
    3691            0 :                             if (state.dataZoneCtrls->ComfortControlledZone(TstatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    3692            0 :                                 continue;
    3693              :                             }
    3694            0 :                             AirNodeFound = true;
    3695              :                         }
    3696              :                     }
    3697            0 :                     if (AirLoopFound) {
    3698            0 :                         break;
    3699              :                     }
    3700              :                 }
    3701            0 :                 if (!AirNodeFound) {
    3702            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3703            0 :                     ShowContinueError(state, "Did not find air node (zone with thermostat).");
    3704            0 :                     ShowContinueError(state, format("Specified {} = {}", cAlphaFields(5), Alphas(5)));
    3705            0 :                     ShowContinueError(
    3706              :                         state, "Both a ZoneHVAC:EquipmentConnections object and a ZoneControl:Thermostat object must be specified for this zone.");
    3707            0 :                     ErrorsFound = true;
    3708              :                 }
    3709            0 :                 if (!AirLoopFound) {
    3710            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3711            0 :                     ShowContinueError(state, "Did not find correct AirLoopHVAC.");
    3712            0 :                     ShowContinueError(state, format("Specified {} = {}", cAlphaFields(5), Alphas(5)));
    3713            0 :                     ErrorsFound = true;
    3714              :                 }
    3715              :             }
    3716              : 
    3717              :             // Get fan data
    3718            0 :             FanName = Alphas(7);
    3719            0 :             errFlag = false;
    3720            0 :             thisFurnace.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(6)));
    3721              : 
    3722            0 :             if (thisFurnace.fanType != HVAC::FanType::OnOff) {
    3723            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3724            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(6), Alphas(6)));
    3725            0 :                 ErrorsFound = true;
    3726              : 
    3727            0 :             } else if ((thisFurnace.FanIndex = Fans::GetFanIndex(state, FanName)) == 0) {
    3728            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(7), FanName);
    3729            0 :                 ErrorsFound = true;
    3730              : 
    3731              :             } else {
    3732            0 :                 auto *fan = state.dataFans->fans(thisFurnace.FanIndex);
    3733            0 :                 FanInletNode = fan->inletNodeNum;
    3734            0 :                 FanOutletNode = fan->outletNodeNum;
    3735            0 :                 thisFurnace.fanAvailSched = fan->availSched;
    3736              :             }
    3737              : 
    3738              :             // Get heating coil type and name data
    3739            0 :             if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION") {
    3740            0 :                 HeatingCoilType = Alphas(8);
    3741            0 :                 thisFurnace.HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHP;
    3742            0 :                 HeatingCoilName = Alphas(9);
    3743            0 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    3744            0 :                 if (IsNotOK) {
    3745            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3746            0 :                     ErrorsFound = true;
    3747              :                 } else {
    3748            0 :                     thisFurnace.HeatingCoilIndex = WaterToAirHeatPump::GetCoilIndex(state, HeatingCoilType, HeatingCoilName, errFlag);
    3749            0 :                     HeatingCoilInletNode = WaterToAirHeatPump::GetCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    3750            0 :                     HeatingCoilOutletNode = WaterToAirHeatPump::GetCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    3751              :                 }
    3752            0 :             } else if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
    3753            0 :                 HeatingCoilType = Alphas(8);
    3754            0 :                 thisFurnace.HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPSimple;
    3755            0 :                 HeatingCoilName = Alphas(9);
    3756            0 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    3757            0 :                 if (IsNotOK) {
    3758            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3759            0 :                     ErrorsFound = true;
    3760              :                 } else {
    3761            0 :                     thisFurnace.HeatingCoilIndex = WaterToAirHeatPumpSimple::GetCoilIndex(state, HeatingCoilType, HeatingCoilName, errFlag);
    3762            0 :                     HeatingCoilInletNode = WaterToAirHeatPumpSimple::GetCoilInletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    3763            0 :                     HeatingCoilOutletNode = WaterToAirHeatPumpSimple::GetCoilOutletNode(state, HeatingCoilType, HeatingCoilName, errFlag);
    3764              :                 }
    3765            0 :             } else if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
    3766            0 :                 HeatingCoilType = Alphas(8);
    3767            0 :                 thisFurnace.HeatingCoilType_Num = HVAC::Coil_HeatingWaterToAirHPVSEquationFit;
    3768            0 :                 HeatingCoilName = Alphas(9);
    3769            0 :                 ValidateComponent(state, HeatingCoilType, HeatingCoilName, IsNotOK, CurrentModuleObject);
    3770            0 :                 if (IsNotOK) {
    3771            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3772            0 :                     ErrorsFound = true;
    3773              :                 } else {
    3774            0 :                     thisFurnace.HeatingCoilIndex = VariableSpeedCoils::GetCoilIndexVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    3775            0 :                     HeatingCoilInletNode = VariableSpeedCoils::GetCoilInletNodeVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    3776            0 :                     HeatingCoilOutletNode = VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    3777              :                 }
    3778              :             } else {
    3779            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3780            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(8), Alphas(8)));
    3781            0 :                 ErrorsFound = true;
    3782              :             }
    3783              : 
    3784              :             // Get Cooling Coil Information if available
    3785            0 :             if (Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION") {
    3786            0 :                 CoolingCoilType = Alphas(10);
    3787            0 :                 thisFurnace.CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHP;
    3788            0 :                 CoolingCoilName = Alphas(11);
    3789            0 :                 ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
    3790            0 :                 if (IsNotOK) {
    3791            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3792            0 :                     ErrorsFound = true;
    3793              :                 } else {
    3794            0 :                     thisFurnace.CoolingCoilIndex = WaterToAirHeatPump::GetCoilIndex(state, CoolingCoilType, CoolingCoilName, errFlag);
    3795            0 :                     CoolingCoilInletNode = WaterToAirHeatPump::GetCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    3796            0 :                     CoolingCoilOutletNode = WaterToAirHeatPump::GetCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    3797              :                 }
    3798            0 :             } else if (Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
    3799            0 :                 CoolingCoilType = Alphas(10);
    3800            0 :                 thisFurnace.CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPSimple;
    3801            0 :                 CoolingCoilName = Alphas(11);
    3802            0 :                 ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
    3803            0 :                 if (IsNotOK) {
    3804            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3805            0 :                     ErrorsFound = true;
    3806              :                 } else {
    3807            0 :                     thisFurnace.CoolingCoilIndex = WaterToAirHeatPumpSimple::GetCoilIndex(state, CoolingCoilType, CoolingCoilName, errFlag);
    3808            0 :                     CoolingCoilInletNode = WaterToAirHeatPumpSimple::GetCoilInletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    3809            0 :                     CoolingCoilOutletNode = WaterToAirHeatPumpSimple::GetCoilOutletNode(state, CoolingCoilType, CoolingCoilName, errFlag);
    3810              :                 }
    3811            0 :             } else if (Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
    3812            0 :                 CoolingCoilType = Alphas(10);
    3813            0 :                 thisFurnace.CoolingCoilType_Num = HVAC::Coil_CoolingWaterToAirHPVSEquationFit;
    3814            0 :                 CoolingCoilName = Alphas(11);
    3815            0 :                 ValidateComponent(state, CoolingCoilType, CoolingCoilName, IsNotOK, CurrentModuleObject);
    3816            0 :                 if (IsNotOK) {
    3817            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3818            0 :                     ErrorsFound = true;
    3819              :                 } else {
    3820            0 :                     thisFurnace.CoolingCoilIndex = VariableSpeedCoils::GetCoilIndexVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    3821            0 :                     CoolingCoilInletNode = VariableSpeedCoils::GetCoilInletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    3822            0 :                     CoolingCoilOutletNode = VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    3823              :                 }
    3824              :             } else {
    3825            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    3826            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(10), Alphas(10)));
    3827            0 :                 ErrorsFound = true;
    3828              :             }
    3829              : 
    3830            0 :             thisFurnace.WaterCyclingMode = (NumAlphas < 18 || lAlphaBlanks(18))
    3831            0 :                                                ? HVAC::WaterFlow::Cycling
    3832            0 :                                                : static_cast<HVAC::WaterFlow>(getEnumValue(HVAC::waterFlowNamesUC, Alphas(18)));
    3833              : 
    3834              :             // end get water flow mode info
    3835            0 :             if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT" && Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") {
    3836            0 :                 thisFurnace.WatertoAirHPType = WAHPCoilType::Simple;
    3837            0 :                 WaterToAirHeatPumpSimple::SetSimpleWSHPData(
    3838            0 :                     state, thisFurnace.CoolingCoilIndex, ErrorsFound, thisFurnace.WaterCyclingMode, _, thisFurnace.HeatingCoilIndex);
    3839            0 :             } else if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION" &&
    3840            0 :                        Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION") {
    3841            0 :                 thisFurnace.WatertoAirHPType = WAHPCoilType::ParEst;
    3842            0 :             } else if (Alphas(8) == "COIL:HEATING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT" &&
    3843            0 :                        Alphas(10) == "COIL:COOLING:WATERTOAIRHEATPUMP:VARIABLESPEEDEQUATIONFIT") {
    3844            0 :                 thisFurnace.WatertoAirHPType = WAHPCoilType::VarSpeedEquationFit;
    3845            0 :                 VariableSpeedCoils::SetVarSpeedCoilData(state, thisFurnace.CoolingCoilIndex, ErrorsFound, _, thisFurnace.HeatingCoilIndex);
    3846              :             } else {
    3847            0 :                 ShowContinueError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    3848            0 :                 ShowContinueError(state, "Cooling coil and heating coil should be of same general type");
    3849            0 :                 ErrorsFound = true;
    3850              :             }
    3851              : 
    3852              :             // Get supplemental heating coil information
    3853              : 
    3854            0 :             SuppHeatCoilType = Alphas(12);
    3855            0 :             SuppHeatCoilName = Alphas(13);
    3856            0 :             thisFurnace.SuppHeatCoilType = SuppHeatCoilType;
    3857            0 :             thisFurnace.SuppHeatCoilName = SuppHeatCoilName;
    3858            0 :             errFlag = false;
    3859            0 :             if (Util::SameString(SuppHeatCoilType, "Coil:Heating:Fuel") || Util::SameString(SuppHeatCoilType, "Coil:Heating:Electric")) {
    3860              : 
    3861            0 :                 thisFurnace.SuppHeatCoilType_Num = HeatingCoils::GetHeatingCoilTypeNum(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3862            0 :                 if (errFlag) {
    3863            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3864            0 :                     ErrorsFound = true;
    3865              :                 } else {
    3866            0 :                     IsNotOK = false;
    3867            0 :                     ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
    3868            0 :                     if (IsNotOK) {
    3869            0 :                         ShowContinueError(state, format("In {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3870            0 :                         ErrorsFound = true;
    3871              : 
    3872              :                     } else { // mine data from the supplemental heating coil
    3873              : 
    3874            0 :                         HeatingCoils::GetCoilIndex(state, SuppHeatCoilName, thisFurnace.SuppHeatCoilIndex, IsNotOK);
    3875            0 :                         if (IsNotOK) {
    3876            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3877            0 :                             ErrorsFound = true;
    3878              :                         }
    3879              : 
    3880              :                         // Get the Supplemental Heating Coil Inlet Node Number
    3881            0 :                         errFlag = false;
    3882            0 :                         SupHeatCoilInletNode = HeatingCoils::GetCoilInletNode(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3883            0 :                         if (errFlag) {
    3884            0 :                             ShowContinueError(state, format("...occurs in {} \"{}\"", CurrentModuleObject, Alphas(1)));
    3885            0 :                             ErrorsFound = true;
    3886              :                         }
    3887              : 
    3888              :                         // Get the Supplemental Heating Coil Outlet Node Number
    3889            0 :                         errFlag = false;
    3890            0 :                         SupHeatCoilOutletNode = HeatingCoils::GetCoilOutletNode(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3891            0 :                         if (errFlag) {
    3892            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3893            0 :                             ErrorsFound = true;
    3894              :                         }
    3895              : 
    3896              :                         // Get the supplemental heating coil design capacity
    3897            0 :                         errFlag = false;
    3898            0 :                         thisFurnace.DesignSuppHeatingCapacity = HeatingCoils::GetCoilCapacity(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3899            0 :                         if (errFlag) {
    3900            0 :                             ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3901            0 :                             ErrorsFound = true;
    3902              :                         }
    3903              : 
    3904              :                     } // IF (IsNotOK) THEN
    3905              :                 }
    3906            0 :             } else if (Util::SameString(SuppHeatCoilType, "Coil:Heating:Water")) {
    3907            0 :                 thisFurnace.SuppHeatCoilType_Num = HVAC::Coil_HeatingWater;
    3908            0 :                 ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
    3909            0 :                 if (IsNotOK) {
    3910            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3911            0 :                     ErrorsFound = true;
    3912              :                 } else { // mine data from heating coil object
    3913              : 
    3914              :                     // Get the Heating Coil water Inlet or control Node number
    3915            0 :                     errFlag = false;
    3916            0 :                     thisFurnace.SuppCoilControlNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
    3917            0 :                     if (errFlag) {
    3918            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3919            0 :                         ErrorsFound = true;
    3920              :                     }
    3921              : 
    3922              :                     // Get the ReHeat Coil hot water max volume flow rate
    3923            0 :                     errFlag = false;
    3924            0 :                     thisFurnace.MaxSuppCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
    3925            0 :                     if (errFlag) {
    3926            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3927            0 :                         ErrorsFound = true;
    3928              :                     }
    3929              : 
    3930              :                     // Get the ReHeat Coil Inlet Node
    3931            0 :                     errFlag = false;
    3932            0 :                     SupHeatCoilInletNode = WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
    3933            0 :                     thisFurnace.SuppCoilAirInletNode = SupHeatCoilInletNode;
    3934            0 :                     if (errFlag) {
    3935            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3936            0 :                         ErrorsFound = true;
    3937              :                     }
    3938              : 
    3939              :                     // Get the ReHeat Coil Outlet Node
    3940            0 :                     errFlag = false;
    3941            0 :                     SupHeatCoilOutletNode = WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", SuppHeatCoilName, errFlag);
    3942            0 :                     thisFurnace.SuppCoilAirOutletNode = SupHeatCoilOutletNode;
    3943            0 :                     if (errFlag) {
    3944            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3945            0 :                         ErrorsFound = true;
    3946              :                     }
    3947              : 
    3948            0 :                     errFlag = false;
    3949            0 :                     HVACControllers::CheckCoilWaterInletNode(state, thisFurnace.CoilControlNode, errFlag);
    3950            0 :                     if (!errFlag) { // then did find a controller so that is bad
    3951            0 :                         ShowSevereError(state,
    3952            0 :                                         format("{} = {} has a conflicting Controller:WaterCoil object", CurrentModuleObject, thisFurnace.Name));
    3953            0 :                         ShowContinueError(state, "Hot water coils are controlled directly by unitary and furnace systems.");
    3954            0 :                         ShowContinueError(state, "No water coil controller should be input for the coil.");
    3955            0 :                         ErrorsFound = true;
    3956              :                     }
    3957              :                 }
    3958              : 
    3959            0 :             } else if (Util::SameString(SuppHeatCoilType, "Coil:Heating:Steam")) {
    3960            0 :                 thisFurnace.SuppHeatCoilType_Num = HVAC::Coil_HeatingSteam;
    3961            0 :                 ValidateComponent(state, SuppHeatCoilType, SuppHeatCoilName, IsNotOK, CurrentModuleObject);
    3962            0 :                 if (IsNotOK) {
    3963            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    3964            0 :                     ErrorsFound = true;
    3965              :                 } else { // mine data from heating coil object
    3966              : 
    3967            0 :                     errFlag = false;
    3968            0 :                     thisFurnace.SuppHeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, SuppHeatCoilType, SuppHeatCoilName, errFlag);
    3969            0 :                     if (thisFurnace.SuppHeatCoilIndex == 0) {
    3970            0 :                         ShowSevereError(state, format("{} illegal {} = {}", CurrentModuleObject, cAlphaFields(12), SuppHeatCoilName));
    3971            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3972            0 :                         ErrorsFound = true;
    3973              :                     }
    3974              : 
    3975              :                     // Get the Heating Coil steam inlet node number
    3976            0 :                     errFlag = false;
    3977            0 :                     thisFurnace.SuppCoilControlNode = SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", SuppHeatCoilName, errFlag);
    3978            0 :                     if (errFlag) {
    3979            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3980            0 :                         ErrorsFound = true;
    3981              :                     }
    3982              : 
    3983              :                     // Get the Heating Coil steam max volume flow rate
    3984            0 :                     thisFurnace.MaxSuppCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.SuppHeatCoilIndex, errFlag);
    3985            0 :                     if (thisFurnace.MaxSuppCoilFluidFlow > 0.0) {
    3986              :                         SteamDensity =
    3987            0 :                             Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, getAirLoopHVACHeatCoolInput);
    3988            0 :                         thisFurnace.MaxSuppCoilFluidFlow =
    3989            0 :                             SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.SuppHeatCoilIndex, errFlag) * SteamDensity;
    3990              :                     }
    3991              : 
    3992              :                     // Get the Heating Coil Inlet Node
    3993            0 :                     errFlag = false;
    3994            0 :                     SupHeatCoilInletNode = SteamCoils::GetCoilAirInletNode(state, thisFurnace.SuppHeatCoilIndex, SuppHeatCoilName, errFlag);
    3995            0 :                     thisFurnace.SuppCoilAirInletNode = SupHeatCoilInletNode;
    3996            0 :                     if (errFlag) {
    3997            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    3998            0 :                         ErrorsFound = true;
    3999              :                     }
    4000              : 
    4001              :                     // Get the Heating Coil Outlet Node
    4002            0 :                     errFlag = false;
    4003            0 :                     SupHeatCoilOutletNode = SteamCoils::GetCoilAirOutletNode(state, thisFurnace.SuppHeatCoilIndex, SuppHeatCoilName, errFlag);
    4004            0 :                     thisFurnace.SuppCoilAirOutletNode = SupHeatCoilOutletNode;
    4005            0 :                     if (errFlag) {
    4006            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisFurnace.Name));
    4007            0 :                         ErrorsFound = true;
    4008              :                     }
    4009              :                 }
    4010              : 
    4011              :             } else {
    4012            0 :                 ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    4013            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(12), Alphas(12)));
    4014            0 :                 ErrorsFound = true;
    4015              :             } // IF (Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingGasOrOtherFuel .OR. &, etc.
    4016              : 
    4017            0 :             if (lAlphaBlanks(14)) {
    4018            0 :                 thisFurnace.CondenserNodeNum = 0;
    4019              :             } else {
    4020            0 :                 thisFurnace.CondenserNodeNum =
    4021            0 :                     NodeInputManager::GetOnlySingleNode(state,
    4022            0 :                                                         Alphas(14),
    4023              :                                                         ErrorsFound,
    4024              :                                                         DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatPumpWaterToAir,
    4025            0 :                                                         Alphas(1),
    4026              :                                                         DataLoopNode::NodeFluidType::Air,
    4027              :                                                         DataLoopNode::ConnectionType::OutsideAirReference,
    4028              :                                                         NodeInputManager::CompFluidStream::Primary,
    4029              :                                                         DataLoopNode::ObjectIsNotParent);
    4030              :                 // need better verification.
    4031            0 :                 if (!OutAirNodeManager::CheckOutAirNodeNumber(state, thisFurnace.CondenserNodeNum)) {
    4032            0 :                     ShowSevereError(state, format("For {} = {}", CurrentModuleObject, Alphas(1)));
    4033            0 :                     ShowContinueError(state, format(" Node name of outdoor dry-bulb temperature sensor not valid outdoor air node= {}", Alphas(14)));
    4034            0 :                     ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
    4035            0 :                     ErrorsFound = true;
    4036              :                 }
    4037              :             }
    4038              : 
    4039            0 :             thisFurnace.fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Alphas(15)));
    4040            0 :             assert(thisFurnace.fanPlace != HVAC::FanPlace::Invalid);
    4041              : 
    4042            0 :             if (lAlphaBlanks(16)) {
    4043            0 :                 thisFurnace.fanOp = HVAC::FanOp::Cycling;
    4044            0 :                 if (thisFurnace.fanType != HVAC::FanType::OnOff) {
    4045            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, thisFurnace.Name));
    4046            0 :                     ShowContinueError(state, format("{} = {}", cAlphaFields(6), Alphas(6)));
    4047            0 :                     ShowContinueError(state, format("Fan type must be Fan:OnOff when {} = Blank.", cAlphaFields(16)));
    4048            0 :                     ErrorsFound = true;
    4049              :                 }
    4050            0 :             } else if ((thisFurnace.fanOpModeSched = Sched::GetSchedule(state, Alphas(16))) == nullptr) {
    4051            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(16), Alphas(16));
    4052            0 :                 ErrorsFound = true;
    4053              :             }
    4054              : 
    4055              :             // add the Dehumidification Type
    4056            0 :             if (Util::SameString(Alphas(17), "None") || Util::SameString(Alphas(17), "CoolReheat")) {
    4057            0 :                 AirNodeFound = false;
    4058            0 :                 if (Util::SameString(Alphas(17), "CoolReheat")) {
    4059            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::CoolReheat;
    4060            0 :                     thisFurnace.Humidistat = true;
    4061            0 :                     if (lAlphaBlanks(17)) {
    4062            0 :                         ShowWarningError(state, format("{} \"{}\"", CurrentModuleObject, Alphas(1)));
    4063            0 :                         ShowContinueError(state,
    4064              :                                           "Dehumidification control type is assumed to be None since a supplemental reheat coil has not been "
    4065              :                                           "specified and the simulation continues.");
    4066            0 :                         thisFurnace.Humidistat = false;
    4067            0 :                         thisFurnace.DehumidControlType_Num = DehumidificationControlMode::None;
    4068              :                     }
    4069              :                 }
    4070            0 :                 if (Util::SameString(Alphas(17), "None")) {
    4071            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::None;
    4072            0 :                     thisFurnace.Humidistat = false;
    4073              :                 }
    4074            0 :                 if (thisFurnace.Humidistat) {
    4075            0 :                     for (HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
    4076            0 :                         if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum != thisFurnace.ControlZoneNum) {
    4077            0 :                             continue;
    4078              :                         }
    4079            0 :                         AirNodeFound = true;
    4080              :                     }
    4081            0 :                     if (!AirNodeFound) {
    4082            0 :                         ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    4083            0 :                         ShowContinueError(state, "Did not find Air Node (Zone with Humidistat).");
    4084            0 :                         ShowContinueError(state, format("Specified {} = {}", cAlphaFields(5), Alphas(5)));
    4085            0 :                         ErrorsFound = true;
    4086              :                     }
    4087              :                 }
    4088              :             } else { // invalid input or blank
    4089            0 :                 if (!lAlphaBlanks(17)) {
    4090            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
    4091            0 :                     ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(17), Alphas(17)));
    4092            0 :                     ErrorsFound = true;
    4093              :                 } else {
    4094            0 :                     thisFurnace.Humidistat = false;
    4095            0 :                     thisFurnace.DehumidControlType_Num = DehumidificationControlMode::None;
    4096              :                 }
    4097              :             }
    4098              : 
    4099              :             // Add fan to component sets array
    4100              : 
    4101            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    4102            0 :                 CompSetFanInlet = Alphas(3);
    4103            0 :                 CompSetCoolInlet = "UNDEFINED";
    4104            0 :                 if (FanInletNode != thisFurnace.FurnaceInletNodeNum) {
    4105            0 :                     ShowSevereError(
    4106            0 :                         state, format("For {} = {}, Mismatch between unitary system inlet node and fan inlet node.", CurrentModuleObject, Alphas(1)));
    4107            0 :                     ShowContinueError(state, "..For \"BlowThrough\" fan, the inlet node name for the HeatPump should match the fan inlet node name.");
    4108            0 :                     ShowContinueError(state, format("..HeatPump Inlet Node = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    4109            0 :                     ShowContinueError(state, format("..Fan Inlet Node      = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    4110            0 :                     ErrorsFound = true;
    4111              :                 }
    4112            0 :                 if (FanOutletNode != CoolingCoilInletNode) {
    4113            0 :                     ShowSevereError(
    4114            0 :                         state, format("For {} = {}, Mismatch between fan outlet node and cooling coil inlet node.", CurrentModuleObject, Alphas(1)));
    4115            0 :                     ShowContinueError(state, "..For \"BlowThrough\" fan, the fan outlet node name must match the cooling coil inlet node name.");
    4116            0 :                     ShowContinueError(state, format("..Fan outlet node         = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    4117            0 :                     ShowContinueError(state, format("..Cooling coil inlet node = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    4118            0 :                     ErrorsFound = true;
    4119              :                 }
    4120            0 :                 if (CoolingCoilOutletNode != HeatingCoilInletNode) {
    4121            0 :                     ShowSevereError(state,
    4122            0 :                                     format("For {} = {}, Mismatch between cooling coil outlet node and heating coil inlet node.",
    4123              :                                            CurrentModuleObject,
    4124              :                                            Alphas(1)));
    4125            0 :                     ShowContinueError(state, "..The cooling coil outlet node name must match the heating coil inlet node name.");
    4126            0 :                     ShowContinueError(state, format("..Cooling coil outlet node = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    4127            0 :                     ShowContinueError(state, format("..Heating coil inlet node  = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    4128            0 :                     ErrorsFound = true;
    4129              :                 }
    4130            0 :                 if (HeatingCoilOutletNode != SupHeatCoilInletNode) {
    4131            0 :                     ShowSevereError(state,
    4132            0 :                                     format("For {} = {}, Mismatch between heating coil outlet node and supplemental heating coil inlet node.",
    4133              :                                            CurrentModuleObject,
    4134              :                                            Alphas(1)));
    4135            0 :                     ShowContinueError(
    4136              :                         state,
    4137              :                         "..For \"BlowThrough\" fan, the heating coil outlet node name must match the supplemental heating coil inlet node name.");
    4138            0 :                     ShowContinueError(state,
    4139            0 :                                       format("..Heating coil outlet node             = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    4140            0 :                     ShowContinueError(state,
    4141            0 :                                       format("..Supplemental heating coil inlet node = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
    4142            0 :                     ErrorsFound = true;
    4143              :                 }
    4144            0 :                 if (SupHeatCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    4145            0 :                     ShowSevereError(state,
    4146            0 :                                     format("For {} = {}, Mismatch between supplemental heating coil outlet node and HeatPump outlet node.",
    4147              :                                            CurrentModuleObject,
    4148              :                                            Alphas(1)));
    4149            0 :                     ShowContinueError(state, "..The supplemental heating coil outlet node name must match the HeatPump outlet node name.");
    4150            0 :                     ShowContinueError(state,
    4151            0 :                                       format("..Supplemental heating coil outlet node = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
    4152            0 :                     ShowContinueError(
    4153            0 :                         state, format("..HeatPump outlet node                  = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    4154            0 :                     ErrorsFound = true;
    4155              :                 }
    4156              :             } else {
    4157            0 :                 CompSetFanInlet = "UNDEFINED";
    4158            0 :                 CompSetCoolInlet = Alphas(3);
    4159            0 :                 if (CoolingCoilInletNode != thisFurnace.FurnaceInletNodeNum) {
    4160            0 :                     ShowSevereError(state,
    4161            0 :                                     format("For {} = {}, Mismatch between unitary system inlet node and cooling coil inlet node.",
    4162              :                                            CurrentModuleObject,
    4163              :                                            Alphas(1)));
    4164            0 :                     ShowContinueError(
    4165              :                         state, "..For \"DrawThrough\" fan, the inlet node name for the HeatPump should match the cooling coil inlet node name.");
    4166            0 :                     ShowContinueError(state, format("..HeatPump inlet node     = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceInletNodeNum)));
    4167            0 :                     ShowContinueError(state, format("..Cooling coil inlet node = {}", state.dataLoopNodes->NodeID(CoolingCoilInletNode)));
    4168            0 :                     ErrorsFound = true;
    4169              :                 }
    4170            0 :                 if (CoolingCoilOutletNode != HeatingCoilInletNode) {
    4171            0 :                     ShowSevereError(state,
    4172            0 :                                     format("For {} = {}, Mismatch between cooling coil outlet node and heating coil inlet node.",
    4173              :                                            CurrentModuleObject,
    4174              :                                            Alphas(1)));
    4175            0 :                     ShowContinueError(state, "..The outlet node name for the cooling coil should match the heating coil inlet node name.");
    4176            0 :                     ShowContinueError(state, format("..Cooling coil outlet node = {}", state.dataLoopNodes->NodeID(CoolingCoilOutletNode)));
    4177            0 :                     ShowContinueError(state, format("..Heating coil inlet node  = {}", state.dataLoopNodes->NodeID(HeatingCoilInletNode)));
    4178            0 :                     ErrorsFound = true;
    4179              :                 }
    4180            0 :                 if (HeatingCoilOutletNode != FanInletNode) {
    4181            0 :                     ShowSevereError(
    4182            0 :                         state, format("For {} = {}, Mismatch between heating coil outlet node and fan inlet node.", CurrentModuleObject, Alphas(1)));
    4183            0 :                     ShowContinueError(state,
    4184              :                                       "..For \"DrawThrough\" fan, the outlet node name for the heating coil should match the fan inlet node name.");
    4185            0 :                     ShowContinueError(state, format("..Heating coil outlet node = {}", state.dataLoopNodes->NodeID(HeatingCoilOutletNode)));
    4186            0 :                     ShowContinueError(state, format("..Fan inlet node           = {}", state.dataLoopNodes->NodeID(FanInletNode)));
    4187            0 :                     ErrorsFound = true;
    4188              :                 }
    4189            0 :                 if (FanOutletNode != SupHeatCoilInletNode) {
    4190            0 :                     ShowSevereError(state,
    4191            0 :                                     format("For {} = {}, Mismatch between fan outlet node and supplemental heating coil inlet node.",
    4192              :                                            CurrentModuleObject,
    4193              :                                            Alphas(1)));
    4194            0 :                     ShowContinueError(
    4195              :                         state,
    4196              :                         "..For \"DrawThrough\" fan, the outlet node name for the fan should match the supplemental heating coil inlet node name.");
    4197            0 :                     ShowContinueError(state, format("..Fan outlet node                      = {}", state.dataLoopNodes->NodeID(FanOutletNode)));
    4198            0 :                     ShowContinueError(state,
    4199            0 :                                       format("..Supplemental heating coil inlet node = {}", state.dataLoopNodes->NodeID(SupHeatCoilInletNode)));
    4200            0 :                     ErrorsFound = true;
    4201              :                 }
    4202            0 :                 if (SupHeatCoilOutletNode != thisFurnace.FurnaceOutletNodeNum) {
    4203            0 :                     ShowSevereError(state,
    4204            0 :                                     format("For {} = {}, Mismatch between supplemental heating coil outlet node and HeatPump outlet node.",
    4205              :                                            CurrentModuleObject,
    4206              :                                            Alphas(1)));
    4207            0 :                     ShowContinueError(state, "..The supplemental heating coil outlet node name must match the HeatPump outlet node name.");
    4208            0 :                     ShowContinueError(state,
    4209            0 :                                       format("..Supplemental heating coil outlet node = {}", state.dataLoopNodes->NodeID(SupHeatCoilOutletNode)));
    4210            0 :                     ShowContinueError(
    4211            0 :                         state, format("..HeatPump outlet node                  = {}", state.dataLoopNodes->NodeID(thisFurnace.FurnaceOutletNodeNum)));
    4212            0 :                     ErrorsFound = true;
    4213              :                 }
    4214              :             }
    4215              :             //  (Set up validation here for the fan or cooling coil inlet?)
    4216            0 :             BranchNodeConnections::SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(6), Alphas(7), CompSetFanInlet, "UNDEFINED");
    4217              : 
    4218              :             // Add DX heating coil to component sets array
    4219            0 :             BranchNodeConnections::SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(8), Alphas(9), "UNDEFINED", "UNDEFINED");
    4220              : 
    4221              :             // Add DX cooling coil to component sets array
    4222            0 :             BranchNodeConnections::SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(10), Alphas(11), CompSetCoolInlet, "UNDEFINED");
    4223              : 
    4224              :             // Add supplemental heating coil to component sets array
    4225            0 :             BranchNodeConnections::SetUpCompSets(state, CurrentModuleObject, Alphas(1), Alphas(12), Alphas(13), "UNDEFINED", Alphas(4));
    4226              : 
    4227              :             // Set the Design Fan Volume Flow Rate
    4228            0 :             thisFurnace.ActualFanVolFlowRate = state.dataFans->fans(thisFurnace.FanIndex)->maxAirFlowRate;
    4229              : 
    4230              :             // CR8094 - simple water to air heat pump MUST operate at the same flow rate specified in the coil objects
    4231              :             //        Furnace(FurnaceNum)%DesignFanVolFlowRate = Numbers(1)
    4232              :             //        Furnace(FurnaceNum)%MaxHeatAirVolFlow    = Furnace(FurnaceNum)%DesignFanVolFlowRate
    4233              :             //        Furnace(FurnaceNum)%MaxCoolAirVolFlow    = Furnace(FurnaceNum)%DesignFanVolFlowRate
    4234              : 
    4235              :             // parameter estimate model only specifies air flow rate in parent object
    4236            0 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
    4237            0 :                 thisFurnace.MaxHeatAirVolFlow = Numbers(1);
    4238            0 :                 thisFurnace.MaxCoolAirVolFlow = Numbers(1);
    4239              :                 // simple HP model specifies air flow rate in both the parent and child coils. Use coil air flow rates.
    4240              :                 // simple HP model air flow rate input will not be used.
    4241            0 :             } else if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
    4242            0 :                 errFlag = false;
    4243            0 :                 thisFurnace.MaxHeatAirVolFlow = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(state, HeatingCoilType, HeatingCoilName, errFlag);
    4244            0 :                 thisFurnace.MaxCoolAirVolFlow = WaterToAirHeatPumpSimple::GetCoilAirFlowRate(state, CoolingCoilType, CoolingCoilName, errFlag);
    4245            0 :                 if (errFlag) {
    4246            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4247            0 :                     ErrorsFound = true;
    4248              :                 }
    4249            0 :             } else if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
    4250            0 :                 errFlag = false;
    4251            0 :                 thisFurnace.MaxHeatAirVolFlow = VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    4252            0 :                 thisFurnace.MaxCoolAirVolFlow = VariableSpeedCoils::GetCoilAirFlowRateVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    4253            0 :                 if (errFlag) {
    4254            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4255            0 :                     ErrorsFound = true;
    4256              :                 }
    4257              :             }
    4258              : 
    4259            0 :             thisFurnace.MaxNoCoolHeatAirVolFlow = min(thisFurnace.MaxHeatAirVolFlow, thisFurnace.MaxCoolAirVolFlow);
    4260            0 :             if (thisFurnace.MaxHeatAirVolFlow != DataSizing::AutoSize && thisFurnace.MaxCoolAirVolFlow != DataSizing::AutoSize) {
    4261            0 :                 thisFurnace.DesignFanVolFlowRate = max(thisFurnace.MaxHeatAirVolFlow, thisFurnace.MaxCoolAirVolFlow);
    4262              :             } else {
    4263            0 :                 thisFurnace.DesignFanVolFlowRate = DataSizing::AutoSize;
    4264              :             }
    4265              : 
    4266            0 :             thisFurnace.AirFlowControl = AirFlowControlConstFan::UseCompressorOnFlow;
    4267              : 
    4268            0 :             if (thisFurnace.ActualFanVolFlowRate != DataSizing::AutoSize && thisFurnace.DesignFanVolFlowRate != DataSizing::AutoSize) {
    4269            0 :                 if (thisFurnace.DesignFanVolFlowRate > thisFurnace.ActualFanVolFlowRate) {
    4270            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4271            0 :                     ShowContinueError(state, "... has a Cooling or Heating Air Flow Rate > Max Fan Volume Flow Rate, should be <=.");
    4272            0 :                     ShowContinueError(state,
    4273            0 :                                       format("... Entered value={:.2R}... Fan [{}:{}] Max Value={:.2R}",
    4274            0 :                                              thisFurnace.DesignFanVolFlowRate,
    4275            0 :                                              HVAC::fanTypeNames[(int)thisFurnace.fanType],
    4276              :                                              FanName,
    4277            0 :                                              thisFurnace.ActualFanVolFlowRate));
    4278              :                 }
    4279              :             }
    4280            0 :             if (thisFurnace.ActualFanVolFlowRate != DataSizing::AutoSize && thisFurnace.DesignFanVolFlowRate != DataSizing::AutoSize) {
    4281            0 :                 if (thisFurnace.DesignFanVolFlowRate <= 0.0) {
    4282            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4283            0 :                     ShowContinueError(state, "... has a Design Fan Flow Rate <= 0.0, it must be >0.0");
    4284            0 :                     ShowContinueError(state, format("... Entered value={:.2R}", thisFurnace.DesignFanVolFlowRate));
    4285            0 :                     ErrorsFound = true;
    4286              :                 }
    4287              :             }
    4288              : 
    4289              :             // Set the heat pump heating coil capacity
    4290              :             //  Get from coil module.
    4291            0 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHP) {
    4292            0 :                 errFlag = false;
    4293            0 :                 thisFurnace.DesignHeatingCapacity = WaterToAirHeatPump::GetCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
    4294            0 :                 if (errFlag) {
    4295            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4296            0 :                     ErrorsFound = true;
    4297              :                 }
    4298            0 :             } else if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
    4299            0 :                 errFlag = false;
    4300            0 :                 thisFurnace.DesignHeatingCapacity = WaterToAirHeatPumpSimple::GetCoilCapacity(state, HeatingCoilType, HeatingCoilName, errFlag);
    4301            0 :                 if (errFlag) {
    4302            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4303            0 :                     ErrorsFound = true;
    4304              :                 }
    4305            0 :             } else if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit) {
    4306            0 :                 errFlag = false;
    4307            0 :                 thisFurnace.DesignHeatingCapacity =
    4308            0 :                     VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, HeatingCoilType, HeatingCoilName, errFlag);
    4309            0 :                 if (errFlag) {
    4310            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4311            0 :                     ErrorsFound = true;
    4312              :                 }
    4313              :             }
    4314              :             // Set the heat pump heating coil convergence
    4315            0 :             thisFurnace.HeatingConvergenceTolerance = Numbers(2);
    4316              :             // Set the heat pump cooling coil capacity (Total capacity)
    4317              :             //  Get from coil module.
    4318            0 :             if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHP) {
    4319            0 :                 errFlag = false;
    4320            0 :                 thisFurnace.DesignCoolingCapacity = WaterToAirHeatPump::GetCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
    4321            0 :                 if (errFlag) {
    4322            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4323            0 :                     ErrorsFound = true;
    4324              :                 }
    4325            0 :             } else if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
    4326            0 :                 errFlag = false;
    4327            0 :                 thisFurnace.DesignCoolingCapacity = WaterToAirHeatPumpSimple::GetCoilCapacity(state, CoolingCoilType, CoolingCoilName, errFlag);
    4328            0 :                 if (errFlag) {
    4329            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4330            0 :                     ErrorsFound = true;
    4331              :                 }
    4332            0 :             } else if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit) {
    4333            0 :                 errFlag = false;
    4334            0 :                 thisFurnace.DesignCoolingCapacity =
    4335            0 :                     VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, CoolingCoilType, CoolingCoilName, errFlag);
    4336            0 :                 if (errFlag) {
    4337            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
    4338            0 :                     ErrorsFound = true;
    4339              :                 }
    4340              :             }
    4341              :             // Set the heat pump cooling coil convergence
    4342            0 :             thisFurnace.CoolingConvergenceTolerance = Numbers(3);
    4343              : 
    4344              :             // Set the heatpump design supplemental heating capacity
    4345              :             //  Get from coil module.
    4346              : 
    4347              :             // Set the heatpump max outlet temperature
    4348            0 :             thisFurnace.DesignMaxOutletTemp = Numbers(4);
    4349              : 
    4350              :             // Set maximum supply air temperature for supplemental heating coil
    4351            0 :             thisFurnace.MaxOATSuppHeat = Numbers(5);
    4352            0 :             OutputReportPredefined::PreDefTableEntry(
    4353            0 :                 state, state.dataOutRptPredefined->pdchDXHeatCoilSuppHiT, HeatingCoilName, thisFurnace.MaxOATSuppHeat);
    4354              : 
    4355              :             // set minimum outdoor temperature for compressor operation
    4356            0 :             SetMinOATCompressor(state, FurnaceNum, cCurrentModuleObject, ErrorsFound);
    4357              : 
    4358              :         } // End of the Unitary System WaterToAirHeatPump Loop
    4359              : 
    4360            2 :         Alphas.deallocate();
    4361            2 :         Numbers.deallocate();
    4362              : 
    4363            2 :         if (ErrorsFound) {
    4364            0 :             ShowFatalError(state, "Errors found in getting Furnace or Unitary System input.");
    4365              :         }
    4366              : 
    4367            2 :         for (int HeatOnlyNum = 1; HeatOnlyNum <= NumHeatOnly; ++HeatOnlyNum) {
    4368            0 :             FurnaceNum = HeatOnlyNum;
    4369            0 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    4370              :             // Setup Report variables for the Furnace that are not reported in the components themselves
    4371            0 :             SetupOutputVariable(state,
    4372              :                                 "Unitary System Fan Part Load Ratio",
    4373              :                                 Constant::Units::None,
    4374            0 :                                 thisFurnace.FanPartLoadRatio,
    4375              :                                 OutputProcessor::TimeStepType::System,
    4376              :                                 OutputProcessor::StoreType::Average,
    4377            0 :                                 thisFurnace.Name);
    4378            0 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    4379            0 :                 SetupEMSActuator(state,
    4380              :                                  "AirLoopHVAC:Unitary:Furnace:HeatOnly",
    4381              :                                  thisFurnace.Name,
    4382              :                                  "Autosized Supply Air Flow Rate",
    4383              :                                  "[m3/s]",
    4384            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideOn,
    4385            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideValue);
    4386              :             }
    4387              :         }
    4388              : 
    4389            2 :         for (int UnitaryHeatOnlyNum = NumHeatOnly + 1; UnitaryHeatOnlyNum <= NumHeatOnly + NumUnitaryHeatOnly; ++UnitaryHeatOnlyNum) {
    4390            0 :             FurnaceNum = UnitaryHeatOnlyNum;
    4391            0 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    4392              :             // Setup Report variables for Unitary System that are not reported in the components themselves
    4393            0 :             SetupOutputVariable(state,
    4394              :                                 "Unitary System Fan Part Load Ratio",
    4395              :                                 Constant::Units::None,
    4396            0 :                                 thisFurnace.FanPartLoadRatio,
    4397              :                                 OutputProcessor::TimeStepType::System,
    4398              :                                 OutputProcessor::StoreType::Average,
    4399            0 :                                 thisFurnace.Name);
    4400            0 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    4401            0 :                 SetupEMSActuator(state,
    4402              :                                  "AirLoopHVAC:UnitaryHeatOnly",
    4403              :                                  thisFurnace.Name,
    4404              :                                  "Autosized Supply Air Flow Rate",
    4405              :                                  "[m3/s]",
    4406            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideOn,
    4407            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideValue);
    4408              :             }
    4409              :         }
    4410              : 
    4411            2 :         for (int HeatCoolNum = NumHeatOnly + NumUnitaryHeatOnly + 1; HeatCoolNum <= NumHeatOnly + NumUnitaryHeatOnly + NumHeatCool; ++HeatCoolNum) {
    4412            0 :             FurnaceNum = HeatCoolNum;
    4413            0 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    4414              :             // Setup Report variables for the Furnace that are not reported in the components themselves
    4415            0 :             SetupOutputVariable(state,
    4416              :                                 "Unitary System Fan Part Load Ratio",
    4417              :                                 Constant::Units::None,
    4418            0 :                                 thisFurnace.FanPartLoadRatio,
    4419              :                                 OutputProcessor::TimeStepType::System,
    4420              :                                 OutputProcessor::StoreType::Average,
    4421            0 :                                 thisFurnace.Name);
    4422            0 :             SetupOutputVariable(state,
    4423              :                                 "Unitary System Compressor Part Load Ratio",
    4424              :                                 Constant::Units::None,
    4425            0 :                                 thisFurnace.CompPartLoadRatio,
    4426              :                                 OutputProcessor::TimeStepType::System,
    4427              :                                 OutputProcessor::StoreType::Average,
    4428            0 :                                 thisFurnace.Name);
    4429              : 
    4430            0 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    4431            0 :                 SetupEMSActuator(state,
    4432              :                                  "AirLoopHVAC:Unitary:Furnace:HeatCool",
    4433              :                                  thisFurnace.Name,
    4434              :                                  "Autosized Supply Air Flow Rate",
    4435              :                                  "[m3/s]",
    4436            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideOn,
    4437            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideValue);
    4438            0 :                 SetupEMSActuator(state,
    4439              :                                  "AirLoopHVAC:Unitary:Furnace:HeatCool",
    4440              :                                  thisFurnace.Name,
    4441              :                                  "Autosized Supply Air Flow Rate During Cooling Operation",
    4442              :                                  "[m3/s]",
    4443            0 :                                  thisFurnace.MaxCoolAirVolFlowEMSOverrideOn,
    4444            0 :                                  thisFurnace.MaxCoolAirVolFlowEMSOverrideValue);
    4445            0 :                 SetupEMSActuator(state,
    4446              :                                  "AirLoopHVAC:Unitary:Furnace:HeatCool",
    4447              :                                  thisFurnace.Name,
    4448              :                                  "Autosized Supply Air Flow Rate During Heating Operation",
    4449              :                                  "[m3/s]",
    4450            0 :                                  thisFurnace.MaxHeatAirVolFlowEMSOverrideOn,
    4451            0 :                                  thisFurnace.MaxHeatAirVolFlowEMSOverrideValue);
    4452            0 :                 SetupEMSActuator(state,
    4453              :                                  "AirLoopHVAC:Unitary:Furnace:HeatCool",
    4454              :                                  thisFurnace.Name,
    4455              :                                  "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
    4456              :                                  "[m3/s]",
    4457            0 :                                  thisFurnace.MaxNoCoolHeatAirVolFlowEMSOverrideOn,
    4458            0 :                                  thisFurnace.MaxNoCoolHeatAirVolFlowEMSOverrideValue);
    4459              :             }
    4460              :         }
    4461              : 
    4462            2 :         for (int UnitaryHeatCoolNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + 1;
    4463            2 :              UnitaryHeatCoolNum <= NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool;
    4464              :              ++UnitaryHeatCoolNum) {
    4465            0 :             FurnaceNum = UnitaryHeatCoolNum;
    4466            0 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    4467              :             // Setup Report variables for Unitary System that are not reported in the components themselves
    4468            0 :             SetupOutputVariable(state,
    4469              :                                 "Unitary System Fan Part Load Ratio",
    4470              :                                 Constant::Units::None,
    4471            0 :                                 thisFurnace.FanPartLoadRatio,
    4472              :                                 OutputProcessor::TimeStepType::System,
    4473              :                                 OutputProcessor::StoreType::Average,
    4474            0 :                                 thisFurnace.Name);
    4475            0 :             SetupOutputVariable(state,
    4476              :                                 "Unitary System Compressor Part Load Ratio",
    4477              :                                 Constant::Units::None,
    4478            0 :                                 thisFurnace.CompPartLoadRatio,
    4479              :                                 OutputProcessor::TimeStepType::System,
    4480              :                                 OutputProcessor::StoreType::Average,
    4481            0 :                                 thisFurnace.Name);
    4482            0 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    4483            0 :                 SetupEMSActuator(state,
    4484              :                                  "AirLoopHVAC:UnitaryHeatCool",
    4485              :                                  thisFurnace.Name,
    4486              :                                  "Autosized Supply Air Flow Rate",
    4487              :                                  "[m3/s]",
    4488            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideOn,
    4489            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideValue);
    4490            0 :                 SetupEMSActuator(state,
    4491              :                                  "AirLoopHVAC:UnitaryHeatCool",
    4492              :                                  thisFurnace.Name,
    4493              :                                  "Autosized Supply Air Flow Rate During Cooling Operation",
    4494              :                                  "[m3/s]",
    4495            0 :                                  thisFurnace.MaxCoolAirVolFlowEMSOverrideOn,
    4496            0 :                                  thisFurnace.MaxCoolAirVolFlowEMSOverrideValue);
    4497            0 :                 SetupEMSActuator(state,
    4498              :                                  "AirLoopHVAC:UnitaryHeatCool",
    4499              :                                  thisFurnace.Name,
    4500              :                                  "Autosized Supply Air Flow Rate During Heating Operation",
    4501              :                                  "[m3/s]",
    4502            0 :                                  thisFurnace.MaxHeatAirVolFlowEMSOverrideOn,
    4503            0 :                                  thisFurnace.MaxHeatAirVolFlowEMSOverrideValue);
    4504            0 :                 SetupEMSActuator(state,
    4505              :                                  "AirLoopHVAC:UnitaryHeatCool",
    4506              :                                  thisFurnace.Name,
    4507              :                                  "Autosized Supply Air Flow Rate During No Heating or Cooling Operation",
    4508              :                                  "[m3/s]",
    4509            0 :                                  thisFurnace.MaxNoCoolHeatAirVolFlowEMSOverrideOn,
    4510            0 :                                  thisFurnace.MaxNoCoolHeatAirVolFlowEMSOverrideValue);
    4511              :             }
    4512              :         }
    4513              : 
    4514            4 :         for (int HeatPumpNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + 1;
    4515            4 :              HeatPumpNum <= state.dataFurnaces->NumFurnaces - NumWaterToAirHeatPump;
    4516              :              ++HeatPumpNum) {
    4517            2 :             FurnaceNum = HeatPumpNum;
    4518            2 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    4519              :             // Setup Report variables for Unitary System that are not reported in the components themselves
    4520            4 :             SetupOutputVariable(state,
    4521              :                                 "Unitary System Fan Part Load Ratio",
    4522              :                                 Constant::Units::None,
    4523            2 :                                 thisFurnace.FanPartLoadRatio,
    4524              :                                 OutputProcessor::TimeStepType::System,
    4525              :                                 OutputProcessor::StoreType::Average,
    4526            2 :                                 thisFurnace.Name);
    4527            4 :             SetupOutputVariable(state,
    4528              :                                 "Unitary System Compressor Part Load Ratio",
    4529              :                                 Constant::Units::None,
    4530            2 :                                 thisFurnace.CompPartLoadRatio,
    4531              :                                 OutputProcessor::TimeStepType::System,
    4532              :                                 OutputProcessor::StoreType::Average,
    4533            2 :                                 thisFurnace.Name);
    4534            4 :             SetupOutputVariable(state,
    4535              :                                 "Unitary System Dehumidification Induced Heating Demand Rate",
    4536              :                                 Constant::Units::W,
    4537            2 :                                 thisFurnace.DehumidInducedHeatingDemandRate,
    4538              :                                 OutputProcessor::TimeStepType::System,
    4539              :                                 OutputProcessor::StoreType::Average,
    4540            2 :                                 thisFurnace.Name);
    4541              : 
    4542            2 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    4543            0 :                 SetupEMSActuator(state,
    4544              :                                  "AirLoopHVAC:UnitaryHeatPump:AirToAir",
    4545              :                                  thisFurnace.Name,
    4546              :                                  "Autosized Supply Air Flow Rate",
    4547              :                                  "[m3/s]",
    4548            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideOn,
    4549            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideValue);
    4550              :             }
    4551              :         }
    4552              : 
    4553            2 :         for (int HeatPumpNum = NumHeatOnly + NumHeatCool + NumUnitaryHeatOnly + NumUnitaryHeatCool + NumHeatPump + 1;
    4554            2 :              HeatPumpNum <= state.dataFurnaces->NumFurnaces;
    4555              :              ++HeatPumpNum) {
    4556            0 :             FurnaceNum = HeatPumpNum;
    4557            0 :             auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    4558              :             // Setup Report variables for Unitary System that are not reported in the components themselves
    4559            0 :             SetupOutputVariable(state,
    4560              :                                 "Unitary System Fan Part Load Ratio",
    4561              :                                 Constant::Units::None,
    4562            0 :                                 thisFurnace.FanPartLoadRatio,
    4563              :                                 OutputProcessor::TimeStepType::System,
    4564              :                                 OutputProcessor::StoreType::Average,
    4565            0 :                                 thisFurnace.Name);
    4566            0 :             SetupOutputVariable(state,
    4567              :                                 "Unitary System Compressor Part Load Ratio",
    4568              :                                 Constant::Units::None,
    4569            0 :                                 thisFurnace.CompPartLoadRatio,
    4570              :                                 OutputProcessor::TimeStepType::System,
    4571              :                                 OutputProcessor::StoreType::Average,
    4572            0 :                                 thisFurnace.Name);
    4573            0 :             SetupOutputVariable(state,
    4574              :                                 "Unitary System Requested Sensible Cooling Rate",
    4575              :                                 Constant::Units::W,
    4576            0 :                                 thisFurnace.CoolingCoilSensDemand,
    4577              :                                 OutputProcessor::TimeStepType::System,
    4578              :                                 OutputProcessor::StoreType::Average,
    4579            0 :                                 thisFurnace.Name);
    4580            0 :             SetupOutputVariable(state,
    4581              :                                 "Unitary System Requested Latent Cooling Rate",
    4582              :                                 Constant::Units::W,
    4583            0 :                                 thisFurnace.CoolingCoilLatentDemand,
    4584              :                                 OutputProcessor::TimeStepType::System,
    4585              :                                 OutputProcessor::StoreType::Average,
    4586            0 :                                 thisFurnace.Name);
    4587            0 :             SetupOutputVariable(state,
    4588              :                                 "Unitary System Requested Heating Rate",
    4589              :                                 Constant::Units::W,
    4590            0 :                                 thisFurnace.HeatingCoilSensDemand,
    4591              :                                 OutputProcessor::TimeStepType::System,
    4592              :                                 OutputProcessor::StoreType::Average,
    4593            0 :                                 thisFurnace.Name);
    4594            0 :             SetupOutputVariable(state,
    4595              :                                 "Unitary System Dehumidification Induced Heating Demand Rate",
    4596              :                                 Constant::Units::W,
    4597            0 :                                 thisFurnace.DehumidInducedHeatingDemandRate,
    4598              :                                 OutputProcessor::TimeStepType::System,
    4599              :                                 OutputProcessor::StoreType::Average,
    4600            0 :                                 thisFurnace.Name);
    4601              : 
    4602            0 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    4603            0 :                 SetupEMSActuator(state,
    4604              :                                  "AirLoopHVAC:UnitaryHeatPump:WaterToAir",
    4605              :                                  thisFurnace.Name,
    4606              :                                  "Autosized Supply Air Flow Rate",
    4607              :                                  "[m3/s]",
    4608            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideOn,
    4609            0 :                                  thisFurnace.DesignFanVolFlowRateEMSOverrideValue);
    4610              :             }
    4611              :         }
    4612              : 
    4613            2 :         if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    4614            0 :             for (FurnaceNum = 1; FurnaceNum <= state.dataFurnaces->NumFurnaces; ++FurnaceNum) {
    4615            0 :                 auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    4616            0 :                 SetupEMSInternalVariable(state, "Unitary HVAC Design Heating Capacity", thisFurnace.Name, "[W]", thisFurnace.DesignHeatingCapacity);
    4617            0 :                 SetupEMSInternalVariable(state, "Unitary HVAC Design Cooling Capacity", thisFurnace.Name, "[W]", thisFurnace.DesignCoolingCapacity);
    4618            0 :                 SetupEMSActuator(state,
    4619              :                                  "Unitary HVAC",
    4620              :                                  thisFurnace.Name,
    4621              :                                  "Sensible Load Request",
    4622              :                                  "[W]",
    4623            0 :                                  thisFurnace.EMSOverrideSensZoneLoadRequest,
    4624            0 :                                  thisFurnace.EMSSensibleZoneLoadValue);
    4625            0 :                 SetupEMSActuator(state,
    4626              :                                  "Unitary HVAC",
    4627              :                                  thisFurnace.Name,
    4628              :                                  "Moisture Load Request",
    4629              :                                  "[W]",
    4630            0 :                                  thisFurnace.EMSOverrideMoistZoneLoadRequest,
    4631            0 :                                  thisFurnace.EMSMoistureZoneLoadValue);
    4632              :             }
    4633              :         }
    4634              :         bool anyRan;
    4635            2 :         EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::ComponentGetInput, anyRan, ObjexxFCL::Optional_int_const());
    4636            2 :     }
    4637              : 
    4638              :     // End of Get Input subroutines for this Module
    4639              :     //******************************************************************************
    4640              : 
    4641              :     // Beginning Initialization Section of the Module
    4642              :     //******************************************************************************
    4643              : 
    4644        15222 :     void InitFurnace(EnergyPlusData &state,
    4645              :                      int const FurnaceNum,         // index to Furnace
    4646              :                      int const AirLoopNum,         // index to air loop
    4647              :                      Real64 &OnOffAirFlowRatio,    // ratio of on to off air mass flow rate
    4648              :                      HVAC::FanOp &fanOp,           // fan operating mode
    4649              :                      Real64 &ZoneLoad,             // zone sensible load to be met (modified here as needed) (W)
    4650              :                      Real64 &MoistureLoad,         // zone moisture load (W)
    4651              :                      bool const FirstHVACIteration // TRUE if first HVAC iteration
    4652              :     )
    4653              :     {
    4654              : 
    4655              :         // SUBROUTINE INFORMATION:
    4656              :         //       AUTHOR         Richard J. Liesen
    4657              :         //       DATE WRITTEN   Feb 2001
    4658              :         //       MODIFIED       Oct 2001, Richard Raustad
    4659              :         //                      Sep 2008, R. Raustad - revised logic to determine load to be met
    4660              :         //                      Bereket Nigusse, June 2010 - added a procedure to calculate supply air flow fraction
    4661              :         //                      through controlled zone
    4662              :         //                      Bo Shen, March 2012 - for VS WSHP
    4663              :         //                      Bo Shen, ORNL, July 2012 - added variable-speed air source heat pump cooling and heating coils, using curve-fits
    4664              : 
    4665              :         // PURPOSE OF THIS SUBROUTINE:
    4666              :         // This subroutine is for initializations of the Furnace Components.
    4667              : 
    4668              :         // METHODOLOGY EMPLOYED:
    4669              :         // Uses the status flags to trigger initializations.
    4670              :         // The HeatCool furnace/unitarysystem and air-to-air heat pump may have alternate air flow rates
    4671              :         // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
    4672              :         // air flow rates during InitFurnace. Use these flow rates during the Calc routines to set the
    4673              :         // average mass flow rates based on PLR.
    4674              : 
    4675              :         // SUBROUTINE PARAMETER DEFINITIONS:
    4676        15222 :         Real64 constexpr Small5WLoad(5.0);
    4677        15222 :         std::string_view constexpr RoutineName("InitFurnace");
    4678              : 
    4679              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4680              :         bool errFlag;          // error flag for mining functions
    4681              :         Real64 QZnReq;         // furnace load based on control zone frac (W)
    4682              :         Real64 PartLoadRatio;  // furnace part-load ratio
    4683              :         Real64 SensibleOutput; // no load sensible output (coils off) (W)
    4684              :         Real64 LatentOutput;   // no load latent output (coils off) (W)
    4685              :         Real64 QToCoolSetPt;   // sensible load to cooling setpoint (W)
    4686              :         Real64 QToHeatSetPt;   // sensible load to heating setpoint (W)
    4687              :         // calculation (kg/kg)
    4688              :         Real64 DeltaMassRate; // Difference of mass flow rate between
    4689              :         // inlet node and system outlet node
    4690              :         Real64 MassFlowRate; // mass flow rate to calculate loss
    4691              : 
    4692        15222 :         Real64 SumOfMassFlowRateMax(0.0);                 // the sum of mass flow rates at inlet to zones in an airloop
    4693        15222 :         Real64 CntrlZoneTerminalUnitMassFlowRateMax(0.0); // Maximum mass flow rate through controlled zone terminal unit
    4694              : 
    4695        15222 :         bool ErrorsFound(false);                 // flag returned from mining call
    4696        15222 :         Real64 mdot(0.0);                        // local temporary for mass flow rate (kg/s)
    4697        15222 :         Real64 rho(0.0);                         // local for fluid density
    4698        15222 :         Real64 SteamDensity(0.0);                // density of steam at 100C, used for steam heating coils
    4699        15222 :         Real64 CoilMaxVolFlowRate(0.0);          // coil fluid maximum volume flow rate
    4700        15222 :         Real64 QActual(0.0);                     // coil actual capacity
    4701        15222 :         Real64 SUPHEATERLOAD(0.0);               // SUPPLEMENTAL HEATER LOAD
    4702              :         Real64 RhoAir;                           // Air density at InNode
    4703              :         Furnaces::ModeOfOperation OperatingMode; // track cooling, heating, and no cooling or heating modes
    4704              :         Furnaces::ModeOfOperation OperatingModeMinusOne;
    4705              :         Furnaces::ModeOfOperation OperatingModeMinusTwo;
    4706              :         bool Oscillate; // detection of oscillating operating modes
    4707              : 
    4708        15222 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    4709        15222 :         int InNode = thisFurnace.FurnaceInletNodeNum;
    4710        15222 :         int OutNode = thisFurnace.FurnaceOutletNodeNum;
    4711              : 
    4712        15222 :         if (state.dataFurnaces->InitFurnaceMyOneTimeFlag) {
    4713              :             // initialize the environment and sizing flags
    4714            2 :             state.dataFurnaces->MyEnvrnFlag.allocate(state.dataFurnaces->NumFurnaces);
    4715            2 :             state.dataFurnaces->MySizeFlag.allocate(state.dataFurnaces->NumFurnaces);
    4716            2 :             state.dataFurnaces->MySecondOneTimeFlag.allocate(state.dataFurnaces->NumFurnaces);
    4717            2 :             state.dataFurnaces->MyFanFlag.allocate(state.dataFurnaces->NumFurnaces);
    4718            2 :             state.dataFurnaces->MyCheckFlag.allocate(state.dataFurnaces->NumFurnaces);
    4719            2 :             state.dataFurnaces->MyFlowFracFlag.allocate(state.dataFurnaces->NumFurnaces);
    4720            2 :             state.dataFurnaces->MyPlantScanFlag.allocate(state.dataFurnaces->NumFurnaces);
    4721            2 :             state.dataFurnaces->MySuppCoilPlantScanFlag.allocate(state.dataFurnaces->NumFurnaces);
    4722            2 :             state.dataFurnaces->MyEnvrnFlag = true;
    4723            2 :             state.dataFurnaces->MySizeFlag = true;
    4724            2 :             state.dataFurnaces->MySecondOneTimeFlag = true;
    4725            2 :             state.dataFurnaces->MyFanFlag = true;
    4726            2 :             state.dataFurnaces->MyCheckFlag = true;
    4727            2 :             state.dataFurnaces->MyFlowFracFlag = true;
    4728            2 :             state.dataFurnaces->InitFurnaceMyOneTimeFlag = false;
    4729            2 :             state.dataFurnaces->MyPlantScanFlag = true;
    4730            2 :             state.dataFurnaces->MySuppCoilPlantScanFlag = true;
    4731              :         }
    4732              : 
    4733        15222 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataFurnaces->MyAirLoopPass) {
    4734            6 :             state.dataFurnaces->AirLoopPass = 0;
    4735            6 :             state.dataFurnaces->MyAirLoopPass = false;
    4736              :         }
    4737        15222 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    4738        15136 :             state.dataFurnaces->MyAirLoopPass = true;
    4739              :         }
    4740              : 
    4741        15222 :         ++state.dataFurnaces->AirLoopPass;
    4742        15222 :         if (state.dataFurnaces->AirLoopPass > 2) {
    4743         7605 :             state.dataFurnaces->AirLoopPass = 1;
    4744              :         }
    4745              : 
    4746        15222 :         if (!state.dataGlobal->SysSizingCalc && state.dataFurnaces->MySizeFlag(FurnaceNum)) {
    4747              :             // for each furnace, do the sizing once.
    4748            2 :             SizeFurnace(state, FurnaceNum, FirstHVACIteration);
    4749            2 :             thisFurnace.ControlZoneMassFlowFrac = 1.0;
    4750              : 
    4751            2 :             state.dataFurnaces->MySizeFlag(FurnaceNum) = false;
    4752              :             // Pass the fan cycling schedule index up to the air loop. Set the air loop unitary system flag.
    4753            2 :             state.dataAirLoop->AirLoopControlInfo(AirLoopNum).cycFanSched = thisFurnace.fanOpModeSched;
    4754            2 :             state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = true;
    4755              :             // RR this is wrong, Op mode needs to be updated each time atep
    4756            2 :             state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = thisFurnace.fanOp;
    4757              : 
    4758              :             // Check that heat pump heating capacity is within 20% of cooling capacity
    4759            2 :             if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir) {
    4760            2 :                 if (std::abs(thisFurnace.DesignCoolingCapacity - thisFurnace.DesignHeatingCapacity) / thisFurnace.DesignCoolingCapacity > 0.2) {
    4761            0 :                     ShowWarningError(state,
    4762            0 :                                      format("{} \"{}\" heating capacity is disproportionate (> 20% different) to total cooling capacity",
    4763            0 :                                             HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    4764            0 :                                             thisFurnace.Name));
    4765              :                 }
    4766              :             }
    4767              :         }
    4768              : 
    4769        15222 :         if (!state.dataGlobal->DoingSizing && state.dataFurnaces->MySecondOneTimeFlag(FurnaceNum)) {
    4770              :             // sizing all done.  check fan air flow rates
    4771            4 :             thisFurnace.ActualFanVolFlowRate = state.dataFans->fans(thisFurnace.FanIndex)->maxAirFlowRate;
    4772            4 :             if (thisFurnace.ActualFanVolFlowRate != DataSizing::AutoSize) {
    4773            2 :                 if (thisFurnace.DesignFanVolFlowRate > thisFurnace.ActualFanVolFlowRate) {
    4774            0 :                     ShowWarningError(state,
    4775            0 :                                      format("{}={} has a Design Fan Volume Flow Rate > Max Fan Volume Flow Rate, should be <=",
    4776            0 :                                             HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    4777            0 :                                             thisFurnace.Name));
    4778            0 :                     ShowContinueError(state,
    4779            0 :                                       format("... Entered value={:.2R}... Fan [{}] Max Value={:.2R}",
    4780            0 :                                              thisFurnace.DesignFanVolFlowRate,
    4781            0 :                                              HVAC::fanTypeNames[(int)thisFurnace.fanType],
    4782            0 :                                              thisFurnace.ActualFanVolFlowRate));
    4783              :                 }
    4784            2 :                 if (thisFurnace.DesignFanVolFlowRate <= 0.0) {
    4785            0 :                     ShowSevereError(state,
    4786            0 :                                     format("{}={} has a Design Fan Volume Flow Rate <= 0.0, it must be >0.0",
    4787            0 :                                            HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    4788            0 :                                            thisFurnace.Name));
    4789            0 :                     ShowContinueError(state, format("... Entered value={:.2R}", thisFurnace.DesignFanVolFlowRate));
    4790              :                 }
    4791              : 
    4792            2 :                 state.dataFurnaces->MySecondOneTimeFlag(FurnaceNum) = false;
    4793              :             }
    4794              :         }
    4795              : 
    4796              :         // Scan hot water and steam heating coil plant components for one time initializations
    4797        15222 :         if (state.dataFurnaces->MyPlantScanFlag(FurnaceNum) && allocated(state.dataPlnt->PlantLoop)) {
    4798            2 :             if ((thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWater) || (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingSteam)) {
    4799              : 
    4800            0 :                 if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
    4801              : 
    4802            0 :                     errFlag = false;
    4803            0 :                     PlantUtilities::ScanPlantLoopsForObject(state,
    4804              :                                                             thisFurnace.HeatingCoilName,
    4805              :                                                             DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
    4806            0 :                                                             thisFurnace.plantLoc,
    4807              :                                                             errFlag,
    4808              :                                                             _,
    4809              :                                                             _,
    4810              :                                                             _,
    4811              :                                                             _,
    4812              :                                                             _);
    4813            0 :                     if (errFlag) {
    4814            0 :                         ShowFatalError(state, "InitFurnace: Program terminated for previous conditions.");
    4815              :                     }
    4816            0 :                     thisFurnace.MaxHeatCoilFluidFlow =
    4817            0 :                         WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", thisFurnace.HeatingCoilName, ErrorsFound);
    4818            0 :                     if (thisFurnace.MaxHeatCoilFluidFlow > 0.0) {
    4819              :                         rho =
    4820            0 :                             state.dataPlnt->PlantLoop(thisFurnace.plantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    4821            0 :                         thisFurnace.MaxHeatCoilFluidFlow *= rho;
    4822              :                     }
    4823            0 :                 } else if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
    4824              : 
    4825            0 :                     errFlag = false;
    4826            0 :                     PlantUtilities::ScanPlantLoopsForObject(state,
    4827              :                                                             thisFurnace.HeatingCoilName,
    4828              :                                                             DataPlant::PlantEquipmentType::CoilSteamAirHeating,
    4829            0 :                                                             thisFurnace.plantLoc,
    4830              :                                                             errFlag,
    4831              :                                                             _,
    4832              :                                                             _,
    4833              :                                                             _,
    4834              :                                                             _,
    4835              :                                                             _);
    4836            0 :                     if (errFlag) {
    4837            0 :                         ShowFatalError(state, "InitFurnace: Program terminated for previous conditions.");
    4838              :                     }
    4839            0 :                     thisFurnace.MaxHeatCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.HeatingCoilIndex, ErrorsFound);
    4840            0 :                     if (thisFurnace.MaxHeatCoilFluidFlow > 0.0) {
    4841            0 :                         SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, RoutineName);
    4842            0 :                         thisFurnace.MaxHeatCoilFluidFlow *= SteamDensity;
    4843              :                     }
    4844              :                 }
    4845              :                 // fill outlet node for coil
    4846            0 :                 thisFurnace.CoilOutletNode = DataPlant::CompData::getPlantComponent(state, thisFurnace.plantLoc).NodeNumOut;
    4847            0 :                 state.dataFurnaces->MyPlantScanFlag(FurnaceNum) = false;
    4848              :             } else { // pthp not connected to plant
    4849            2 :                 state.dataFurnaces->MyPlantScanFlag(FurnaceNum) = false;
    4850              :             }
    4851        15220 :         } else if (state.dataFurnaces->MyPlantScanFlag(FurnaceNum) && !state.dataGlobal->AnyPlantInModel) {
    4852            0 :             state.dataFurnaces->MyPlantScanFlag(FurnaceNum) = false;
    4853              :         }
    4854              : 
    4855              :         // Scan Supplemental hot water and steam heating coil plant components for one time initializations
    4856        15222 :         if (state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) && allocated(state.dataPlnt->PlantLoop)) {
    4857            2 :             if ((thisFurnace.SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) || (thisFurnace.SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam)) {
    4858              : 
    4859            0 :                 if (thisFurnace.SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
    4860            0 :                     errFlag = false;
    4861            0 :                     PlantUtilities::ScanPlantLoopsForObject(state,
    4862              :                                                             thisFurnace.SuppHeatCoilName,
    4863              :                                                             DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
    4864            0 :                                                             thisFurnace.SuppPlantLoc,
    4865              :                                                             errFlag,
    4866              :                                                             _,
    4867              :                                                             _,
    4868              :                                                             _,
    4869              :                                                             _,
    4870              :                                                             _);
    4871            0 :                     if (errFlag) {
    4872            0 :                         ShowFatalError(state, "InitFurnace: Program terminated for previous conditions.");
    4873              :                     }
    4874            0 :                     thisFurnace.MaxSuppCoilFluidFlow =
    4875            0 :                         WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", thisFurnace.SuppHeatCoilName, ErrorsFound);
    4876            0 :                     if (thisFurnace.MaxSuppCoilFluidFlow > 0.0) {
    4877            0 :                         rho = state.dataPlnt->PlantLoop(thisFurnace.SuppPlantLoc.loopNum)
    4878            0 :                                   .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    4879            0 :                         thisFurnace.MaxSuppCoilFluidFlow *= rho;
    4880              :                     }
    4881            0 :                 } else if (thisFurnace.SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
    4882            0 :                     errFlag = false;
    4883            0 :                     PlantUtilities::ScanPlantLoopsForObject(state,
    4884              :                                                             thisFurnace.SuppHeatCoilName,
    4885              :                                                             DataPlant::PlantEquipmentType::CoilSteamAirHeating,
    4886            0 :                                                             thisFurnace.SuppPlantLoc,
    4887              :                                                             errFlag,
    4888              :                                                             _,
    4889              :                                                             _,
    4890              :                                                             _,
    4891              :                                                             _,
    4892              :                                                             _);
    4893            0 :                     if (errFlag) {
    4894            0 :                         ShowFatalError(state, "InitFurnace: Program terminated for previous conditions.");
    4895              :                     }
    4896            0 :                     thisFurnace.MaxSuppCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.SuppHeatCoilIndex, ErrorsFound);
    4897            0 :                     if (thisFurnace.MaxSuppCoilFluidFlow > 0.0) {
    4898            0 :                         SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, RoutineName);
    4899            0 :                         thisFurnace.MaxSuppCoilFluidFlow *= SteamDensity;
    4900              :                     }
    4901              :                 }
    4902              :                 // fill outlet node for coil
    4903            0 :                 thisFurnace.SuppCoilOutletNode = DataPlant::CompData::getPlantComponent(state, thisFurnace.SuppPlantLoc).NodeNumOut;
    4904            0 :                 state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) = false;
    4905              :             } else { // pthp not connected to plant
    4906            2 :                 state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) = false;
    4907              :             }
    4908              : 
    4909        15220 :         } else if (state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) && !state.dataGlobal->AnyPlantInModel) {
    4910            0 :             state.dataFurnaces->MySuppCoilPlantScanFlag(FurnaceNum) = false;
    4911              :         }
    4912              : 
    4913              :         // Do the Begin Environment initializations
    4914        15222 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataFurnaces->MyEnvrnFlag(FurnaceNum)) {
    4915              :             // Change the Volume Flow Rates to Mass Flow Rates
    4916            6 :             thisFurnace.DesignMassFlowRate = thisFurnace.DesignFanVolFlowRate * state.dataEnvrn->StdRhoAir;
    4917            6 :             thisFurnace.MaxCoolAirMassFlow = thisFurnace.MaxCoolAirVolFlow * state.dataEnvrn->StdRhoAir;
    4918            6 :             thisFurnace.MaxHeatAirMassFlow = thisFurnace.MaxHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
    4919            6 :             thisFurnace.MaxNoCoolHeatAirMassFlow = thisFurnace.MaxNoCoolHeatAirVolFlow * state.dataEnvrn->StdRhoAir;
    4920            6 :             thisFurnace.CompPartLoadRatio = 0.0;
    4921            6 :             thisFurnace.CoolingCoilSensDemand = 0.0;
    4922            6 :             thisFurnace.CoolingCoilLatentDemand = 0.0;
    4923            6 :             thisFurnace.HeatingCoilSensDemand = 0.0;
    4924              : 
    4925            6 :             thisFurnace.SenLoadLoss = 0.0;
    4926            6 :             if (thisFurnace.Humidistat) {
    4927            0 :                 thisFurnace.LatLoadLoss = 0.0;
    4928              :             }
    4929              : 
    4930              :             //   set fluid-side hardware limits
    4931            6 :             if (thisFurnace.CoilControlNode > 0) {
    4932              : 
    4933            0 :                 if (thisFurnace.MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
    4934              :                     // If water coil max water flow rate is autosized, simulate once in order to mine max flow rate
    4935            0 :                     if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
    4936            0 :                         WaterCoils::SimulateWaterCoilComponents(state, thisFurnace.HeatingCoilName, FirstHVACIteration, thisFurnace.HeatingCoilIndex);
    4937              :                         CoilMaxVolFlowRate =
    4938            0 :                             WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", thisFurnace.HeatingCoilName, ErrorsFound);
    4939            0 :                         if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
    4940            0 :                             rho = state.dataPlnt->PlantLoop(thisFurnace.plantLoc.loopNum)
    4941            0 :                                       .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    4942            0 :                             thisFurnace.MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * rho;
    4943              :                         }
    4944              :                     }
    4945              :                     // If steam coil max steam flow rate is autosized, simulate once in order to mine max flow rate
    4946            0 :                     if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
    4947            0 :                         SteamCoils::SimulateSteamCoilComponents(state,
    4948              :                                                                 thisFurnace.HeatingCoilName,
    4949              :                                                                 FirstHVACIteration,
    4950            0 :                                                                 thisFurnace.HeatingCoilIndex,
    4951            0 :                                                                 1.0,
    4952              :                                                                 QActual); // QCoilReq, simulate any load > 0 to get max capacity
    4953            0 :                         CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.HeatingCoilIndex, ErrorsFound);
    4954            0 :                         if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
    4955            0 :                             SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, RoutineName);
    4956            0 :                             thisFurnace.MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
    4957              :                         }
    4958              :                     }
    4959              :                 }
    4960              : 
    4961            0 :                 PlantUtilities::InitComponentNodes(
    4962              :                     state, 0.0, thisFurnace.MaxHeatCoilFluidFlow, thisFurnace.CoilControlNode, thisFurnace.CoilOutletNode);
    4963              :             }
    4964            6 :             if (thisFurnace.SuppCoilControlNode > 0) {
    4965            0 :                 if (thisFurnace.MaxSuppCoilFluidFlow == DataSizing::AutoSize) {
    4966            0 :                     if (thisFurnace.SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
    4967              :                         // If water coil max water flow rate is autosized, simulate once in order to mine max flow rate
    4968            0 :                         WaterCoils::SimulateWaterCoilComponents(
    4969            0 :                             state, thisFurnace.SuppHeatCoilName, FirstHVACIteration, thisFurnace.SuppHeatCoilIndex);
    4970              :                         CoilMaxVolFlowRate =
    4971            0 :                             WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", thisFurnace.SuppHeatCoilName, ErrorsFound);
    4972            0 :                         if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
    4973            0 :                             rho = state.dataPlnt->PlantLoop(thisFurnace.SuppPlantLoc.loopNum)
    4974            0 :                                       .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    4975            0 :                             thisFurnace.MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * rho;
    4976              :                         }
    4977              :                     }
    4978            0 :                     if (thisFurnace.SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
    4979            0 :                         SteamCoils::SimulateSteamCoilComponents(state,
    4980              :                                                                 thisFurnace.SuppHeatCoilName,
    4981              :                                                                 FirstHVACIteration,
    4982            0 :                                                                 thisFurnace.SuppHeatCoilIndex,
    4983            0 :                                                                 1.0,
    4984              :                                                                 QActual); // QCoilReq, simulate any load > 0 to get max capacity
    4985            0 :                         CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, thisFurnace.SuppHeatCoilIndex, ErrorsFound);
    4986            0 :                         if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
    4987            0 :                             SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, state.dataFurnaces->TempSteamIn, 1.0, RoutineName);
    4988            0 :                             thisFurnace.MaxSuppCoilFluidFlow = CoilMaxVolFlowRate * SteamDensity;
    4989              :                         }
    4990              :                     }
    4991            0 :                     PlantUtilities::InitComponentNodes(
    4992              :                         state, 0.0, thisFurnace.MaxSuppCoilFluidFlow, thisFurnace.SuppCoilControlNode, thisFurnace.SuppCoilOutletNode);
    4993              :                 }
    4994              :             }
    4995            6 :             state.dataFurnaces->MyEnvrnFlag(FurnaceNum) = false;
    4996              :         }
    4997              : 
    4998        15222 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    4999        15136 :             state.dataFurnaces->MyEnvrnFlag(FurnaceNum) = true;
    5000              :         }
    5001              : 
    5002        15222 :         if (state.dataFurnaces->MyFanFlag(FurnaceNum)) {
    5003            4 :             if (thisFurnace.ActualFanVolFlowRate != DataSizing::AutoSize) {
    5004            2 :                 if (thisFurnace.ActualFanVolFlowRate > 0.0) {
    5005            2 :                     thisFurnace.HeatingSpeedRatio = thisFurnace.MaxHeatAirVolFlow / thisFurnace.ActualFanVolFlowRate;
    5006            2 :                     thisFurnace.CoolingSpeedRatio = thisFurnace.MaxCoolAirVolFlow / thisFurnace.ActualFanVolFlowRate;
    5007            2 :                     thisFurnace.NoHeatCoolSpeedRatio = thisFurnace.MaxNoCoolHeatAirVolFlow / thisFurnace.ActualFanVolFlowRate;
    5008              :                 }
    5009            2 :                 if (dynamic_cast<Fans::FanComponent *>(state.dataFans->fans(thisFurnace.FanIndex))->powerRatioAtSpeedRatioCurveNum > 0) {
    5010            0 :                     if (thisFurnace.ActualFanVolFlowRate == thisFurnace.MaxHeatAirVolFlow &&
    5011            0 :                         thisFurnace.ActualFanVolFlowRate == thisFurnace.MaxCoolAirVolFlow &&
    5012            0 :                         thisFurnace.ActualFanVolFlowRate == thisFurnace.MaxNoCoolHeatAirVolFlow) {
    5013            0 :                         std::string FanName = state.dataFans->fans(thisFurnace.FanIndex)->Name;
    5014            0 :                         ShowWarningError(state, format("{} \"{}\"", HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name));
    5015            0 :                         ShowContinueError(state,
    5016            0 :                                           format("...For fan type and name = {} \"{}\"", HVAC::fanTypeNames[(int)thisFurnace.fanType], FanName));
    5017            0 :                         ShowContinueError(state,
    5018              :                                           "...Fan power ratio function of speed ratio curve has no impact if fan volumetric flow rate is the same as "
    5019              :                                           "the unitary system volumetric flow rate.");
    5020            0 :                         ShowContinueError(state, format("...Fan volumetric flow rate            = {:.5R} m3/s.", thisFurnace.ActualFanVolFlowRate));
    5021            0 :                         ShowContinueError(state, format("...Unitary system volumetric flow rate = {:.5R} m3/s.", thisFurnace.MaxHeatAirVolFlow));
    5022            0 :                     }
    5023              :                 }
    5024            2 :                 state.dataFurnaces->MyFanFlag(FurnaceNum) = false;
    5025              :             } else {
    5026            2 :                 thisFurnace.ActualFanVolFlowRate = state.dataFans->fans(thisFurnace.FanIndex)->maxAirFlowRate;
    5027              :             }
    5028              :         }
    5029              : 
    5030        15222 :         if (allocated(state.dataZoneEquip->ZoneEquipConfig) && state.dataFurnaces->MyCheckFlag(FurnaceNum)) {
    5031            2 :             int zoneNum = thisFurnace.ControlZoneNum;
    5032            2 :             int zoneInlet = thisFurnace.ZoneInletNode;
    5033              :             // setup furnace zone equipment sequence information based on finding matching air terminal
    5034            2 :             if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex > 0) {
    5035            2 :                 int coolingPriority = 0;
    5036            2 :                 int heatingPriority = 0;
    5037            2 :                 state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex)
    5038            2 :                     .getPrioritiesForInletNode(state, zoneInlet, coolingPriority, heatingPriority);
    5039            2 :                 thisFurnace.ZoneSequenceCoolingNum = coolingPriority;
    5040            2 :                 thisFurnace.ZoneSequenceHeatingNum = heatingPriority;
    5041              :             }
    5042            2 :             state.dataFurnaces->MyCheckFlag(FurnaceNum) = false;
    5043            2 :             if (thisFurnace.ZoneSequenceCoolingNum == 0 || thisFurnace.ZoneSequenceHeatingNum == 0) {
    5044            0 :                 ShowSevereError(state,
    5045            0 :                                 format("{} \"{}\": Airloop air terminal in the zone equipment list for zone = {} not found or is not allowed Zone "
    5046              :                                        "Equipment Cooling or Heating Sequence = 0.",
    5047            0 :                                        HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    5048            0 :                                        thisFurnace.Name,
    5049            0 :                                        state.dataHeatBal->Zone(thisFurnace.ControlZoneNum).Name));
    5050            0 :                 ShowFatalError(state,
    5051            0 :                                format("Subroutine InitFurnace: Errors found in getting {} input.  Preceding condition(s) causes termination.",
    5052            0 :                                       HVAC::unitarySysTypeNames[(int)thisFurnace.type]));
    5053              :             }
    5054              :         }
    5055              : 
    5056              :         // Find the number of zones (zone Inlet Nodes) attached to an air loop from the air loop number
    5057              :         int NumAirLoopZones =
    5058        15222 :             state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled + state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated;
    5059        15222 :         if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataFurnaces->MyFlowFracFlag(FurnaceNum)) {
    5060            2 :             state.dataFurnaces->FlowFracFlagReady = true;
    5061            4 :             for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
    5062              :                 // zone inlet nodes for cooling
    5063            2 :                 if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesCooled > 0) {
    5064            2 :                     if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex) == -999) {
    5065              :                         // the data structure for the zones inlet nodes has not been filled
    5066            0 :                         state.dataFurnaces->FlowFracFlagReady = false;
    5067              :                     }
    5068              :                 }
    5069              :                 // zone inlet nodes for heating
    5070            2 :                 if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).NumZonesHeated > 0) {
    5071            0 :                     if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitHeatInletNodes(ZoneInSysIndex) == -999) {
    5072              :                         // the data structure for the zones inlet nodes has not been filled
    5073            0 :                         state.dataFurnaces->FlowFracFlagReady = false;
    5074              :                     }
    5075              :                 }
    5076              :             }
    5077              :         }
    5078              : 
    5079        15222 :         if (state.dataFurnaces->MyFlowFracFlag(FurnaceNum)) {
    5080            2 :             if (allocated(state.dataAirLoop->AirToZoneNodeInfo) && state.dataFurnaces->FlowFracFlagReady) {
    5081            2 :                 SumOfMassFlowRateMax = 0.0; // initialize the sum of the maximum flows
    5082            4 :                 for (int ZoneInSysIndex = 1; ZoneInSysIndex <= NumAirLoopZones; ++ZoneInSysIndex) {
    5083            2 :                     int ZoneInletNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).TermUnitCoolInletNodes(ZoneInSysIndex);
    5084            2 :                     SumOfMassFlowRateMax += state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
    5085            2 :                     if (state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).CoolCtrlZoneNums(ZoneInSysIndex) == thisFurnace.ControlZoneNum) {
    5086            2 :                         CntrlZoneTerminalUnitMassFlowRateMax = state.dataLoopNodes->Node(ZoneInletNodeNum).MassFlowRateMax;
    5087              :                     }
    5088              :                 }
    5089            2 :                 if (SumOfMassFlowRateMax != 0.0) {
    5090            2 :                     if (CntrlZoneTerminalUnitMassFlowRateMax >= HVAC::SmallAirVolFlow) {
    5091            2 :                         thisFurnace.ControlZoneMassFlowFrac = CntrlZoneTerminalUnitMassFlowRateMax / SumOfMassFlowRateMax;
    5092              :                     } else {
    5093            0 :                         ShowSevereError(state, format("{} = {}", HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name));
    5094            0 :                         ShowContinueError(state, " The Fraction of Supply Air Flow That Goes Through the Controlling Zone is set to 1.");
    5095              :                     }
    5096            4 :                     BaseSizer::reportSizerOutput(state,
    5097            2 :                                                  HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    5098              :                                                  thisFurnace.Name,
    5099              :                                                  "Fraction of Supply Air Flow That Goes Through the Controlling Zone",
    5100              :                                                  thisFurnace.ControlZoneMassFlowFrac);
    5101            2 :                     state.dataFurnaces->MyFlowFracFlag(FurnaceNum) = false;
    5102              :                 }
    5103              :             }
    5104              :         }
    5105              : 
    5106              :         // Calculate air distribution losses
    5107        15222 :         if (!FirstHVACIteration && state.dataFurnaces->AirLoopPass == 1) {
    5108         3778 :             int ZoneInNode = thisFurnace.ZoneInletNode;
    5109         3778 :             MassFlowRate = state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / thisFurnace.ControlZoneMassFlowFrac;
    5110         3778 :             if (state.afn->distribution_simulated) {
    5111         2764 :                 DeltaMassRate = state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).MassFlowRate -
    5112         2764 :                                 state.dataLoopNodes->Node(ZoneInNode).MassFlowRate / thisFurnace.ControlZoneMassFlowFrac;
    5113         2764 :                 if (DeltaMassRate < 0.0) {
    5114         1077 :                     DeltaMassRate = 0.0;
    5115              :                 }
    5116              :             } else {
    5117         1014 :                 MassFlowRate = state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).MassFlowRate;
    5118         1014 :                 DeltaMassRate = 0.0;
    5119              :             }
    5120         3778 :             Real64 TotalOutput(0.0);         // total output rate, {W}
    5121         3778 :             Real64 SensibleOutputDelta(0.0); // delta sensible output rate, {W}
    5122         3778 :             Real64 LatentOutputDelta(0.0);   // delta latent output rate, {W}
    5123         3778 :             Real64 TotalOutputDelta(0.0);    // delta total output rate, {W}
    5124        15112 :             CalcZoneSensibleLatentOutput(MassFlowRate,
    5125         3778 :                                          state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).Temp,
    5126         3778 :                                          state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).HumRat,
    5127         3778 :                                          state.dataLoopNodes->Node(ZoneInNode).Temp,
    5128         3778 :                                          state.dataLoopNodes->Node(ZoneInNode).HumRat,
    5129         3778 :                                          thisFurnace.SenLoadLoss,
    5130         3778 :                                          thisFurnace.LatLoadLoss,
    5131              :                                          TotalOutput);
    5132        15112 :             CalcZoneSensibleLatentOutput(DeltaMassRate,
    5133         3778 :                                          state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).Temp,
    5134         3778 :                                          state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).HumRat,
    5135         3778 :                                          state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).Temp,
    5136         3778 :                                          state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).HumRat,
    5137              :                                          SensibleOutputDelta,
    5138              :                                          LatentOutputDelta,
    5139              :                                          TotalOutputDelta);
    5140         3778 :             thisFurnace.SenLoadLoss = thisFurnace.SenLoadLoss + SensibleOutputDelta;
    5141         3778 :             if (std::abs(thisFurnace.SensibleLoadMet) > 0.0) {
    5142         3777 :                 if (std::abs(thisFurnace.SenLoadLoss / thisFurnace.SensibleLoadMet) < 0.001) {
    5143         1013 :                     thisFurnace.SenLoadLoss = 0.0;
    5144              :                 }
    5145              :             }
    5146         3778 :             if (thisFurnace.Humidistat) {
    5147            0 :                 thisFurnace.LatLoadLoss = thisFurnace.LatLoadLoss + LatentOutputDelta;
    5148            0 :                 if (std::abs(thisFurnace.LatentLoadMet) > 0.0) {
    5149            0 :                     if (std::abs(thisFurnace.LatLoadLoss / thisFurnace.LatentLoadMet) < 0.001) {
    5150            0 :                         thisFurnace.LatLoadLoss = 0.0;
    5151              :                     }
    5152              :                 }
    5153              :             }
    5154              :         }
    5155              : 
    5156        15222 :         if (thisFurnace.fanOpModeSched != nullptr) {
    5157        15222 :             thisFurnace.fanOp = (thisFurnace.fanOpModeSched->getCurrentVal() == 0.0) ? HVAC::FanOp::Cycling : HVAC::FanOp::Continuous;
    5158        15222 :             if (AirLoopNum > 0) {
    5159        15222 :                 state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = thisFurnace.fanOp;
    5160              :             }
    5161              :         }
    5162              : 
    5163        15222 :         fanOp = thisFurnace.fanOp;
    5164        15222 :         state.dataFurnaces->EconomizerFlag = state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive;
    5165              : 
    5166        15222 :         if (thisFurnace.ControlZoneMassFlowFrac > 0.0) {
    5167        15222 :             QZnReq = ZoneLoad / thisFurnace.ControlZoneMassFlowFrac;
    5168        15222 :             MoistureLoad /= thisFurnace.ControlZoneMassFlowFrac;
    5169        15222 :             ZoneLoad = QZnReq;
    5170              :         } else {
    5171            0 :             QZnReq = ZoneLoad;
    5172              :         }
    5173              : 
    5174              :         // Original thermostat control logic (works only for cycling fan systems)
    5175        23584 :         if (QZnReq > HVAC::SmallLoad && QZnReq > (Small5WLoad / thisFurnace.ControlZoneMassFlowFrac) &&
    5176         8362 :             !state.dataZoneEnergyDemand->CurDeadBandOrSetback(thisFurnace.ControlZoneNum)) {
    5177         8362 :             state.dataFurnaces->HeatingLoad = true;
    5178         8362 :             state.dataFurnaces->CoolingLoad = false;
    5179        13608 :         } else if (QZnReq < -HVAC::SmallLoad && std::abs(QZnReq) > (Small5WLoad / thisFurnace.ControlZoneMassFlowFrac) &&
    5180         6748 :                    !state.dataZoneEnergyDemand->CurDeadBandOrSetback(thisFurnace.ControlZoneNum)) {
    5181         6748 :             state.dataFurnaces->HeatingLoad = false;
    5182         6748 :             state.dataFurnaces->CoolingLoad = true;
    5183              :         } else {
    5184          112 :             state.dataFurnaces->HeatingLoad = false;
    5185          112 :             state.dataFurnaces->CoolingLoad = false;
    5186              :         }
    5187              : 
    5188        15222 :         if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    5189            0 :             (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir &&
    5190            0 :              (thisFurnace.WatertoAirHPType == WAHPCoilType::Simple || thisFurnace.WatertoAirHPType == WAHPCoilType::VarSpeedEquationFit))) {
    5191        15222 :             if (MoistureLoad < 0.0 && thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
    5192            0 :                 state.dataFurnaces->HPDehumidificationLoadFlag = true;
    5193            0 :                 state.dataFurnaces->HeatingLoad = false;
    5194            0 :                 state.dataFurnaces->CoolingLoad = true;
    5195              :             } else {
    5196        15222 :                 state.dataFurnaces->HPDehumidificationLoadFlag = false;
    5197              :             }
    5198              :         }
    5199              : 
    5200              :         // Check for heat only furnace
    5201        15222 :         if (thisFurnace.type != HVAC::UnitarySysType::Furnace_HeatOnly && thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatOnly) {
    5202              : 
    5203        30444 :             if (thisFurnace.availSched->getCurrentVal() > 0.0) {
    5204        15222 :                 if ((state.dataFurnaces->HeatingLoad || state.dataFurnaces->CoolingLoad) || (thisFurnace.Humidistat && MoistureLoad < 0.0)) {
    5205        15110 :                     PartLoadRatio = 1.0;
    5206              :                 } else {
    5207          112 :                     PartLoadRatio = 0.0;
    5208              :                 }
    5209              :             } else {
    5210            0 :                 PartLoadRatio = 0.0;
    5211              :             }
    5212              :         } else {
    5213            0 :             PartLoadRatio = 1.0;
    5214              :         }
    5215              : 
    5216              :         // get current time step operating capacity of water and steam coils
    5217              :         // (dependent on entering water and steam temperature)
    5218        15222 :         if (FirstHVACIteration) {
    5219         4846 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWater) {
    5220              :                 // set water-side mass flow rates
    5221            0 :                 state.dataLoopNodes->Node(thisFurnace.HWCoilAirInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
    5222            0 :                 mdot = thisFurnace.MaxHeatCoilFluidFlow;
    5223            0 :                 PlantUtilities::SetComponentFlowRate(state, mdot, thisFurnace.CoilControlNode, thisFurnace.CoilOutletNode, thisFurnace.plantLoc);
    5224              :                 //     simulate water coil to find operating capacity
    5225            0 :                 WaterCoils::SimulateWaterCoilComponents(
    5226            0 :                     state, thisFurnace.HeatingCoilName, FirstHVACIteration, thisFurnace.HeatingCoilIndex, QActual);
    5227            0 :                 thisFurnace.DesignHeatingCapacity = QActual;
    5228              : 
    5229              :             } // from IF(furnace%HeatingCoilType_Num == Coil_HeatingWater) THEN
    5230              : 
    5231         4846 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
    5232              :                 // set air-side and steam-side mass flow rates
    5233            0 :                 state.dataLoopNodes->Node(thisFurnace.HWCoilAirInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
    5234            0 :                 mdot = thisFurnace.MaxHeatCoilFluidFlow;
    5235            0 :                 PlantUtilities::SetComponentFlowRate(state, mdot, thisFurnace.CoilControlNode, thisFurnace.CoilOutletNode, thisFurnace.plantLoc);
    5236              : 
    5237              :                 //     simulate steam coil to find operating capacity
    5238            0 :                 SteamCoils::SimulateSteamCoilComponents(state,
    5239              :                                                         thisFurnace.HeatingCoilName,
    5240              :                                                         FirstHVACIteration,
    5241            0 :                                                         thisFurnace.HeatingCoilIndex,
    5242            0 :                                                         1.0,
    5243              :                                                         QActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
    5244            0 :                 thisFurnace.DesignHeatingCapacity =
    5245            0 :                     SteamCoils::GetCoilCapacity(state, thisFurnace.HeatingCoilType, thisFurnace.HeatingCoilName, ErrorsFound);
    5246              : 
    5247              :             } // from IF(Furnace(FurnaceNum)%HeatingCoilType_Num == Coil_HeatingSteam) THEN
    5248              : 
    5249         4846 :             if (thisFurnace.SuppHeatCoilType_Num == HVAC::Coil_HeatingWater) {
    5250              : 
    5251              :                 //     set air-side and steam-side mass flow rates
    5252            0 :                 state.dataLoopNodes->Node(thisFurnace.SuppCoilAirInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
    5253            0 :                 mdot = thisFurnace.MaxSuppCoilFluidFlow;
    5254            0 :                 PlantUtilities::SetComponentFlowRate(
    5255            0 :                     state, mdot, thisFurnace.SuppCoilControlNode, thisFurnace.SuppCoilOutletNode, thisFurnace.SuppPlantLoc);
    5256              : 
    5257              :                 //     simulate water coil to find operating capacity
    5258            0 :                 WaterCoils::SimulateWaterCoilComponents(
    5259            0 :                     state, thisFurnace.SuppHeatCoilName, FirstHVACIteration, thisFurnace.SuppHeatCoilIndex, QActual);
    5260            0 :                 thisFurnace.DesignSuppHeatingCapacity = QActual;
    5261              : 
    5262              :             } // from IF(Furnace(FurnaceNum)%SuppHeatCoilType_Num == Coil_HeatingWater) THEN
    5263         4846 :             if (thisFurnace.SuppHeatCoilType_Num == HVAC::Coil_HeatingSteam) {
    5264              :                 //     set air-side and steam-side mass flow rates
    5265            0 :                 state.dataLoopNodes->Node(thisFurnace.SuppCoilAirInletNode).MassFlowRate = state.dataFurnaces->CompOnMassFlow;
    5266            0 :                 mdot = thisFurnace.MaxSuppCoilFluidFlow;
    5267            0 :                 PlantUtilities::SetComponentFlowRate(
    5268            0 :                     state, mdot, thisFurnace.SuppCoilControlNode, thisFurnace.SuppCoilOutletNode, thisFurnace.SuppPlantLoc);
    5269              : 
    5270              :                 //     simulate steam coil to find operating capacity
    5271            0 :                 SteamCoils::SimulateSteamCoilComponents(state,
    5272              :                                                         thisFurnace.SuppHeatCoilName,
    5273              :                                                         FirstHVACIteration,
    5274            0 :                                                         thisFurnace.SuppHeatCoilIndex,
    5275            0 :                                                         1.0,
    5276              :                                                         QActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
    5277            0 :                 thisFurnace.DesignSuppHeatingCapacity =
    5278            0 :                     SteamCoils::GetCoilCapacity(state, thisFurnace.SuppHeatCoilType, thisFurnace.SuppHeatCoilName, ErrorsFound);
    5279              : 
    5280              :             } // from IF(Furnace(FurnaceNum)%SuppHeatCoilType_Num == Coil_HeatingSteam) THEN
    5281              :         } // from IF( FirstHVACIteration ) THEN
    5282              : 
    5283        15222 :         if (thisFurnace.NumOfSpeedCooling > 0) { // BoS, variable-speed water source hp
    5284              :             // Furnace(FurnaceNum)%IdleMassFlowRate = RhoAir*Furnace(FurnaceNum)%IdleVolumeAirRate
    5285            0 :             int NumOfSpeedCooling = thisFurnace.NumOfSpeedCooling;
    5286            0 :             int NumOfSpeedHeating = thisFurnace.NumOfSpeedHeating;
    5287              :             // IF MSHP system was not autosized and the fan is autosized, check that fan volumetric flow rate is greater than MSHP flow rates
    5288            0 :             if (thisFurnace.CheckFanFlow) {
    5289            0 :                 state.dataFurnaces->CurrentModuleObject = "AirLoopHVAC:UnitaryHeatPump:VariableSpeed";
    5290            0 :                 thisFurnace.FanVolFlow = state.dataFans->fans(thisFurnace.FanIndex)->maxAirFlowRate;
    5291              : 
    5292            0 :                 if (thisFurnace.FanVolFlow != DataSizing::AutoSize) {
    5293              :                     //     Check fan versus system supply air flow rates
    5294            0 :                     if (thisFurnace.FanVolFlow + 1e-10 < thisFurnace.CoolVolumeFlowRate(NumOfSpeedCooling)) {
    5295            0 :                         ShowWarningError(state,
    5296            0 :                                          format("{} - air flow rate = {:.7T} in fan object is less than the MSHP system air flow rate when cooling "
    5297              :                                                 "is required ({:.7T}).",
    5298            0 :                                                 state.dataFurnaces->CurrentModuleObject,
    5299            0 :                                                 thisFurnace.FanVolFlow,
    5300              :                                                 thisFurnace.CoolVolumeFlowRate(NumOfSpeedCooling)));
    5301            0 :                         ShowContinueError(
    5302              :                             state, " The MSHP system flow rate when cooling is required is reset to the fan flow rate and the simulation continues.");
    5303            0 :                         ShowContinueError(state, format(" Occurs in {} = {}", state.dataFurnaces->CurrentModuleObject, thisFurnace.Name));
    5304            0 :                         thisFurnace.CoolVolumeFlowRate(NumOfSpeedCooling) = thisFurnace.FanVolFlow;
    5305              : 
    5306            0 :                         if (thisFurnace.bIsIHP) // set max fan flow rate to the IHP collection
    5307              :                         {
    5308            0 :                             state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).MaxCoolAirVolFlow = thisFurnace.FanVolFlow;
    5309            0 :                             state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).MaxCoolAirMassFlow =
    5310            0 :                                 thisFurnace.FanVolFlow * state.dataEnvrn->StdRhoAir;
    5311              :                         }
    5312              : 
    5313              :                         // Check flow rates in other speeds and ensure flow rates are not above the max flow rate
    5314            0 :                         for (int i = NumOfSpeedCooling - 1; i >= 1; --i) {
    5315            0 :                             if (thisFurnace.CoolVolumeFlowRate(i) > thisFurnace.CoolVolumeFlowRate(i + 1)) {
    5316            0 :                                 ShowContinueError(state,
    5317            0 :                                                   format(" The MSHP system flow rate when cooling is required is reset to the flow rate at higher "
    5318              :                                                          "speed and the simulation continues at Speed{}.",
    5319              :                                                          i));
    5320            0 :                                 ShowContinueError(state, format(" Occurs in {} = {}", state.dataFurnaces->CurrentModuleObject, thisFurnace.Name));
    5321            0 :                                 thisFurnace.CoolVolumeFlowRate(i) = thisFurnace.CoolVolumeFlowRate(i + 1);
    5322              :                             }
    5323              :                         }
    5324              :                     }
    5325            0 :                     if (NumOfSpeedHeating > 0) {
    5326            0 :                         if (thisFurnace.FanVolFlow + 1e-10 < thisFurnace.HeatVolumeFlowRate(NumOfSpeedHeating)) {
    5327            0 :                             ShowWarningError(state,
    5328            0 :                                              format("{} - air flow rate = {:.7T} in fan object is less than the MSHP system air flow rate when "
    5329              :                                                     "heating is required ({:.7T}).",
    5330            0 :                                                     state.dataFurnaces->CurrentModuleObject,
    5331            0 :                                                     thisFurnace.FanVolFlow,
    5332              :                                                     thisFurnace.HeatVolumeFlowRate(NumOfSpeedHeating)));
    5333            0 :                             ShowContinueError(
    5334              :                                 state,
    5335              :                                 " The MSHP system flow rate when heating is required is reset to the fan flow rate and the simulation continues.");
    5336            0 :                             ShowContinueError(state, format(" Occurs in {} = {}", state.dataFurnaces->CurrentModuleObject, thisFurnace.Name));
    5337            0 :                             thisFurnace.HeatVolumeFlowRate(NumOfSpeedHeating) = thisFurnace.FanVolFlow;
    5338              : 
    5339            0 :                             if (thisFurnace.bIsIHP) // set max fan flow rate to the IHP collection
    5340              :                             {
    5341            0 :                                 state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).MaxHeatAirVolFlow = thisFurnace.FanVolFlow;
    5342            0 :                                 state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).MaxHeatAirMassFlow =
    5343            0 :                                     thisFurnace.FanVolFlow * state.dataEnvrn->StdRhoAir;
    5344              :                             }
    5345              : 
    5346            0 :                             for (int i = NumOfSpeedHeating - 1; i >= 1; --i) {
    5347            0 :                                 if (thisFurnace.HeatVolumeFlowRate(i) > thisFurnace.HeatVolumeFlowRate(i + 1)) {
    5348            0 :                                     ShowContinueError(state,
    5349            0 :                                                       format(" The MSHP system flow rate when heating is required is reset to the flow rate at "
    5350              :                                                              "higher speed and the simulation continues at Speed{}.",
    5351              :                                                              i));
    5352            0 :                                     ShowContinueError(state,
    5353            0 :                                                       format(" Occurs in {} system = {}", state.dataFurnaces->CurrentModuleObject, thisFurnace.Name));
    5354            0 :                                     thisFurnace.HeatVolumeFlowRate(i) = thisFurnace.HeatVolumeFlowRate(i + 1);
    5355              :                                 }
    5356              :                             }
    5357              :                         }
    5358              :                     }
    5359            0 :                     if (thisFurnace.FanVolFlow < thisFurnace.IdleVolumeAirRate && thisFurnace.IdleVolumeAirRate != 0.0) {
    5360            0 :                         ShowWarningError(state,
    5361            0 :                                          format("{} - air flow rate = {:.7T} in fan object is less than the MSHP system air flow rate when no "
    5362              :                                                 "heating or cooling is needed ({:.7T}).",
    5363            0 :                                                 state.dataFurnaces->CurrentModuleObject,
    5364            0 :                                                 thisFurnace.FanVolFlow,
    5365            0 :                                                 thisFurnace.IdleVolumeAirRate));
    5366            0 :                         ShowContinueError(state,
    5367              :                                           " The MSHP system flow rate when no heating or cooling is needed is reset to the fan flow rate and the "
    5368              :                                           "simulation continues.");
    5369            0 :                         ShowContinueError(state, format(" Occurs in {} = {}", state.dataFurnaces->CurrentModuleObject, thisFurnace.Name));
    5370            0 :                         thisFurnace.IdleVolumeAirRate = thisFurnace.FanVolFlow;
    5371              :                     }
    5372            0 :                     RhoAir = state.dataEnvrn->StdRhoAir;
    5373              :                     // set the mass flow rates from the reset volume flow rates
    5374            0 :                     for (int i = 1; i <= NumOfSpeedCooling; ++i) {
    5375            0 :                         thisFurnace.CoolMassFlowRate(i) = RhoAir * thisFurnace.CoolVolumeFlowRate(i);
    5376            0 :                         if (thisFurnace.FanVolFlow > 0.0) {
    5377            0 :                             thisFurnace.MSCoolingSpeedRatio(i) = thisFurnace.CoolVolumeFlowRate(i) / thisFurnace.FanVolFlow;
    5378              :                         }
    5379              :                     }
    5380            0 :                     for (int i = 1; i <= NumOfSpeedHeating; ++i) {
    5381            0 :                         thisFurnace.HeatMassFlowRate(i) = RhoAir * thisFurnace.HeatVolumeFlowRate(i);
    5382            0 :                         if (thisFurnace.FanVolFlow > 0.0) {
    5383            0 :                             thisFurnace.MSHeatingSpeedRatio(i) = thisFurnace.HeatVolumeFlowRate(i) / thisFurnace.FanVolFlow;
    5384              :                         }
    5385              :                     }
    5386            0 :                     thisFurnace.IdleMassFlowRate = RhoAir * thisFurnace.IdleVolumeAirRate;
    5387            0 :                     if (thisFurnace.FanVolFlow > 0.0) {
    5388            0 :                         thisFurnace.IdleSpeedRatio = thisFurnace.IdleVolumeAirRate / thisFurnace.FanVolFlow;
    5389              :                     }
    5390              :                     // set the node max and min mass flow rates based on reset volume flow rates
    5391            0 :                     if (NumOfSpeedCooling > 0 && NumOfSpeedHeating == 0) {
    5392            0 :                         state.dataLoopNodes->Node(InNode).MassFlowRateMax =
    5393            0 :                             max(thisFurnace.CoolMassFlowRate(NumOfSpeedCooling), thisFurnace.MaxHeatAirMassFlow);
    5394            0 :                         state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail =
    5395            0 :                             max(thisFurnace.CoolMassFlowRate(NumOfSpeedCooling), thisFurnace.MaxHeatAirMassFlow);
    5396            0 :                     } else if (NumOfSpeedCooling == 0 && NumOfSpeedHeating > 0) {
    5397            0 :                         state.dataLoopNodes->Node(InNode).MassFlowRateMax =
    5398            0 :                             max(thisFurnace.MaxCoolAirMassFlow, thisFurnace.HeatMassFlowRate(NumOfSpeedHeating));
    5399            0 :                         state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail =
    5400            0 :                             max(thisFurnace.MaxCoolAirMassFlow, thisFurnace.HeatMassFlowRate(NumOfSpeedHeating));
    5401              :                     } else {
    5402            0 :                         state.dataLoopNodes->Node(InNode).MassFlowRateMax =
    5403            0 :                             max(thisFurnace.CoolMassFlowRate(NumOfSpeedCooling), thisFurnace.HeatMassFlowRate(NumOfSpeedHeating));
    5404            0 :                         state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail =
    5405            0 :                             max(thisFurnace.CoolMassFlowRate(NumOfSpeedCooling), thisFurnace.HeatMassFlowRate(NumOfSpeedHeating));
    5406              :                     }
    5407            0 :                     state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
    5408            0 :                     state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
    5409            0 :                     state.dataLoopNodes->Node(OutNode) = state.dataLoopNodes->Node(InNode);
    5410              :                 }
    5411              :             }
    5412              : 
    5413            0 :             thisFurnace.CheckFanFlow = false;
    5414              :         }
    5415        15222 :         SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, QZnReq, MoistureLoad, PartLoadRatio);
    5416              : 
    5417              :         // Check ventilation/fan load for constant fan systems to see if load to be met changes
    5418              :         // Same IF logic used in Subroutine SetAverageAirFlow to determine if unit is ON or OFF
    5419              : 
    5420        15222 :         QToCoolSetPt = 0.0;
    5421        15222 :         QToHeatSetPt = 0.0;
    5422        15222 :         if (fanOp == HVAC::FanOp::Continuous && thisFurnace.availSched->getCurrentVal() > 0.0 &&
    5423            0 :             ((thisFurnace.fanAvailSched->getCurrentVal() > 0.0 || state.dataHVACGlobal->TurnFansOn) && !state.dataHVACGlobal->TurnFansOff)) {
    5424              : 
    5425            0 :             if (thisFurnace.NumOfSpeedCooling > 0) {
    5426            0 :                 CalcVarSpeedHeatPump(state,
    5427              :                                      FurnaceNum,
    5428              :                                      false,
    5429              :                                      HVAC::CompressorOp::Off,
    5430              :                                      1,
    5431              :                                      0.0,
    5432              :                                      0.0,
    5433              :                                      SensibleOutput,
    5434              :                                      LatentOutput,
    5435              :                                      0.0,
    5436              :                                      0.0,
    5437              :                                      OnOffAirFlowRatio,
    5438              :                                      SUPHEATERLOAD);
    5439              :             } else {
    5440            0 :                 CalcFurnaceOutput(state,
    5441              :                                   FurnaceNum,
    5442              :                                   false,
    5443              :                                   HVAC::FanOp::Invalid, // Looks like Invalid is used to mean that the fan is off here?
    5444              :                                   HVAC::CompressorOp::Off,
    5445              :                                   0.0,
    5446              :                                   0.0,
    5447              :                                   0.0,
    5448              :                                   0.0,
    5449              :                                   SensibleOutput,
    5450              :                                   LatentOutput,
    5451              :                                   OnOffAirFlowRatio,
    5452              :                                   false);
    5453              :             }
    5454              : 
    5455            0 :             if (thisFurnace.ControlZoneMassFlowFrac > 0.0) {
    5456            0 :                 if (thisFurnace.ZoneSequenceCoolingNum > 0 && thisFurnace.ZoneSequenceHeatingNum > 0) {
    5457            0 :                     QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum)
    5458            0 :                                        .SequencedOutputRequiredToCoolingSP(thisFurnace.ZoneSequenceCoolingNum) /
    5459            0 :                                    thisFurnace.ControlZoneMassFlowFrac;
    5460            0 :                     QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum)
    5461            0 :                                        .SequencedOutputRequiredToHeatingSP(thisFurnace.ZoneSequenceHeatingNum) /
    5462            0 :                                    thisFurnace.ControlZoneMassFlowFrac;
    5463              :                 } else {
    5464            0 :                     QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum).OutputRequiredToCoolingSP /
    5465            0 :                                    thisFurnace.ControlZoneMassFlowFrac;
    5466            0 :                     QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum).OutputRequiredToHeatingSP /
    5467            0 :                                    thisFurnace.ControlZoneMassFlowFrac;
    5468              :                 }
    5469              :                 //     If the furnace has a net cooling capacity (SensibleOutput < 0) and
    5470              :                 //     the zone temp is above the Tstat heating setpoint (QToHeatSetPt < 0) and
    5471              :                 //     the net cooling capacity does not just offset the cooling load
    5472            0 :                 if (SensibleOutput < 0.0 && QToHeatSetPt < 0.0 &&
    5473            0 :                     std::abs(QToCoolSetPt - SensibleOutput) > (Small5WLoad / thisFurnace.ControlZoneMassFlowFrac)) {
    5474              :                     //       Only switch modes when humidistat is not used or no moisture load exists, otherwise let
    5475              :                     //       reheat coil pick up load
    5476              :                     //        IF((SensibleOutput .LT. QToHeatSetPt .AND. .NOT. Furnace(FurnaceNum)%Humidistat) .OR. &
    5477              :                     //           (SensibleOutput .LT. QToHeatSetPt .AND. Furnace(FurnaceNum)%Humidistat .AND. MoistureLoad .GE. 0.0))THEN
    5478            0 :                     if ((SensibleOutput < QToHeatSetPt && !thisFurnace.Humidistat) ||
    5479            0 :                         (SensibleOutput < QToHeatSetPt && thisFurnace.Humidistat && MoistureLoad >= 0.0)) {
    5480            0 :                         QZnReq = QToHeatSetPt;
    5481            0 :                         state.dataFurnaces->CoolingLoad = false;
    5482              :                         //         Don't set mode TRUE unless mode is allowed. Also check for floating zone.
    5483            0 :                         if (state.dataHeatBalFanSys->TempControlType(thisFurnace.ControlZoneNum) == HVAC::SetptType::SingleCool ||
    5484            0 :                             state.dataHeatBalFanSys->TempControlType(thisFurnace.ControlZoneNum) == HVAC::SetptType::Uncontrolled) {
    5485            0 :                             state.dataFurnaces->HeatingLoad = false;
    5486              :                         } else {
    5487            0 :                             state.dataFurnaces->HeatingLoad = true;
    5488              :                         }
    5489              : 
    5490            0 :                         SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, QZnReq, MoistureLoad, PartLoadRatio);
    5491            0 :                         if (thisFurnace.NumOfSpeedCooling > 0) {
    5492            0 :                             CalcVarSpeedHeatPump(state,
    5493              :                                                  FurnaceNum,
    5494              :                                                  false,
    5495              :                                                  HVAC::CompressorOp::Off,
    5496              :                                                  1,
    5497              :                                                  0.0,
    5498              :                                                  0.0,
    5499              :                                                  SensibleOutput,
    5500              :                                                  LatentOutput,
    5501              :                                                  0.0,
    5502              :                                                  0.0,
    5503              :                                                  OnOffAirFlowRatio,
    5504              :                                                  SUPHEATERLOAD);
    5505              :                         } else {
    5506            0 :                             CalcFurnaceOutput(state,
    5507              :                                               FurnaceNum,
    5508              :                                               false,
    5509              :                                               HVAC::FanOp::Invalid,
    5510              :                                               HVAC::CompressorOp::Off,
    5511              :                                               0.0,
    5512              :                                               0.0,
    5513              :                                               0.0,
    5514              :                                               0.0,
    5515              :                                               SensibleOutput,
    5516              :                                               LatentOutput,
    5517              :                                               OnOffAirFlowRatio,
    5518              :                                               false);
    5519              :                         }
    5520            0 :                         if (SensibleOutput > QToHeatSetPt) {
    5521              :                             // If changing operating mode (flow rates) does not overshoot heating setpoint, turn off heating
    5522            0 :                             QZnReq = 0.0;
    5523            0 :                             state.dataFurnaces->HeatingLoad = false;
    5524            0 :                             SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, QZnReq, MoistureLoad, PartLoadRatio);
    5525              :                         }
    5526            0 :                     } else if (SensibleOutput < QZnReq) {
    5527              :                         //         If the net cooling capacity meets the zone cooling load but does not overshoot heating setpoint, turn off cooling
    5528              :                         //         (dehumidification may still occur)
    5529            0 :                         QZnReq = 0.0;
    5530            0 :                         state.dataFurnaces->CoolingLoad = false;
    5531            0 :                         if (state.dataFurnaces->HPDehumidificationLoadFlag) {
    5532            0 :                             state.dataFurnaces->CoolingLoad = true;
    5533            0 :                             state.dataFurnaces->HeatingLoad = false;
    5534              :                         }
    5535            0 :                         SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, QZnReq, MoistureLoad, PartLoadRatio);
    5536              :                     }
    5537              :                     // the net cooling capacity just offsets the cooling load, turn off cooling
    5538            0 :                 } else if (SensibleOutput < 0.0 && QToCoolSetPt < 0.0 &&
    5539            0 :                            std::abs(QToCoolSetPt - SensibleOutput) < (Small5WLoad / thisFurnace.ControlZoneMassFlowFrac)) {
    5540            0 :                     state.dataFurnaces->CoolingLoad = false;
    5541            0 :                     if (state.dataFurnaces->HPDehumidificationLoadFlag) {
    5542            0 :                         state.dataFurnaces->CoolingLoad = true;
    5543            0 :                         state.dataFurnaces->HeatingLoad = false;
    5544              :                     }
    5545              :                 } // SensibleOutput .LT. 0.0d0 .AND. QToHeatSetPt .LT. 0.0d0
    5546              : 
    5547              :                 //     If the furnace has a net heating capacity and the zone temp is below the Tstat cooling setpoint and
    5548              :                 //     the net heating capacity does not just offset the heating load
    5549            0 :                 if (SensibleOutput > 0.0 && QToCoolSetPt > 0.0 &&
    5550            0 :                     std::abs(SensibleOutput - QToHeatSetPt) > (Small5WLoad / thisFurnace.ControlZoneMassFlowFrac)) {
    5551            0 :                     if (SensibleOutput > QToCoolSetPt) {
    5552            0 :                         QZnReq = QToCoolSetPt;
    5553              :                         //         Don't set mode TRUE unless mode is allowed. Also check for floating zone.
    5554            0 :                         if (state.dataHeatBalFanSys->TempControlType(thisFurnace.ControlZoneNum) == HVAC::SetptType::SingleHeat ||
    5555            0 :                             state.dataHeatBalFanSys->TempControlType(thisFurnace.ControlZoneNum) == HVAC::SetptType::Uncontrolled) {
    5556            0 :                             state.dataFurnaces->CoolingLoad = false;
    5557              :                         } else {
    5558            0 :                             state.dataFurnaces->CoolingLoad = true;
    5559              :                         }
    5560            0 :                         state.dataFurnaces->HeatingLoad = false;
    5561              : 
    5562            0 :                         SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, QZnReq, MoistureLoad, PartLoadRatio);
    5563            0 :                         if (thisFurnace.NumOfSpeedCooling > 0) {
    5564            0 :                             CalcVarSpeedHeatPump(state,
    5565              :                                                  FurnaceNum,
    5566              :                                                  false,
    5567              :                                                  HVAC::CompressorOp::Off,
    5568              :                                                  1,
    5569              :                                                  0.0,
    5570              :                                                  0.0,
    5571              :                                                  SensibleOutput,
    5572              :                                                  LatentOutput,
    5573              :                                                  0.0,
    5574              :                                                  0.0,
    5575              :                                                  OnOffAirFlowRatio,
    5576              :                                                  SUPHEATERLOAD);
    5577              :                         } else {
    5578            0 :                             CalcFurnaceOutput(state,
    5579              :                                               FurnaceNum,
    5580              :                                               false,
    5581              :                                               HVAC::FanOp::Invalid,
    5582              :                                               HVAC::CompressorOp::Off,
    5583              :                                               0.0,
    5584              :                                               0.0,
    5585              :                                               0.0,
    5586              :                                               0.0,
    5587              :                                               SensibleOutput,
    5588              :                                               LatentOutput,
    5589              :                                               OnOffAirFlowRatio,
    5590              :                                               false);
    5591              :                         }
    5592            0 :                         if (SensibleOutput < QToCoolSetPt) {
    5593              :                             //           If changing operating mode (flow rates) does not overshoot cooling setpoint, turn off cooling
    5594            0 :                             if (state.dataFurnaces->HPDehumidificationLoadFlag) {
    5595            0 :                                 state.dataFurnaces->CoolingLoad = true;
    5596            0 :                                 state.dataFurnaces->HeatingLoad = false;
    5597              :                             } else {
    5598            0 :                                 QZnReq = 0.0;
    5599            0 :                                 state.dataFurnaces->CoolingLoad = false;
    5600              :                             }
    5601            0 :                             SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, QZnReq, MoistureLoad, PartLoadRatio);
    5602              :                         }
    5603            0 :                     } else if (SensibleOutput > QZnReq) {
    5604              :                         //         If the net heating capacity meets the zone heating load but does not overshoot, turn off heating
    5605            0 :                         QZnReq = 0.0;
    5606            0 :                         state.dataFurnaces->HeatingLoad = false;
    5607            0 :                         SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, QZnReq, MoistureLoad, PartLoadRatio);
    5608              :                     }
    5609              :                     //     the net heating capacity just offsets the heating load, turn off heating
    5610            0 :                 } else if (SensibleOutput > 0.0 && QToHeatSetPt > 0.0 &&
    5611            0 :                            std::abs(SensibleOutput - QToHeatSetPt) < (Small5WLoad / thisFurnace.ControlZoneMassFlowFrac)) {
    5612            0 :                     state.dataFurnaces->HeatingLoad = false;
    5613              :                 } // SensibleOutput .GT. 0.0d0 .AND. QToCoolSetPt .GT. 0.0d0
    5614              :             } // Furnace(FurnaceNum)%ControlZoneMassFlowFrac .GT. 0.0d0
    5615            0 :             ZoneLoad = QZnReq;
    5616              :         } // fanOp .EQ. FanOp::Continuous
    5617              : 
    5618        15222 :         if (FirstHVACIteration) {
    5619         4846 :             thisFurnace.iterationCounter = 0;
    5620         4846 :             thisFurnace.iterationMode = Furnaces::ModeOfOperation::NoCoolHeat;
    5621              :         }
    5622        15222 :         thisFurnace.iterationCounter += 1;
    5623              : 
    5624              :         // push iteration mode stack and set current mode
    5625        15222 :         thisFurnace.iterationMode(3) = thisFurnace.iterationMode(2);
    5626        15222 :         thisFurnace.iterationMode(2) = thisFurnace.iterationMode(1);
    5627        15222 :         if (state.dataFurnaces->CoolingLoad) {
    5628         6748 :             thisFurnace.iterationMode(1) = Furnaces::ModeOfOperation::CoolingMode;
    5629         8474 :         } else if (state.dataFurnaces->HeatingLoad) {
    5630         8362 :             thisFurnace.iterationMode(1) = Furnaces::ModeOfOperation::HeatingMode;
    5631              :         } else {
    5632          112 :             thisFurnace.iterationMode(1) = Furnaces::ModeOfOperation::NoCoolHeat;
    5633              :         }
    5634              : 
    5635              :         // IF small loads to meet or not converging, just shut down unit
    5636        15222 :         if (std::abs(ZoneLoad) < Small5WLoad) {
    5637          112 :             ZoneLoad = 0.0;
    5638          112 :             state.dataFurnaces->CoolingLoad = false;
    5639          112 :             state.dataFurnaces->HeatingLoad = false;
    5640        15110 :         } else if (thisFurnace.iterationCounter > (state.dataHVACGlobal->MinAirLoopIterationsAfterFirst + 4)) {
    5641              :             // attempt to lock output (air flow) if oscillations are detected
    5642            0 :             OperatingMode = thisFurnace.iterationMode(1);
    5643            0 :             OperatingModeMinusOne = thisFurnace.iterationMode(2);
    5644            0 :             OperatingModeMinusTwo = thisFurnace.iterationMode(3);
    5645            0 :             Oscillate = true;
    5646            0 :             if (OperatingMode == OperatingModeMinusOne && OperatingMode == OperatingModeMinusTwo) {
    5647            0 :                 Oscillate = false;
    5648              :             }
    5649            0 :             if (Oscillate) {
    5650            0 :                 if (QToCoolSetPt < 0.0) {
    5651            0 :                     state.dataFurnaces->HeatingLoad = false;
    5652            0 :                     state.dataFurnaces->CoolingLoad = true;
    5653            0 :                     ZoneLoad = QToCoolSetPt;
    5654            0 :                 } else if (QToHeatSetPt > 0.0) {
    5655            0 :                     state.dataFurnaces->HeatingLoad = true;
    5656            0 :                     state.dataFurnaces->CoolingLoad = false;
    5657            0 :                     ZoneLoad = QToHeatSetPt;
    5658              :                 } else {
    5659            0 :                     state.dataFurnaces->HeatingLoad = false;
    5660            0 :                     state.dataFurnaces->CoolingLoad = false;
    5661            0 :                     ZoneLoad = 0.0;
    5662              :                 }
    5663              :             }
    5664              :         }
    5665              : 
    5666              :         // EMS override point
    5667        15222 :         if (thisFurnace.EMSOverrideSensZoneLoadRequest) {
    5668            0 :             ZoneLoad = thisFurnace.EMSSensibleZoneLoadValue;
    5669              :         }
    5670        15222 :         if (thisFurnace.EMSOverrideMoistZoneLoadRequest) {
    5671            0 :             MoistureLoad = thisFurnace.EMSMoistureZoneLoadValue;
    5672              :         }
    5673        15222 :         if (thisFurnace.EMSOverrideSensZoneLoadRequest || thisFurnace.EMSOverrideMoistZoneLoadRequest) {
    5674            0 :             if ((ZoneLoad != 0.0) && (thisFurnace.EMSOverrideSensZoneLoadRequest)) {
    5675            0 :                 PartLoadRatio = 1.0;
    5676            0 :             } else if ((MoistureLoad != 0.0) && (thisFurnace.EMSOverrideMoistZoneLoadRequest)) {
    5677            0 :                 PartLoadRatio = 1.0;
    5678              :             } else {
    5679            0 :                 PartLoadRatio = 0.0;
    5680              :             }
    5681            0 :             if (thisFurnace.NumOfSpeedCooling > 0) {
    5682            0 :                 SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, QZnReq, MoistureLoad, PartLoadRatio);
    5683              :             } else {
    5684              :                 // This line is suspicious - all other calls to SetOnOffMassFlowRate pass in QZnReq, not ZoneLoad
    5685              :                 // either way, it seems these two should be using the same parameters.
    5686            0 :                 SetOnOffMassFlowRate(state, FurnaceNum, AirLoopNum, OnOffAirFlowRatio, fanOp, ZoneLoad, MoistureLoad, PartLoadRatio);
    5687              :             }
    5688              :         }
    5689              : 
    5690              :         // AirflowNetwork global variable
    5691        15222 :         if (state.afn->distribution_simulated) {
    5692        11168 :             state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).AFNLoopHeatingCoilMaxRTF = 0.0;
    5693              :         }
    5694        15222 :     }
    5695              : 
    5696        15222 :     void SetOnOffMassFlowRate(EnergyPlusData &state,
    5697              :                               int const FurnaceNum,                   // index to furnace
    5698              :                               [[maybe_unused]] int const AirLoopNum,  // index to air loop !unused1208
    5699              :                               Real64 &OnOffAirFlowRatio,              // ratio of coil on to coil off air flow rate
    5700              :                               HVAC::FanOp const fanOp,                // fan operating mode
    5701              :                               [[maybe_unused]] Real64 const ZoneLoad, // sensible load to be met (W) !unused1208
    5702              :                               Real64 const MoistureLoad,              // moisture load to be met (W)
    5703              :                               Real64 const PartLoadRatio              // coil part-load ratio
    5704              :     )
    5705              :     {
    5706              : 
    5707              :         // SUBROUTINE INFORMATION:
    5708              :         //       AUTHOR         Richard Raustad
    5709              :         //       DATE WRITTEN   Sep 2008
    5710              : 
    5711              :         // PURPOSE OF THIS SUBROUTINE:
    5712              :         // This subroutine is for initializations of the Furnace Components.
    5713              : 
    5714              :         // METHODOLOGY EMPLOYED:
    5715              :         // The HeatCool furnace/unitarysystem and air-to-air heat pump may have alternate air flow rates
    5716              :         // in cooling, heating, and when no cooling or heating is needed. Set up the coil (comp) ON and OFF
    5717              :         // air flow rates. Use these flow rates during the Calc routines to set the average mass flow rates
    5718              :         // based on PLR.
    5719              : 
    5720        15222 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    5721              :         // Check for heat only furnace
    5722        15222 :         if (thisFurnace.type != HVAC::UnitarySysType::Furnace_HeatOnly && thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatOnly) {
    5723              : 
    5724              :             // Set the system mass flow rates
    5725        15222 :             if (fanOp == HVAC::FanOp::Continuous) {
    5726              :                 // Set the compressor or coil ON mass flow rate
    5727              :                 // constant fan mode
    5728            0 :                 if (state.dataFurnaces->HeatingLoad) {
    5729              :                     //       IF a heating and moisture load exists, operate at the cooling mass flow rate ELSE operate at the heating flow rate
    5730            0 :                     if (MoistureLoad < 0.0 && thisFurnace.Humidistat &&
    5731            0 :                         thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
    5732            0 :                         state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxCoolAirMassFlow;
    5733            0 :                         state.dataFurnaces->CompOnFlowRatio = thisFurnace.CoolingSpeedRatio;
    5734              :                     } else {
    5735            0 :                         state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxHeatAirMassFlow;
    5736            0 :                         state.dataFurnaces->CompOnFlowRatio = thisFurnace.HeatingSpeedRatio;
    5737              :                     }
    5738            0 :                     thisFurnace.LastMode = Furnaces::ModeOfOperation::HeatingMode;
    5739              :                     //     IF a cooling load exists, operate at the cooling mass flow rate
    5740            0 :                 } else if (state.dataFurnaces->CoolingLoad) {
    5741            0 :                     state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxCoolAirMassFlow;
    5742            0 :                     state.dataFurnaces->CompOnFlowRatio = thisFurnace.CoolingSpeedRatio;
    5743            0 :                     thisFurnace.LastMode = Furnaces::ModeOfOperation::CoolingMode;
    5744              :                     //     If no load exists, set the compressor on mass flow rate.
    5745              :                     //     Set equal the mass flow rate when no heating or cooling is needed if no moisture load exists.
    5746              :                     //     If the user has set the off mass flow rate to 0, set according to the last operating mode.
    5747              :                 } else {
    5748            0 :                     if (MoistureLoad < 0.0 && thisFurnace.Humidistat &&
    5749            0 :                         thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
    5750            0 :                         state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxCoolAirMassFlow;
    5751            0 :                         state.dataFurnaces->CompOnFlowRatio = thisFurnace.CoolingSpeedRatio;
    5752              :                     } else {
    5753            0 :                         state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxNoCoolHeatAirMassFlow;
    5754            0 :                         state.dataFurnaces->CompOnFlowRatio = thisFurnace.HeatingSpeedRatio;
    5755              :                         //         User may have entered a 0 for MaxNoCoolHeatAirMassFlow
    5756            0 :                         if (state.dataFurnaces->CompOnMassFlow == 0.0) {
    5757            0 :                             if (thisFurnace.LastMode == Furnaces::ModeOfOperation::HeatingMode) {
    5758            0 :                                 state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxHeatAirMassFlow;
    5759            0 :                                 state.dataFurnaces->CompOnFlowRatio = thisFurnace.HeatingSpeedRatio;
    5760              :                             } else {
    5761            0 :                                 state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxCoolAirMassFlow;
    5762            0 :                                 state.dataFurnaces->CompOnFlowRatio = thisFurnace.CoolingSpeedRatio;
    5763              :                             }
    5764              :                         }
    5765              :                     }
    5766              :                 }
    5767              : 
    5768              :                 //     Set the compressor or coil OFF mass flow rate based on LOGICAL flag
    5769              :                 //     UseCompressorOnFlow is used when the user does not enter a value for no cooling or heating flow rate
    5770            0 :                 if (thisFurnace.AirFlowControl == AirFlowControlConstFan::UseCompressorOnFlow) {
    5771            0 :                     if (thisFurnace.LastMode == Furnaces::ModeOfOperation::HeatingMode) {
    5772            0 :                         if (MoistureLoad < 0.0 && thisFurnace.Humidistat &&
    5773            0 :                             thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
    5774            0 :                             state.dataFurnaces->CompOffMassFlow = thisFurnace.MaxCoolAirMassFlow;
    5775            0 :                             state.dataFurnaces->CompOffFlowRatio = thisFurnace.CoolingSpeedRatio;
    5776              :                         } else {
    5777            0 :                             state.dataFurnaces->CompOffMassFlow = thisFurnace.MaxHeatAirMassFlow;
    5778            0 :                             state.dataFurnaces->CompOffFlowRatio = thisFurnace.HeatingSpeedRatio;
    5779              :                         }
    5780              :                     } else {
    5781            0 :                         state.dataFurnaces->CompOffMassFlow = thisFurnace.MaxCoolAirMassFlow;
    5782            0 :                         state.dataFurnaces->CompOffFlowRatio = thisFurnace.CoolingSpeedRatio;
    5783              :                     }
    5784              :                     //     ELSE use the user specified value
    5785              :                 } else {
    5786            0 :                     state.dataFurnaces->CompOffMassFlow = thisFurnace.MaxNoCoolHeatAirMassFlow;
    5787            0 :                     state.dataFurnaces->CompOffFlowRatio = thisFurnace.NoHeatCoolSpeedRatio;
    5788              :                 }
    5789              :             } else {
    5790              :                 //     cycling fan mode
    5791        22082 :                 if (state.dataFurnaces->HeatingLoad ||
    5792         6860 :                     (thisFurnace.Humidistat && MoistureLoad < 0.0 && thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat)) {
    5793              : 
    5794         8362 :                     if (thisFurnace.Humidistat && MoistureLoad < 0.0 &&
    5795            0 :                         thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
    5796            0 :                         state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxCoolAirMassFlow;
    5797            0 :                         state.dataFurnaces->CompOnFlowRatio = thisFurnace.CoolingSpeedRatio;
    5798            0 :                         thisFurnace.LastMode = Furnaces::ModeOfOperation::CoolingMode;
    5799              :                     } else {
    5800         8362 :                         state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxHeatAirMassFlow;
    5801         8362 :                         state.dataFurnaces->CompOnFlowRatio = thisFurnace.HeatingSpeedRatio;
    5802         8362 :                         thisFurnace.LastMode = Furnaces::ModeOfOperation::HeatingMode;
    5803              :                     }
    5804         6860 :                 } else if (state.dataFurnaces->CoolingLoad) {
    5805         6748 :                     state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxCoolAirMassFlow;
    5806         6748 :                     state.dataFurnaces->CompOnFlowRatio = thisFurnace.CoolingSpeedRatio;
    5807              :                 } else {
    5808          112 :                     state.dataFurnaces->CompOnMassFlow = 0.0;
    5809          112 :                     state.dataFurnaces->CompOnFlowRatio = 0.0;
    5810              :                 }
    5811        15222 :                 state.dataFurnaces->CompOffMassFlow = 0.0;
    5812        15222 :                 state.dataFurnaces->CompOffFlowRatio = 0.0;
    5813              :             }
    5814              :         } else { //  Is a HeatOnly furnace
    5815              : 
    5816            0 :             state.dataFurnaces->CompOnMassFlow = thisFurnace.DesignMassFlowRate;
    5817            0 :             state.dataFurnaces->CompOnFlowRatio = thisFurnace.HeatingSpeedRatio;
    5818            0 :             if (fanOp == HVAC::FanOp::Continuous) {
    5819            0 :                 state.dataFurnaces->CompOffMassFlow = thisFurnace.MaxNoCoolHeatAirMassFlow;
    5820            0 :                 state.dataFurnaces->CompOffFlowRatio = thisFurnace.HeatingSpeedRatio;
    5821              :             } else {
    5822            0 :                 state.dataFurnaces->CompOffMassFlow = 0.0;
    5823            0 :                 state.dataFurnaces->CompOffFlowRatio = 0.0;
    5824              :             }
    5825              : 
    5826              :         } // End check for heat only furnace or water-to-air heat pump
    5827              : 
    5828              :         // Set the system mass flow rates
    5829        15222 :         SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
    5830        15222 :     }
    5831              : 
    5832            2 :     void SizeFurnace(EnergyPlusData &state, int const FurnaceNum, bool const FirstHVACIteration)
    5833              :     {
    5834              : 
    5835              :         // SUBROUTINE INFORMATION:
    5836              :         //       AUTHOR         Fred Buhl
    5837              :         //       DATE WRITTEN   January 2002
    5838              :         //       MODIFIED       Bereket Nigusse, May 2010, removed the autosize option for the input field supply air
    5839              :         //                                                 flow fraction through controlled zone.
    5840              :         //                      Bo Shen, March 2012, size the air flow rates at individual speed levels for VS WSHP
    5841              :         //                      Bo Shen, ORNL, July 2012 - added variable-speed air source heat pump cooling and heating coils, using curve-fits
    5842              : 
    5843              :         // PURPOSE OF THIS SUBROUTINE:
    5844              :         // This subroutine is for sizing Furnace Components for which nominal capacities
    5845              :         // and flow rates have not been specified in the input
    5846              : 
    5847              :         // METHODOLOGY EMPLOYED:
    5848              :         // Obtains heating capacities and flow rates from the zone or system sizing arrays.
    5849              :         // NOTE: In UNITARYSYSTEM:HEATPUMP:AIRTOAIR we are sizing the heating capacity to be
    5850              :         // equal to the cooling capacity.  Thus the cooling and
    5851              :         // and heating capacities of a DX heat pump system will be identical. In real life the ARI
    5852              :         // heating and cooling capacities are close but not identical.
    5853              : 
    5854              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5855              :         int Iter;                 // iteration count
    5856              :         Real64 MulSpeedFlowScale; // variable speed air flow scaling factor
    5857              :         int IHPCoilIndex;         // refer to cooling or heating coil in IHP
    5858            2 :         Real64 dummy(0.0);
    5859              :         bool anyRan;
    5860            2 :         EMSManager::ManageEMS(state, EMSManager::EMSCallFrom::UnitarySystemSizing, anyRan, ObjexxFCL::Optional_int_const()); // calling point
    5861              : 
    5862            2 :         state.dataSize->DXCoolCap = 0.0;
    5863            2 :         state.dataSize->UnitaryHeatCap = 0.0;
    5864            2 :         state.dataSize->SuppHeatCap = 0.0;
    5865            2 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    5866              : 
    5867            2 :         state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum = thisFurnace.FanIndex;
    5868            2 :         state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanType = thisFurnace.fanType;
    5869            2 :         state.dataSize->DataFanType = thisFurnace.fanType;
    5870            2 :         state.dataSize->DataFanIndex = thisFurnace.FanIndex;
    5871              : 
    5872            2 :         state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace = thisFurnace.fanPlace;
    5873              : 
    5874            2 :         if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
    5875            2 :             DXCoils::SimDXCoil(state, BlankString, HVAC::CompressorOp::On, true, thisFurnace.CoolingCoilIndex, HVAC::FanOp::Cycling, 0.0);
    5876            0 :         } else if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
    5877            0 :             int HXCC_Index = thisFurnace.CoolingCoilIndex;
    5878            0 :             int childCCType_Num = state.dataHVACAssistedCC->HXAssistedCoil(HXCC_Index).CoolingCoilType_Num;
    5879            0 :             if (childCCType_Num == HVAC::CoilDX_Cooling) {
    5880            0 :                 int childCCIndex = state.dataHVACAssistedCC->HXAssistedCoil(HXCC_Index).CoolingCoilIndex;
    5881            0 :                 if (childCCIndex < 0) {
    5882            0 :                     ShowContinueError(state, "Occurs in sizing HeatExchangerAssistedCoolingCoil.");
    5883              :                 }
    5884            0 :                 auto &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex];
    5885            0 :                 newCoil.size(state);
    5886              :             }
    5887            0 :             HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(
    5888            0 :                 state, BlankString, true, HVAC::CompressorOp::On, 0.0, thisFurnace.CoolingCoilIndex, HVAC::FanOp::Cycling, false, 1.0, false);
    5889            0 :         } else if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPSimple) {
    5890            0 :             WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
    5891              :                                                             BlankString,
    5892            0 :                                                             thisFurnace.CoolingCoilIndex,
    5893              :                                                             thisFurnace.CoolingCoilSensDemand,
    5894              :                                                             thisFurnace.CoolingCoilLatentDemand,
    5895              :                                                             HVAC::FanOp::Invalid, // Using invalid to mean off?
    5896              :                                                             HVAC::CompressorOp::Off,
    5897              :                                                             0.0,
    5898              :                                                             FirstHVACIteration); // CoolPartLoadRatio
    5899            0 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
    5900            0 :                 WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
    5901              :                                                                 BlankString,
    5902            0 :                                                                 thisFurnace.HeatingCoilIndex,
    5903              :                                                                 thisFurnace.HeatingCoilSensDemand,
    5904              :                                                                 dummy,
    5905              :                                                                 HVAC::FanOp::Invalid, // using Invalid to mean off?
    5906              :                                                                 HVAC::CompressorOp::Off,
    5907              :                                                                 0.0,
    5908              :                                                                 FirstHVACIteration);
    5909              :             }
    5910            0 :         } else if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingWaterToAirHPVSEquationFit ||
    5911            0 :                    thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    5912            0 :             if (thisFurnace.bIsIHP) {
    5913            0 :                 IntegratedHeatPump::SizeIHP(state, thisFurnace.CoolingCoilIndex);
    5914            0 :                 IHPCoilIndex = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SCCoilIndex;
    5915            0 :                 thisFurnace.NumOfSpeedCooling = state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).NumOfSpeeds;
    5916            0 :                 MulSpeedFlowScale = state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).RatedAirVolFlowRate /
    5917            0 :                                     state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex)
    5918            0 :                                         .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).NormSpedLevel);
    5919            0 :                 state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).CoolVolFlowScale = MulSpeedFlowScale;
    5920              :             } else {
    5921            0 :                 VariableSpeedCoils::SimVariableSpeedCoils(state,
    5922              :                                                           BlankString,
    5923            0 :                                                           thisFurnace.CoolingCoilIndex,
    5924              :                                                           HVAC::FanOp::Invalid, // USing Invalid for off?
    5925              :                                                           HVAC::CompressorOp::Off,
    5926              :                                                           0.0,
    5927              :                                                           1,
    5928              :                                                           0.0,
    5929              :                                                           0.0,
    5930              :                                                           0.0,
    5931              :                                                           0.0); // conduct the sizing operation in the VS WSHP
    5932            0 :                 thisFurnace.NumOfSpeedCooling = state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.CoolingCoilIndex).NumOfSpeeds;
    5933            0 :                 MulSpeedFlowScale =
    5934            0 :                     state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.CoolingCoilIndex).RatedAirVolFlowRate /
    5935            0 :                     state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.CoolingCoilIndex)
    5936            0 :                         .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.CoolingCoilIndex).NormSpedLevel);
    5937            0 :                 IHPCoilIndex = thisFurnace.CoolingCoilIndex;
    5938              :             }
    5939              : 
    5940            0 :             for (Iter = 1; Iter <= thisFurnace.NumOfSpeedCooling; ++Iter) {
    5941            0 :                 thisFurnace.CoolVolumeFlowRate(Iter) =
    5942            0 :                     state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(Iter) * MulSpeedFlowScale;
    5943            0 :                 thisFurnace.CoolMassFlowRate(Iter) =
    5944            0 :                     state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirMassFlowRate(Iter) * MulSpeedFlowScale;
    5945            0 :                 thisFurnace.MSCoolingSpeedRatio(Iter) =
    5946            0 :                     state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(Iter) /
    5947            0 :                     state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(thisFurnace.NumOfSpeedCooling);
    5948              :             }
    5949              : 
    5950            0 :             if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPVSEquationFit ||
    5951            0 :                 thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
    5952              : 
    5953            0 :                 if (thisFurnace.bIsIHP) {
    5954            0 :                     IntegratedHeatPump::SizeIHP(state, thisFurnace.CoolingCoilIndex);
    5955            0 :                     IHPCoilIndex = state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).SHCoilIndex;
    5956            0 :                     thisFurnace.NumOfSpeedHeating = state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).NumOfSpeeds;
    5957            0 :                     MulSpeedFlowScale = state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).RatedAirVolFlowRate /
    5958            0 :                                         state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex)
    5959            0 :                                             .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).NormSpedLevel);
    5960            0 :                     state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).HeatVolFlowScale = MulSpeedFlowScale;
    5961              :                 } else {
    5962            0 :                     VariableSpeedCoils::SimVariableSpeedCoils(state,
    5963              :                                                               BlankString,
    5964            0 :                                                               thisFurnace.HeatingCoilIndex,
    5965              :                                                               HVAC::FanOp::Invalid, // Invalid for off?
    5966              :                                                               HVAC::CompressorOp::Off,
    5967              :                                                               0.0,
    5968              :                                                               1,
    5969              :                                                               0.0,
    5970              :                                                               0.0,
    5971              :                                                               0.0,
    5972              :                                                               0.0); // conduct the sizing operation in the VS WSHP
    5973            0 :                     thisFurnace.NumOfSpeedHeating = state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.HeatingCoilIndex).NumOfSpeeds;
    5974            0 :                     MulSpeedFlowScale =
    5975            0 :                         state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.HeatingCoilIndex).RatedAirVolFlowRate /
    5976            0 :                         state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.HeatingCoilIndex)
    5977            0 :                             .MSRatedAirVolFlowRate(state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.HeatingCoilIndex).NormSpedLevel);
    5978            0 :                     IHPCoilIndex = thisFurnace.HeatingCoilIndex;
    5979              :                 }
    5980              : 
    5981            0 :                 for (Iter = 1; Iter <= thisFurnace.NumOfSpeedHeating; ++Iter) {
    5982            0 :                     thisFurnace.HeatVolumeFlowRate(Iter) =
    5983            0 :                         state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(Iter) * MulSpeedFlowScale;
    5984            0 :                     thisFurnace.HeatMassFlowRate(Iter) =
    5985            0 :                         state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirMassFlowRate(Iter) * MulSpeedFlowScale;
    5986            0 :                     thisFurnace.MSHeatingSpeedRatio(Iter) =
    5987            0 :                         state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(Iter) /
    5988            0 :                         state.dataVariableSpeedCoils->VarSpeedCoil(IHPCoilIndex).MSRatedAirVolFlowRate(thisFurnace.NumOfSpeedHeating);
    5989              :                 }
    5990              :             }
    5991              : 
    5992            0 :             if (thisFurnace.NumOfSpeedHeating > 0) {
    5993            0 :                 thisFurnace.IdleMassFlowRate = min(thisFurnace.HeatMassFlowRate(1), thisFurnace.CoolMassFlowRate(1));
    5994            0 :                 thisFurnace.IdleSpeedRatio = min(thisFurnace.MSHeatingSpeedRatio(1), thisFurnace.MSCoolingSpeedRatio(1));
    5995            0 :                 thisFurnace.IdleVolumeAirRate = min(thisFurnace.HeatVolumeFlowRate(1), thisFurnace.CoolVolumeFlowRate(1));
    5996              :             } else {
    5997            0 :                 thisFurnace.IdleMassFlowRate = thisFurnace.CoolMassFlowRate(1);
    5998            0 :                 thisFurnace.IdleSpeedRatio = thisFurnace.MSCoolingSpeedRatio(1);
    5999            0 :                 thisFurnace.IdleVolumeAirRate = thisFurnace.CoolVolumeFlowRate(1);
    6000              :             }
    6001              : 
    6002            0 :             if (thisFurnace.fanOp == HVAC::FanOp::Continuous) {
    6003            0 :                 thisFurnace.MaxNoCoolHeatAirVolFlow = thisFurnace.IdleVolumeAirRate;
    6004            0 :                 thisFurnace.MaxNoCoolHeatAirMassFlow = thisFurnace.IdleMassFlowRate;
    6005            0 :                 thisFurnace.NoHeatCoolSpeedRatio = thisFurnace.IdleSpeedRatio;
    6006              :             }
    6007              :         }
    6008              : 
    6009            2 :         if (thisFurnace.DesignFanVolFlowRate == DataSizing::AutoSize) {
    6010              : 
    6011            2 :             if (state.dataSize->CurSysNum > 0) {
    6012              : 
    6013            2 :                 CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6014            2 :                 if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= HVAC::SmallAirVolFlow) {
    6015            2 :                     thisFurnace.DesignFanVolFlowRate = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
    6016              :                 } else {
    6017            0 :                     thisFurnace.DesignFanVolFlowRate = 0.0;
    6018              :                 }
    6019              : 
    6020            2 :                 if (thisFurnace.DesignFanVolFlowRateEMSOverrideOn) {
    6021            0 :                     thisFurnace.DesignFanVolFlowRate = thisFurnace.DesignFanVolFlowRateEMSOverrideValue;
    6022              :                 }
    6023              : 
    6024            4 :                 BaseSizer::reportSizerOutput(state,
    6025            2 :                                              HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6026              :                                              thisFurnace.Name,
    6027              :                                              "Supply Air Flow Rate [m3/s]",
    6028              :                                              thisFurnace.DesignFanVolFlowRate);
    6029              :             }
    6030              :         }
    6031              : 
    6032            2 :         if (thisFurnace.MaxHeatAirVolFlow == DataSizing::AutoSize) {
    6033              : 
    6034            2 :             if (state.dataSize->CurSysNum > 0) {
    6035              : 
    6036            2 :                 CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6037            2 :                 if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= HVAC::SmallAirVolFlow) {
    6038            2 :                     thisFurnace.MaxHeatAirVolFlow = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
    6039              :                 } else {
    6040            0 :                     thisFurnace.MaxHeatAirVolFlow = 0.0;
    6041              :                 }
    6042              : 
    6043            2 :                 if (thisFurnace.MaxHeatAirVolFlowEMSOverrideOn) {
    6044            0 :                     thisFurnace.MaxHeatAirVolFlow = thisFurnace.MaxHeatAirVolFlowEMSOverrideValue;
    6045              :                 }
    6046            4 :                 BaseSizer::reportSizerOutput(state,
    6047            2 :                                              HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6048              :                                              thisFurnace.Name,
    6049              :                                              "Supply Air Flow Rate During Heating Operation [m3/s]",
    6050              :                                              thisFurnace.MaxHeatAirVolFlow);
    6051              :             }
    6052              :         }
    6053              : 
    6054            2 :         if (thisFurnace.MaxCoolAirVolFlow == DataSizing::AutoSize) {
    6055              : 
    6056            2 :             if (state.dataSize->CurSysNum > 0) {
    6057              : 
    6058            2 :                 CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6059            2 :                 if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= HVAC::SmallAirVolFlow) {
    6060            2 :                     thisFurnace.MaxCoolAirVolFlow = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
    6061              :                 } else {
    6062            0 :                     thisFurnace.MaxCoolAirVolFlow = 0.0;
    6063              :                 }
    6064              : 
    6065            2 :                 if (thisFurnace.MaxCoolAirVolFlowEMSOverrideOn) {
    6066            0 :                     thisFurnace.MaxCoolAirVolFlow = thisFurnace.MaxCoolAirVolFlowEMSOverrideValue;
    6067              :                 }
    6068              : 
    6069            4 :                 BaseSizer::reportSizerOutput(state,
    6070            2 :                                              HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6071              :                                              thisFurnace.Name,
    6072              :                                              "Supply Air Flow Rate During Cooling Operation [m3/s]",
    6073              :                                              thisFurnace.MaxCoolAirVolFlow);
    6074              :             }
    6075              :         }
    6076              : 
    6077            2 :         if (thisFurnace.MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
    6078              : 
    6079            1 :             if (state.dataSize->CurSysNum > 0) {
    6080              : 
    6081            1 :                 CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6082            1 :                 if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= HVAC::SmallAirVolFlow) {
    6083            1 :                     thisFurnace.MaxNoCoolHeatAirVolFlow = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
    6084              :                 } else {
    6085            0 :                     thisFurnace.MaxNoCoolHeatAirVolFlow = 0.0;
    6086              :                 }
    6087              : 
    6088            1 :                 if (thisFurnace.MaxNoCoolHeatAirVolFlowEMSOverrideOn) {
    6089            0 :                     thisFurnace.MaxNoCoolHeatAirVolFlow = thisFurnace.MaxNoCoolHeatAirVolFlowEMSOverrideValue;
    6090              :                 }
    6091              : 
    6092            2 :                 BaseSizer::reportSizerOutput(state,
    6093            1 :                                              HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6094              :                                              thisFurnace.Name,
    6095              :                                              "Supply Air Flow Rate When No Cooling or Heating is Needed [m3/s]",
    6096              :                                              thisFurnace.MaxNoCoolHeatAirVolFlow);
    6097              :             }
    6098              :         }
    6099              : 
    6100            2 :         if (thisFurnace.DesignHeatingCapacity == DataSizing::AutoSize) {
    6101              : 
    6102            2 :             if (state.dataSize->CurSysNum > 0) {
    6103              : 
    6104            2 :                 if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    6105            0 :                     thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir) {
    6106              : 
    6107            2 :                     CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6108              : 
    6109            2 :                     if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingWaterToAirHPSimple) {
    6110            0 :                         thisFurnace.DesignHeatingCapacity =
    6111            0 :                             state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(thisFurnace.HeatingCoilIndex).RatedCapHeat;
    6112              :                     } else {
    6113            2 :                         thisFurnace.DesignHeatingCapacity = state.dataSize->DXCoolCap;
    6114              :                     }
    6115              : 
    6116              :                 } else {
    6117              : 
    6118            0 :                     CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6119              : 
    6120            0 :                     thisFurnace.DesignHeatingCapacity = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatCap;
    6121              :                 }
    6122              : 
    6123            2 :                 if (thisFurnace.DesignHeatingCapacity < HVAC::SmallLoad) {
    6124            0 :                     thisFurnace.DesignHeatingCapacity = 0.0;
    6125              :                 }
    6126              : 
    6127            4 :                 BaseSizer::reportSizerOutput(state,
    6128            2 :                                              HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6129              :                                              thisFurnace.Name,
    6130              :                                              "Nominal Heating Capacity [W]",
    6131              :                                              thisFurnace.DesignHeatingCapacity);
    6132              :             }
    6133              :         }
    6134              : 
    6135            2 :         if (thisFurnace.DesignCoolingCapacity == DataSizing::AutoSize) {
    6136              : 
    6137            2 :             if (state.dataSize->CurSysNum > 0) {
    6138              : 
    6139            2 :                 CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6140            2 :                 if (state.dataSize->DXCoolCap >= HVAC::SmallLoad) {
    6141            2 :                     thisFurnace.DesignCoolingCapacity = state.dataSize->DXCoolCap;
    6142              :                 } else {
    6143            0 :                     thisFurnace.DesignCoolingCapacity = 0.0;
    6144              :                 }
    6145            4 :                 BaseSizer::reportSizerOutput(state,
    6146            2 :                                              HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6147              :                                              thisFurnace.Name,
    6148              :                                              "Nominal Cooling Capacity [W]",
    6149              :                                              thisFurnace.DesignCoolingCapacity);
    6150              :             }
    6151              :         }
    6152              : 
    6153            2 :         if (thisFurnace.DesignMaxOutletTemp == DataSizing::AutoSize) {
    6154              : 
    6155            1 :             if (state.dataSize->CurSysNum > 0) {
    6156              : 
    6157            1 :                 CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6158            1 :                 thisFurnace.DesignMaxOutletTemp = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatSupTemp;
    6159            2 :                 BaseSizer::reportSizerOutput(state,
    6160            1 :                                              HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6161              :                                              thisFurnace.Name,
    6162              :                                              "Maximum Supply Air Temperature from Supplemental Heater [C]",
    6163              :                                              thisFurnace.DesignMaxOutletTemp);
    6164              :             }
    6165              :         }
    6166              : 
    6167            2 :         if (thisFurnace.DesignSuppHeatingCapacity == DataSizing::AutoSize) {
    6168              : 
    6169            1 :             if (state.dataSize->CurSysNum > 0) {
    6170              : 
    6171            1 :                 CheckSysSizing(state, HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name);
    6172            1 :                 if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    6173            0 :                     thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir) {
    6174              :                     // set the supplemental heating capacity to the actual heating load
    6175            1 :                     thisFurnace.DesignSuppHeatingCapacity = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatCap;
    6176              :                     // if reheat needed for humidity control, make sure supplemental heating is at least as big
    6177              :                     // as the cooling capacity
    6178            1 :                     if (thisFurnace.Humidistat && thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
    6179            0 :                         thisFurnace.DesignSuppHeatingCapacity = max(thisFurnace.DesignSuppHeatingCapacity, thisFurnace.DesignCoolingCapacity);
    6180            0 :                         if (thisFurnace.DesignSuppHeatingCapacity < HVAC::SmallLoad) {
    6181            0 :                             thisFurnace.DesignSuppHeatingCapacity = 0.0;
    6182              :                         }
    6183              :                     }
    6184              : 
    6185              :                 } else {
    6186              : 
    6187            0 :                     if (thisFurnace.Humidistat && thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
    6188            0 :                         thisFurnace.DesignSuppHeatingCapacity = thisFurnace.DesignCoolingCapacity;
    6189              :                     } else {
    6190            0 :                         thisFurnace.DesignSuppHeatingCapacity = 0.0;
    6191              :                     }
    6192              :                 }
    6193              : 
    6194            2 :                 BaseSizer::reportSizerOutput(state,
    6195            1 :                                              HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6196              :                                              thisFurnace.Name,
    6197              :                                              "Supplemental Heating Coil Nominal Capacity [W]",
    6198              :                                              thisFurnace.DesignSuppHeatingCapacity);
    6199              :             }
    6200              :         }
    6201              : 
    6202            2 :         state.dataSize->UnitaryHeatCap = thisFurnace.DesignHeatingCapacity;
    6203            2 :         state.dataSize->SuppHeatCap = thisFurnace.DesignSuppHeatingCapacity;
    6204            2 :     }
    6205              : 
    6206              :     // End Initialization Section of the Module
    6207              :     //******************************************************************************
    6208              : 
    6209              :     // Beginning of Update subroutines for the Furnace Module
    6210              :     // *****************************************************************************
    6211              : 
    6212            0 :     void CalcNewZoneHeatOnlyFlowRates(EnergyPlusData &state,
    6213              :                                       int const FurnaceNum,          // Index to furnace
    6214              :                                       bool const FirstHVACIteration, // Iteration flag
    6215              :                                       Real64 const ZoneLoad,         // load to be met by furnace (W)
    6216              :                                       Real64 &HeatCoilLoad,          // actual load passed to heating coil (W)
    6217              :                                       Real64 &OnOffAirFlowRatio      // ratio of coil on to coil off air flow rate
    6218              :     )
    6219              :     {
    6220              :         // SUBROUTINE INFORMATION:
    6221              :         //       AUTHOR         Richard Liesen
    6222              :         //       DATE WRITTEN   Feb 2001
    6223              :         //       MODIFIED       Don Shirey and R. Raustad, Mar 2001 & Mar 2003
    6224              : 
    6225              :         // PURPOSE OF THIS SUBROUTINE:
    6226              :         // This subroutine updates the coil outlet nodes by simulating a heat-only
    6227              :         // furnace or unitary system.
    6228              : 
    6229              :         // METHODOLOGY EMPLOYED:
    6230              :         // Determine the operating PLR to meet the zone sensible load.
    6231              : 
    6232              :         // SUBROUTINE PARAMETER DEFINITIONS:
    6233            0 :         int constexpr MaxIter(15);    // maximum number of iterations
    6234            0 :         Real64 constexpr MinPLR(0.0); // minimum part load ratio allowed
    6235              : 
    6236              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6237            0 :         Real64 Error(1.0);
    6238              :         Real64 SystemSensibleLoad;   // Sensible load to be met by furnace (W)
    6239              :         Real64 FullSensibleOutput;   // Full sensible output of furnace (W)
    6240              :         Real64 FullLatentOutput;     // Full latent output of furnace = 0 (W)
    6241              :         Real64 NoSensibleOutput;     // Sensible output of furnace with no heating allowed (W)
    6242              :         Real64 NoLatentOutput;       // Latent output of furnace = 0 (W)
    6243              :         Real64 PartLoadRatio;        // Part load ratio of furnace
    6244              :         Real64 HeatErrorToler;       // Error tolerance in heating mode
    6245              :         Real64 IterRelax;            // Relaxation factor for iterations
    6246              :         Real64 ActualSensibleOutput; // Actual furnace sensible capacity
    6247              :         Real64 ActualLatentOutput;   // Actual furnace latent capacity = 0
    6248              :         Real64 deltaT;               // Heater outlet temp minus design heater outlet temp
    6249              : 
    6250            0 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    6251              :         // Retrieve the load on the controlled zone
    6252            0 :         auto &furnaceInNode = state.dataLoopNodes->Node(thisFurnace.FurnaceInletNodeNum);
    6253            0 :         auto const &furnaceOutNode = state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum);
    6254            0 :         int ControlZoneNode = thisFurnace.NodeNumOfControlledZone;
    6255            0 :         HVAC::FanOp fanOp = thisFurnace.fanOp; // fan operating mode
    6256            0 :         thisFurnace.MdotFurnace = thisFurnace.DesignMassFlowRate;
    6257            0 :         thisFurnace.CoolPartLoadRatio = 0.0;
    6258              : 
    6259              :         // Calculate the Cp Air of zone
    6260            0 :         Real64 cpair = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ControlZoneNode).HumRat);
    6261              : 
    6262            0 :         if (FirstHVACIteration) {
    6263            0 :             HeatCoilLoad = ZoneLoad;
    6264            0 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    6265              :         } else {
    6266              :             // If Furnace runs then set HeatCoilLoad on Heating Coil and the Mass Flow
    6267            0 :             if ((thisFurnace.availSched->getCurrentVal() > 0.0) && (furnaceInNode.MassFlowRate > 0.0) && (state.dataFurnaces->HeatingLoad)) {
    6268              : 
    6269            0 :                 furnaceInNode.MassFlowRate = thisFurnace.MdotFurnace;
    6270            0 :                 HeatCoilLoad = thisFurnace.DesignHeatingCapacity;
    6271            0 :                 SystemSensibleLoad = ZoneLoad;
    6272              : 
    6273              :                 // Get no load result
    6274            0 :                 if (fanOp == HVAC::FanOp::Cycling) {
    6275            0 :                     furnaceInNode.MassFlowRate = 0.0;
    6276              :                 }
    6277            0 :                 if (fanOp == HVAC::FanOp::Continuous) {
    6278            0 :                     state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // The on/off fan will not cycle, so set part-load fraction = 1
    6279              :                 }
    6280              : 
    6281              :                 //     Set the inlet mass flow rate based on user specified coil OFF flow rate
    6282            0 :                 PartLoadRatio = 0.0;
    6283            0 :                 SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
    6284              : 
    6285            0 :                 CalcFurnaceOutput(state,
    6286              :                                   FurnaceNum,
    6287              :                                   FirstHVACIteration,
    6288              :                                   fanOp,
    6289              :                                   HVAC::CompressorOp::On,
    6290              :                                   0.0,
    6291              :                                   0.0,
    6292              :                                   0.0,
    6293              :                                   0.0,
    6294              :                                   NoSensibleOutput,
    6295              :                                   NoLatentOutput,
    6296              :                                   OnOffAirFlowRatio,
    6297              :                                   false);
    6298              : 
    6299            0 :                 furnaceInNode.MassFlowRate = thisFurnace.MdotFurnace;
    6300              : 
    6301              :                 // Set fan part-load fraction equal to 1 while getting full load result
    6302            0 :                 state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    6303            0 :                 OnOffAirFlowRatio = 1.0;
    6304              : 
    6305              :                 // Get full load result
    6306            0 :                 CalcFurnaceOutput(state,
    6307              :                                   FurnaceNum,
    6308              :                                   FirstHVACIteration,
    6309              :                                   fanOp,
    6310              :                                   HVAC::CompressorOp::On,
    6311              :                                   0.0,
    6312              :                                   1.0,
    6313              :                                   HeatCoilLoad,
    6314              :                                   0.0,
    6315              :                                   FullSensibleOutput,
    6316              :                                   FullLatentOutput,
    6317              :                                   OnOffAirFlowRatio,
    6318              :                                   false);
    6319              : 
    6320              :                 // Since we are heating, we expect FullSensibleOutput to be > 0 and FullSensibleOutput > NoSensibleOutput
    6321              :                 // Check that this is the case; if not set PartLoadRatio = 0.0d0 (off) and return
    6322              : 
    6323            0 :                 if (FullSensibleOutput > NoSensibleOutput) {
    6324              :                     PartLoadRatio =
    6325            0 :                         max(MinPLR, min(1.0, std::abs(SystemSensibleLoad - NoSensibleOutput) / std::abs(FullSensibleOutput - NoSensibleOutput)));
    6326            0 :                     if (fanOp == HVAC::FanOp::Cycling) {
    6327            0 :                         furnaceInNode.MassFlowRate = thisFurnace.MdotFurnace * PartLoadRatio;
    6328            0 :                         HeatCoilLoad = thisFurnace.DesignHeatingCapacity * PartLoadRatio;
    6329              :                     } else { // FanOp::Continuous
    6330            0 :                         if (furnaceOutNode.Temp > thisFurnace.DesignMaxOutletTemp) {
    6331            0 :                             deltaT = furnaceOutNode.Temp - thisFurnace.DesignMaxOutletTemp;
    6332            0 :                             if (HeatCoilLoad > thisFurnace.DesignHeatingCapacity) {
    6333            0 :                                 HeatCoilLoad = thisFurnace.DesignHeatingCapacity;
    6334              :                             }
    6335            0 :                             HeatCoilLoad -= furnaceInNode.MassFlowRate * cpair * deltaT;
    6336              :                         } else {
    6337            0 :                             HeatCoilLoad = SystemSensibleLoad - NoSensibleOutput;
    6338              :                         }
    6339              :                     }
    6340              : 
    6341              :                     // Calculate the part load ratio through iteration
    6342            0 :                     HeatErrorToler = thisFurnace.HeatingConvergenceTolerance; // Error tolerance for convergence from input deck
    6343            0 :                     Error = 1.0;                                              // initialize error value for comparison against tolerance
    6344            0 :                     state.dataFurnaces->Iter = 0;                             // initialize iteration counter
    6345            0 :                     IterRelax = 0.9;                                          // relaxation factor for iterations
    6346            0 :                     while (state.dataFurnaces->Iter <= MaxIter) {
    6347              : 
    6348            0 :                         if (fanOp == HVAC::FanOp::Cycling) {
    6349            0 :                             furnaceInNode.MassFlowRate = thisFurnace.MdotFurnace * PartLoadRatio;
    6350              :                         }
    6351            0 :                         CalcFurnaceOutput(state,
    6352              :                                           FurnaceNum,
    6353              :                                           FirstHVACIteration,
    6354              :                                           fanOp,
    6355              :                                           HVAC::CompressorOp::On,
    6356              :                                           0.0,
    6357              :                                           PartLoadRatio,
    6358              :                                           HeatCoilLoad,
    6359              :                                           0.0,
    6360              :                                           ActualSensibleOutput,
    6361              :                                           ActualLatentOutput,
    6362              :                                           OnOffAirFlowRatio,
    6363              :                                           false);
    6364              : 
    6365            0 :                         if (SystemSensibleLoad != 0.0) {
    6366            0 :                             Error = (SystemSensibleLoad - ActualSensibleOutput) / (SystemSensibleLoad);
    6367              :                         }
    6368            0 :                         if (std::abs(Error) <= HeatErrorToler) {
    6369            0 :                             break;
    6370              :                         }
    6371            0 :                         PartLoadRatio = max(
    6372              :                             MinPLR,
    6373              :                             min(1.0,
    6374            0 :                                 PartLoadRatio + IterRelax * (SystemSensibleLoad - ActualSensibleOutput) / (FullSensibleOutput - NoSensibleOutput)));
    6375              : 
    6376              :                         // limit the heating coil outlet air temperature to DesignMaxOutletTemp
    6377            0 :                         if (furnaceOutNode.Temp > thisFurnace.DesignMaxOutletTemp) {
    6378            0 :                             deltaT = furnaceOutNode.Temp - thisFurnace.DesignMaxOutletTemp;
    6379            0 :                             if (HeatCoilLoad > thisFurnace.DesignHeatingCapacity) {
    6380            0 :                                 HeatCoilLoad = thisFurnace.DesignHeatingCapacity;
    6381              :                             }
    6382            0 :                             HeatCoilLoad -= furnaceInNode.MassFlowRate * cpair * deltaT;
    6383            0 :                             CalcFurnaceOutput(state,
    6384              :                                               FurnaceNum,
    6385              :                                               FirstHVACIteration,
    6386              :                                               fanOp,
    6387              :                                               HVAC::CompressorOp::On,
    6388              :                                               0.0,
    6389              :                                               PartLoadRatio,
    6390              :                                               HeatCoilLoad,
    6391              :                                               0.0,
    6392              :                                               ActualSensibleOutput,
    6393              :                                               ActualLatentOutput,
    6394              :                                               OnOffAirFlowRatio,
    6395              :                                               false);
    6396              : 
    6397            0 :                             if (SystemSensibleLoad != 0.0) {
    6398            0 :                                 Error = (SystemSensibleLoad - ActualSensibleOutput) / (SystemSensibleLoad);
    6399              :                             }
    6400            0 :                             PartLoadRatio = max(MinPLR,
    6401              :                                                 min(1.0,
    6402            0 :                                                     PartLoadRatio + IterRelax * (SystemSensibleLoad - ActualSensibleOutput) /
    6403            0 :                                                                         (FullSensibleOutput - NoSensibleOutput)));
    6404              :                         } else {
    6405            0 :                             HeatCoilLoad = thisFurnace.DesignHeatingCapacity * PartLoadRatio;
    6406              :                         }
    6407              : 
    6408            0 :                         if (PartLoadRatio == MinPLR) {
    6409            0 :                             break;
    6410              :                         }
    6411            0 :                         if (PartLoadRatio == 1.0) {
    6412            0 :                             break;
    6413              :                         }
    6414            0 :                         ++state.dataFurnaces->Iter;
    6415            0 :                         if (state.dataFurnaces->Iter == 7) {
    6416            0 :                             IterRelax = 0.7;
    6417              :                         }
    6418            0 :                         if (state.dataFurnaces->Iter == 15) {
    6419            0 :                             IterRelax = 0.4;
    6420              :                         }
    6421              :                     }
    6422              : 
    6423            0 :                     if (state.dataFurnaces->Iter > MaxIter) {
    6424            0 :                         if (thisFurnace.HeatingMaxIterIndex2 == 0) {
    6425            0 :                             ShowWarningMessage(state,
    6426            0 :                                                format("{} \"{}\" -- Exceeded max heating iterations ({}) while adjusting furnace runtime.",
    6427            0 :                                                       HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6428            0 :                                                       thisFurnace.Name,
    6429              :                                                       MaxIter));
    6430            0 :                             ShowContinueErrorTimeStamp(state, "");
    6431              :                         }
    6432            0 :                         ShowRecurringWarningErrorAtEnd(state,
    6433            0 :                                                        format("{} \"{}\" -- Exceeded max heating iterations error continues...",
    6434            0 :                                                               HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6435            0 :                                                               thisFurnace.Name),
    6436            0 :                                                        thisFurnace.HeatingMaxIterIndex2);
    6437              :                     }
    6438              : 
    6439              :                 } else { // ELSE from IF(FullSensibleOutput.GT.NoSensibleOutput)THEN above
    6440              :                     // Set part load ratio to 1 and run heater at design heating capacity
    6441            0 :                     PartLoadRatio = 1.0;
    6442            0 :                     HeatCoilLoad = thisFurnace.DesignHeatingCapacity;
    6443              :                 }
    6444              :                 // Set the final results
    6445              :                 //      IF (fanOp .EQ. FanOp::Cycling) THEN
    6446              :                 //        Furnace(FurnaceNum)%MdotFurnace = Furnace(FurnaceNum)%MdotFurnace * PartLoadRatio
    6447              :                 //      END IF
    6448            0 :                 thisFurnace.MdotFurnace = furnaceInNode.MassFlowRate;
    6449              : 
    6450            0 :             } else if ((thisFurnace.availSched->getCurrentVal() > 0.0) && (furnaceInNode.MassFlowRate > 0.0) && (fanOp == HVAC::FanOp::Continuous)) {
    6451            0 :                 HeatCoilLoad = 0.0;
    6452              :             } else { // no heating and no flow
    6453            0 :                 thisFurnace.MdotFurnace = 0.0;
    6454            0 :                 HeatCoilLoad = 0.0;
    6455              :             } // End of the Scheduled Furnace If block
    6456              : 
    6457              :         } // End of the FirstHVACIteration control of the mass flow If block
    6458              : 
    6459              :         // Set the fan inlet node flow rates
    6460            0 :         furnaceInNode.MassFlowRateMaxAvail = thisFurnace.MdotFurnace;
    6461            0 :         furnaceInNode.MassFlowRate = thisFurnace.MdotFurnace;
    6462            0 :     }
    6463              : 
    6464        15225 :     void CalcNewZoneHeatCoolFlowRates(EnergyPlusData &state,
    6465              :                                       int const FurnaceNum,
    6466              :                                       bool const FirstHVACIteration,
    6467              :                                       HVAC::CompressorOp const compressorOp, // compressor operation flag (1=On, 0=Off)
    6468              :                                       Real64 const ZoneLoad,                 // the control zone load (watts)
    6469              :                                       Real64 const MoistureLoad,             // the control zone latent load (watts)
    6470              :                                       Real64 &HeatCoilLoad,                  // Heating load to be met by heating coil ( excluding heat pump DX coil)
    6471              :                                       Real64 &ReheatCoilLoad,    // Heating load to be met by reheat coil using hstat (excluding HP DX coil)
    6472              :                                       Real64 &OnOffAirFlowRatio, // Ratio of compressor ON air flow to AVERAGE air flow over time step
    6473              :                                       bool &HXUnitOn             // flag to control HX based on zone moisture load
    6474              :     )
    6475              :     {
    6476              :         // SUBROUTINE INFORMATION:
    6477              :         //       AUTHOR         Richard Liesen
    6478              :         //       DATE WRITTEN   Feb 2001
    6479              :         //       MODIFIED       R. Raustad and D. Shirey, Feb/Mar/Sept/Oct/Dec 2001, Jan/Oct 2002
    6480              :         //       RE-ENGINEERED  R. Raustad, Feb. 2005 (added RegulaFalsi for iteration technique)
    6481              : 
    6482              :         // PURPOSE OF THIS SUBROUTINE:
    6483              :         // This subroutine updates the coil outlet nodes.
    6484              : 
    6485              :         // METHODOLOGY EMPLOYED:
    6486              :         // Determine the operating PLR to meet the zone sensible load. If a humidistat is specified, determine
    6487              :         // the operating PLR (greater of the sensible and latent PLR) to meet the zone SENSIBLE load
    6488              :         // (Multimode dehumidification control) or zone LATENT load (CoolReheat dehumidification control).
    6489              :         // For dehumidification control type COOLREHEAT, both a sensible and latent PLR may exist for a
    6490              :         // single time step (heating and dehumidification can occur). For all other system types,
    6491              :         // only a single PLR is allowed for any given time step.
    6492              :         // Order of simulation depends on dehumidification control option as described below.
    6493              :         // Dehumidification control options:
    6494              :         // Dehumidification Control NONE:   Cooling performance is simulated first and then heating performance. If a HX
    6495              :         //                                  assisted cooling coil is selected, the HX is always active.
    6496              :         // Dehumidification Control COOLREHEAT: Continuous Fan Operation:
    6497              :         //                                      For cooling operation, the sensible and latent capacities are calculated to
    6498              :         //                                      meet the thermostat setpoint. If a HX assisted cooling coil is selected,
    6499              :         //                                      the HX is always active. If the latent load is not met by operating the
    6500              :         //                                      system at the sensible PLR, a new PLR is calculated to meet the humidistat
    6501              :         //                                      setpoint. The reheat coil load is then calculated to meet the HEATING
    6502              :         //                                      setpoint temperature.
    6503              :         //                                      Cycling Fan Operation:
    6504              :         //                                      The heating part-load ratio is calculated first. Since the fan will be
    6505              :         //                                      controlled at the higher of the heating or cooling PLR's, a ratio of the
    6506              :         //                                      cooling to heating PLR is used to pass to the cooling coil (MAX=1). This allows
    6507              :         //                                      the cooling coil to operate at the heating PLR when the heating PLR is
    6508              :         //                                      higher than the cooling PLR. The sensible and latent capacities are then
    6509              :         //                                      calculated to meet the thermostat setpoint.
    6510              :         //                                      If a HX assisted cooling coil is selected, the HX is always active.
    6511              :         //                                      If the latent load is not met by operating the system at the sensible PLR,
    6512              :         //                                      a new PLR is calculated to meet the humidistat setpoint.
    6513              :         //                                      The reheat coil load is then calculated to meet the HEATING setpoint temperature.
    6514              :         // Dehumidification Control MULTIMODE: For cooling operation, the sensible and latent capacities are calculated to
    6515              :         //                                     meet the thermostat setpoint. If a HX assisted cooling coil is selected,
    6516              :         //                                     the HX is off for this calculation. If the latent load is not met by operating
    6517              :         //                                     the system at the sensible PLR, a new PLR is calculated with the HX operating
    6518              :         //                                     and the target is the thermostat setpoint. Humidity is not controlled in this
    6519              :         //                                     mode. No reheat coil is used in this configuration.
    6520              :         //  Note: A supplemental heater augments the heating capacity for air-to-air heat pumps.
    6521              :         //        A reheat coil is used for the HeatCool furnace/unitarysystem to offset the sensible cooling when the
    6522              :         //        dehumidification control type is COOLREHEAT. Both the supplemental and reheat heating coil load is calculated
    6523              :         //        in the Calc routines. The actual simulation of these coils is performed in the SimFurnace routine (i.e. the
    6524              :         //        supplemental and reheat coil loads are passed as 0 to CalcFurnaceOutput).
    6525              : 
    6526              :         // SUBROUTINE PARAMETER DEFINITIONS:
    6527        15225 :         int constexpr MaxIter(100);   // maximum number of iterations
    6528        15225 :         Real64 constexpr MinPLR(0.0); // minimum part load ratio allowed
    6529              : 
    6530              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6531              :         Real64 SystemMoistureLoad;   // Total latent load to be removed by furnace/unitary system
    6532              :         Real64 deltaT;               // Temperature rise across heating coil (C)
    6533              :         Real64 TempOutHeatingCoil;   // Temperature leaving heating coil (C)
    6534              :         Real64 FullSensibleOutput;   // Full sensible output of AC (W)
    6535              :         Real64 FullLatentOutput;     // Full latent output of AC (W)
    6536              :         Real64 NoCoolOutput;         // Sensible output of AC with no cooling allowed (W)
    6537              :         Real64 NoHeatOutput;         // Sensible output of heater with no heating allowed (W)
    6538              :         Real64 NoLatentOutput;       // Latent output of AC with no cooling allowed (W)
    6539              :         Real64 CoolErrorToler;       // Error tolerance in cooling mode
    6540              :         Real64 HeatErrorToler;       // Error tolerance in heating mode
    6541              :         Real64 ActualSensibleOutput; // Actual furnace sensible capacity
    6542              :         Real64 ActualLatentOutput;   // Actual furnace latent capacity
    6543              :         Real64 PartLoadRatio;        // Part load ratio (greater of sensible or latent part load ratio for cooling,
    6544              :         // or heating PLR)
    6545              :         Real64 LatentPartLoadRatio; // Part load ratio to meet dehumidification load
    6546              :         Real64 TempCoolOutput;      // Temporary Sensible output of AC while iterating on PLR (W)
    6547              :         Real64 TempHeatOutput;      // Temporary Sensible output of heating coil while iterating on PLR (W)
    6548              :         Real64 TempLatentOutput;    // Temporary Latent output of AC at increasing PLR (W)
    6549              :         //                                           ! (Temp variables are used to find min PLR for positive latent removal)
    6550              :         Real64 TempMinPLR;             // Temporary min latent PLR when hum control is required and iter is exceeded
    6551              :         Real64 TempMinPLR2;            // Temporary min latent PLR when cyc fan hum control is required and iter is exceeded
    6552              :         Real64 TempMaxPLR;             // Temporary max latent PLR when hum control is required and iter is exceeded
    6553              :         Real64 QToHeatSetPt;           // Load required to meet heating setpoint temp (>0 is a heating load)
    6554              :         Real64 CoolingHeatingPLRRatio; // ratio of cooling to heating PLR (MAX=1). Used in heating mode.
    6555              :         Real64 HeatingSensibleOutput;
    6556              :         Real64 HeatingLatentOutput;
    6557              :         Real64 OutdoorDryBulbTemp; // secondary coil (condenser) entering dry bulb temperature
    6558              : 
    6559        15225 :         Real64 &SystemSensibleLoad = state.dataFurnaces->SystemSensibleLoad;
    6560        15225 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    6561              :         // Set local variables
    6562        15225 :         int FurnaceOutletNode = thisFurnace.FurnaceOutletNodeNum;
    6563        15225 :         int FurnaceInletNode = thisFurnace.FurnaceInletNodeNum;
    6564        15225 :         int ControlZoneNode = thisFurnace.NodeNumOfControlledZone;
    6565        15225 :         HVAC::FanOp fanOp = thisFurnace.fanOp; // fan operating mode
    6566        15225 :         bool HumControl = false;
    6567              :         // Calculate the Cp Air of zone
    6568        15225 :         Real64 cpair = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ControlZoneNode).HumRat);
    6569        15225 :         NoHeatOutput = 0.0;
    6570        15225 :         SystemSensibleLoad = 0.0;
    6571        15225 :         ReheatCoilLoad = 0.0;
    6572        15225 :         HeatCoilLoad = 0.0;
    6573        15225 :         ReheatCoilLoad = 0.0;
    6574        15225 :         PartLoadRatio = 0.0;
    6575              : 
    6576        15225 :         if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir) {
    6577        15222 :             if (state.dataDXCoils->DXCoil(thisFurnace.HeatingCoilIndex)
    6578        15222 :                     .IsSecondaryDXCoilInZone) { // assumes compressor is in same location as secondary coil
    6579            0 :                 OutdoorDryBulbTemp =
    6580            0 :                     state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(thisFurnace.HeatingCoilIndex).SecZonePtr).ZT;
    6581        15222 :             } else if (state.dataDXCoils->DXCoil(thisFurnace.CoolingCoilIndex).IsSecondaryDXCoilInZone) {
    6582            0 :                 OutdoorDryBulbTemp =
    6583            0 :                     state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(thisFurnace.CoolingCoilIndex).SecZonePtr).ZT;
    6584              :             } else {
    6585        15222 :                 if (thisFurnace.CondenserNodeNum > 0) {
    6586            0 :                     OutdoorDryBulbTemp = state.dataLoopNodes->Node(thisFurnace.CondenserNodeNum).Temp;
    6587              :                 } else {
    6588        15222 :                     OutdoorDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
    6589              :                 }
    6590              :             }
    6591              :         } else {
    6592            3 :             OutdoorDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
    6593              :         }
    6594        15225 :         if (FirstHVACIteration) {
    6595              :             // Set selected values during first HVAC iteration
    6596              : 
    6597              :             // Init for heating
    6598         4847 :             if (state.dataFurnaces->HeatingLoad) {
    6599         3103 :                 if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    6600            0 :                     (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir && thisFurnace.WatertoAirHPType == WAHPCoilType::Simple)) {
    6601         3103 :                     thisFurnace.HeatPartLoadRatio = 1.0;
    6602         3103 :                     HeatCoilLoad = 0.0;
    6603         3103 :                     thisFurnace.HeatingCoilSensDemand = 0.0;
    6604         3103 :                     thisFurnace.CoolingCoilSensDemand = 0.0;
    6605         3103 :                     thisFurnace.CoolingCoilLatentDemand = 0.0;
    6606              :                 } else { // for furnaces
    6607            0 :                     thisFurnace.HeatPartLoadRatio = 0.0;
    6608            0 :                     HeatCoilLoad = ZoneLoad;
    6609            0 :                     state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    6610            0 :                     thisFurnace.HeatingCoilSensDemand = 0.0;
    6611            0 :                     thisFurnace.CoolingCoilSensDemand = 0.0;
    6612            0 :                     thisFurnace.CoolingCoilLatentDemand = 0.0;
    6613              :                 }
    6614         3103 :                 ReheatCoilLoad = 0.0;
    6615         3103 :                 thisFurnace.CoolPartLoadRatio = 0.0;
    6616              : 
    6617              :                 // Init for cooling
    6618         1744 :             } else if (state.dataFurnaces->CoolingLoad) {
    6619              :                 // air to air heat pumps
    6620         1687 :                 thisFurnace.CoolPartLoadRatio = 1.0;
    6621         1687 :                 thisFurnace.HeatPartLoadRatio = 0.0;
    6622         1687 :                 HeatCoilLoad = 0.0;
    6623         1687 :                 ReheatCoilLoad = 0.0;
    6624              : 
    6625              :                 // Init for moisture load only
    6626              :             } else {
    6627           57 :                 thisFurnace.CoolPartLoadRatio = 0.0;
    6628           57 :                 thisFurnace.HeatPartLoadRatio = 0.0;
    6629           57 :                 HeatCoilLoad = 0.0;
    6630           57 :                 ReheatCoilLoad = 0.0;
    6631           57 :                 thisFurnace.HeatingCoilSensDemand = 0.0;
    6632           57 :                 thisFurnace.CoolingCoilSensDemand = 0.0;
    6633           57 :                 thisFurnace.CoolingCoilLatentDemand = 0.0;
    6634              :             }
    6635              : 
    6636         4847 :             SetAverageAirFlow(state, FurnaceNum, max(thisFurnace.HeatPartLoadRatio, thisFurnace.CoolPartLoadRatio), OnOffAirFlowRatio);
    6637              :             //  if dehumidification load exists (for heat pumps) turn on the supplemental heater
    6638         4847 :             if (state.dataFurnaces->HPDehumidificationLoadFlag) {
    6639            0 :                 HumControl = true;
    6640              :             }
    6641              :         } else { // not FirstHVACIteration
    6642              :             // Init for heating
    6643        10378 :             Real64 &CoolCoilLoad = state.dataFurnaces->CoolCoilLoad;
    6644        10378 :             if (state.dataFurnaces->HeatingLoad) {
    6645         5260 :                 CoolCoilLoad = 0.0;
    6646         5260 :                 if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    6647            1 :                     (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir && thisFurnace.WatertoAirHPType == WAHPCoilType::Simple)) {
    6648         5260 :                     SystemSensibleLoad = ZoneLoad;
    6649         5260 :                     SystemMoistureLoad = 0.0;
    6650         5260 :                     HeatCoilLoad = 0.0;
    6651         5260 :                     thisFurnace.HeatingCoilSensDemand = SystemSensibleLoad;
    6652         5260 :                     thisFurnace.CoolingCoilSensDemand = 0.0;
    6653         5260 :                     thisFurnace.CoolingCoilLatentDemand = 0.0;
    6654              :                 } else {
    6655            0 :                     SystemMoistureLoad = MoistureLoad;
    6656            0 :                     HeatCoilLoad = ZoneLoad;
    6657              :                 }
    6658              : 
    6659              :                 // Init for cooling
    6660         5118 :             } else if (state.dataFurnaces->CoolingLoad) {
    6661         5061 :                 CoolCoilLoad = ZoneLoad;
    6662         5061 :                 SystemMoistureLoad = MoistureLoad;
    6663         5061 :                 HeatCoilLoad = 0.0;
    6664         5061 :                 thisFurnace.CoolingCoilSensDemand = std::abs(CoolCoilLoad);
    6665         5061 :                 thisFurnace.CoolingCoilLatentDemand = std::abs(SystemMoistureLoad);
    6666         5061 :                 thisFurnace.HeatingCoilSensDemand = 0.0;
    6667              : 
    6668              :                 // Init for latent
    6669              :             } else {
    6670           57 :                 SystemMoistureLoad = MoistureLoad;
    6671           57 :                 CoolCoilLoad = 0.0;
    6672           57 :                 HeatCoilLoad = 0.0;
    6673              :                 // set report variables
    6674           57 :                 thisFurnace.CoolingCoilSensDemand = 0.0;
    6675           57 :                 thisFurnace.CoolingCoilLatentDemand = SystemMoistureLoad;
    6676           57 :                 thisFurnace.HeatingCoilSensDemand = 0.0;
    6677              :             }
    6678        10378 :             HeatingSensibleOutput = 0.0;
    6679        10378 :             HeatingLatentOutput = 0.0;
    6680        10378 :             ReheatCoilLoad = 0.0;
    6681        10378 :             thisFurnace.CoolPartLoadRatio = 0.0;
    6682        10378 :             thisFurnace.HeatPartLoadRatio = 0.0;
    6683        10378 :             thisFurnace.CompPartLoadRatio = 0.0;
    6684        10378 :             thisFurnace.DehumidInducedHeatingDemandRate = 0.0;
    6685              : 
    6686              :             // When humidity control is used with cycling fan control and a heating load exists, if a moisture load
    6687              :             // also exists, the heating PLR must be available for the cooling coil calculations.
    6688              :             //*********** Heating Section ************
    6689              :             // If Furnace runs with a heating load then set HeatCoilLoad on Heating Coil and the Mass Flow
    6690              :             //         (Node(FurnaceInletNode)%MassFlowRate .gt. 0.0d0) .and. &
    6691        10378 :             if ((thisFurnace.availSched->getCurrentVal() > 0.0) && (state.dataFurnaces->HeatingLoad)) {
    6692              : 
    6693              :                 //    Heat pumps only calculate a single PLR each time step (i.e. only cooling or heating allowed in a single time step)
    6694         5260 :                 if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    6695            1 :                     (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir && thisFurnace.WatertoAirHPType == WAHPCoilType::Simple)) {
    6696              : 
    6697         5260 :                     state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    6698              : 
    6699              :                     // Get no load result
    6700         5260 :                     if (fanOp == HVAC::FanOp::Cycling) {
    6701         5259 :                         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = 0.0;
    6702              :                     }
    6703              : 
    6704              :                     //     Set the inlet mass flow rate based on user specified coil OFF flow rate
    6705         5260 :                     PartLoadRatio = 0.0;
    6706              : 
    6707         5260 :                     SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
    6708              : 
    6709              :                     // Set the input parameters for CalcFurnaceOutput
    6710         5260 :                     thisFurnace.CompPartLoadRatio = 0.0; // compressor off
    6711              : 
    6712         5260 :                     CalcFurnaceOutput(state,
    6713              :                                       FurnaceNum,
    6714              :                                       FirstHVACIteration,
    6715              :                                       fanOp,
    6716              :                                       compressorOp,
    6717              :                                       0.0,
    6718              :                                       MinPLR,
    6719              :                                       0.0,
    6720              :                                       0.0,
    6721              :                                       NoHeatOutput,
    6722              :                                       NoLatentOutput,
    6723              :                                       OnOffAirFlowRatio,
    6724              :                                       false);
    6725              : 
    6726         5260 :                     PartLoadRatio = 1.0;
    6727         5260 :                     state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    6728              : 
    6729         5260 :                     thisFurnace.CompPartLoadRatio = 1.0; // compressor ON
    6730              : 
    6731              :                     // Set fan part-load fraction equal to 1 while getting full load result
    6732         5260 :                     state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    6733         5260 :                     OnOffAirFlowRatio = 1.0;
    6734              : 
    6735              :                     // Get full load result
    6736         5260 :                     CalcFurnaceOutput(state,
    6737              :                                       FurnaceNum,
    6738              :                                       FirstHVACIteration,
    6739              :                                       fanOp,
    6740              :                                       compressorOp,
    6741              :                                       0.0,
    6742              :                                       PartLoadRatio,
    6743              :                                       0.0,
    6744              :                                       0.0,
    6745              :                                       FullSensibleOutput,
    6746              :                                       FullLatentOutput,
    6747              :                                       OnOffAirFlowRatio,
    6748              :                                       false);
    6749              : 
    6750              :                     // Check that SystemSensibleLoad is between FullSensibleOutput and NoHeatOutput
    6751              :                     // If so then calculate PartLoadRatio for the DX Heating coil
    6752         5260 :                     if (SystemSensibleLoad < FullSensibleOutput && SystemSensibleLoad > NoHeatOutput) {
    6753              : 
    6754              :                         // Calculate the part load ratio through iteration
    6755            8 :                         HeatErrorToler = thisFurnace.HeatingConvergenceTolerance; // Error tolerance for convergence from input deck
    6756              : 
    6757            8 :                         int SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
    6758              :                         // HeatErrorToler is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
    6759           32 :                         auto f = [&state, FurnaceNum, FirstHVACIteration, fanOp, compressorOp, SystemSensibleLoad](Real64 const PartLoadRatio) {
    6760           24 :                             return CalcFurnaceResidual(state,
    6761              :                                                        PartLoadRatio,
    6762              :                                                        FurnaceNum,
    6763              :                                                        FirstHVACIteration,
    6764              :                                                        fanOp,
    6765              :                                                        compressorOp,
    6766              :                                                        SystemSensibleLoad,
    6767              :                                                        0.0,  // par6_loadFlag,
    6768              :                                                        1.0,  // par7_sensLatentFlag,
    6769              :                                                        0.0,  // par9_HXOnFlag,
    6770           24 :                                                        0.0); // par10_HeatingCoilPLR);
    6771            8 :                         };
    6772            8 :                         General::SolveRoot(state, HeatErrorToler, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
    6773              :                         //         OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
    6774            8 :                         OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
    6775            8 :                         if (SolFlag < 0) {
    6776            0 :                             if (SolFlag == -1) {
    6777            0 :                                 CalcFurnaceOutput(state,
    6778              :                                                   FurnaceNum,
    6779              :                                                   FirstHVACIteration,
    6780              :                                                   fanOp,
    6781              :                                                   compressorOp,
    6782              :                                                   0.0,
    6783              :                                                   PartLoadRatio,
    6784              :                                                   0.0,
    6785              :                                                   0.0,
    6786              :                                                   TempHeatOutput,
    6787              :                                                   TempLatentOutput,
    6788              :                                                   OnOffAirFlowRatio,
    6789              :                                                   false);
    6790            0 :                                 if (std::abs(SystemSensibleLoad - TempHeatOutput) > HVAC::SmallLoad) {
    6791            0 :                                     if (thisFurnace.DXHeatingMaxIterIndex == 0) {
    6792            0 :                                         ShowWarningMessage(state,
    6793            0 :                                                            format("Heating coil control failed to converge for {}:{}",
    6794            0 :                                                                   HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6795            0 :                                                                   thisFurnace.Name));
    6796            0 :                                         ShowContinueError(state,
    6797              :                                                           "  Iteration limit exceeded in calculating DX heating coil sensible part-load ratio.");
    6798            0 :                                         ShowContinueErrorTimeStamp(
    6799              :                                             state,
    6800            0 :                                             format("Sensible load to be met by DX heating coil = {:.2T} (watts), sensible output of DX heating "
    6801              :                                                    "coil = {:.2T} (watts), and the simulation continues.",
    6802              :                                                    SystemSensibleLoad,
    6803              :                                                    TempHeatOutput));
    6804              :                                     }
    6805            0 :                                     ShowRecurringWarningErrorAtEnd(state,
    6806            0 :                                                                    format("{} \"{}\" - Iteration limit exceeded in calculating DX sensible heating "
    6807              :                                                                           "part-load ratio error continues. "
    6808              :                                                                           "Sensible load statistics:",
    6809            0 :                                                                           HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6810            0 :                                                                           thisFurnace.Name),
    6811            0 :                                                                    thisFurnace.DXHeatingMaxIterIndex,
    6812              :                                                                    SystemSensibleLoad,
    6813              :                                                                    SystemSensibleLoad);
    6814              :                                 }
    6815            0 :                             } else if (SolFlag == -2) {
    6816            0 :                                 if (thisFurnace.DXHeatingRegulaFalsiFailedIndex == 0) {
    6817            0 :                                     ShowWarningMessage(state,
    6818            0 :                                                        format("Heating coil control failed for {}:{}",
    6819            0 :                                                               HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6820            0 :                                                               thisFurnace.Name));
    6821            0 :                                     ShowContinueError(state, "  DX sensible heating part-load ratio determined to be outside the range of 0-1.");
    6822            0 :                                     ShowContinueErrorTimeStamp(
    6823              :                                         state,
    6824            0 :                                         format("Sensible load to be met by DX heating coil = {:.2T} (watts), and the simulation continues.",
    6825              :                                                SystemSensibleLoad));
    6826              :                                 }
    6827            0 :                                 ShowRecurringWarningErrorAtEnd(
    6828              :                                     state,
    6829            0 :                                     format("{} \"{}\" -  DX sensible heating part-load ratio out of range error continues. Sensible load statistics:",
    6830            0 :                                            HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    6831            0 :                                            thisFurnace.Name),
    6832            0 :                                     thisFurnace.DXHeatingRegulaFalsiFailedIndex,
    6833              :                                     SystemSensibleLoad,
    6834              :                                     SystemSensibleLoad);
    6835              :                             }
    6836              :                         }
    6837              : 
    6838            8 :                         thisFurnace.HeatPartLoadRatio = PartLoadRatio;
    6839              :                         //       Check if Heat Pump compressor is allowed to run based on outdoor temperature
    6840            8 :                         if (OutdoorDryBulbTemp > thisFurnace.MinOATCompressorHeating) {
    6841            0 :                             thisFurnace.CompPartLoadRatio = PartLoadRatio;
    6842              :                         } else {
    6843            8 :                             thisFurnace.CompPartLoadRatio = 0.0;
    6844              :                         }
    6845         5260 :                     } else if (SystemSensibleLoad > FullSensibleOutput) {
    6846              :                         //       SystemSensibleLoad is greater than full DX Heating coil output so heat pump runs entire
    6847              :                         //       timestep and additional supplemental heating is required
    6848         5252 :                         thisFurnace.HeatPartLoadRatio = 1.0;
    6849         5252 :                         if (OutdoorDryBulbTemp > thisFurnace.MinOATCompressorHeating) {
    6850              :                             //       Check to see if Heat Pump compressor was allowed to run based on outdoor temperature
    6851            1 :                             thisFurnace.CompPartLoadRatio = 1.0;
    6852              :                         } else {
    6853         5251 :                             thisFurnace.CompPartLoadRatio = 0.0;
    6854              :                         }
    6855            0 :                     } else if (SystemSensibleLoad < NoHeatOutput) {
    6856              :                         //       SystemSensibleLoad is less than minimum DX Heating coil output so heat pump does not run and
    6857              :                         //       the load will be met by the supplemental heater
    6858            0 :                         thisFurnace.CompPartLoadRatio = 0.0;
    6859            0 :                         thisFurnace.HeatPartLoadRatio = 1.0;
    6860              :                     }
    6861         5260 :                     if (thisFurnace.HeatPartLoadRatio == 1.0) {
    6862              :                         //       Determine the load on the supplemental heating coil
    6863         5252 :                         if ((SystemSensibleLoad - FullSensibleOutput) > thisFurnace.DesignSuppHeatingCapacity) {
    6864            1 :                             HeatCoilLoad = thisFurnace.DesignSuppHeatingCapacity;
    6865            1 :                             TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceOutletNode).Temp + HeatCoilLoad / (cpair * thisFurnace.MdotFurnace);
    6866         5251 :                         } else if (SystemSensibleLoad < NoHeatOutput) {
    6867            0 :                             HeatCoilLoad = max(0.0, SystemSensibleLoad); // BG 10/22/2008 need a case for when its all suppl heat
    6868            0 :                             TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceInletNode).Temp + HeatCoilLoad / (cpair * thisFurnace.MdotFurnace);
    6869              :                         } else {
    6870         5251 :                             HeatCoilLoad = max(0.0, (SystemSensibleLoad - FullSensibleOutput));
    6871         5251 :                             TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceOutletNode).Temp + HeatCoilLoad / (cpair * thisFurnace.MdotFurnace);
    6872              :                         }
    6873         5252 :                         if (OutdoorDryBulbTemp > thisFurnace.MaxOATSuppHeat) {
    6874            1 :                             HeatCoilLoad = 0.0;
    6875            1 :                             if (SystemSensibleLoad < NoHeatOutput) {
    6876            0 :                                 TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceInletNode).Temp;
    6877              :                             } else {
    6878            1 :                                 TempOutHeatingCoil = state.dataLoopNodes->Node(FurnaceOutletNode).Temp;
    6879              :                             }
    6880              :                         }
    6881         5252 :                         if ((TempOutHeatingCoil > thisFurnace.DesignMaxOutletTemp) && (HeatCoilLoad > 0.0)) {
    6882              :                             // deltaT = Furnace(FurnaceNum)%DesignMaxOutletTemp - Node(FurnaceOutletNode)%Temp
    6883              :                             // BG 10/22/2008 above made no sense if DX heat is off and its all supplemental,
    6884              :                             //  because Node(FurnaceOutletNode)%Temp will have been calc'd with full DX heat in last faux call to CalcFurnaceOutput
    6885              : 
    6886         1584 :                             Real64 cpairSupply = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(FurnaceInletNode).HumRat);
    6887         1584 :                             deltaT = (thisFurnace.DesignMaxOutletTemp - TempOutHeatingCoil);
    6888         1584 :                             HeatCoilLoad += (state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate * cpairSupply * deltaT);
    6889         1584 :                             HeatCoilLoad = max(0.0, HeatCoilLoad);
    6890              :                         }
    6891              :                     } else {
    6892            8 :                         HeatCoilLoad = 0.0;
    6893              :                     }
    6894         5260 :                     PartLoadRatio = 0.0;
    6895              : 
    6896              :                     //   HeatCool systems can have both a sensible and latent PLR in a single time step
    6897              :                     //   (i.e. both cooling and heating can occur in a single time step)
    6898         5260 :                 } else { // else not a heatpump DX coil ** non-HP heating coils are not DX so testing if OutdoorDryBulbTemp < MinOATCompressorHeating
    6899              :                          // is not necessary **
    6900              : 
    6901            0 :                     state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    6902            0 :                     HeatCoilLoad = thisFurnace.DesignHeatingCapacity;
    6903            0 :                     SystemSensibleLoad = ZoneLoad;
    6904              : 
    6905              :                     // Get no load result
    6906            0 :                     if (fanOp == HVAC::FanOp::Cycling) {
    6907            0 :                         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = 0.0;
    6908              :                     }
    6909            0 :                     if (fanOp == HVAC::FanOp::Continuous) {
    6910            0 :                         state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // The on/off fan will not cycle, so set part-load fraction = 1
    6911              :                     }
    6912              : 
    6913              :                     //     Set the inlet mass flow rate based on user specified coil OFF flow rate
    6914            0 :                     PartLoadRatio = 0.0;
    6915            0 :                     SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
    6916              : 
    6917            0 :                     CalcFurnaceOutput(state,
    6918              :                                       FurnaceNum,
    6919              :                                       FirstHVACIteration,
    6920              :                                       fanOp,
    6921              :                                       compressorOp,
    6922              :                                       0.0,
    6923              :                                       MinPLR,
    6924              :                                       0.0,
    6925              :                                       0.0,
    6926              :                                       NoHeatOutput,
    6927              :                                       NoLatentOutput,
    6928              :                                       OnOffAirFlowRatio,
    6929              :                                       false);
    6930              : 
    6931            0 :                     if (NoHeatOutput < SystemSensibleLoad) {
    6932            0 :                         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    6933              : 
    6934              :                         // Set fan part-load fraction equal to 1 while getting full load result
    6935            0 :                         state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    6936            0 :                         OnOffAirFlowRatio = 1.0;
    6937              : 
    6938              :                         // Get full load result
    6939            0 :                         CalcFurnaceOutput(state,
    6940              :                                           FurnaceNum,
    6941              :                                           FirstHVACIteration,
    6942              :                                           fanOp,
    6943              :                                           compressorOp,
    6944              :                                           0.0,
    6945              :                                           1.0,
    6946              :                                           HeatCoilLoad,
    6947              :                                           0.0,
    6948              :                                           FullSensibleOutput,
    6949              :                                           FullLatentOutput,
    6950              :                                           OnOffAirFlowRatio,
    6951              :                                           false);
    6952              :                     } else {
    6953            0 :                         FullSensibleOutput = NoHeatOutput + 0.000000001;
    6954              :                     }
    6955              : 
    6956              :                     // Since we are heating, we expect FullSensibleOutput to be > 0 and FullSensibleOutput > NoSensibleOutput
    6957              :                     // Check that this is the case; if not set PartLoadRatio = 0.0 (off) and return
    6958              : 
    6959            0 :                     if (FullSensibleOutput > NoHeatOutput) {
    6960              : 
    6961              :                         // check bounds on sensible output prior to iteration using RegulaFalsi
    6962            0 :                         if (FullSensibleOutput <= SystemSensibleLoad) {
    6963            0 :                             PartLoadRatio = 1.0;
    6964              :                             //         save modified HeatCoilLoad in case it was reset because outlet temp > DesignMaxOutletTemp
    6965            0 :                             if (state.dataFurnaces->ModifiedHeatCoilLoad > 0.0) {
    6966            0 :                                 HeatCoilLoad = state.dataFurnaces->ModifiedHeatCoilLoad;
    6967              :                             } else {
    6968            0 :                                 HeatCoilLoad = thisFurnace.DesignHeatingCapacity;
    6969              :                             }
    6970            0 :                         } else if (NoHeatOutput >= SystemSensibleLoad) {
    6971            0 :                             PartLoadRatio = 0.0;
    6972            0 :                             HeatCoilLoad = 0.0;
    6973              :                         } else {
    6974              : 
    6975              :                             // Calculate the part load ratio through iteration
    6976            0 :                             HeatErrorToler = thisFurnace.HeatingConvergenceTolerance; // Error tolerance for convergence from input deck
    6977              : 
    6978            0 :                             int SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
    6979              :                             // HeatErrorToler is in fraction load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
    6980            0 :                             auto f = [&state, FurnaceNum, FirstHVACIteration, fanOp, compressorOp, SystemSensibleLoad](Real64 const PartLoadRatio) {
    6981            0 :                                 return CalcFurnaceResidual(state,
    6982              :                                                            PartLoadRatio,
    6983              :                                                            FurnaceNum,
    6984              :                                                            FirstHVACIteration,
    6985              :                                                            fanOp,
    6986              :                                                            compressorOp,
    6987              :                                                            SystemSensibleLoad,
    6988              :                                                            0.0,  // par6_loadFlag,
    6989              :                                                            1.0,  // par7_sensLatentFlag,
    6990              :                                                            0.0,  // par9_HXOnFlag,
    6991            0 :                                                            0.0); // par10_HeatingCoilPLR);
    6992            0 :                             };
    6993            0 :                             General::SolveRoot(state, HeatErrorToler, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
    6994              :                             //         OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
    6995            0 :                             OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
    6996              :                             //         Reset HeatCoilLoad calculated in CalcFurnaceResidual (in case it was reset because output temp >
    6997              :                             //         DesignMaxOutletTemp)
    6998            0 :                             if (state.dataFurnaces->ModifiedHeatCoilLoad > 0.0) {
    6999            0 :                                 HeatCoilLoad = state.dataFurnaces->ModifiedHeatCoilLoad;
    7000              :                             } else {
    7001            0 :                                 HeatCoilLoad = thisFurnace.DesignHeatingCapacity * PartLoadRatio;
    7002              :                             }
    7003            0 :                             if (SolFlag == -1) {
    7004              : 
    7005              :                                 //           RegulaFalsi may not find heating PLR when the maximum supply air temperature is exceeded.
    7006              :                                 //           If iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
    7007            0 :                                 TempMaxPLR = -0.1;
    7008            0 :                                 TempHeatOutput = NoHeatOutput;
    7009            0 :                                 while ((TempHeatOutput - SystemSensibleLoad) < 0.0 && TempMaxPLR < 1.0) {
    7010              :                                     //             find upper limit of HeatingPLR
    7011            0 :                                     TempMaxPLR += 0.1;
    7012            0 :                                     HeatCoilLoad = thisFurnace.DesignHeatingCapacity * TempMaxPLR;
    7013            0 :                                     CalcFurnaceOutput(state,
    7014              :                                                       FurnaceNum,
    7015              :                                                       FirstHVACIteration,
    7016              :                                                       fanOp,
    7017              :                                                       compressorOp,
    7018              :                                                       0.0,
    7019              :                                                       TempMaxPLR,
    7020              :                                                       HeatCoilLoad,
    7021              :                                                       0.0,
    7022              :                                                       TempHeatOutput,
    7023              :                                                       TempLatentOutput,
    7024              :                                                       OnOffAirFlowRatio,
    7025              :                                                       false);
    7026              :                                 }
    7027            0 :                                 TempMinPLR = TempMaxPLR;
    7028            0 :                                 while ((TempHeatOutput - SystemSensibleLoad) > 0.0 && TempMinPLR > 0.0) {
    7029              :                                     //             pull upper limit of HeatingPLR down to last valid limit (i.e. heat output still exceeds
    7030              :                                     //             SystemSensibleLoad)
    7031            0 :                                     TempMaxPLR = TempMinPLR;
    7032              :                                     //             find minimum limit of HeatingPLR
    7033            0 :                                     TempMinPLR -= 0.01;
    7034              : 
    7035            0 :                                     HeatCoilLoad = thisFurnace.DesignHeatingCapacity * TempMinPLR;
    7036            0 :                                     CalcFurnaceOutput(state,
    7037              :                                                       FurnaceNum,
    7038              :                                                       FirstHVACIteration,
    7039              :                                                       fanOp,
    7040              :                                                       compressorOp,
    7041              :                                                       0.0,
    7042              :                                                       TempMinPLR,
    7043              :                                                       HeatCoilLoad,
    7044              :                                                       0.0,
    7045              :                                                       TempHeatOutput,
    7046              :                                                       TempLatentOutput,
    7047              :                                                       OnOffAirFlowRatio,
    7048              :                                                       false);
    7049              :                                 }
    7050              :                                 //           Now solve again with tighter PLR limits
    7051              :                                 auto f2 = // (AUTO_OK_LAMBDA)
    7052            0 :                                     [&state, FurnaceNum, FirstHVACIteration, fanOp, compressorOp, SystemSensibleLoad](Real64 const PartLoadRatio) {
    7053            0 :                                         return CalcFurnaceResidual(state,
    7054              :                                                                    PartLoadRatio,
    7055              :                                                                    FurnaceNum,
    7056              :                                                                    FirstHVACIteration,
    7057              :                                                                    fanOp,
    7058              :                                                                    compressorOp,
    7059              :                                                                    SystemSensibleLoad,
    7060              :                                                                    0.0,  // par6_loadFlag,
    7061              :                                                                    1.0,  // par7_sensLatentFlag,
    7062              :                                                                    0.0,  // par9_HXOnFlag,
    7063            0 :                                                                    0.0); // par10_HeatingCoilPLR);
    7064            0 :                                     };
    7065            0 :                                 General::SolveRoot(state, HeatErrorToler, MaxIter, SolFlag, PartLoadRatio, f2, TempMinPLR, TempMaxPLR);
    7066            0 :                                 if (state.dataFurnaces->ModifiedHeatCoilLoad > 0.0) {
    7067            0 :                                     HeatCoilLoad = state.dataFurnaces->ModifiedHeatCoilLoad;
    7068              :                                 } else {
    7069            0 :                                     HeatCoilLoad = thisFurnace.DesignHeatingCapacity * PartLoadRatio;
    7070              :                                 }
    7071            0 :                                 CalcFurnaceOutput(state,
    7072              :                                                   FurnaceNum,
    7073              :                                                   FirstHVACIteration,
    7074              :                                                   fanOp,
    7075              :                                                   compressorOp,
    7076              :                                                   0.0,
    7077              :                                                   PartLoadRatio,
    7078              :                                                   HeatCoilLoad,
    7079              :                                                   0.0,
    7080              :                                                   TempHeatOutput,
    7081              :                                                   TempLatentOutput,
    7082              :                                                   OnOffAirFlowRatio,
    7083              :                                                   false);
    7084              : 
    7085              :                                 //           After iterating with tighter boundaries, if still out of tolerance, show warning.
    7086            0 :                                 if (SolFlag == -1 && std::abs(SystemSensibleLoad - TempHeatOutput) > HVAC::SmallLoad) {
    7087            0 :                                     if (thisFurnace.HeatingMaxIterIndex == 0) {
    7088            0 :                                         ShowWarningMessage(state,
    7089            0 :                                                            format("Heating coil control failed to converge for {}:{}",
    7090            0 :                                                                   HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7091            0 :                                                                   thisFurnace.Name));
    7092            0 :                                         ShowContinueError(state, "  Iteration limit exceeded in calculating heating coil sensible part-load ratio.");
    7093            0 :                                         ShowContinueErrorTimeStamp(state,
    7094            0 :                                                                    format("Sensible load to be met by heating coil = {:.2T} (watts), sensible output "
    7095              :                                                                           "of heating coil = {:.2T} (watts), and the simulation continues.",
    7096              :                                                                           SystemSensibleLoad,
    7097              :                                                                           TempHeatOutput));
    7098              :                                     }
    7099            0 :                                     ShowRecurringWarningErrorAtEnd(
    7100              :                                         state,
    7101            0 :                                         format("{} \"{}\" - Iteration limit exceeded in calculating sensible heating part-load "
    7102              :                                                "ratio error continues. Sensible load statistics:",
    7103            0 :                                                HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7104            0 :                                                thisFurnace.Name),
    7105            0 :                                         thisFurnace.HeatingMaxIterIndex,
    7106              :                                         SystemSensibleLoad,
    7107              :                                         SystemSensibleLoad);
    7108              :                                 }
    7109            0 :                             } else if (SolFlag == -2) {
    7110            0 :                                 if (thisFurnace.HeatingRegulaFalsiFailedIndex == 0) {
    7111            0 :                                     ShowWarningMessage(state,
    7112            0 :                                                        format("Heating coil control failed for {}:{}",
    7113            0 :                                                               HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7114            0 :                                                               thisFurnace.Name));
    7115            0 :                                     ShowContinueError(state, "  Sensible heating part-load ratio determined to be outside the range of 0-1.");
    7116            0 :                                     ShowContinueErrorTimeStamp(
    7117              :                                         state,
    7118            0 :                                         format("Sensible load to be met by heating coil = {:.2T} (watts), and the simulation continues.",
    7119              :                                                SystemSensibleLoad));
    7120              :                                 }
    7121            0 :                                 ShowRecurringWarningErrorAtEnd(
    7122              :                                     state,
    7123            0 :                                     format("{} \"{}\" -  Sensible heating part-load ratio out of range error continues. Sensible load statistics:",
    7124            0 :                                            HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7125            0 :                                            thisFurnace.Name),
    7126            0 :                                     thisFurnace.HeatingRegulaFalsiFailedIndex,
    7127              :                                     SystemSensibleLoad,
    7128              :                                     SystemSensibleLoad);
    7129              :                             }
    7130              :                         }
    7131              : 
    7132              :                     } else { // ELSE from IF(FullSensibleOutput.GT.NoSensibleOutput)THEN above
    7133              :                         // Set part load ratio to 1 and run heater at design heating capacity
    7134            0 :                         PartLoadRatio = 1.0;
    7135            0 :                         HeatCoilLoad = thisFurnace.DesignHeatingCapacity;
    7136              :                     }
    7137              : 
    7138              :                 } // End of IF HeatPump
    7139              : 
    7140              :             } // End of IF for heating
    7141              : 
    7142              :             // Non-heat pump systems do not set a heating PLR, set it here for use with the DX cooling coil calculations.
    7143              :             // Set this variable back to 0 for non-heat pump systems at the end of this routine.
    7144        10378 :             thisFurnace.HeatPartLoadRatio = max(PartLoadRatio, thisFurnace.HeatPartLoadRatio);
    7145        10378 :             CalcFurnaceOutput(state,
    7146              :                               FurnaceNum,
    7147              :                               FirstHVACIteration,
    7148              :                               fanOp,
    7149              :                               compressorOp,
    7150              :                               0.0,
    7151              :                               thisFurnace.HeatPartLoadRatio,
    7152              :                               HeatCoilLoad,
    7153              :                               0.0,
    7154              :                               HeatingSensibleOutput,
    7155              :                               HeatingLatentOutput,
    7156              :                               OnOffAirFlowRatio,
    7157              :                               false);
    7158              : 
    7159        10380 :             if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    7160            2 :                 (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir && thisFurnace.WatertoAirHPType == WAHPCoilType::Simple &&
    7161            2 :                  state.dataFurnaces->CoolingLoad)) {
    7162        10376 :                 HeatingSensibleOutput = 0.0;
    7163        10376 :                 HeatingLatentOutput = 0.0;
    7164              :             }
    7165              :             //***********Cooling Section*****************
    7166              :             // Simulate if scheduled ON and cooling load or if a moisture load exists when using a humidistat
    7167              :             // Check of HeatingLatentOutput is used to reduce overshoot during simultaneous heating and cooling
    7168              :             // Setback flag is used to avoid continued RH control when Tstat is setback (RH should float down)
    7169        15695 :             if ((thisFurnace.availSched->getCurrentVal() > 0.0 && state.dataFurnaces->CoolingLoad) ||
    7170         5317 :                 (thisFurnace.Humidistat && thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat &&
    7171            0 :                  (SystemMoistureLoad < 0.0 || (SystemMoistureLoad >= 0.0 && HeatingLatentOutput > SystemMoistureLoad &&
    7172            0 :                                                !state.dataZoneEnergyDemand->Setback(thisFurnace.ControlZoneNum))))) {
    7173              : 
    7174              :                 //     For cooling operation, the first step is to set the HX operation flag in case a HX assisted coil is used.
    7175              :                 //      (if a HX assisted coil is not used, this flag is not used. It's only used in the CALL to SimHXAssistedCoolingCoil)
    7176              :                 //     Check the dehumidification control type:
    7177              :                 //           For dehumidification control options CoolReheat and None, the HX is always active (locked ON).
    7178              :                 //           For dehumidification control option Multimode, the system is operated first with the HX off.
    7179              :                 //           If the moisture load is not met, the HX will then be turned on and the system is re-simulated.
    7180              : 
    7181         5061 :                 if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat ||
    7182         5061 :                     thisFurnace.DehumidControlType_Num == DehumidificationControlMode::None) {
    7183         5061 :                     HXUnitOn = true;
    7184              :                 } else {
    7185            0 :                     HXUnitOn = false;
    7186              :                 }
    7187              : 
    7188              :                 //     The next step is to determine the system output at no load (PLR=0) and full load (PLR=1)
    7189              : 
    7190              :                 //     Set the inlet mass flow rate based on user specified coil OFF flow rate
    7191         5061 :                 PartLoadRatio = 0.0;
    7192              : 
    7193         5061 :                 thisFurnace.CompPartLoadRatio = 0.0; // compressor off
    7194              : 
    7195              :                 //     SetAverageAirFlow calculates the operating mass flow rate based on PLR and the user specified inputs
    7196              :                 //     for MaxCoolAirMassFlow and MaxNoCoolHeatAirMassFlow.
    7197              :                 //     Air flow rate is set according to max of cooling and heating PLR if heating and latent load exists.
    7198         5061 :                 if (fanOp == HVAC::FanOp::Cycling && thisFurnace.HeatPartLoadRatio > 0.0 && thisFurnace.Humidistat &&
    7199        10122 :                     thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat &&
    7200            0 :                     (SystemMoistureLoad < 0.0 || (SystemMoistureLoad >= 0.0 && HeatingLatentOutput > SystemMoistureLoad &&
    7201            0 :                                                   !state.dataZoneEnergyDemand->Setback(thisFurnace.ControlZoneNum)))) {
    7202            0 :                     CoolingHeatingPLRRatio = min(1.0, PartLoadRatio / thisFurnace.HeatPartLoadRatio);
    7203            0 :                     SetAverageAirFlow(state, FurnaceNum, max(PartLoadRatio, thisFurnace.HeatPartLoadRatio), OnOffAirFlowRatio);
    7204              : 
    7205              :                 } else {
    7206         5061 :                     CoolingHeatingPLRRatio = 1.0;
    7207         5061 :                     SetAverageAirFlow(state, FurnaceNum, PartLoadRatio, OnOffAirFlowRatio);
    7208              :                 }
    7209              : 
    7210              :                 // Get no load result (coils simulated OFF)
    7211         5061 :                 CalcFurnaceOutput(state,
    7212              :                                   FurnaceNum,
    7213              :                                   FirstHVACIteration,
    7214              :                                   fanOp,
    7215              :                                   compressorOp,
    7216              :                                   MinPLR,
    7217              :                                   PartLoadRatio,
    7218              :                                   0.0,
    7219              :                                   0.0,
    7220              :                                   NoCoolOutput,
    7221              :                                   NoLatentOutput,
    7222              :                                   OnOffAirFlowRatio,
    7223         5061 :                                   HXUnitOn,
    7224              :                                   CoolingHeatingPLRRatio);
    7225              : 
    7226              :                 //     Don't calculate full load output if no load output can meet sensible load
    7227         5061 :                 if (NoCoolOutput >= CoolCoilLoad && (CoolCoilLoad != 0.0 || state.dataFurnaces->HPDehumidificationLoadFlag)) {
    7228              :                     //       Set full mass flow rate for full load calculation
    7229         5061 :                     state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    7230              : 
    7231              :                     // Set fan part-load fraction equal to 1 while getting full load result
    7232         5061 :                     state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    7233         5061 :                     OnOffAirFlowRatio = 1.0;
    7234         5061 :                     PartLoadRatio = 1.0;
    7235         5061 :                     thisFurnace.CompPartLoadRatio = 1.0; // compressor ON
    7236              : 
    7237              :                     // Get full load result (coils simulated full ON)
    7238         5061 :                     CalcFurnaceOutput(state,
    7239              :                                       FurnaceNum,
    7240              :                                       FirstHVACIteration,
    7241              :                                       fanOp,
    7242              :                                       compressorOp,
    7243              :                                       PartLoadRatio,
    7244              :                                       0.0,
    7245              :                                       0.0,
    7246              :                                       0.0,
    7247              :                                       FullSensibleOutput,
    7248              :                                       FullLatentOutput,
    7249              :                                       OnOffAirFlowRatio,
    7250         5061 :                                       HXUnitOn);
    7251              :                 } else {
    7252            0 :                     FullSensibleOutput = NoCoolOutput - 0.00000001;
    7253              :                 }
    7254              : 
    7255              :                 //     The next step is to compare the results of the full load and no load results
    7256              :                 //     1) Since we are cooling, we expect FullSensibleOutput < NoCoolOutput
    7257              :                 //        Check that this is the case; if not set PartLoadRatio = 0.0 (off)
    7258              :                 //     2) Verify that the load to be met is within the range of available output
    7259              :                 //        (i.e. between FullSensibleOutput and NoCoolOutput)
    7260              :                 //     3) Set PLR if load is out of range or RegulaFalsi on PLR if system can meet the load
    7261         5061 :                 if (FullSensibleOutput < NoCoolOutput) {
    7262         5061 :                     if (CoolCoilLoad != 0.0 || state.dataFurnaces->HPDehumidificationLoadFlag) {
    7263              : 
    7264              :                         // check bounds on sensible output prior to iteration using RegulaFalsi
    7265              :                         // Negative value represents cooling load, IF FullSensibleOutput .GT. CoolCoilLoad, load is greater than capacity
    7266         5061 :                         if (FullSensibleOutput >= CoolCoilLoad) {
    7267            0 :                             PartLoadRatio = 1.0;
    7268              :                             //           Likewise IF NoCoolOutput .LT. CoolCoilLoad, then load can be met using only the fan (constant fan mode only)
    7269         5061 :                         } else if (NoCoolOutput <= CoolCoilLoad) {
    7270            0 :                             PartLoadRatio = 0.0;
    7271              :                             //           ELSE load is between NoCoolOutput and FullSensibleOuput, find PLR required to meet load
    7272              :                         } else {
    7273              : 
    7274              :                             // Calculate the sensible part load ratio through iteration
    7275         5061 :                             CoolErrorToler = thisFurnace.CoolingConvergenceTolerance; // Error tolerance for convergence from input deck
    7276         5061 :                             int SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
    7277         5061 :                             Real64 par8_HXFlag = HXUnitOn ? 1.0 : 0.0;
    7278              :                             // CoolErrorToler is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
    7279              :                             auto f =
    7280        25305 :                                 [&state, FurnaceNum, FirstHVACIteration, fanOp, compressorOp, CoolCoilLoad, par8_HXFlag](Real64 const PartLoadRatio) {
    7281        20244 :                                     return CalcFurnaceResidual(state,
    7282              :                                                                PartLoadRatio,
    7283              :                                                                FurnaceNum,
    7284              :                                                                FirstHVACIteration,
    7285              :                                                                fanOp,
    7286              :                                                                compressorOp,
    7287              :                                                                CoolCoilLoad,
    7288              :                                                                1.0,         // par6_loadFlag,
    7289              :                                                                1.0,         // par7_sensLatentFlag,
    7290              :                                                                par8_HXFlag, // par9_HXOnFlag,
    7291        20244 :                                                                0.0);        // par10_HeatingCoilPLR);
    7292         5061 :                                 };
    7293         5061 :                             General::SolveRoot(state, CoolErrorToler, MaxIter, SolFlag, PartLoadRatio, f, 0.0, 1.0);
    7294              :                             //             OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
    7295         5061 :                             OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
    7296         5061 :                             if (SolFlag < 0) {
    7297            0 :                                 if (SolFlag == -1) {
    7298            0 :                                     CalcFurnaceOutput(state,
    7299              :                                                       FurnaceNum,
    7300              :                                                       FirstHVACIteration,
    7301              :                                                       fanOp,
    7302              :                                                       compressorOp,
    7303              :                                                       PartLoadRatio,
    7304              :                                                       0.0,
    7305              :                                                       0.0,
    7306              :                                                       0.0,
    7307              :                                                       TempCoolOutput,
    7308              :                                                       TempLatentOutput,
    7309              :                                                       OnOffAirFlowRatio,
    7310            0 :                                                       HXUnitOn);
    7311            0 :                                     if (!state.dataGlobal->WarmupFlag) {
    7312            0 :                                         if (std::abs(CoolCoilLoad - TempCoolOutput) > HVAC::SmallLoad) {
    7313            0 :                                             if (thisFurnace.SensibleMaxIterIndex == 0) {
    7314            0 :                                                 ShowWarningMessage(state,
    7315            0 :                                                                    format("Cooling coil control failed to converge for {}:{}",
    7316            0 :                                                                           HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7317            0 :                                                                           thisFurnace.Name));
    7318            0 :                                                 ShowContinueError(
    7319              :                                                     state, "  Iteration limit exceeded in calculating DX cooling coil sensible part-load ratio.");
    7320            0 :                                                 ShowContinueErrorTimeStamp(state,
    7321            0 :                                                                            format("Sensible load to be met by DX coil = {:.2T} (watts), sensible "
    7322              :                                                                                   "output of DX coil = {:.2T} (watts), and the simulation continues.",
    7323              :                                                                                   CoolCoilLoad,
    7324              :                                                                                   TempCoolOutput));
    7325              :                                             }
    7326            0 :                                             ShowRecurringWarningErrorAtEnd(
    7327              :                                                 state,
    7328            0 :                                                 format("{} \"{}\" - Iteration limit exceeded in calculating sensible cooling "
    7329              :                                                        "part-load ratio error continues. Sensible load statistics:",
    7330            0 :                                                        HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7331            0 :                                                        thisFurnace.Name),
    7332            0 :                                                 thisFurnace.SensibleMaxIterIndex,
    7333              :                                                 CoolCoilLoad,
    7334              :                                                 CoolCoilLoad);
    7335              :                                         }
    7336              :                                     }
    7337            0 :                                 } else if (SolFlag == -2) {
    7338            0 :                                     if (!state.dataGlobal->WarmupFlag) {
    7339            0 :                                         if (thisFurnace.SensibleRegulaFalsiFailedIndex == 0) {
    7340            0 :                                             ShowWarningMessage(state,
    7341            0 :                                                                format("Cooling coil control failed for {}:{}",
    7342            0 :                                                                       HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7343            0 :                                                                       thisFurnace.Name));
    7344            0 :                                             ShowContinueError(state, "  Cooling sensible part-load ratio determined to be outside the range of 0-1.");
    7345            0 :                                             ShowContinueErrorTimeStamp(state, format("  Cooling sensible load = {:.2T}", CoolCoilLoad));
    7346              :                                         }
    7347            0 :                                         ShowRecurringWarningErrorAtEnd(
    7348              :                                             state,
    7349            0 :                                             format("{} \"{}\" - Cooling sensible part-load ratio out of range error continues. Sensible cooling load "
    7350              :                                                    "statistics:",
    7351            0 :                                                    HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7352            0 :                                                    thisFurnace.Name),
    7353            0 :                                             thisFurnace.SensibleRegulaFalsiFailedIndex,
    7354              :                                             CoolCoilLoad,
    7355              :                                             CoolCoilLoad);
    7356              :                                     }
    7357              :                                 }
    7358              :                             }
    7359              :                         }
    7360              : 
    7361              :                     } else {
    7362            0 :                         PartLoadRatio = 0.0;
    7363              :                     } // EndIf for IF(CoolCoilLoad.NE.0.0)
    7364              : 
    7365              :                     //       Calculate the delivered capacity from the PLR calculated above
    7366         5061 :                     CalcFurnaceOutput(state,
    7367              :                                       FurnaceNum,
    7368              :                                       FirstHVACIteration,
    7369              :                                       fanOp,
    7370              :                                       compressorOp,
    7371              :                                       PartLoadRatio,
    7372              :                                       thisFurnace.HeatPartLoadRatio,
    7373              :                                       0.0,
    7374              :                                       0.0,
    7375              :                                       TempCoolOutput,
    7376              :                                       TempLatentOutput,
    7377              :                                       OnOffAirFlowRatio,
    7378         5061 :                                       HXUnitOn);
    7379              : 
    7380              :                     //       Calculate the latent part load ratio through iteration
    7381              :                     //       Negative SystemMoistureLoad means dehumidification load is present
    7382              :                     //       IF this furnace uses MultiMode control AND there is a moisture load AND the moisture load met by the furnace in
    7383              :                     //       cooling only mode above is sufficient to meet the moisture demand OR there is no sensible load (PLR=0 from above)
    7384              :                     //       then set LatentPartLoadRatio to 0 (no additional dehumidification is required).
    7385         5061 :                     if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::Multimode &&
    7386            0 :                         ((SystemMoistureLoad < 0.0 && TempLatentOutput < SystemMoistureLoad) || PartLoadRatio == 0.0)) {
    7387            0 :                         LatentPartLoadRatio = 0.0;
    7388              :                         //       ELSE calculate a new PLR for valid dehumidification control types if a moisture load exists.
    7389         5061 :                     } else if (thisFurnace.DehumidControlType_Num != DehumidificationControlMode::None &&
    7390            0 :                                (SystemMoistureLoad < 0.0 || (SystemMoistureLoad >= 0.0 && TempLatentOutput > SystemMoistureLoad &&
    7391            0 :                                                              !state.dataZoneEnergyDemand->Setback(thisFurnace.ControlZoneNum)))) {
    7392              : 
    7393              :                         //         IF the furnace uses dehumidification control MultiMode, turn on the HX and calculate the latent output with
    7394              :                         //         the HX ON to compare to the moisture load predicted by the humidistat.
    7395            0 :                         if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::Multimode) {
    7396            0 :                             HXUnitOn = true;
    7397            0 :                             state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    7398              :                             // Set fan part-load fraction equal to 1 while getting full load result
    7399            0 :                             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    7400            0 :                             OnOffAirFlowRatio = 1.0;
    7401              :                             // Get full load result
    7402            0 :                             CalcFurnaceOutput(state,
    7403              :                                               FurnaceNum,
    7404              :                                               FirstHVACIteration,
    7405              :                                               fanOp,
    7406              :                                               compressorOp,
    7407              :                                               1.0,
    7408              :                                               0.0,
    7409              :                                               0.0,
    7410              :                                               0.0,
    7411              :                                               TempCoolOutput,
    7412              :                                               TempLatentOutput,
    7413              :                                               OnOffAirFlowRatio,
    7414            0 :                                               HXUnitOn);
    7415              :                         }
    7416              : 
    7417              :                         //         Set the global cooling to heating PLR ratio. CoolHeatPLRRat = MIN(1,CoolingPLR/HeatingPLR)
    7418            0 :                         state.dataFurnaces->CoolHeatPLRRat = 1.0; // means cooling dominated operation (applies to cycling fan mode)
    7419              : 
    7420            0 :                         if (TempLatentOutput > SystemMoistureLoad) {
    7421              :                             //           Set full mass flow rate for full load calculation
    7422            0 :                             state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    7423              : 
    7424              :                             // Set fan part-load fraction equal to 1 while getting full load result
    7425            0 :                             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    7426            0 :                             OnOffAirFlowRatio = 1.0;
    7427            0 :                             thisFurnace.CompPartLoadRatio = 1.0; // compressor ON
    7428              : 
    7429              :                             // Get full load result (coils simulated full ON)
    7430            0 :                             CalcFurnaceOutput(state,
    7431              :                                               FurnaceNum,
    7432              :                                               FirstHVACIteration,
    7433              :                                               fanOp,
    7434              :                                               compressorOp,
    7435              :                                               1.0,
    7436              :                                               0.0,
    7437              :                                               0.0,
    7438              :                                               0.0,
    7439              :                                               TempCoolOutput,
    7440              :                                               TempLatentOutput,
    7441              :                                               OnOffAirFlowRatio,
    7442            0 :                                               HXUnitOn);
    7443              :                         }
    7444              : 
    7445              :                         // check bounds on latent output prior to iteration using RegulaFalsi
    7446            0 :                         if (TempLatentOutput > SystemMoistureLoad ||
    7447            0 :                             (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::Multimode && TempCoolOutput > CoolCoilLoad)) {
    7448            0 :                             LatentPartLoadRatio = 1.0;
    7449            0 :                         } else if (NoLatentOutput < SystemMoistureLoad || HeatingLatentOutput < SystemMoistureLoad) {
    7450            0 :                             LatentPartLoadRatio = 0.0;
    7451              :                         } else {
    7452              : 
    7453            0 :                             CoolErrorToler = thisFurnace.CoolingConvergenceTolerance; // Error tolerance for convergence
    7454              : 
    7455            0 :                             int SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
    7456              :                             // Multimode always controls to meet the SENSIBLE load (however, HXUnitOn is now TRUE)
    7457              :                             Real64 par4_load;
    7458            0 :                             if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::Multimode) {
    7459            0 :                                 par4_load = CoolCoilLoad;
    7460              :                             } else {
    7461            0 :                                 par4_load = SystemMoistureLoad;
    7462              :                             }
    7463              :                             // Multimode always controls to meet the SENSIBLE load (however, HXUnitOn is now TRUE)
    7464              :                             Real64 par6_LatentSens;
    7465            0 :                             if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::Multimode) {
    7466            0 :                                 par6_LatentSens = 1.0;
    7467              :                             } else {
    7468            0 :                                 par6_LatentSens = 0.0;
    7469              :                             }
    7470            0 :                             Real64 par8_HXUnit = HXUnitOn ? 1.0 : 0.0;
    7471              :                             Real64 par9_HtgCoilPLR;
    7472            0 :                             if (fanOp == HVAC::FanOp::Cycling && thisFurnace.HeatPartLoadRatio > 0.0 && par6_LatentSens == 0.0) {
    7473            0 :                                 par9_HtgCoilPLR = thisFurnace.HeatPartLoadRatio;
    7474              :                             } else {
    7475            0 :                                 par9_HtgCoilPLR = 0.0;
    7476              :                             }
    7477            0 :                             auto f = [&state,
    7478              :                                       FurnaceNum,
    7479              :                                       FirstHVACIteration,
    7480              :                                       fanOp,
    7481              :                                       compressorOp,
    7482              :                                       par4_load,
    7483              :                                       par6_LatentSens,
    7484              :                                       par8_HXUnit,
    7485              :                                       par9_HtgCoilPLR](Real64 const PartLoadRatio) {
    7486            0 :                                 return CalcFurnaceResidual(state,
    7487              :                                                            PartLoadRatio,
    7488              :                                                            FurnaceNum,
    7489              :                                                            FirstHVACIteration,
    7490              :                                                            fanOp,
    7491              :                                                            compressorOp,
    7492              :                                                            par4_load,
    7493              :                                                            1.0,              // par6_loadFlag,
    7494              :                                                            par6_LatentSens,  // par7_sensLatentFlag,
    7495              :                                                            par8_HXUnit,      // par9_HXOnFlag,
    7496            0 :                                                            par9_HtgCoilPLR); // par10_HeatingCoilPLR);
    7497            0 :                             };
    7498              :                             //           CoolErrorToler is in fraction of load, MaxIter = 30, SolFalg = # of iterations or error as appropriate
    7499            0 :                             General::SolveRoot(state, CoolErrorToler, MaxIter, SolFlag, LatentPartLoadRatio, f, 0.0, 1.0);
    7500              :                             //           OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
    7501            0 :                             OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
    7502            0 :                             if (SolFlag == -1) {
    7503              :                                 //             RegulaFalsi may not find latent PLR when the latent degradation model is used.
    7504              :                                 //             If iteration limit is exceeded, find tighter boundary of solution and repeat RegulaFalsi
    7505            0 :                                 TempMaxPLR = -0.1;
    7506            0 :                                 TempLatentOutput = NoLatentOutput;
    7507            0 :                                 while ((TempLatentOutput - SystemMoistureLoad) > 0.0 && TempMaxPLR < 1.0) {
    7508              :                                     //               find upper limit of LatentPLR
    7509            0 :                                     TempMaxPLR += 0.1;
    7510              : 
    7511              :                                     //               Same calculation as is done in Function CalcFurnaceResidual for latent PLR calculation.
    7512              :                                     //               Set cooling to heating PLR for use with Subroutine CalcFurnaceOutput. IF Par(10) = 0,
    7513              :                                     //               heating PLR = 0 so set the CoolingHeatingPLRRatio to 1 so the cooling PLR is used in the
    7514              :                                     //               DX cooling coil calculations.
    7515            0 :                                     if (par9_HtgCoilPLR > 0.0) {
    7516              :                                         //                 Par(10) = Furnace(FurnaceNum)%HeatPartLoadRatio
    7517              :                                         //                 fanOp = CycFan and Furnace(FurnaceNum)%HeatPartLoadRatio must be > 0 for Part(10) to be
    7518              :                                         //                 greater than 0
    7519            0 :                                         CoolingHeatingPLRRatio = min(1.0, TempMaxPLR / thisFurnace.HeatPartLoadRatio);
    7520              :                                     } else {
    7521            0 :                                         CoolingHeatingPLRRatio = 1.0;
    7522              :                                     }
    7523              : 
    7524            0 :                                     CalcFurnaceOutput(state,
    7525              :                                                       FurnaceNum,
    7526              :                                                       FirstHVACIteration,
    7527              :                                                       fanOp,
    7528              :                                                       compressorOp,
    7529              :                                                       TempMaxPLR,
    7530              :                                                       0.0,
    7531              :                                                       0.0,
    7532              :                                                       0.0,
    7533              :                                                       TempCoolOutput,
    7534              :                                                       TempLatentOutput,
    7535              :                                                       OnOffAirFlowRatio,
    7536            0 :                                                       HXUnitOn,
    7537              :                                                       CoolingHeatingPLRRatio);
    7538              :                                 }
    7539            0 :                                 TempMinPLR = TempMaxPLR;
    7540            0 :                                 while ((TempLatentOutput - SystemMoistureLoad) < 0.0 && TempMinPLR > 0.0) {
    7541              :                                     //               pull upper limit of LatentPLR down to last valid limit (i.e. latent output still exceeds
    7542              :                                     //               SystemMoisuterLoad) CR7558 - relax final limits to allow HX assisted coils to converge
    7543            0 :                                     TempMaxPLR = TempMinPLR + 0.001;
    7544              :                                     //               find minimum limit of Latent PLR
    7545            0 :                                     TempMinPLR -= 0.001;
    7546              : 
    7547              :                                     //               Set cooling to heating PLR for use with Subroutine CalcFurnaceOutput.
    7548            0 :                                     if (par9_HtgCoilPLR > 0.0) {
    7549              :                                         //                 Par(10) = Furnace(FurnaceNum)%HeatPartLoadRatio
    7550              :                                         //                 fanOp = CycFan and Furnace(FurnaceNum)%HeatPartLoadRatio must be > 0 for Part(10) to be
    7551              :                                         //                 greater than 0 Since the latent output of cycling fan systems is 0 at PLR=0, do not allow
    7552              :                                         //                 the PLR to be 0, otherwise RegulaFalsi can fail when a heating and moisture load exists and
    7553              :                                         //                 heating PLR > latent PLR.
    7554            0 :                                         TempMinPLR2 = max(0.0000000001, TempMinPLR);
    7555            0 :                                         CoolingHeatingPLRRatio = min(1.0, TempMinPLR2 / thisFurnace.HeatPartLoadRatio);
    7556              :                                     } else {
    7557            0 :                                         TempMinPLR2 = TempMinPLR;
    7558            0 :                                         CoolingHeatingPLRRatio = 1.0;
    7559              :                                     }
    7560              : 
    7561            0 :                                     CalcFurnaceOutput(state,
    7562              :                                                       FurnaceNum,
    7563              :                                                       FirstHVACIteration,
    7564              :                                                       fanOp,
    7565              :                                                       compressorOp,
    7566              :                                                       TempMinPLR2,
    7567              :                                                       0.0,
    7568              :                                                       0.0,
    7569              :                                                       0.0,
    7570              :                                                       TempCoolOutput,
    7571              :                                                       TempLatentOutput,
    7572              :                                                       OnOffAirFlowRatio,
    7573            0 :                                                       HXUnitOn,
    7574              :                                                       CoolingHeatingPLRRatio);
    7575              :                                 }
    7576              :                                 //             tighter boundary of solution has been found, call RegulaFalsi a second time
    7577            0 :                                 auto f2 = [&state,
    7578              :                                            FurnaceNum,
    7579              :                                            FirstHVACIteration,
    7580              :                                            fanOp,
    7581              :                                            compressorOp,
    7582              :                                            par4_load,
    7583              :                                            par6_LatentSens,
    7584              :                                            par8_HXUnit,
    7585              :                                            par9_HtgCoilPLR](Real64 const PartLoadRatio) {
    7586            0 :                                     return CalcFurnaceResidual(state,
    7587              :                                                                PartLoadRatio,
    7588              :                                                                FurnaceNum,
    7589              :                                                                FirstHVACIteration,
    7590              :                                                                fanOp,
    7591              :                                                                compressorOp,
    7592              :                                                                par4_load,
    7593              :                                                                1.0,              // par6_loadFlag,
    7594              :                                                                par6_LatentSens,  // par7_sensLatentFlag,
    7595              :                                                                par8_HXUnit,      // par9_HXOnFlag,
    7596            0 :                                                                par9_HtgCoilPLR); // par10_HeatingCoilPLR);
    7597            0 :                                 };
    7598            0 :                                 General::SolveRoot(state, CoolErrorToler, MaxIter, SolFlag, LatentPartLoadRatio, f2, TempMinPLR2, TempMaxPLR);
    7599              :                                 //             OnOffAirFlowRatio is updated during the above iteration. Reset to correct value based on PLR.
    7600            0 :                                 OnOffAirFlowRatio = state.dataFurnaces->OnOffAirFlowRatioSave;
    7601            0 :                                 if (SolFlag == -1) {
    7602              : 
    7603              :                                     //               Set cooling to heating PLR for use with Subroutine CalcFurnaceOutput.
    7604            0 :                                     if (par9_HtgCoilPLR > 0.0) {
    7605              :                                         //                 Par(10) = Furnace(FurnaceNum)%HeatPartLoadRatio
    7606              :                                         //                 fanOp = CycFan and Furnace(FurnaceNum)%HeatPartLoadRatio must be > 0 for Part(10) to be
    7607              :                                         //                 greater than 0
    7608            0 :                                         CoolingHeatingPLRRatio = min(1.0, LatentPartLoadRatio / thisFurnace.HeatPartLoadRatio);
    7609              :                                     } else {
    7610            0 :                                         CoolingHeatingPLRRatio = 1.0;
    7611              :                                     }
    7612              : 
    7613            0 :                                     CalcFurnaceOutput(state,
    7614              :                                                       FurnaceNum,
    7615              :                                                       FirstHVACIteration,
    7616              :                                                       fanOp,
    7617              :                                                       compressorOp,
    7618              :                                                       LatentPartLoadRatio,
    7619              :                                                       0.0,
    7620              :                                                       0.0,
    7621              :                                                       0.0,
    7622              :                                                       TempCoolOutput,
    7623              :                                                       TempLatentOutput,
    7624              :                                                       OnOffAirFlowRatio,
    7625            0 :                                                       HXUnitOn,
    7626              :                                                       CoolingHeatingPLRRatio);
    7627            0 :                                     if (std::abs((SystemMoistureLoad - TempLatentOutput) / SystemMoistureLoad) > CoolErrorToler &&
    7628            0 :                                         std::abs(SystemMoistureLoad - TempLatentOutput) > 10.0) {
    7629            0 :                                         if (!state.dataGlobal->WarmupFlag) {
    7630            0 :                                             if (thisFurnace.LatentMaxIterIndex == 0) {
    7631            0 :                                                 ShowWarningMessage(state,
    7632            0 :                                                                    format("Cooling coil control failed to converge for {}:{}",
    7633            0 :                                                                           HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7634            0 :                                                                           thisFurnace.Name));
    7635            0 :                                                 ShowContinueError(state,
    7636              :                                                                   "  Iteration limit exceeded in calculating cooling coil latent part-load ratio.");
    7637            0 :                                                 ShowContinueError(
    7638              :                                                     state,
    7639            0 :                                                     format("  Latent load convergence error (percent) = {:.2T}",
    7640            0 :                                                            100.0 * std::abs((SystemMoistureLoad - TempLatentOutput) / SystemMoistureLoad)));
    7641            0 :                                                 ShowContinueErrorTimeStamp(state,
    7642            0 :                                                                            format("Moisture load to be met by DX coil = {:.2T} (watts), Latent "
    7643              :                                                                                   "output of DX coil = {:.2T} (watts), and the simulation continues.",
    7644              :                                                                                   SystemMoistureLoad,
    7645              :                                                                                   TempLatentOutput));
    7646              :                                             }
    7647            0 :                                             ShowRecurringWarningErrorAtEnd(
    7648              :                                                 state,
    7649            0 :                                                 format("{} \"{}\" - Iteration limit exceeded in calculating latent part-load ratio error continues. "
    7650              :                                                        "Latent "
    7651              :                                                        "load convergence error (percent) statistics follow.",
    7652            0 :                                                        HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7653            0 :                                                        thisFurnace.Name),
    7654            0 :                                                 thisFurnace.LatentMaxIterIndex,
    7655            0 :                                                 100.0 * std::abs((SystemMoistureLoad - TempLatentOutput) / SystemMoistureLoad),
    7656            0 :                                                 100.0 * std::abs((SystemMoistureLoad - TempLatentOutput) / SystemMoistureLoad));
    7657              :                                         }
    7658              :                                     }
    7659            0 :                                 } else if (SolFlag == -2) {
    7660            0 :                                     if (thisFurnace.LatentRegulaFalsiFailedIndex2 == 0) {
    7661            0 :                                         ShowWarningMessage(state,
    7662            0 :                                                            format("Cooling coil control failed for {}:{}",
    7663            0 :                                                                   HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7664            0 :                                                                   thisFurnace.Name));
    7665            0 :                                         ShowContinueError(state,
    7666            0 :                                                           format("  Latent part-load ratio determined to be outside the range of {:.3T} to {:.3T}.",
    7667              :                                                                  TempMinPLR,
    7668              :                                                                  TempMaxPLR));
    7669            0 :                                         ShowContinueErrorTimeStamp(state,
    7670            0 :                                                                    format("A PLR of {:.3T} will be used and the simulation continues.", TempMinPLR));
    7671              :                                     }
    7672            0 :                                     ShowRecurringWarningErrorAtEnd(state,
    7673            0 :                                                                    format("{} \"{}\" - Cooling sensible part-load ratio out of range error "
    7674              :                                                                           "continues. System moisture load statistics:",
    7675            0 :                                                                           HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7676            0 :                                                                           thisFurnace.Name),
    7677            0 :                                                                    thisFurnace.LatentRegulaFalsiFailedIndex2,
    7678              :                                                                    SystemMoistureLoad,
    7679              :                                                                    SystemMoistureLoad);
    7680            0 :                                     LatentPartLoadRatio = TempMinPLR;
    7681              :                                 }
    7682            0 :                             } else if (SolFlag == -2) {
    7683            0 :                                 if (thisFurnace.LatentRegulaFalsiFailedIndex == 0) {
    7684            0 :                                     ShowWarningMessage(state,
    7685            0 :                                                        format("Cooling coil control failed for {}:{}",
    7686            0 :                                                               HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7687            0 :                                                               thisFurnace.Name));
    7688            0 :                                     ShowContinueError(state, "  Latent part-load ratio determined to be outside the range of 0-1.");
    7689            0 :                                     ShowContinueErrorTimeStamp(state, "A PLR of 0 will be used and the simulation continues.");
    7690              :                                 }
    7691            0 :                                 ShowRecurringWarningErrorAtEnd(
    7692              :                                     state,
    7693            0 :                                     format("{} \"{}\" - Latent part-load ratio out of range or 0-1 error continues. System moisture load statistics:",
    7694            0 :                                            HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    7695            0 :                                            thisFurnace.Name),
    7696            0 :                                     thisFurnace.LatentRegulaFalsiFailedIndex,
    7697              :                                     SystemMoistureLoad,
    7698              :                                     SystemMoistureLoad);
    7699            0 :                                 LatentPartLoadRatio = 0.0;
    7700              :                             }
    7701              :                         }
    7702              : 
    7703              :                         //         Cooling to heating PLR ratio is now known as CoolHeatPLRRat (Module level global set in CalcFurnaceOutput
    7704              :                         //         This same variable is use in Subroutine SimFurnace for final calculations.
    7705              :                         //         Get the actual output in case reheat needs to be calculated (HumControl=TRUE [latent PLR > sensible PLR])
    7706            0 :                         CalcFurnaceOutput(state,
    7707              :                                           FurnaceNum,
    7708              :                                           FirstHVACIteration,
    7709              :                                           fanOp,
    7710              :                                           compressorOp,
    7711              :                                           LatentPartLoadRatio,
    7712              :                                           0.0,
    7713              :                                           0.0,
    7714              :                                           0.0,
    7715              :                                           ActualSensibleOutput,
    7716              :                                           ActualLatentOutput,
    7717              :                                           OnOffAirFlowRatio,
    7718            0 :                                           HXUnitOn,
    7719            0 :                                           state.dataFurnaces->CoolHeatPLRRat);
    7720              : 
    7721              :                     } else {
    7722         5061 :                         LatentPartLoadRatio = 0.0;
    7723              :                     } // ENDIF for valid dehumidification control types
    7724              : 
    7725              :                     //       IF a humidistat is used and there is a moisture load, check if the latent PLR is greater than the (sensible) PLR
    7726              :                     //        IF(LatentPartLoadRatio .GT. PartLoadRatio .and. SystemMoistureLoad .lt. 0.0 .and. Furnace(FurnaceNum)%Humidistat) THEN
    7727         5061 :                     if (LatentPartLoadRatio > PartLoadRatio && thisFurnace.Humidistat) {
    7728              :                         // For dehumidification mode CoolReheat, compare the Sensible and Latent PLR values, if latentPLR is greater
    7729              :                         // than PLR (sensible), then overcooling is required and reheat will be activated using the HumControl flag.
    7730            0 :                         if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat) {
    7731            0 :                             PartLoadRatio = LatentPartLoadRatio;
    7732            0 :                             HumControl = true;
    7733              :                         }
    7734              :                         // For dehumidification mode MultiMode, compare the Sensible and Latent PLR values, if latentPLR is
    7735              :                         // greater than PLR (sensible), then use the latent PLR to control the unit.
    7736              :                         // For MultiMode control, the latent PLR is found by enabling the HX and calculating a PLR required to meet the
    7737              :                         // sensible load. Overcooling is not required, and reheat will not be activated using the HumControl flag.
    7738            0 :                         if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::Multimode) {
    7739            0 :                             PartLoadRatio = LatentPartLoadRatio;
    7740              :                         }
    7741              :                     }
    7742              : 
    7743         5061 :                     thisFurnace.CoolPartLoadRatio = PartLoadRatio;
    7744         5061 :                     if (compressorOp == HVAC::CompressorOp::Off) {
    7745            0 :                         thisFurnace.CompPartLoadRatio = 0.0;
    7746              :                     } else {
    7747         5061 :                         thisFurnace.CompPartLoadRatio = PartLoadRatio;
    7748              :                     }
    7749              : 
    7750              :                 } else { // ELSE from IF(FullSensibleOutput.LT.NoCoolOutput)THEN above
    7751              :                     // CR8679 - Unitary Heat Cool control problem, will not run to meeting cooling load
    7752              :                     // underlying problem is that FullSensibleOutput is greater than 0 due to very high inlet temp, so the system should be on
    7753              :                     // NoCoolOutput was 0 since the defect file is a cycling fan system and the system was turned off
    7754              : 
    7755              :                     // if FullSensibleOutput > NoCoolOutput, it means the system cannot meet the load and will run full out
    7756              :                     // this same logic for WSHP does not seem to work (only the Unitary Heat Pump Compressor Part-Load Ratio report
    7757              :                     // variable was affected in the HeatPumpWaterToAirRHControl.idf file while other variables showed very small diffs).
    7758              :                     // The defect files meter.csv showed 2% diffs so this IF test is used to keep the results the same in that file.
    7759              :                     // Additional logic is used here to make sure the coil actually turned on, e.g., if DX coil PLR > 0 then set to 1,
    7760              :                     // otherwise 0 (to make sure coil is actually ON and not off due to schedule, OAT, or other reason).
    7761              :                     // The global variable DXCoilPartLoadRatio(DXCoilNum) is not yet used for the WSHP to make the same check.
    7762            0 :                     if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir) {
    7763            0 :                         thisFurnace.CoolPartLoadRatio = 0.0;
    7764            0 :                         thisFurnace.CompPartLoadRatio = 0.0;
    7765              :                     } else {
    7766            0 :                         if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
    7767              : 
    7768              :                             // VS coil issue here...
    7769            0 :                             if (state.dataDXCoils->DXCoilPartLoadRatio(thisFurnace.ActualDXCoilIndexForHXAssisted) > 0.0) {
    7770            0 :                                 thisFurnace.CoolPartLoadRatio = 1.0;
    7771            0 :                                 thisFurnace.CompPartLoadRatio = 1.0;
    7772              :                             } else {
    7773            0 :                                 thisFurnace.CoolPartLoadRatio = 0.0;
    7774            0 :                                 thisFurnace.CompPartLoadRatio = 0.0;
    7775              :                             }
    7776              :                         } else {
    7777            0 :                             if (state.dataDXCoils->DXCoilPartLoadRatio(thisFurnace.CoolingCoilIndex) > 0.0) {
    7778            0 :                                 thisFurnace.CoolPartLoadRatio = 1.0;
    7779            0 :                                 thisFurnace.CompPartLoadRatio = 1.0;
    7780              :                             } else {
    7781            0 :                                 thisFurnace.CoolPartLoadRatio = 0.0;
    7782            0 :                                 thisFurnace.CompPartLoadRatio = 0.0;
    7783              :                             }
    7784              :                         }
    7785              :                     }
    7786              :                 }
    7787              : 
    7788              :                 //     Calculate the reheat coil output
    7789         5061 :                 if (HumControl) { // HumControl = .TRUE. if a Humidistat is installed and dehumidification control type is CoolReheat
    7790            0 :                     if (thisFurnace.ZoneSequenceHeatingNum > 0) {
    7791            0 :                         QToHeatSetPt = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum)
    7792            0 :                                             .SequencedOutputRequiredToHeatingSP(thisFurnace.ZoneSequenceHeatingNum) /
    7793            0 :                                         thisFurnace.ControlZoneMassFlowFrac);
    7794              :                     } else {
    7795            0 :                         QToHeatSetPt = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum).OutputRequiredToHeatingSP /
    7796            0 :                                         thisFurnace.ControlZoneMassFlowFrac);
    7797              :                     }
    7798              :                     //       Cooling mode or floating condition and dehumidification is required
    7799            0 :                     if (QToHeatSetPt < 0.0) {
    7800              :                         //         Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
    7801              :                         //         the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
    7802            0 :                         ReheatCoilLoad = max(0.0, (QToHeatSetPt - ActualSensibleOutput));
    7803            0 :                         thisFurnace.DehumidInducedHeatingDemandRate = ReheatCoilLoad;
    7804              :                         //       Heating mode and dehumidification is required
    7805              :                     } else {
    7806              :                         //         Calculate the reheat coil load as the sensible capacity of the DX cooling coil only. Let
    7807              :                         //         the heating coil pick up the load due to outdoor air.
    7808            0 :                         ReheatCoilLoad = max(0.0, (ActualSensibleOutput - NoCoolOutput) * (-1.0));
    7809              :                         //         Dehumidification is not required
    7810            0 :                         if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    7811            0 :                             (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir &&
    7812            0 :                              thisFurnace.WatertoAirHPType == WAHPCoilType::Simple)) {
    7813            0 :                             ReheatCoilLoad = max(QToHeatSetPt, QToHeatSetPt - ActualSensibleOutput);
    7814              :                         }
    7815            0 :                         thisFurnace.DehumidInducedHeatingDemandRate = max(0.0, ActualSensibleOutput * (-1.0));
    7816              :                     }
    7817              :                 } else {
    7818              :                     //       No humidistat installed
    7819         5061 :                     ReheatCoilLoad = 0.0;
    7820              :                 }
    7821              :             } // End of cooling section IF statement
    7822              : 
    7823        10378 :             if (NoHeatOutput > SystemSensibleLoad && ReheatCoilLoad > 0.0) {
    7824              :                 // Reduce reheat coil load if you are controlling high humidity but outside air
    7825              :                 // and/or the supply air fan is providing enough heat to meet the system sensible load.
    7826              :                 // This will bring the zone temp closer to the heating setpoint temp.
    7827            0 :                 ReheatCoilLoad = max(0.0, ReheatCoilLoad - (NoHeatOutput - SystemSensibleLoad));
    7828              :             }
    7829              : 
    7830              :             // Set the final air flow. MdotFurnace will be used to set the fan part-load ratio in ReportFurnace
    7831        10378 :             if (HumControl && SystemMoistureLoad < 0.0) {
    7832            0 :                 if (fanOp == HVAC::FanOp::Cycling) {
    7833              :                     //       set the flow rate at the maximum of the cooling and heating PLR's
    7834            0 :                     SetAverageAirFlow(state, FurnaceNum, max(thisFurnace.CoolPartLoadRatio, thisFurnace.HeatPartLoadRatio), OnOffAirFlowRatio);
    7835              :                 } else {
    7836              :                     //       ELSE set the flow rate at the cooling PLR
    7837            0 :                     SetAverageAirFlow(state, FurnaceNum, thisFurnace.CoolPartLoadRatio, OnOffAirFlowRatio);
    7838              :                 }
    7839              :             } else {
    7840        10378 :                 SetAverageAirFlow(state, FurnaceNum, max(thisFurnace.CoolPartLoadRatio, thisFurnace.HeatPartLoadRatio), OnOffAirFlowRatio);
    7841              :             }
    7842        10378 :             thisFurnace.MdotFurnace = state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate;
    7843              : 
    7844        10378 :             if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir ||
    7845            2 :                 (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir && thisFurnace.WatertoAirHPType == WAHPCoilType::Simple)) {
    7846              :             } else {
    7847              :                 // Non-HeatPump (non-DX) heating coils do not set PLR, reset to 0 here. This variable was set for non-DX
    7848              :                 // coils to allow the SetAverageAirFlow CALL above to set the correct air mass flow rate. See this
    7849              :                 // IF block above in heating section. HeatPLR is not set in the ELSE part of the IF (only HeatCoilLoad is set).
    7850            0 :                 thisFurnace.HeatPartLoadRatio = 0.0;
    7851              :             }
    7852              : 
    7853              :             //*********HVAC Scheduled OFF*************
    7854              :             // No heating or cooling or dehumidification
    7855              :             //!!LKL discrepancy with < 0?
    7856        10378 :             if (thisFurnace.availSched->getCurrentVal() == 0.0 || state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate == 0.0) {
    7857           57 :                 thisFurnace.MdotFurnace = 0.0;
    7858           57 :                 CoolCoilLoad = 0.0;
    7859           57 :                 HeatCoilLoad = 0.0;
    7860           57 :                 ReheatCoilLoad = 0.0;
    7861           57 :                 state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // System off, so set on/off fan part-load fraction = 1
    7862           57 :                 thisFurnace.CoolPartLoadRatio = 0.0;
    7863           57 :                 thisFurnace.HeatPartLoadRatio = 0.0;
    7864           57 :                 thisFurnace.CompPartLoadRatio = 0.0;
    7865              :                 // set report variables
    7866           57 :                 thisFurnace.CoolingCoilSensDemand = 0.0;
    7867           57 :                 thisFurnace.CoolingCoilLatentDemand = 0.0;
    7868           57 :                 thisFurnace.HeatingCoilSensDemand = 0.0;
    7869              :             }
    7870              : 
    7871              :         } // End of the FirstHVACIteration control of the mass flow If block
    7872              : 
    7873              :         // Set the fan inlet node flow rates
    7874        15225 :         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = thisFurnace.MdotFurnace;
    7875        15225 :         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    7876        15225 :     }
    7877              : 
    7878            0 :     void CalcWaterToAirHeatPump(EnergyPlusData &state,
    7879              :                                 int const FurnaceNum,                  // index to Furnace
    7880              :                                 bool const FirstHVACIteration,         // TRUE on first HVAC iteration
    7881              :                                 HVAC::CompressorOp const compressorOp, // compressor operation flag (1=On, 0=Off)
    7882              :                                 Real64 const ZoneLoad,                 // the control zone load (watts)
    7883              :                                 Real64 const MoistureLoad              // the control zone latent load (watts)
    7884              :     )
    7885              :     {
    7886              : 
    7887              :         // SUBROUTINE INFORMATION:
    7888              :         //       AUTHOR         Dan Fisher
    7889              :         //       DATE WRITTEN   Feb 2004
    7890              :         //       MODIFIED       R. Raustad (Oct 2006) Revised iteration technique
    7891              : 
    7892              :         // PURPOSE OF THIS SUBROUTINE:
    7893              :         // This subroutine manages the heat pump simulation
    7894              : 
    7895              :         // METHODOLOGY EMPLOYED:
    7896              :         // Calculate the part-load ratio required to meet the zone sensible load.
    7897              : 
    7898              :         // SUBROUTINE PARAMETER DEFINITIONS:
    7899            0 :         int constexpr MaxIter(600);   // maximum number of iterations
    7900            0 :         Real64 constexpr MinPLR(0.0); // minimum part load ratio allowed
    7901              : 
    7902              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    7903              :         Real64 ZoneSensLoadMet;             // Actual zone sensible load met by heat pump (W)
    7904              :         Real64 ZoneLatLoadMet;              // Actual zone latent load met by heat pump (W)
    7905              :         Real64 ZoneSensLoadMetFanONCompON;  // Max Zone sensible load heat pump can meet (W)
    7906              :         Real64 ZoneLatLoadMetFanONCompON;   // Max Zone latent load heat pump can meet (W)
    7907              :         Real64 ZoneSensLoadMetFanONCompOFF; // control zone sensible load met using only outside air
    7908              :         // and fan heat (no coil output) (W)
    7909              :         Real64 ZoneLatLoadMetFanONCompOFF; // control zone Latent   load met using only outside air
    7910              :         // and fan heat (no coil output) (W)
    7911              :         Real64 HPCoilSensDemand;   // Heat pump sensible demand
    7912              :         Real64 HPCoilSensCapacity; // Heat pump sensible capacity
    7913              : 
    7914              :         Real64 SuppHeatCoilLoad; // Load passed to supplemental heater (W)
    7915              :         Real64 CoolErrorToler;   // convergence tolerance used in cooling mode
    7916              :         Real64 HeatErrorToler;   // convergence tolerance used in heating mode
    7917              :         int SolFlag;             // flag returned from iteration routine to denote problems
    7918              : 
    7919            0 :         Real64 &TotalZoneLatentLoad = state.dataFurnaces->TotalZoneLatentLoad;
    7920            0 :         Real64 &TotalZoneSensLoad = state.dataFurnaces->TotalZoneSensLoad;
    7921            0 :         Real64 &CoolPartLoadRatio = state.dataFurnaces->CoolPartLoadRatio;
    7922            0 :         Real64 &HeatPartLoadRatio = state.dataFurnaces->HeatPartLoadRatio;
    7923            0 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    7924              : 
    7925              :         // Set local variables
    7926            0 :         Real64 Dummy2 = 0.0;            // used as dummy heat and reheat coil load
    7927            0 :         Real64 OnOffAirFlowRatio = 1.0; // Ratio of compressor ON air mass flow to AVERAGE air mass flow over time step
    7928            0 :         int FurnaceInletNode = thisFurnace.FurnaceInletNodeNum;
    7929            0 :         HVAC::FanOp fanOp = thisFurnace.fanOp; // fan operating mode
    7930            0 :         thisFurnace.MdotFurnace = thisFurnace.DesignMassFlowRate;
    7931              : 
    7932              :         //*********INITIAL CALCULATIONS****************
    7933              :         // set the fan part load fraction
    7934              :         // Note: OnOffFanPartLoadFraction is passed to the
    7935              :         //       fan module by DataHVACGlobals.  It should be
    7936              :         //     set =1 for all cases except cycling fan/cycling
    7937              :         //     coil. For this case it is set to the part load
    7938              :         //     factor.  In SimOnOffFan, the part load ratio is
    7939              :         //     divided by the part load factor (OnOffFanPartLoadFraction)
    7940              :         //     in order to match the run time fraction of the cycling
    7941              :         //     fan with the run time fraction of the cycling compressor
    7942            0 :         if (FirstHVACIteration) {
    7943            0 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    7944              :         }
    7945              : 
    7946              :         // Calc Zone sensible loads for heating (+) and cooling (-)
    7947            0 :         TotalZoneSensLoad = ZoneLoad;
    7948              : 
    7949            0 :         if (state.dataFurnaces->HeatingLoad) {
    7950            0 :             TotalZoneLatentLoad = 0.0; // Set latent load for heating
    7951              :         } else {
    7952            0 :             TotalZoneLatentLoad = MoistureLoad; // Set latent load for cooling and no sensible load condition
    7953              :         }
    7954              : 
    7955              :         //*********COOLING CALCULATIONS****************
    7956              :         // IF scheduled on...
    7957              :         // AND air flow rate is greater than zero...
    7958              :         // AND the air system has a cooling load and is not set back or in the deadband...
    7959              :         // OR the system is controlled by a humidistat and there is a latent load
    7960            0 :         if ((thisFurnace.availSched->getCurrentVal() > 0.0 && state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate > 0.0) &&
    7961            0 :             ((state.dataFurnaces->CoolingLoad) || (thisFurnace.Humidistat && thisFurnace.CoolingCoilLatentDemand < 0.0))) {
    7962              : 
    7963              :             // Set the air flow rate to the design flow rate and set the fan operation fraction to 1 (continuous operation)
    7964            0 :             state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.DesignMassFlowRate;
    7965            0 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // see 'Note' under INITIAL CALCULATIONS
    7966              : 
    7967              :             //         !Set the operation flag to run the fan continuously
    7968              :             //         fanOp = FanOp::Continuous
    7969              : 
    7970              :             // Set the input parameters for CalcFurnaceOutput
    7971            0 :             thisFurnace.HeatingCoilSensDemand = 0.0;
    7972            0 :             thisFurnace.CoolingCoilLatentDemand = 0.0;
    7973            0 :             thisFurnace.CoolingCoilSensDemand = 0.0;
    7974            0 :             thisFurnace.CompPartLoadRatio = 0.0; // compressor off
    7975            0 :             thisFurnace.InitHeatPump = true;     // initialization call to Calc Furnace
    7976            0 :             CoolPartLoadRatio = 0.0;
    7977              : 
    7978              :             // Get no load result in order to calculate the effect of the fan and the mixed air equipment
    7979            0 :             CalcFurnaceOutput(state,
    7980              :                               FurnaceNum,
    7981              :                               FirstHVACIteration,
    7982              :                               fanOp,
    7983              :                               compressorOp,
    7984              :                               CoolPartLoadRatio,
    7985              :                               HeatPartLoadRatio,
    7986              :                               Dummy2,
    7987              :                               Dummy2,
    7988              :                               ZoneSensLoadMetFanONCompOFF,
    7989              :                               ZoneLatLoadMetFanONCompOFF,
    7990              :                               OnOffAirFlowRatio,
    7991              :                               false);
    7992              : 
    7993              :             // Set the input parameters for CalcFurnaceOutput
    7994            0 :             thisFurnace.CoolingCoilSensDemand = 1.0;
    7995            0 :             thisFurnace.CompPartLoadRatio = 1.0; // compressor ON
    7996            0 :             CoolPartLoadRatio = 1.0;
    7997              : 
    7998              :             // Get full load result in order to estimate the operating part load ratio for continuous fan operation
    7999            0 :             CalcFurnaceOutput(state,
    8000              :                               FurnaceNum,
    8001              :                               FirstHVACIteration,
    8002              :                               fanOp,
    8003              :                               compressorOp,
    8004              :                               CoolPartLoadRatio,
    8005              :                               HeatPartLoadRatio,
    8006              :                               Dummy2,
    8007              :                               Dummy2,
    8008              :                               ZoneSensLoadMetFanONCompON,
    8009              :                               ZoneLatLoadMetFanONCompON,
    8010              :                               OnOffAirFlowRatio,
    8011              :                               false);
    8012              : 
    8013              :             // Calculate the heating coil demand for continuous fan operation as:
    8014              :             //    (the zone sensible load - the zone sensible load met by fan heat and mixed air)
    8015              :             // Note; The sensible zone load met by fan heat and mixed air is calculated as:
    8016              :             //     mdotsys(control zone inlet enthalpy - control zone outlet enthalpy)
    8017              :             // This accounts for the negative sign in the equation.
    8018            0 :             HPCoilSensDemand = TotalZoneSensLoad - ZoneSensLoadMetFanONCompOFF;
    8019              : 
    8020              :             // Calculate the heating coil capacity for continuous fan operation as:
    8021              :             //    (the zone sensible load met by fan heat and mixed air and coil
    8022              :             //   - the zone sensible load met by fan heat and mixed air)
    8023            0 :             HPCoilSensCapacity = ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF;
    8024              : 
    8025              :             // Calculate the part load ratio for continuous fan operation with cycling coil
    8026            0 :             if (HPCoilSensCapacity == 0.0) {
    8027            0 :                 CoolPartLoadRatio = 0.0;
    8028              :             } else {
    8029            0 :                 CoolPartLoadRatio = max(MinPLR, min(1.0, std::abs(HPCoilSensDemand) / std::abs(HPCoilSensCapacity)));
    8030              :             }
    8031              : 
    8032            0 :             thisFurnace.InitHeatPump = false;
    8033              : 
    8034              :             // check bounds on sensible output prior to iteration using RegulaFalsi
    8035            0 :             if (ZoneSensLoadMetFanONCompON > TotalZoneSensLoad) {
    8036            0 :                 CoolPartLoadRatio = 1.0;
    8037            0 :                 HPCoilSensDemand = std::abs(ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF);
    8038            0 :                 thisFurnace.CoolingCoilSensDemand = HPCoilSensDemand;
    8039            0 :             } else if (ZoneSensLoadMetFanONCompOFF < TotalZoneSensLoad) {
    8040            0 :                 CoolPartLoadRatio = 0.0;
    8041            0 :                 thisFurnace.CompPartLoadRatio = 0.0; // compressor OFF
    8042            0 :                 thisFurnace.CoolingCoilSensDemand = 0.0;
    8043            0 :                 CalcFurnaceOutput(state,
    8044              :                                   FurnaceNum,
    8045              :                                   FirstHVACIteration,
    8046              :                                   fanOp,
    8047              :                                   compressorOp,
    8048              :                                   CoolPartLoadRatio,
    8049              :                                   HeatPartLoadRatio,
    8050              :                                   Dummy2,
    8051              :                                   Dummy2,
    8052              :                                   ZoneSensLoadMetFanONCompOFF,
    8053              :                                   ZoneLatLoadMetFanONCompOFF,
    8054              :                                   OnOffAirFlowRatio,
    8055              :                                   false);
    8056              :             } else {
    8057              :                 //         Calculate the sensible part load ratio through iteration
    8058            0 :                 CoolErrorToler = thisFurnace.CoolingConvergenceTolerance;
    8059            0 :                 SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
    8060              :                 // CoolErrorToler is in fraction of load, MaxIter = 600, SolFalg = # of iterations or error as appropriate
    8061            0 :                 auto f = [&state, FurnaceNum, FirstHVACIteration, fanOp, compressorOp, TotalZoneSensLoad, ZoneSensLoadMetFanONCompOFF](
    8062              :                              Real64 const PartLoadRatio) {
    8063            0 :                     return CalcWaterToAirResidual(state,
    8064              :                                                   PartLoadRatio,
    8065              :                                                   FurnaceNum,
    8066              :                                                   FirstHVACIteration,
    8067              :                                                   fanOp,
    8068              :                                                   compressorOp,
    8069              :                                                   TotalZoneSensLoad,
    8070              :                                                   1.0,
    8071              :                                                   1.0,
    8072              :                                                   ZoneSensLoadMetFanONCompOFF,
    8073            0 :                                                   0.0);
    8074            0 :                 };
    8075            0 :                 General::SolveRoot(state, CoolErrorToler, MaxIter, SolFlag, CoolPartLoadRatio, f, 0.0, 1.0);
    8076            0 :                 if (SolFlag == -1 && !state.dataGlobal->WarmupFlag && !FirstHVACIteration) {
    8077            0 :                     state.dataHVACGlobal->OnOffFanPartLoadFraction = state.dataFurnaces->OnOffFanPartLoadFractionSave;
    8078            0 :                     CalcFurnaceOutput(state,
    8079              :                                       FurnaceNum,
    8080              :                                       FirstHVACIteration,
    8081              :                                       fanOp,
    8082              :                                       compressorOp,
    8083              :                                       CoolPartLoadRatio,
    8084              :                                       0.0,
    8085              :                                       0.0,
    8086              :                                       0.0,
    8087              :                                       ZoneSensLoadMet,
    8088              :                                       ZoneLatLoadMet,
    8089              :                                       OnOffAirFlowRatio,
    8090              :                                       false);
    8091            0 :                     if (std::abs(ZoneSensLoadMet - TotalZoneSensLoad) / TotalZoneSensLoad > CoolErrorToler) {
    8092            0 :                         if (thisFurnace.SensibleMaxIterIndex == 0) {
    8093            0 :                             ShowWarningMessage(state,
    8094            0 :                                                format("Cooling coil control failed to converge for {}:{}",
    8095            0 :                                                       HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    8096            0 :                                                       thisFurnace.Name));
    8097            0 :                             ShowContinueError(state, "  Iteration limit exceeded in calculating DX cooling coil sensible part-load ratio.");
    8098            0 :                             ShowContinueErrorTimeStamp(state,
    8099            0 :                                                        format("Sensible load to be met by DX coil = {:.2T} (watts), sensible output of DX coil = "
    8100              :                                                               "{:.2T} (watts), and the simulation continues.",
    8101              :                                                               TotalZoneSensLoad,
    8102              :                                                               ZoneSensLoadMet));
    8103              :                         }
    8104            0 :                         ShowRecurringWarningErrorAtEnd(
    8105              :                             state,
    8106            0 :                             format("{} \"{}\" - Iteration limit exceeded in calculating sensible cooling part-load ratio error "
    8107              :                                    "continues. Sensible load statistics:",
    8108            0 :                                    HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    8109            0 :                                    thisFurnace.Name),
    8110            0 :                             thisFurnace.SensibleMaxIterIndex,
    8111              :                             TotalZoneSensLoad,
    8112              :                             TotalZoneSensLoad);
    8113              :                     }
    8114            0 :                 } else if (SolFlag == -2 && !state.dataGlobal->WarmupFlag && !FirstHVACIteration) {
    8115            0 :                     CoolPartLoadRatio = max(MinPLR, min(1.0, std::abs(HPCoilSensDemand) / std::abs(HPCoilSensCapacity)));
    8116            0 :                     state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    8117            0 :                     CalcFurnaceOutput(state,
    8118              :                                       FurnaceNum,
    8119              :                                       FirstHVACIteration,
    8120              :                                       fanOp,
    8121              :                                       compressorOp,
    8122              :                                       CoolPartLoadRatio,
    8123              :                                       0.0,
    8124              :                                       0.0,
    8125              :                                       0.0,
    8126              :                                       ZoneSensLoadMet,
    8127              :                                       ZoneLatLoadMet,
    8128              :                                       OnOffAirFlowRatio,
    8129              :                                       false);
    8130            0 :                     if ((ZoneSensLoadMet - TotalZoneSensLoad) / TotalZoneSensLoad > CoolErrorToler) {
    8131            0 :                         if (thisFurnace.SensibleRegulaFalsiFailedIndex == 0) {
    8132            0 :                             ShowWarningMessage(
    8133              :                                 state,
    8134            0 :                                 format("Cooling coil control failed for {}:{}", HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name));
    8135            0 :                             ShowContinueError(state, "  Cooling sensible part-load ratio determined to be outside the range of 0-1.");
    8136            0 :                             ShowContinueError(
    8137              :                                 state,
    8138            0 :                                 format("  An estimated part-load ratio = {:.2T} will be used and the simulation continues.", CoolPartLoadRatio));
    8139            0 :                             ShowContinueError(
    8140            0 :                                 state, format("  The estimated part-load ratio provides a cooling sensible capacity = {:.2T}", ZoneSensLoadMet));
    8141            0 :                             ShowContinueErrorTimeStamp(state, format("  Cooling sensible load required = {:.2T}", TotalZoneSensLoad));
    8142              :                         }
    8143            0 :                         ShowRecurringWarningErrorAtEnd(
    8144              :                             state,
    8145            0 :                             format("{} \"{}\" - Cooling sensible part-load ratio out of range error continues. Sensible cooling load statistics:",
    8146            0 :                                    HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    8147            0 :                                    thisFurnace.Name),
    8148            0 :                             thisFurnace.SensibleRegulaFalsiFailedIndex,
    8149              :                             TotalZoneSensLoad,
    8150              :                             TotalZoneSensLoad);
    8151              :                     }
    8152              :                 }
    8153              :             }
    8154              : 
    8155            0 :             if (fanOp == HVAC::FanOp::Cycling) {
    8156            0 :                 thisFurnace.MdotFurnace *= CoolPartLoadRatio;
    8157              :             }
    8158              : 
    8159              :             //*********HEATING CALCULATIONS****************
    8160              :             // If Furnace runs with a heating load then set HeatCoilLoad on Heating Coil and the Mass Flow
    8161            0 :         } else if ((thisFurnace.availSched->getCurrentVal() > 0.0) && (state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate > 0.0) &&
    8162            0 :                    state.dataFurnaces->HeatingLoad) {
    8163              : 
    8164              :             // Set the air flow rate to the design flow rate and set the fan operation fraction to 1 (continuous operation)
    8165            0 :             state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.DesignMassFlowRate;
    8166            0 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // see 'Note' under INITIAL CALCULATIONS
    8167              : 
    8168              :             //         !Set the operation flag to run the fan continuously
    8169              :             //         fanOp = FanOp::Continuous
    8170              : 
    8171              :             // Set the input parameters for CalcFurnaceOutput
    8172            0 :             thisFurnace.HeatingCoilSensDemand = 0.0;
    8173            0 :             thisFurnace.CoolingCoilLatentDemand = 0.0;
    8174            0 :             thisFurnace.CoolingCoilSensDemand = 0.0;
    8175            0 :             thisFurnace.CompPartLoadRatio = 0.0; // compressor off
    8176            0 :             thisFurnace.InitHeatPump = true;     // initialization call to Calc Furnace
    8177            0 :             HeatPartLoadRatio = 0.0;
    8178              : 
    8179              :             // Get no load result in order to calculate the effect of the fan and the mixed air equipment
    8180            0 :             CalcFurnaceOutput(state,
    8181              :                               FurnaceNum,
    8182              :                               FirstHVACIteration,
    8183              :                               fanOp,
    8184              :                               compressorOp,
    8185              :                               CoolPartLoadRatio,
    8186              :                               HeatPartLoadRatio,
    8187              :                               Dummy2,
    8188              :                               Dummy2,
    8189              :                               ZoneSensLoadMetFanONCompOFF,
    8190              :                               ZoneLatLoadMetFanONCompOFF,
    8191              :                               OnOffAirFlowRatio,
    8192              :                               false);
    8193              : 
    8194              :             // Set the input parameters for CalcFurnaceOutput
    8195            0 :             thisFurnace.HeatingCoilSensDemand = 1.0;
    8196            0 :             thisFurnace.CompPartLoadRatio = 1.0; // compressor ON
    8197            0 :             HeatPartLoadRatio = 1.0;
    8198              : 
    8199              :             // Get full load result in order to estimate the operating part load ratio for continuous fan operation
    8200              : 
    8201            0 :             CalcFurnaceOutput(state,
    8202              :                               FurnaceNum,
    8203              :                               FirstHVACIteration,
    8204              :                               fanOp,
    8205              :                               compressorOp,
    8206              :                               CoolPartLoadRatio,
    8207              :                               HeatPartLoadRatio,
    8208              :                               Dummy2,
    8209              :                               Dummy2,
    8210              :                               ZoneSensLoadMetFanONCompON,
    8211              :                               ZoneLatLoadMetFanONCompON,
    8212              :                               OnOffAirFlowRatio,
    8213              :                               false);
    8214              : 
    8215              :             // Calculate the heating coil demand for continuous fan operation as:
    8216              :             //    (the zone sensible load - the zone sensible load met by fan heat and mixed air)
    8217              :             // Note; The sensible zone load met by fan heat and mixed air is calculated as:
    8218              :             //     mdotsys(control zone inlet enthalpy - control zone outlet enthalpy)
    8219              :             // This accounts for the negative sign in the equation.
    8220            0 :             HPCoilSensDemand = TotalZoneSensLoad - ZoneSensLoadMetFanONCompOFF;
    8221              : 
    8222              :             // Calculate the heating coil capacity for continuous fan operation as:
    8223              :             //    (the zone sensible load met by fan heat and mixed air and coil
    8224              :             //   - the zone sensible load met by fan heat and mixed air)
    8225            0 :             HPCoilSensCapacity = ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF;
    8226              : 
    8227              :             // Calculate the part load ratio for continuous fan operation with cycling coil
    8228            0 :             if (HPCoilSensCapacity == 0.0) {
    8229            0 :                 HeatPartLoadRatio = 0.0;
    8230              :             } else {
    8231            0 :                 HeatPartLoadRatio = max(MinPLR, min(1.0, std::abs(HPCoilSensDemand) / std::abs(HPCoilSensCapacity)));
    8232              :             }
    8233              : 
    8234            0 :             thisFurnace.InitHeatPump = false;
    8235              : 
    8236              :             // check bounds on sensible output prior to iteration using RegulaFalsi
    8237            0 :             if (ZoneSensLoadMetFanONCompON < TotalZoneSensLoad) {
    8238            0 :                 HeatPartLoadRatio = 1.0;
    8239            0 :                 ZoneSensLoadMet = ZoneSensLoadMetFanONCompON;
    8240            0 :                 HPCoilSensDemand = std::abs(ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF);
    8241            0 :                 thisFurnace.HeatingCoilSensDemand = HPCoilSensDemand;
    8242            0 :             } else if (ZoneSensLoadMetFanONCompOFF > TotalZoneSensLoad) {
    8243            0 :                 HeatPartLoadRatio = 0.0;
    8244            0 :                 ZoneSensLoadMet = ZoneSensLoadMetFanONCompOFF;
    8245            0 :                 thisFurnace.CompPartLoadRatio = 0.0; // compressor ON
    8246            0 :                 CalcFurnaceOutput(state,
    8247              :                                   FurnaceNum,
    8248              :                                   FirstHVACIteration,
    8249              :                                   fanOp,
    8250              :                                   compressorOp,
    8251              :                                   CoolPartLoadRatio,
    8252              :                                   HeatPartLoadRatio,
    8253              :                                   Dummy2,
    8254              :                                   Dummy2,
    8255              :                                   ZoneSensLoadMet,
    8256              :                                   ZoneLatLoadMet,
    8257              :                                   OnOffAirFlowRatio,
    8258              :                                   false);
    8259              :             } else {
    8260              :                 //         Calculate the sensible part load ratio through iteration
    8261            0 :                 HeatErrorToler = thisFurnace.HeatingConvergenceTolerance;
    8262            0 :                 SolFlag = 0; // # of iterations if positive, -1 means failed to converge, -2 means bounds are incorrect
    8263              :                 // HeatErrorToler is in fraction of load, MaxIter = 600, SolFalg = # of iterations or error as appropriate
    8264            0 :                 auto f = [&state, FurnaceNum, FirstHVACIteration, fanOp, compressorOp, TotalZoneSensLoad, ZoneSensLoadMetFanONCompOFF](
    8265              :                              Real64 const PartLoadRatio) {
    8266            0 :                     return CalcWaterToAirResidual(state,
    8267              :                                                   PartLoadRatio,
    8268              :                                                   FurnaceNum,
    8269              :                                                   FirstHVACIteration,
    8270              :                                                   fanOp,
    8271              :                                                   compressorOp,
    8272              :                                                   TotalZoneSensLoad,
    8273              :                                                   0.0,
    8274              :                                                   1.0,
    8275              :                                                   ZoneSensLoadMetFanONCompOFF,
    8276            0 :                                                   0.0);
    8277            0 :                 };
    8278            0 :                 General::SolveRoot(state, HeatErrorToler, MaxIter, SolFlag, HeatPartLoadRatio, f, 0.0, 1.0);
    8279            0 :                 state.dataHVACGlobal->OnOffFanPartLoadFraction = state.dataFurnaces->OnOffFanPartLoadFractionSave;
    8280            0 :                 CalcFurnaceOutput(state,
    8281              :                                   FurnaceNum,
    8282              :                                   FirstHVACIteration,
    8283              :                                   fanOp,
    8284              :                                   compressorOp,
    8285              :                                   CoolPartLoadRatio,
    8286              :                                   HeatPartLoadRatio,
    8287              :                                   Dummy2,
    8288              :                                   Dummy2,
    8289              :                                   ZoneSensLoadMet,
    8290              :                                   ZoneLatLoadMet,
    8291              :                                   OnOffAirFlowRatio,
    8292              :                                   false);
    8293            0 :                 if (SolFlag == -1 && !state.dataGlobal->WarmupFlag && !FirstHVACIteration) {
    8294            0 :                     if (std::abs(ZoneSensLoadMet - TotalZoneSensLoad) / TotalZoneSensLoad > HeatErrorToler) {
    8295            0 :                         if (thisFurnace.WSHPHeatMaxIterIndex == 0) {
    8296            0 :                             ShowWarningMessage(state,
    8297            0 :                                                format("Heating coil control failed to converge for {}:{}",
    8298            0 :                                                       HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    8299            0 :                                                       thisFurnace.Name));
    8300            0 :                             ShowContinueError(state, "  Iteration limit exceeded in calculating DX heating coil sensible part-load ratio.");
    8301            0 :                             ShowContinueErrorTimeStamp(state,
    8302            0 :                                                        format("Sensible load to be met by DX coil = {:.2T} (watts), sensible output of DX coil = "
    8303              :                                                               "{:.2T} (watts), and the simulation continues.",
    8304              :                                                               TotalZoneSensLoad,
    8305              :                                                               ZoneSensLoadMet));
    8306              :                         }
    8307            0 :                         ShowRecurringWarningErrorAtEnd(
    8308              :                             state,
    8309            0 :                             format("{} \"{}\" - Iteration limit exceeded in calculating sensible heating part-load ratio error continues.",
    8310            0 :                                    HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    8311            0 :                                    thisFurnace.Name),
    8312            0 :                             thisFurnace.WSHPHeatMaxIterIndex,
    8313              :                             TotalZoneSensLoad,
    8314              :                             TotalZoneSensLoad);
    8315              :                     }
    8316            0 :                 } else if (SolFlag == -2) {
    8317            0 :                     HeatPartLoadRatio = max(MinPLR, min(1.0, std::abs(HPCoilSensDemand) / std::abs(HPCoilSensCapacity)));
    8318            0 :                     CalcFurnaceOutput(state,
    8319              :                                       FurnaceNum,
    8320              :                                       FirstHVACIteration,
    8321              :                                       fanOp,
    8322              :                                       compressorOp,
    8323              :                                       0.0,
    8324              :                                       HeatPartLoadRatio,
    8325              :                                       0.0,
    8326              :                                       0.0,
    8327              :                                       ZoneSensLoadMet,
    8328              :                                       ZoneLatLoadMet,
    8329              :                                       OnOffAirFlowRatio,
    8330              :                                       false);
    8331            0 :                     if ((ZoneSensLoadMet - TotalZoneSensLoad) / TotalZoneSensLoad > HeatErrorToler) {
    8332            0 :                         if (thisFurnace.WSHPHeatRegulaFalsiFailedIndex == 0) {
    8333            0 :                             ShowWarningError(
    8334              :                                 state,
    8335            0 :                                 format("Heating coil control failed for {}:{}", HVAC::unitarySysTypeNames[(int)thisFurnace.type], thisFurnace.Name));
    8336            0 :                             ShowContinueError(state, "  Heating sensible part-load ratio determined to be outside the range of 0-1.");
    8337            0 :                             ShowContinueError(
    8338              :                                 state,
    8339            0 :                                 format("  An estimated part-load ratio = {:.2T} will be used and the simulation continues.", HeatPartLoadRatio));
    8340            0 :                             ShowContinueError(
    8341            0 :                                 state, format("  The estimated part-load ratio provides a heating sensible capacity = {:.2T}", ZoneSensLoadMet));
    8342            0 :                             ShowContinueErrorTimeStamp(state, format("  Heating sensible load required = {:.2T}", TotalZoneSensLoad));
    8343              :                         }
    8344            0 :                         ShowRecurringWarningErrorAtEnd(state,
    8345            0 :                                                        format("{} \"{}\" - Heating sensible part-load ratio out of range error continues.",
    8346            0 :                                                               HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    8347            0 :                                                               thisFurnace.Name),
    8348            0 :                                                        thisFurnace.WSHPHeatRegulaFalsiFailedIndex,
    8349              :                                                        TotalZoneSensLoad,
    8350              :                                                        TotalZoneSensLoad);
    8351              :                     }
    8352              :                 }
    8353              :             }
    8354              : 
    8355              :             //       CALL supplemental heater if required
    8356            0 :             if ((TotalZoneSensLoad - ZoneSensLoadMet) > HVAC::SmallLoad && HeatPartLoadRatio >= 1.0) {
    8357            0 :                 SuppHeatCoilLoad = TotalZoneSensLoad - ZoneSensLoadMet;
    8358            0 :                 CalcFurnaceOutput(state,
    8359              :                                   FurnaceNum,
    8360              :                                   FirstHVACIteration,
    8361              :                                   fanOp,
    8362              :                                   compressorOp,
    8363              :                                   CoolPartLoadRatio,
    8364              :                                   HeatPartLoadRatio,
    8365              :                                   SuppHeatCoilLoad,
    8366              :                                   Dummy2,
    8367              :                                   ZoneSensLoadMet,
    8368              :                                   ZoneLatLoadMet,
    8369              :                                   OnOffAirFlowRatio,
    8370              :                                   false);
    8371              :             }
    8372              : 
    8373            0 :             if (fanOp == HVAC::FanOp::Cycling) {
    8374            0 :                 thisFurnace.MdotFurnace *= HeatPartLoadRatio;
    8375              :             }
    8376              : 
    8377              :             //**********HVAC Scheduled ON, but no cooling, dehumidification or heating load*********
    8378            0 :         } else if (thisFurnace.availSched->getCurrentVal() > 0.0) {
    8379            0 :             thisFurnace.InitHeatPump = true; // initialization call to Calc Furnace
    8380            0 :             HeatPartLoadRatio = 0.0;
    8381            0 :             CoolPartLoadRatio = 0.0;
    8382            0 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; //! see 'Note' under INITIAL CALCULATIONS
    8383              :             // set report variables
    8384            0 :             thisFurnace.CompPartLoadRatio = 0.0;
    8385            0 :             thisFurnace.CoolingCoilSensDemand = 0.0;
    8386            0 :             thisFurnace.CoolingCoilLatentDemand = 0.0;
    8387            0 :             thisFurnace.HeatingCoilSensDemand = 0.0;
    8388            0 :             if (fanOp == HVAC::FanOp::Cycling) {
    8389            0 :                 thisFurnace.MdotFurnace = 0.0;
    8390            0 :                 state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // see 'Note' under INITIAL CALCULATIONS
    8391            0 :                 CalcFurnaceOutput(state,
    8392              :                                   FurnaceNum,
    8393              :                                   FirstHVACIteration,
    8394              :                                   fanOp,
    8395              :                                   compressorOp,
    8396              :                                   CoolPartLoadRatio,
    8397              :                                   HeatPartLoadRatio,
    8398              :                                   Dummy2,
    8399              :                                   Dummy2,
    8400              :                                   ZoneSensLoadMet,
    8401              :                                   ZoneLatLoadMet,
    8402              :                                   OnOffAirFlowRatio,
    8403              :                                   false);
    8404            0 :                 thisFurnace.MdotFurnace = 0.0;
    8405              :             } else { // continuous fan, cycling coil
    8406            0 :                 CalcFurnaceOutput(state,
    8407              :                                   FurnaceNum,
    8408              :                                   FirstHVACIteration,
    8409              :                                   fanOp,
    8410              :                                   compressorOp,
    8411              :                                   CoolPartLoadRatio,
    8412              :                                   HeatPartLoadRatio,
    8413              :                                   Dummy2,
    8414              :                                   Dummy2,
    8415              :                                   ZoneSensLoadMet,
    8416              :                                   ZoneLatLoadMet,
    8417              :                                   OnOffAirFlowRatio,
    8418              :                                   false);
    8419              :             }
    8420              :             //*********No heating or cooling or dehumidification*********
    8421              :         } else {
    8422            0 :             thisFurnace.InitHeatPump = true; // initialization call to Calc Furnace
    8423            0 :             thisFurnace.MdotFurnace = 0.0;
    8424            0 :             HeatPartLoadRatio = 0.0;
    8425            0 :             CoolPartLoadRatio = 0.0;
    8426            0 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0; // see 'Note' under INITIAL CALCULATIONS
    8427            0 :             thisFurnace.CompPartLoadRatio = 0.0;
    8428            0 :             thisFurnace.CoolingCoilSensDemand = 0.0;
    8429            0 :             thisFurnace.CoolingCoilLatentDemand = 0.0;
    8430            0 :             thisFurnace.HeatingCoilSensDemand = 0.0;
    8431            0 :             CalcFurnaceOutput(state,
    8432              :                               FurnaceNum,
    8433              :                               FirstHVACIteration,
    8434              :                               fanOp,
    8435              :                               compressorOp,
    8436              :                               CoolPartLoadRatio,
    8437              :                               HeatPartLoadRatio,
    8438              :                               Dummy2,
    8439              :                               Dummy2,
    8440              :                               ZoneSensLoadMet,
    8441              :                               ZoneLatLoadMet,
    8442              :                               OnOffAirFlowRatio,
    8443              :                               false);
    8444            0 :             thisFurnace.MdotFurnace = 0.0;
    8445              :         }
    8446              : 
    8447              :         // Set the fan inlet node flow rates
    8448            0 :         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRateMaxAvail = thisFurnace.MdotFurnace;
    8449            0 :         state.dataLoopNodes->Node(FurnaceInletNode).MassFlowRate = thisFurnace.MdotFurnace;
    8450            0 :     }
    8451              : 
    8452        56349 :     void CalcFurnaceOutput(EnergyPlusData &state,
    8453              :                            int const FurnaceNum,
    8454              :                            bool const FirstHVACIteration,
    8455              :                            HVAC::FanOp const fanOp,               // Cycling fan or constant fan
    8456              :                            HVAC::CompressorOp const compressorOp, // Compressor on/off; 1=on, 0=off
    8457              :                            Real64 const CoolPartLoadRatio,        // DX cooling coil part load ratio
    8458              :                            Real64 const HeatPartLoadRatio,        // DX heating coil part load ratio (0 for other heating coil types)
    8459              :                            Real64 const HeatCoilLoad,             // Heating coil load for gas heater
    8460              :                            Real64 const ReheatCoilLoad,           // Reheating coil load for gas heater
    8461              :                            Real64 &SensibleLoadMet,               // Sensible cooling load met (furnace outlet with respect to control zone temp)
    8462              :                            Real64 &LatentLoadMet,              // Latent cooling load met (furnace outlet with respect to control zone humidity ratio)
    8463              :                            Real64 &OnOffAirFlowRatio,          // Ratio of compressor ON mass flow rate to AVERAGE
    8464              :                            bool const HXUnitOn,                // flag to enable HX based on zone moisture load
    8465              :                            Real64 const CoolingHeatingPLRRatio // cooling PLR to heating PLR ratio, used for cycling fan RH control
    8466              :     )
    8467              :     {
    8468              : 
    8469              :         // SUBROUTINE INFORMATION:
    8470              :         //       AUTHOR         Richard Raustad
    8471              :         //       DATE WRITTEN   Sept 2001
    8472              :         //       MODIFIED       Dec 2001
    8473              : 
    8474              :         // PURPOSE OF THIS SUBROUTINE:
    8475              :         // This subroutine calculates to sensible and latent loads met by the DX coils
    8476              :         // specified.  Load met is the outlet node with respect to the control zone's
    8477              :         // temperature and humidity ratio.
    8478              : 
    8479              :         // METHODOLOGY EMPLOYED:
    8480              :         // Simulate each child object in the correct order for each system type. This routine is used in the
    8481              :         // RegulaFalsi function CALL. Air mass flow rate is set each iteration based on PLR.
    8482              : 
    8483        56349 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    8484        56349 :         auto &inletNode = state.dataLoopNodes->Node(thisFurnace.FurnaceInletNodeNum);
    8485        56349 :         int CoolingCoilType_Num = thisFurnace.CoolingCoilType_Num;
    8486        56349 :         Real64 QActual = 0.0; // heating coil load met or delivered
    8487        56349 :         state.dataFurnaces->ModifiedHeatCoilLoad = 0.0;
    8488              : 
    8489        56349 :         state.dataFurnaces->CoolHeatPLRRat = CoolingHeatingPLRRatio;
    8490              : 
    8491              :         // Cooling to Heating PLR Ratio (CoolHeatPLRRat) is used to track the air mass flow rate of both the heating
    8492              :         // and cooling coils when RH control is used and the heating coil operates longer than the cooling coil.
    8493              :         // When CoolPartLoadRatio/CoolHeatPLRRat is used, the PLR calculated is actually the PLR for the heating
    8494              :         // coil (heating PLR is greater than cooling PLR), it is this PLR that determines the air mass flow rate.
    8495              :         // When MAX(HeatPartLoadRatio,CoolPartLoadRatio) is used, only one of these values is non-zero.
    8496        56349 :         if (fanOp == HVAC::FanOp::Cycling) {
    8497        56345 :             if (state.dataFurnaces->CoolHeatPLRRat < 1.0) {
    8498            0 :                 if (state.dataFurnaces->CoolHeatPLRRat > 0.0) {
    8499            0 :                     inletNode.MassFlowRate = state.dataFurnaces->CompOnMassFlow * CoolPartLoadRatio / state.dataFurnaces->CoolHeatPLRRat;
    8500            0 :                     if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir) {
    8501            0 :                         SetAverageAirFlow(state, FurnaceNum, CoolPartLoadRatio / state.dataFurnaces->CoolHeatPLRRat, OnOffAirFlowRatio);
    8502              :                     }
    8503              :                 } else {
    8504            0 :                     inletNode.MassFlowRate = state.dataFurnaces->CompOnMassFlow * CoolPartLoadRatio;
    8505            0 :                     if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir) {
    8506            0 :                         SetAverageAirFlow(state, FurnaceNum, max(HeatPartLoadRatio, CoolPartLoadRatio), OnOffAirFlowRatio);
    8507              :                     }
    8508              :                 }
    8509              :             } else {
    8510        56345 :                 inletNode.MassFlowRate = state.dataFurnaces->CompOnMassFlow * max(HeatPartLoadRatio, CoolPartLoadRatio);
    8511        56345 :                 if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir) {
    8512        56345 :                     SetAverageAirFlow(state, FurnaceNum, max(HeatPartLoadRatio, CoolPartLoadRatio), OnOffAirFlowRatio);
    8513              :                 }
    8514              :             }
    8515              :         } else {
    8516            4 :             if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir) {
    8517            0 :                 SetAverageAirFlow(state, FurnaceNum, max(HeatPartLoadRatio, CoolPartLoadRatio), OnOffAirFlowRatio);
    8518              :             }
    8519              :         }
    8520              : 
    8521        56349 :         inletNode.MassFlowRateMaxAvail = inletNode.MassFlowRate;
    8522              : 
    8523              :         // Simulate the air-to-air heat pump
    8524        56349 :         if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir) {
    8525              :             //   Simulate blow-thru fan and non-linear coils twice to update PLF used by the ONOFF Fan
    8526        56345 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    8527        56345 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8528        56345 :                 if (CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
    8529            0 :                     HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
    8530              :                                                                         BlankString,
    8531              :                                                                         FirstHVACIteration,
    8532              :                                                                         compressorOp,
    8533              :                                                                         CoolPartLoadRatio,
    8534            0 :                                                                         thisFurnace.CoolingCoilIndex,
    8535              :                                                                         fanOp,
    8536              :                                                                         HXUnitOn,
    8537              :                                                                         OnOffAirFlowRatio,
    8538            0 :                                                                         state.dataFurnaces->EconomizerFlag);
    8539              :                 } else {
    8540       112690 :                     DXCoils::SimDXCoil(state,
    8541              :                                        BlankString,
    8542              :                                        compressorOp,
    8543              :                                        FirstHVACIteration,
    8544        56345 :                                        thisFurnace.CoolingCoilIndex,
    8545              :                                        fanOp,
    8546              :                                        CoolPartLoadRatio,
    8547              :                                        OnOffAirFlowRatio);
    8548              :                 }
    8549       112690 :                 DXCoils::SimDXCoil(
    8550        56345 :                     state, BlankString, compressorOp, FirstHVACIteration, thisFurnace.HeatingCoilIndex, fanOp, HeatPartLoadRatio, OnOffAirFlowRatio);
    8551        56345 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8552              :             }
    8553              :             //   Simulate cooling and heating coils
    8554        56345 :             if (CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
    8555            0 :                 HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
    8556              :                                                                     BlankString,
    8557              :                                                                     FirstHVACIteration,
    8558              :                                                                     compressorOp,
    8559              :                                                                     CoolPartLoadRatio,
    8560            0 :                                                                     thisFurnace.CoolingCoilIndex,
    8561              :                                                                     fanOp,
    8562              :                                                                     HXUnitOn,
    8563              :                                                                     OnOffAirFlowRatio,
    8564            0 :                                                                     state.dataFurnaces->EconomizerFlag);
    8565              :             } else {
    8566       112690 :                 DXCoils::SimDXCoil(
    8567        56345 :                     state, BlankString, compressorOp, FirstHVACIteration, thisFurnace.CoolingCoilIndex, fanOp, CoolPartLoadRatio, OnOffAirFlowRatio);
    8568              :             }
    8569       112690 :             DXCoils::SimDXCoil(
    8570        56345 :                 state, BlankString, compressorOp, FirstHVACIteration, thisFurnace.HeatingCoilIndex, fanOp, HeatPartLoadRatio, OnOffAirFlowRatio);
    8571              :             //   Simulate the draw-thru fan
    8572        56345 :             if (thisFurnace.fanPlace == HVAC::FanPlace::DrawThru) {
    8573            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8574              :             }
    8575              :             //   Simulate the supplemental heating coil
    8576        56345 :             if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat && ReheatCoilLoad > 0.0) {
    8577            0 :                 bool SuppHeatingCoilFlag = true;
    8578            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, fanOp, QActual);
    8579            0 :             } else {
    8580              :                 // equivalent to QCoilReq=0.0d0 or ReHeatCoilLoad = 0.0d0
    8581        56345 :                 bool SuppHeatingCoilFlag = true;
    8582        56345 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, fanOp, QActual);
    8583              :             }
    8584              :             // Simulate the parameter estimate water-to-air heat pump
    8585            4 :         } else if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir && thisFurnace.WatertoAirHPType == WAHPCoilType::Simple) {
    8586              :             //    Simulate blow-thru fan and non-linear coils twice to update PLF used by the ONOFF Fan
    8587            4 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    8588            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8589              :                 // COIL:WATERTOAIRHPSIMPLE:COOLING
    8590            0 :                 WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
    8591              :                                                                 BlankString,
    8592            0 :                                                                 thisFurnace.CoolingCoilIndex,
    8593              :                                                                 thisFurnace.CoolingCoilSensDemand,
    8594              :                                                                 thisFurnace.CoolingCoilLatentDemand,
    8595              :                                                                 fanOp,
    8596              :                                                                 compressorOp,
    8597              :                                                                 CoolPartLoadRatio,
    8598              :                                                                 FirstHVACIteration); // CoolPartLoadRatio
    8599            0 :                 Real64 Dummy = 0.0;
    8600              :                 // COIL:WATERTOAIRHPSIMPLE:HEATING
    8601            0 :                 WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
    8602              :                                                                 BlankString,
    8603            0 :                                                                 thisFurnace.HeatingCoilIndex,
    8604              :                                                                 thisFurnace.HeatingCoilSensDemand,
    8605              :                                                                 Dummy,
    8606              :                                                                 fanOp,
    8607              :                                                                 compressorOp,
    8608              :                                                                 HeatPartLoadRatio,
    8609              :                                                                 FirstHVACIteration); // HeatPartLoadRatio
    8610              :                 //      Simulate the whole thing a second time so that the correct PLF required by the coils is used by the Fan. *******
    8611            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8612              :             }
    8613              :             //    Simulate the cooling and heating coils
    8614              :             // COIL:WATERTOAIRHPSIMPLE:COOLING
    8615            4 :             WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
    8616              :                                                             BlankString,
    8617            4 :                                                             thisFurnace.CoolingCoilIndex,
    8618              :                                                             thisFurnace.CoolingCoilSensDemand,
    8619              :                                                             thisFurnace.CoolingCoilLatentDemand,
    8620              :                                                             fanOp,
    8621              :                                                             compressorOp,
    8622              :                                                             CoolPartLoadRatio,
    8623              :                                                             FirstHVACIteration); // CoolPartLoadRatio
    8624            4 :             Real64 Dummy = 0.0;
    8625              :             // COIL:WATERTOAIRHPSIMPLE:HEATING
    8626            4 :             WaterToAirHeatPumpSimple::SimWatertoAirHPSimple(state,
    8627              :                                                             BlankString,
    8628            4 :                                                             thisFurnace.HeatingCoilIndex,
    8629              :                                                             thisFurnace.HeatingCoilSensDemand,
    8630              :                                                             Dummy,
    8631              :                                                             fanOp,
    8632              :                                                             compressorOp,
    8633              :                                                             HeatPartLoadRatio,
    8634              :                                                             FirstHVACIteration); // HeatPartLoadRatio
    8635              :             //     Simulate the draw-thru fan
    8636            4 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    8637            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8638              :             }
    8639              :             //     Simulate the supplemental heating coil
    8640            4 :             if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat && ReheatCoilLoad > 0.0) {
    8641            0 :                 bool SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
    8642            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, fanOp, QActual);
    8643            0 :             } else {
    8644            4 :                 bool SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
    8645            4 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
    8646              :             }
    8647              :             // Simulate the detailed water-to-air heat pump
    8648            4 :         } else if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir && thisFurnace.WatertoAirHPType == WAHPCoilType::ParEst) {
    8649              :             //    Simulate the draw-thru fan
    8650            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    8651            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8652              :             }
    8653              :             //    Simulate the cooling and heating coils
    8654            0 :             WaterToAirHeatPump::SimWatertoAirHP(state,
    8655              :                                                 BlankString,
    8656            0 :                                                 thisFurnace.CoolingCoilIndex,
    8657              :                                                 thisFurnace.DesignMassFlowRate,
    8658              :                                                 fanOp,
    8659              :                                                 FirstHVACIteration,
    8660            0 :                                                 thisFurnace.InitHeatPump,
    8661              :                                                 thisFurnace.CoolingCoilSensDemand,
    8662              :                                                 thisFurnace.CoolingCoilLatentDemand,
    8663              :                                                 compressorOp,
    8664              :                                                 CoolPartLoadRatio);
    8665            0 :             Real64 Dummy = 0.0;
    8666            0 :             WaterToAirHeatPump::SimWatertoAirHP(state,
    8667              :                                                 BlankString,
    8668            0 :                                                 thisFurnace.HeatingCoilIndex,
    8669              :                                                 thisFurnace.DesignMassFlowRate,
    8670              :                                                 fanOp,
    8671              :                                                 FirstHVACIteration,
    8672            0 :                                                 thisFurnace.InitHeatPump,
    8673              :                                                 thisFurnace.HeatingCoilSensDemand,
    8674              :                                                 Dummy,
    8675              :                                                 compressorOp,
    8676              :                                                 HeatPartLoadRatio);
    8677              :             //    Simulate the draw-thru fan
    8678            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::DrawThru) {
    8679            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8680              :             }
    8681              :             //    Simulate the supplemental heating coil
    8682            0 :             HeatingCoils::SimulateHeatingCoilComponents(
    8683            0 :                 state, BlankString, FirstHVACIteration, HeatCoilLoad, thisFurnace.SuppHeatCoilIndex, _, true, fanOp);
    8684              : 
    8685            0 :         } else { // ELSE it's not a heat pump
    8686              :             //   Simulate blow-thru fan
    8687            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
    8688              : 
    8689            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8690              : 
    8691              :                 //     For non-linear coils, simulate coil to update PLF used by the ONOFF Fan
    8692            0 :                 if (thisFurnace.fanType == HVAC::FanType::OnOff) {
    8693            0 :                     if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatOnly && thisFurnace.type != HVAC::UnitarySysType::Furnace_HeatOnly) {
    8694              : 
    8695            0 :                         if (!thisFurnace.CoolingCoilUpstream) {
    8696            0 :                             bool SuppHeatingCoilFlag = false; // if false simulates heating coil
    8697            0 :                             CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
    8698              :                         }
    8699              : 
    8700            0 :                         if (CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
    8701            0 :                             HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
    8702              :                                                                                 BlankString,
    8703              :                                                                                 FirstHVACIteration,
    8704              :                                                                                 compressorOp,
    8705              :                                                                                 CoolPartLoadRatio,
    8706            0 :                                                                                 thisFurnace.CoolingCoilIndex,
    8707              :                                                                                 fanOp,
    8708              :                                                                                 HXUnitOn,
    8709              :                                                                                 OnOffAirFlowRatio,
    8710            0 :                                                                                 state.dataFurnaces->EconomizerFlag);
    8711              :                         } else {
    8712            0 :                             DXCoils::SimDXCoil(state,
    8713              :                                                BlankString,
    8714              :                                                compressorOp,
    8715              :                                                FirstHVACIteration,
    8716            0 :                                                thisFurnace.CoolingCoilIndex,
    8717              :                                                fanOp,
    8718              :                                                CoolPartLoadRatio,
    8719              :                                                OnOffAirFlowRatio,
    8720            0 :                                                state.dataFurnaces->CoolHeatPLRRat);
    8721              :                         }
    8722              :                     }
    8723              : 
    8724            0 :                     if (thisFurnace.CoolingCoilUpstream) {
    8725            0 :                         bool SuppHeatingCoilFlag = false; // if false simulates heating coil
    8726            0 :                         CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
    8727              :                     }
    8728            0 :                     state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8729              :                 } // Simple OnOff fan
    8730              : 
    8731              :             } // Blow thru fan
    8732              : 
    8733              :             //   Simulate the cooling and heating coils
    8734            0 :             if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatOnly && thisFurnace.type != HVAC::UnitarySysType::Furnace_HeatOnly) {
    8735              : 
    8736            0 :                 if (!thisFurnace.CoolingCoilUpstream) {
    8737            0 :                     bool SuppHeatingCoilFlag = false; // if false simulates heating coil
    8738            0 :                     CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
    8739              :                 }
    8740              : 
    8741            0 :                 if (CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
    8742            0 :                     HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
    8743              :                                                                         BlankString,
    8744              :                                                                         FirstHVACIteration,
    8745              :                                                                         compressorOp,
    8746              :                                                                         CoolPartLoadRatio,
    8747            0 :                                                                         thisFurnace.CoolingCoilIndex,
    8748              :                                                                         fanOp,
    8749              :                                                                         HXUnitOn,
    8750              :                                                                         OnOffAirFlowRatio,
    8751            0 :                                                                         state.dataFurnaces->EconomizerFlag);
    8752              :                 } else {
    8753            0 :                     DXCoils::SimDXCoil(state,
    8754              :                                        BlankString,
    8755              :                                        compressorOp,
    8756              :                                        FirstHVACIteration,
    8757            0 :                                        thisFurnace.CoolingCoilIndex,
    8758              :                                        fanOp,
    8759              :                                        CoolPartLoadRatio,
    8760              :                                        OnOffAirFlowRatio,
    8761            0 :                                        state.dataFurnaces->CoolHeatPLRRat);
    8762              :                 }
    8763              :             }
    8764              : 
    8765            0 :             if (thisFurnace.CoolingCoilUpstream) {
    8766            0 :                 bool SuppHeatingCoilFlag = false; // if false simulates heating coil
    8767            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, fanOp, QActual);
    8768              :             }
    8769              :             //   Simulate the draw-thru fan
    8770            0 :             if (thisFurnace.fanPlace == HVAC::FanPlace::DrawThru) {
    8771            0 :                 state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
    8772              :             }
    8773            0 :             if (thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat || thisFurnace.SuppHeatCoilIndex > 0) {
    8774            0 :                 bool SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
    8775            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, ReheatCoilLoad, fanOp, QActual);
    8776              :             }
    8777              :         } // IF(Furnace(FurnaceNum)%type == UnitarySys_HeatPump_AirToAir)THEN
    8778              : 
    8779              :         // Get mass flow rate after components are simulated
    8780        56349 :         auto &outletNode = state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum);
    8781        56349 :         Real64 AirMassFlow = inletNode.MassFlowRate; // this should be outlet node as in 9897?
    8782              : 
    8783              :         // check the DesignMaxOutletTemp and reset if necessary (for Coil:Gas:Heating or Coil:Electric:Heating only)
    8784        56349 :         if (outletNode.Temp > thisFurnace.DesignMaxOutletTemp) {
    8785            0 :             Real64 Wout = outletNode.HumRat;
    8786            0 :             Real64 Tout = thisFurnace.DesignMaxOutletTemp;
    8787            0 :             state.dataFurnaces->ModifiedHeatCoilLoad = HeatCoilLoad - (AirMassFlow * Psychrometrics::PsyCpAirFnW(Wout) * (outletNode.Temp - Tout));
    8788            0 :             outletNode.Temp = Tout;
    8789              :         }
    8790              : 
    8791              :         // If the fan runs continually do not allow coils to set OnOffFanPartLoadRatio.
    8792        56349 :         if (fanOp == HVAC::FanOp::Continuous) {
    8793            4 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    8794              :         }
    8795              : 
    8796        56349 :         Real64 SensibleOutput = 0.0; // sensible output rate, {W}
    8797        56349 :         Real64 LatentOutput = 0.0;   // latent output rate, {W}
    8798        56349 :         Real64 TotalOutput = 0.0;    // total output rate, {W}
    8799       112698 :         CalcZoneSensibleLatentOutput(AirMassFlow,
    8800              :                                      outletNode.Temp,
    8801              :                                      outletNode.HumRat,
    8802        56349 :                                      state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).Temp,
    8803        56349 :                                      state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).HumRat,
    8804              :                                      SensibleOutput,
    8805              :                                      LatentOutput,
    8806              :                                      TotalOutput);
    8807        56349 :         SensibleLoadMet = SensibleOutput - thisFurnace.SenLoadLoss;
    8808        56349 :         thisFurnace.SensibleLoadMet = SensibleLoadMet;
    8809              : 
    8810        56349 :         if (thisFurnace.Humidistat) {
    8811            0 :             LatentLoadMet = LatentOutput - thisFurnace.LatLoadLoss;
    8812              :         } else {
    8813        56349 :             LatentLoadMet = 0.0;
    8814              :         }
    8815        56349 :         thisFurnace.LatentLoadMet = LatentLoadMet;
    8816        56349 :     }
    8817              : 
    8818              :     //        End of Update subroutines for the Furnace Module
    8819              :     // *****************************************************************************
    8820              : 
    8821        20268 :     Real64 CalcFurnaceResidual(EnergyPlusData &state,
    8822              :                                Real64 const PartLoadRatio, // DX cooling coil part load ratio
    8823              :                                int FurnaceNum,
    8824              :                                bool FirstHVACIteration,
    8825              :                                HVAC::FanOp const fanOp,
    8826              :                                HVAC::CompressorOp compressorOp,
    8827              :                                Real64 LoadToBeMet,
    8828              :                                Real64 par6_loadFlag,
    8829              :                                Real64 par7_sensLatentFlag,
    8830              :                                Real64 par9_HXOnFlag,
    8831              :                                Real64 par10_HeatingCoilPLR)
    8832              :     {
    8833              : 
    8834              :         // FUNCTION INFORMATION:
    8835              :         //       AUTHOR         Richard Raustad
    8836              :         //       DATE WRITTEN   Feb 2005
    8837              : 
    8838              :         // PURPOSE OF THIS SUBROUTINE:
    8839              :         // To calculate the part-load ratio for cooling and heating coils
    8840              : 
    8841              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    8842              :         Real64 CoolPartLoadRatio;      // DX cooling coil part load ratio
    8843              :         Real64 HeatPartLoadRatio;      // DX heating coil part load ratio (0 for other heating coil types)
    8844              :         Real64 HeatCoilLoad;           // Heating coil load for gas heater
    8845              :         Real64 SensibleLoadMet;        // Sensible cooling load met (furnace outlet with respect to control zone temp)
    8846              :         Real64 LatentLoadMet;          // Latent cooling load met (furnace outlet with respect to control zone humidity ratio)
    8847              :         Real64 OnOffAirFlowRatio;      // Ratio of compressor ON air mass flow to AVERAGE air mass flow over time step
    8848              :         Real64 CoolingHeatingPLRRatio; // ratio of cooling PLR to heating PLR, used for cycling fan RH control
    8849              :         bool HXUnitOn;                 // flag to enable HX based on zone moisture load
    8850              : 
    8851              :         //        // Convert parameters to usable variables
    8852              :         //        int FurnaceNum = int(Par(1));
    8853              :         //        bool FirstHVACIteration = Par(2) == 1.0;
    8854              :         //        int FanfanOp = int(Par(3));
    8855              :         //        CompressorOperation CompressorOp = static_cast<CompressorOperation>(Par(4));
    8856              :         //        Real64 LoadToBeMet = Par(5);
    8857              :         //        Real64 par6_loadFlag = Par(6);
    8858              :         //        Real64 par7_sensLatentFlag = Par(7);
    8859              :         //        Real64 par9_HXOnFlag = Par(9);
    8860              :         //        Real64 par10_HeatingCoilPLR = Par(10);
    8861              : 
    8862        20268 :         if (par6_loadFlag == 1.0) {
    8863        20244 :             CoolPartLoadRatio = PartLoadRatio;
    8864        20244 :             HeatPartLoadRatio = 0.0;
    8865        20244 :             HeatCoilLoad = 0.0;
    8866              :         } else {
    8867           24 :             CoolPartLoadRatio = 0.0;
    8868           24 :             HeatPartLoadRatio = PartLoadRatio;
    8869              : 
    8870           24 :             int const HeatingCoilType_Num(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilType_Num);
    8871           24 :             if (HeatingCoilType_Num == HVAC::Coil_HeatingGasOrOtherFuel || HeatingCoilType_Num == HVAC::Coil_HeatingElectric ||
    8872           24 :                 HeatingCoilType_Num == HVAC::Coil_HeatingWater || HeatingCoilType_Num == HVAC::Coil_HeatingSteam) {
    8873            0 :                 HeatCoilLoad = state.dataFurnaces->Furnace(FurnaceNum).DesignHeatingCapacity * PartLoadRatio;
    8874              :             } else {
    8875           24 :                 HeatCoilLoad = 0.0;
    8876              :             }
    8877              :         }
    8878              : 
    8879              :         //  OnOffAirFlowRatio = Par(8)
    8880        20268 :         if (state.dataFurnaces->Furnace(FurnaceNum).type == HVAC::UnitarySysType::Unitary_HeatPump_WaterToAir) {
    8881            0 :             state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadRatio;
    8882              :         }
    8883              : 
    8884        20268 :         if (par9_HXOnFlag == 1.0) {
    8885        20244 :             HXUnitOn = true;
    8886              :         } else {
    8887           24 :             HXUnitOn = false;
    8888              :         }
    8889              : 
    8890        20268 :         if (par10_HeatingCoilPLR > 0.0) {
    8891              :             //    Par(10) = Furnace(FurnaceNum)%HeatPartLoadRatio
    8892              :             //    FanOp = CycFan and Furnace(FurnaceNum)%HeatPartLoadRatio must be > 0 for Part(10) to be greater than 0
    8893              :             //    This variable used when in heating mode and dehumidification (cooling) is required.
    8894            0 :             CoolingHeatingPLRRatio = min(1.0, CoolPartLoadRatio / state.dataFurnaces->Furnace(FurnaceNum).HeatPartLoadRatio);
    8895              :         } else {
    8896        20268 :             CoolingHeatingPLRRatio = 1.0;
    8897              :         }
    8898              : 
    8899              :         // Subroutine arguments
    8900        20268 :         CalcFurnaceOutput(state,
    8901              :                           FurnaceNum,
    8902              :                           FirstHVACIteration,
    8903              :                           fanOp,
    8904              :                           compressorOp,
    8905              :                           CoolPartLoadRatio,
    8906              :                           HeatPartLoadRatio,
    8907              :                           HeatCoilLoad,
    8908              :                           0.0,
    8909              :                           SensibleLoadMet,
    8910              :                           LatentLoadMet,
    8911              :                           OnOffAirFlowRatio,
    8912              :                           HXUnitOn,
    8913              :                           CoolingHeatingPLRRatio);
    8914              : 
    8915              :         // Calculate residual based on output calculation flag
    8916        20268 :         if (par7_sensLatentFlag == 1.0) {
    8917        20268 :             if (LoadToBeMet == 0.0) {
    8918            0 :                 return (SensibleLoadMet - LoadToBeMet) / 100.0;
    8919              :             } else {
    8920        20268 :                 return (SensibleLoadMet - LoadToBeMet) / LoadToBeMet;
    8921              :             }
    8922              :         } else {
    8923            0 :             if (LoadToBeMet == 0.0) {
    8924            0 :                 return (LatentLoadMet - LoadToBeMet) / 100.0;
    8925              :             } else {
    8926            0 :                 return (LatentLoadMet - LoadToBeMet) / LoadToBeMet;
    8927              :             }
    8928              :         }
    8929              :     }
    8930              : 
    8931            0 :     Real64 CalcWaterToAirResidual(EnergyPlusData &state,
    8932              :                                   Real64 const PartLoadRatio, // DX cooling coil part load ratio
    8933              :                                   int FurnaceNum,
    8934              :                                   bool FirstHVACIteration,
    8935              :                                   HVAC::FanOp const fanOp,
    8936              :                                   HVAC::CompressorOp compressorOp,
    8937              :                                   Real64 LoadToBeMet,
    8938              :                                   Real64 par6_loadTypeFlag,
    8939              :                                   Real64 par7_latentOrSensible,
    8940              :                                   Real64 ZoneSensLoadMetFanONCompOFF,
    8941              :                                   Real64 par9_HXUnitOne)
    8942              :     {
    8943              : 
    8944              :         // FUNCTION INFORMATION:
    8945              :         //       AUTHOR         Richard Raustad
    8946              :         //       DATE WRITTEN   October 2006
    8947              : 
    8948              :         // PURPOSE OF THIS SUBROUTINE:
    8949              :         // To calculate the part-load ratio for water to air HP's
    8950              :         // this is used for parameter estimation WAHPs but not equation fit WAHPs
    8951              : 
    8952              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    8953              :         Real64 CoolPartLoadRatio; // DX cooling coil part load ratio
    8954              :         Real64 HeatPartLoadRatio; // DX heating coil part load ratio (0 for other heating coil types)
    8955              :         Real64 HeatCoilLoad;      // Heating coil load for gas heater
    8956              :         Real64 ZoneSensLoadMet;   // Sensible cooling load met (furnace outlet with respect to control zone temp)
    8957              :         Real64 ZoneLatLoadMet;    // Latent cooling load met (furnace outlet with respect to control zone humidity ratio)
    8958              :         Real64 Dummy;
    8959              :         Real64 HPCoilSensDemand;
    8960              :         Real64 OnOffAirFlowRatio;
    8961              :         bool HXUnitOn; // flag to enable HX based on zone moisture load (not valid for water-to-air HP's
    8962              : 
    8963              :         // Convert parameters to usable variables
    8964              :         //        int FurnaceNum = int(Par[0]);
    8965              :         //        bool FirstHVACIteration = Par[1] == 1.0;
    8966              :         //        int FanOp = int(Par[2]);
    8967              :         //        CompressorOperation CompressorOp = static_cast<CompressorOperation>(Par[3]);
    8968              :         //        Real64 LoadToBeMet = Par[4];
    8969              :         //        Real64 par6_loadTypeFlag = Par[5];
    8970              :         //        Real64 par7_latentOrSensible = Par[6];
    8971              :         //        Real64 ZoneSensLoadMetFanONCompOFF = Par[7];
    8972              :         //        Real64 par9_HXUnitOne = Par[8];
    8973              : 
    8974              :         int CoilIndex;
    8975            0 :         if (par6_loadTypeFlag == 1.0) {
    8976            0 :             CoolPartLoadRatio = PartLoadRatio;
    8977            0 :             HeatPartLoadRatio = 0.0;
    8978            0 :             HeatCoilLoad = 0.0;
    8979            0 :             CoilIndex = state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex;
    8980              :         } else {
    8981            0 :             CoolPartLoadRatio = 0.0;
    8982            0 :             HeatPartLoadRatio = PartLoadRatio;
    8983            0 :             CoilIndex = state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex;
    8984              :         }
    8985              : 
    8986              :         // Get child component RuntimeFrac
    8987              :         Real64 RuntimeFrac;
    8988            0 :         switch (state.dataFurnaces->Furnace(FurnaceNum).WatertoAirHPType) {
    8989            0 :         case WAHPCoilType::Simple: {
    8990            0 :             RuntimeFrac = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CoilIndex).RunFrac;
    8991            0 :             break;
    8992              :         }
    8993            0 :         case WAHPCoilType::ParEst: {
    8994            0 :             RuntimeFrac = state.dataWaterToAirHeatPump->WatertoAirHP(CoilIndex).RunFrac;
    8995            0 :             break;
    8996              :         }
    8997            0 :         case WAHPCoilType::VarSpeedEquationFit: {
    8998            0 :             RuntimeFrac = state.dataVariableSpeedCoils->VarSpeedCoil(CoilIndex).RunFrac;
    8999            0 :             break;
    9000              :         }
    9001            0 :         default:
    9002            0 :             RuntimeFrac = 1.0; // Programming error. Assert failure?
    9003              :         }
    9004              : 
    9005            0 :         state.dataFurnaces->OnOffFanPartLoadFractionSave = state.dataHVACGlobal->OnOffFanPartLoadFraction;
    9006              :         // update fan and compressor run times
    9007            0 :         state.dataFurnaces->Furnace(FurnaceNum).CompPartLoadRatio = PartLoadRatio;
    9008              : 
    9009              :         // Calculate the heating coil demand as (the zone sensible load - load met by fan heat and mixed air)
    9010              :         // Note; The load met by fan heat and mixed air is calculated as mdot(zoneinletenthalpy-zoneoutletenthalpy)
    9011              :         // This accounts for the negative sign in the equation.
    9012              : 
    9013              :         // Calculate the heat coil sensible capacity as the load met by the system with the fan and compressor on less
    9014              :         // the load met by the system with the compressor off.
    9015              :         //  HPCoilSensCapacity = ZoneSensLoadMetFanONCompON - ZoneSensLoadMetFanONCompOFF
    9016              : 
    9017              :         // Set input parameters for heat pump coil model
    9018            0 :         HPCoilSensDemand = LoadToBeMet - RuntimeFrac * ZoneSensLoadMetFanONCompOFF;
    9019              :         //  HPCoilSensDemand = LoadToBeMet  - PartLoadRatio*ZoneSensLoadMetFanONCompOFF
    9020            0 :         if (par6_loadTypeFlag == 1.0) {
    9021            0 :             state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = 0.0;
    9022            0 :             state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = std::abs(HPCoilSensDemand);
    9023              :         } else {
    9024            0 :             state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilSensDemand = HPCoilSensDemand;
    9025            0 :             state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilSensDemand = 0.0;
    9026              :         }
    9027            0 :         state.dataFurnaces->Furnace(FurnaceNum).InitHeatPump = false; // initialization call to Calc Furnace
    9028              : 
    9029              :         // Calculate the zone loads met and the new part load ratio and for the specified run time
    9030            0 :         Dummy = 0.0;
    9031            0 :         OnOffAirFlowRatio = 1.0;
    9032            0 :         if (par9_HXUnitOne == 1.0) {
    9033            0 :             HXUnitOn = true;
    9034              :         } else {
    9035            0 :             HXUnitOn = false;
    9036              :         }
    9037              : 
    9038              :         //  Subroutine arguments
    9039              :         //  CALL CalcFurnaceOutput(FurnaceNum,FirstHVACIteration,FanOp,compressorOp,CoolPartLoadRatio,&
    9040              :         //                         HeatPartLoadRatio, HeatCoilLoad, ReHeatCoilLoad, SensibleLoadMet, LatentLoadMet, HXUnitOn)
    9041            0 :         CalcFurnaceOutput(state,
    9042              :                           FurnaceNum,
    9043              :                           FirstHVACIteration,
    9044              :                           fanOp,
    9045              :                           compressorOp,
    9046              :                           CoolPartLoadRatio,
    9047              :                           HeatPartLoadRatio,
    9048              :                           Dummy,
    9049              :                           Dummy,
    9050              :                           ZoneSensLoadMet,
    9051              :                           ZoneLatLoadMet,
    9052              :                           OnOffAirFlowRatio,
    9053              :                           HXUnitOn);
    9054              : 
    9055              :         // Calculate residual based on output calculation flag
    9056            0 :         if (par7_latentOrSensible == 1.0) {
    9057            0 :             return (ZoneSensLoadMet - LoadToBeMet) / LoadToBeMet;
    9058              :         } else {
    9059            0 :             return (ZoneLatLoadMet - LoadToBeMet) / LoadToBeMet;
    9060              :         }
    9061              :     }
    9062              : 
    9063        97113 :     void SetAverageAirFlow(EnergyPlusData &state,
    9064              :                            int const FurnaceNum,       // Unit index
    9065              :                            Real64 const PartLoadRatio, // unit part load ratio
    9066              :                            Real64 &OnOffAirFlowRatio   // ratio of compressor ON airflow to AVERAGE airflow over timestep
    9067              :     )
    9068              :     {
    9069              : 
    9070              :         // SUBROUTINE INFORMATION:
    9071              :         //       AUTHOR         Richard Raustad
    9072              :         //       DATE WRITTEN   July 2005
    9073              : 
    9074              :         // PURPOSE OF THIS SUBROUTINE:
    9075              :         // Set the average air mass flow rates using the part-load fraction of the HVAC system for this time step
    9076              :         // Set OnOffAirFlowRatio to be used by DX coils
    9077              : 
    9078              :         // METHODOLOGY EMPLOYED:
    9079              :         // The air flow rate in cooling, heating, and no cooling or heating can be different.
    9080              :         // Calculate the air flow rate based on initializations made in InitFurnace.
    9081              : 
    9082        97113 :         int InletNode = state.dataFurnaces->Furnace(FurnaceNum).FurnaceInletNodeNum;
    9083              :         Real64 AverageUnitMassFlow =
    9084        97113 :             (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
    9085        97113 :         if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
    9086            4 :             state.dataFurnaces->FanSpeedRatio =
    9087            4 :                 (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
    9088              :         } else {
    9089        97109 :             state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
    9090              :         }
    9091              : 
    9092              :         // IF the furnace is scheduled on or nightime cycle overrides fan schedule. Uses same logic as fan.
    9093       291339 :         if (state.dataFurnaces->Furnace(FurnaceNum).availSched->getCurrentVal() > 0.0 &&
    9094        97113 :             ((state.dataFurnaces->Furnace(FurnaceNum).fanAvailSched->getCurrentVal() > 0.0 || state.dataHVACGlobal->TurnFansOn) &&
    9095        97113 :              !state.dataHVACGlobal->TurnFansOff)) {
    9096        97107 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = AverageUnitMassFlow;
    9097        97107 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AverageUnitMassFlow;
    9098        97107 :             if (AverageUnitMassFlow > 0.0) {
    9099        66059 :                 OnOffAirFlowRatio = state.dataFurnaces->CompOnMassFlow / AverageUnitMassFlow;
    9100              :             } else {
    9101        31048 :                 OnOffAirFlowRatio = 0.0;
    9102              :             }
    9103              :         } else {
    9104            6 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
    9105            6 :             OnOffAirFlowRatio = 1.0;
    9106              :         }
    9107              : 
    9108        97113 :         state.dataFurnaces->Furnace(FurnaceNum).MdotFurnace = state.dataFurnaces->CompOnMassFlow;
    9109        97113 :         state.dataFurnaces->OnOffAirFlowRatioSave = OnOffAirFlowRatio;
    9110        97113 :     }
    9111              : 
    9112              :     // Beginning of Reporting subroutines for the Furnace Module
    9113              :     // *****************************************************************************
    9114              : 
    9115        15224 :     void ReportFurnace(EnergyPlusData &state, int const FurnaceNum, int const AirLoopNum)
    9116              :     {
    9117              : 
    9118              :         // SUBROUTINE INFORMATION:
    9119              :         //       AUTHOR         Richard Liesen
    9120              :         //       DATE WRITTEN   Feb 2001
    9121              : 
    9122              :         // PURPOSE OF THIS SUBROUTINE:
    9123              :         // This subroutine updates the report variable for the coils.
    9124              : 
    9125              :         // METHODOLOGY EMPLOYED:
    9126              :         // Update fan part-load ratio based on mass flow rate ratio.
    9127              :         // Update global variables used by AirflowNetwork module.
    9128              : 
    9129              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    9130              :         Real64 ratio;
    9131              :         Real64 OnOffRatio;
    9132        15224 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    9133              : 
    9134              :         // Report the Furnace Fan Part Load Ratio
    9135        15224 :         if (thisFurnace.NumOfSpeedCooling < 1) {
    9136        15224 :             if (thisFurnace.DesignMassFlowRate > 0.0) {
    9137        15224 :                 thisFurnace.FanPartLoadRatio = thisFurnace.MdotFurnace / thisFurnace.DesignMassFlowRate;
    9138              :             } else {
    9139            0 :                 thisFurnace.FanPartLoadRatio = 0.0;
    9140              :             }
    9141              :         }
    9142              : 
    9143              :         // Set mass flow rates during on and off cycle using an OnOff fan
    9144        15224 :         if (state.afn->distribution_simulated) {
    9145        11170 :             state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOnMassFlowrate = state.dataFurnaces->CompOnMassFlow;
    9146        11170 :             state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopSystemOffMassFlowrate = state.dataFurnaces->CompOffMassFlow;
    9147        11170 :             state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopFanOperationMode = thisFurnace.fanOp;
    9148        11170 :             state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio = thisFurnace.FanPartLoadRatio;
    9149        11170 :             OnOffRatio = state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio;
    9150        11170 :             if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatPump_AirToAir) {
    9151        11169 :                 state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio =
    9152        11169 :                     max(thisFurnace.FanPartLoadRatio, thisFurnace.HeatPartLoadRatio, thisFurnace.CoolPartLoadRatio);
    9153        11169 :                 state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio =
    9154        11169 :                     min(1.0, state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio);
    9155              :             }
    9156        11170 :             if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool) {
    9157            1 :                 if (thisFurnace.HeatPartLoadRatio == 0.0 && thisFurnace.CoolPartLoadRatio == 0.0 && thisFurnace.FanPartLoadRatio > 0.0) {
    9158            2 :                     if (state.dataFurnaces->CompOnMassFlow < max(thisFurnace.MaxCoolAirMassFlow, thisFurnace.MaxHeatAirMassFlow) &&
    9159            1 :                         state.dataFurnaces->CompOnMassFlow > 0.0) {
    9160            1 :                         ratio = max(thisFurnace.MaxCoolAirMassFlow, thisFurnace.MaxHeatAirMassFlow) / state.dataFurnaces->CompOnMassFlow;
    9161            1 :                         state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio =
    9162            1 :                             state.dataAirLoop->AirLoopAFNInfo(AirLoopNum).LoopOnOffFanPartLoadRatio * ratio;
    9163              :                     }
    9164              :                 }
    9165              :             }
    9166              :         }
    9167        15224 :         if (thisFurnace.FirstPass) {
    9168            3 :             if (!state.dataGlobal->SysSizingCalc) {
    9169            3 :                 DataSizing::resetHVACSizingGlobals(state, 0, state.dataSize->CurSysNum, thisFurnace.FirstPass);
    9170              :             }
    9171              :         }
    9172        15224 :         state.dataHVACGlobal->OnOffFanPartLoadFraction =
    9173              :             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)
    9174        15224 :     }
    9175              : 
    9176        71571 :     void CalcNonDXHeatingCoils(EnergyPlusData &state,
    9177              :                                int const FurnaceNum,           // Furnace Index
    9178              :                                bool const SuppHeatingCoilFlag, // .TRUE. if supplemental heating coil
    9179              :                                bool const FirstHVACIteration,  // flag for first HVAC iteration in the time step
    9180              :                                Real64 const QCoilLoad,         // load met by unit (watts)
    9181              :                                HVAC::FanOp const fanOp,        // fan operation mode
    9182              :                                Real64 &HeatCoilLoadmet         // Heating Load Met
    9183              :     )
    9184              :     {
    9185              :         // SUBROUTINE INFORMATION:
    9186              :         //       AUTHOR         Bereket Nigusse, FSEC/UCF
    9187              :         //       DATE WRITTEN   January 2012
    9188              : 
    9189              :         // PURPOSE OF THIS SUBROUTINE:
    9190              :         // This subroutine simulates the four non dx heating coil types: Gas, Electric, hot water and steam.
    9191              : 
    9192              :         // METHODOLOGY EMPLOYED:
    9193              :         // Simply calls the different heating coil component.  The hot water flow rate matching the coil load
    9194              :         // is calculated iteratively.
    9195              : 
    9196              :         // SUBROUTINE PARAMETER DEFINITIONS:
    9197        71571 :         Real64 constexpr ErrTolerance(0.001); // convergence limit for hotwater coil
    9198        71571 :         int constexpr SolveMaxIter(50);
    9199              : 
    9200              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    9201              :         Real64 mdot;              // heating coil steam or hot water mass flow rate
    9202              :         Real64 MinWaterFlow;      // coil minimum hot water mass flow rate, kg/s
    9203              :         Real64 MaxHotWaterFlow;   // coil maximum hot water mass flow rate, kg/s
    9204              :         Real64 HotWaterMdot;      // actual hot water mass flow rate
    9205        71571 :         int CoilTypeNum(0);       // heating coil type number
    9206        71571 :         int HeatingCoilIndex(0);  // heating coil index
    9207        71571 :         int CoilControlNode(0);   // control node for hot water and steam heating coils
    9208        71571 :         int CoilOutletNode(0);    // air outlet node of the heating coils
    9209        71571 :         PlantLocation plantLoc{}; // plant loop location
    9210              : 
    9211        71571 :         Real64 QActual = 0.0;                                               // actual heating load
    9212        71571 :         std::string &HeatingCoilName = state.dataFurnaces->HeatingCoilName; // name of heating coil
    9213        71571 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    9214              : 
    9215        71571 :         if (SuppHeatingCoilFlag) {
    9216        71571 :             HeatingCoilName = thisFurnace.SuppHeatCoilName;
    9217        71571 :             HeatingCoilIndex = thisFurnace.SuppHeatCoilIndex;
    9218        71571 :             CoilControlNode = thisFurnace.SuppCoilControlNode;
    9219        71571 :             CoilOutletNode = thisFurnace.SuppCoilOutletNode;
    9220        71571 :             CoilTypeNum = thisFurnace.SuppHeatCoilType_Num;
    9221        71571 :             plantLoc = thisFurnace.SuppPlantLoc;
    9222        71571 :             MaxHotWaterFlow = thisFurnace.MaxSuppCoilFluidFlow;
    9223              :         } else {
    9224            0 :             HeatingCoilName = thisFurnace.HeatingCoilName;
    9225            0 :             HeatingCoilIndex = thisFurnace.HeatingCoilIndex;
    9226            0 :             CoilControlNode = thisFurnace.CoilControlNode;
    9227            0 :             CoilOutletNode = thisFurnace.CoilOutletNode;
    9228            0 :             CoilTypeNum = thisFurnace.HeatingCoilType_Num;
    9229            0 :             plantLoc = thisFurnace.plantLoc;
    9230            0 :             MaxHotWaterFlow = thisFurnace.MaxHeatCoilFluidFlow;
    9231              :         }
    9232              : 
    9233        71571 :         switch (CoilTypeNum) {
    9234        71567 :         case HVAC::Coil_HeatingGasOrOtherFuel:
    9235              :         case HVAC::Coil_HeatingElectric:
    9236              :         case HVAC::Coil_HeatingDesuperheater: {
    9237        71567 :             HeatingCoils::SimulateHeatingCoilComponents(
    9238              :                 state, HeatingCoilName, FirstHVACIteration, QCoilLoad, HeatingCoilIndex, QActual, SuppHeatingCoilFlag, fanOp);
    9239        71567 :         } break;
    9240            0 :         case HVAC::Coil_HeatingWater: {
    9241            0 :             if (QCoilLoad > HVAC::SmallLoad) {
    9242            0 :                 PlantUtilities::SetComponentFlowRate(state, MaxHotWaterFlow, CoilControlNode, CoilOutletNode, plantLoc);
    9243            0 :                 WaterCoils::SimulateWaterCoilComponents(state, HeatingCoilName, FirstHVACIteration, HeatingCoilIndex, QActual, fanOp);
    9244              : 
    9245            0 :                 if (QActual > (QCoilLoad + HVAC::SmallLoad)) {
    9246              :                     // control water flow to obtain output matching QCoilLoad
    9247            0 :                     MinWaterFlow = 0.0;
    9248            0 :                     auto f = [&state, FurnaceNum, FirstHVACIteration, QCoilLoad, SuppHeatingCoilFlag](Real64 const HWFlow) {
    9249            0 :                         Real64 QCoilRequested = QCoilLoad;
    9250              : 
    9251              :                         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    9252              :                         Real64 QCoilActual;   // delivered coil load, W
    9253            0 :                         Real64 mdot = HWFlow; // to get non-const argument
    9254            0 :                         QCoilActual = QCoilRequested;
    9255            0 :                         if (!SuppHeatingCoilFlag) {
    9256            0 :                             PlantUtilities::SetComponentFlowRate(state,
    9257              :                                                                  mdot,
    9258            0 :                                                                  state.dataFurnaces->Furnace(FurnaceNum).CoilControlNode,
    9259            0 :                                                                  state.dataFurnaces->Furnace(FurnaceNum).CoilOutletNode,
    9260            0 :                                                                  state.dataFurnaces->Furnace(FurnaceNum).plantLoc);
    9261            0 :                             WaterCoils::SimulateWaterCoilComponents(state,
    9262            0 :                                                                     state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilName,
    9263              :                                                                     FirstHVACIteration,
    9264            0 :                                                                     state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex,
    9265              :                                                                     QCoilActual,
    9266            0 :                                                                     state.dataFurnaces->Furnace(FurnaceNum).fanOp);
    9267              :                         } else {
    9268              :                             // supplemental coil
    9269            0 :                             PlantUtilities::SetComponentFlowRate(state,
    9270              :                                                                  mdot,
    9271            0 :                                                                  state.dataFurnaces->Furnace(FurnaceNum).SuppCoilControlNode,
    9272            0 :                                                                  state.dataFurnaces->Furnace(FurnaceNum).SuppCoilOutletNode,
    9273            0 :                                                                  state.dataFurnaces->Furnace(FurnaceNum).SuppPlantLoc);
    9274              :                             // simulate the hot water supplemental heating coil
    9275            0 :                             WaterCoils::SimulateWaterCoilComponents(state,
    9276            0 :                                                                     state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilName,
    9277              :                                                                     FirstHVACIteration,
    9278            0 :                                                                     state.dataFurnaces->Furnace(FurnaceNum).SuppHeatCoilIndex,
    9279              :                                                                     QCoilActual,
    9280            0 :                                                                     state.dataFurnaces->Furnace(FurnaceNum).fanOp);
    9281              :                         }
    9282            0 :                         return QCoilRequested != 0.0 ? (QCoilActual - QCoilRequested) / QCoilRequested : 0.0;
    9283            0 :                     };
    9284            0 :                     int SolFlag = 0;
    9285            0 :                     General::SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, HotWaterMdot, f, MinWaterFlow, MaxHotWaterFlow);
    9286            0 :                     if (SolFlag == -1) {
    9287            0 :                         if (thisFurnace.HotWaterCoilMaxIterIndex == 0) {
    9288            0 :                             ShowWarningMessage(state,
    9289            0 :                                                format("CalcNonDXHeatingCoils: Hot water coil control failed for {}=\"{}\"",
    9290            0 :                                                       HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    9291            0 :                                                       thisFurnace.Name));
    9292            0 :                             ShowContinueErrorTimeStamp(state, "");
    9293            0 :                             ShowContinueError(state, format("  Iteration limit [{}] exceeded in calculating hot water mass flow rate", SolveMaxIter));
    9294              :                         }
    9295            0 :                         ShowRecurringWarningErrorAtEnd(
    9296              :                             state,
    9297            0 :                             format("CalcNonDXHeatingCoils: Hot water coil control failed (iteration limit [{}]) for {}=\"{}",
    9298              :                                    SolveMaxIter,
    9299            0 :                                    HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    9300            0 :                                    thisFurnace.Name),
    9301            0 :                             thisFurnace.HotWaterCoilMaxIterIndex);
    9302            0 :                     } else if (SolFlag == -2) {
    9303            0 :                         if (thisFurnace.HotWaterCoilMaxIterIndex2 == 0) {
    9304            0 :                             ShowWarningMessage(state,
    9305            0 :                                                format("CalcNonDXHeatingCoils: Hot water coil control failed (maximum flow limits) for {}=\"{}\"",
    9306            0 :                                                       HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    9307            0 :                                                       thisFurnace.Name));
    9308            0 :                             ShowContinueErrorTimeStamp(state, "");
    9309            0 :                             ShowContinueError(state, "...Bad hot water maximum flow rate limits");
    9310            0 :                             ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinWaterFlow));
    9311            0 :                             ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxHotWaterFlow));
    9312              :                         }
    9313            0 :                         ShowRecurringWarningErrorAtEnd(state,
    9314            0 :                                                        format("CalcNonDXHeatingCoils: Hot water coil control failed (flow limits) for {}=\"{}\"",
    9315            0 :                                                               HVAC::unitarySysTypeNames[(int)thisFurnace.type],
    9316            0 :                                                               thisFurnace.Name),
    9317            0 :                                                        thisFurnace.HotWaterCoilMaxIterIndex2,
    9318              :                                                        MaxHotWaterFlow,
    9319              :                                                        MinWaterFlow,
    9320              :                                                        _,
    9321              :                                                        "[kg/s]",
    9322              :                                                        "[kg/s]");
    9323              :                     }
    9324              :                 }
    9325              :             } else {
    9326            0 :                 mdot = 0.0;
    9327            0 :                 PlantUtilities::SetComponentFlowRate(state, mdot, CoilControlNode, CoilOutletNode, plantLoc);
    9328              :             }
    9329              :             // simulate the hot water heating coil
    9330            0 :             WaterCoils::SimulateWaterCoilComponents(state, HeatingCoilName, FirstHVACIteration, HeatingCoilIndex, QActual, fanOp);
    9331            0 :         } break;
    9332            0 :         case HVAC::Coil_HeatingSteam: {
    9333            0 :             if (QCoilLoad > HVAC::SmallLoad) {
    9334            0 :                 PlantUtilities::SetComponentFlowRate(state, MaxHotWaterFlow, CoilControlNode, CoilOutletNode, plantLoc);
    9335              :                 // simulate the steam heating coil
    9336            0 :                 SteamCoils::SimulateSteamCoilComponents(state, HeatingCoilName, FirstHVACIteration, HeatingCoilIndex, QCoilLoad, QActual, fanOp);
    9337              :             } else {
    9338            0 :                 mdot = 0.0;
    9339            0 :                 PlantUtilities::SetComponentFlowRate(state, mdot, CoilControlNode, CoilOutletNode, plantLoc);
    9340              :                 // simulate the steam heating coil
    9341            0 :                 SteamCoils::SimulateSteamCoilComponents(state, HeatingCoilName, FirstHVACIteration, HeatingCoilIndex, QCoilLoad, QActual, fanOp);
    9342              :             }
    9343            0 :         } break;
    9344            4 :         default:
    9345            4 :             break;
    9346              :         }
    9347              : 
    9348        71571 :         HeatCoilLoadmet = QActual;
    9349        71571 :     }
    9350              : 
    9351              :     //        End of Reporting subroutines for the Furnace Module
    9352              : 
    9353              :     //******************************************************************************
    9354              : 
    9355            0 :     void SimVariableSpeedHP(EnergyPlusData &state,
    9356              :                             int const FurnaceNum,          // number of the current engine driven Heat Pump being simulated
    9357              :                             bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
    9358              :                             int const AirLoopNum,          // index to air loop
    9359              :                             Real64 const QZnReq,           // required zone load
    9360              :                             Real64 const QLatReq,          // required latent load
    9361              :                             Real64 &OnOffAirFlowRatio      // ratio of compressor ON airflow to AVERAGE airflow over timestep
    9362              :     )
    9363              :     {
    9364              : 
    9365              :         // SUBROUTINE INFORMATION:
    9366              :         //       AUTHOR         Bo Shen, based on HVACMultiSpeedHeatPump:CalcMSHeatPump
    9367              :         //       DATE WRITTEN   March, 2012
    9368              : 
    9369              :         // PURPOSE OF THIS SUBROUTINE:
    9370              :         // Simulate a multispeed heat pump; adjust its output to match the
    9371              :         // required system load.
    9372              : 
    9373              :         // METHODOLOGY EMPLOYED:
    9374              :         // Calls ControlMSHPOutput to obtain the desired unit output
    9375              : 
    9376              :         Real64 PartLoadFrac; // compressor part load fraction
    9377              :         Real64 SpeedRatio;   // compressor speed ratio
    9378              :         Real64 QTotUnitOut;  // capacity output
    9379            0 :         auto &SpeedNum = state.dataFurnaces->SpeedNum;
    9380            0 :         auto &SupHeaterLoad = state.dataFurnaces->SupHeaterLoad;
    9381              :         HVAC::CompressorOp compressorOp; // compressor operation; 1=on, 0=off
    9382              :         Real64 QSensUnitOut;             // sensible capacity output
    9383              :         Real64 QLatUnitOut;              // latent capacity output
    9384              :         Real64 ActualSensibleOutput;     // Actual furnace sensible capacity
    9385              :         Real64 QToHeatSetPt;             // Load required to meet heating setpoint temp (>0 is a heating load)
    9386              :         Real64 NoCompOutput;             // output when no active compressor [W]
    9387              :         bool EconoActive;                // TRUE if Economizer is active
    9388              : 
    9389              :         // zero DX coils, and supplemental electric heater electricity consumption
    9390            0 :         state.dataHVACGlobal->DXElecHeatingPower = 0.0;
    9391            0 :         state.dataHVACGlobal->DXElecCoolingPower = 0.0;
    9392            0 :         state.dataFurnaces->SaveCompressorPLR = 0.0;
    9393            0 :         state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
    9394            0 :         state.dataHVACGlobal->SuppHeatingCoilPower = 0.0;
    9395            0 :         state.dataHVACGlobal->DefrostElecPower = 0.0;
    9396              : 
    9397            0 :         Real64 SystemSensibleLoad = QZnReq; // Positive value means heating required
    9398            0 :         Real64 TotalZoneSensibleLoad = QZnReq;
    9399            0 :         Real64 TotalZoneLatentLoad = QLatReq;
    9400            0 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    9401              :         // initialize local variables
    9402            0 :         bool UnitOn = true;
    9403            0 :         int OutletNode = thisFurnace.FurnaceOutletNodeNum;
    9404            0 :         int InletNode = thisFurnace.FurnaceInletNodeNum;
    9405            0 :         Real64 AirMassFlow = thisFurnace.DesignMassFlowRate;
    9406            0 :         HVAC::FanOp fanOp = thisFurnace.fanOp; // fan operating mode
    9407            0 :         int ZoneNum = thisFurnace.ControlZoneNum;
    9408              : 
    9409              :         // Set latent load for heating
    9410            0 :         if (state.dataFurnaces->HeatingLoad) {
    9411            0 :             thisFurnace.HeatCoolMode = Furnaces::ModeOfOperation::HeatingMode;
    9412              :             // Set latent load for cooling and no sensible load condition
    9413            0 :         } else if (state.dataFurnaces->CoolingLoad) {
    9414            0 :             thisFurnace.HeatCoolMode = Furnaces::ModeOfOperation::CoolingMode;
    9415              :         } else {
    9416            0 :             thisFurnace.HeatCoolMode = Furnaces::ModeOfOperation::NoCoolHeat;
    9417              :         }
    9418              : 
    9419              :         // set the on/off flags
    9420            0 :         if (thisFurnace.fanOp == HVAC::FanOp::Cycling) {
    9421              :             // cycling unit only runs if there is a cooling or heating load.
    9422            0 :             if (std::abs(QZnReq) < HVAC::SmallLoad || AirMassFlow < HVAC::SmallMassFlow ||
    9423            0 :                 state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
    9424            0 :                 UnitOn = false;
    9425              :             }
    9426            0 :         } else if (thisFurnace.fanOp == HVAC::FanOp::Continuous) {
    9427              :             // continuous unit: fan runs if scheduled on; coil runs only if there is a cooling or heating load
    9428            0 :             if (AirMassFlow < HVAC::SmallMassFlow) {
    9429            0 :                 UnitOn = false;
    9430              :             }
    9431              :         }
    9432              : 
    9433            0 :         state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    9434            0 :         EconoActive = (AirLoopNum != 0) ? state.dataAirLoop->AirLoopControlInfo(AirLoopNum).EconoActive : false;
    9435              : 
    9436            0 :         Real64 SaveMassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    9437              :         // decide current working mode for IHP
    9438            0 :         if ((FirstHVACIteration) && (thisFurnace.bIsIHP)) {
    9439            0 :             IntegratedHeatPump::DecideWorkMode(state, thisFurnace.CoolingCoilIndex, TotalZoneSensibleLoad, TotalZoneLatentLoad);
    9440              :         }
    9441              : 
    9442            0 :         if (!FirstHVACIteration && thisFurnace.fanOp == HVAC::FanOp::Cycling &&
    9443            0 :             (QZnReq < (-1.0 * HVAC::SmallLoad) || TotalZoneLatentLoad < (-HVAC::SmallLoad)) && EconoActive) {
    9444              :             // for cycling fan, cooling load, check whether furnace can meet load with compressor off
    9445            0 :             compressorOp = HVAC::CompressorOp::Off;
    9446            0 :             ControlVSHPOutput(state,
    9447              :                               FurnaceNum,
    9448              :                               FirstHVACIteration,
    9449              :                               compressorOp,
    9450              :                               fanOp,
    9451              :                               TotalZoneSensibleLoad,
    9452              :                               TotalZoneLatentLoad,
    9453              :                               SpeedNum,
    9454              :                               SpeedRatio,
    9455              :                               PartLoadFrac,
    9456              :                               OnOffAirFlowRatio,
    9457              :                               SupHeaterLoad);
    9458              : 
    9459            0 :             TotalZoneSensibleLoad = QZnReq;
    9460            0 :             TotalZoneLatentLoad = QLatReq;
    9461              : 
    9462            0 :             if (SpeedNum == thisFurnace.NumOfSpeedCooling && SpeedRatio == 1.0) {
    9463              :                 // compressor on (reset inlet air mass flow rate to starting value)
    9464            0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = SaveMassFlowRate;
    9465            0 :                 compressorOp = HVAC::CompressorOp::On;
    9466            0 :                 ControlVSHPOutput(state,
    9467              :                                   FurnaceNum,
    9468              :                                   FirstHVACIteration,
    9469              :                                   compressorOp,
    9470              :                                   fanOp,
    9471              :                                   TotalZoneSensibleLoad,
    9472              :                                   TotalZoneLatentLoad,
    9473              :                                   SpeedNum,
    9474              :                                   SpeedRatio,
    9475              :                                   PartLoadFrac,
    9476              :                                   OnOffAirFlowRatio,
    9477              :                                   SupHeaterLoad);
    9478              :             }
    9479              :         } else {
    9480              :             // compressor on
    9481            0 :             compressorOp = HVAC::CompressorOp::On;
    9482              : 
    9483            0 :             ControlVSHPOutput(state,
    9484              :                               FurnaceNum,
    9485              :                               FirstHVACIteration,
    9486              :                               compressorOp,
    9487              :                               fanOp,
    9488              :                               TotalZoneSensibleLoad,
    9489              :                               TotalZoneLatentLoad,
    9490              :                               SpeedNum,
    9491              :                               SpeedRatio,
    9492              :                               PartLoadFrac,
    9493              :                               OnOffAirFlowRatio,
    9494              :                               SupHeaterLoad);
    9495              :         }
    9496              : 
    9497            0 :         if (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool) {
    9498            0 :             state.dataFurnaces->SaveCompressorPLR = PartLoadFrac;
    9499              :         } else {
    9500            0 :             if (SpeedNum > 1) {
    9501            0 :                 state.dataFurnaces->SaveCompressorPLR = 1.0;
    9502              :             }
    9503              : 
    9504            0 :             if (PartLoadFrac == 1.0 && state.dataFurnaces->SaveCompressorPLR < 1.0) {
    9505            0 :                 PartLoadFrac = state.dataFurnaces->SaveCompressorPLR;
    9506              :             }
    9507              :         }
    9508              : 
    9509            0 :         Real64 ReheatCoilLoad = 0.0;
    9510            0 :         TotalZoneSensibleLoad = QZnReq;
    9511            0 :         TotalZoneLatentLoad = QLatReq;
    9512              :         //     Calculate the reheat coil output
    9513            0 :         if ((thisFurnace.availSched->getCurrentVal() > 0.0) &&
    9514            0 :             (thisFurnace.Humidistat && thisFurnace.DehumidControlType_Num == DehumidificationControlMode::CoolReheat &&
    9515              :              (QLatReq < 0.0))) { // if a Humidistat is installed and dehumidification control type is CoolReheat
    9516            0 :             CalcVarSpeedHeatPump(state,
    9517              :                                  FurnaceNum,
    9518              :                                  FirstHVACIteration,
    9519              :                                  compressorOp,
    9520              :                                  SpeedNum,
    9521              :                                  SpeedRatio,
    9522              :                                  PartLoadFrac,
    9523              :                                  ActualSensibleOutput,
    9524              :                                  QLatUnitOut,
    9525              :                                  TotalZoneSensibleLoad,
    9526              :                                  TotalZoneLatentLoad,
    9527              :                                  OnOffAirFlowRatio,
    9528              :                                  ReheatCoilLoad);
    9529            0 :             if (thisFurnace.ZoneSequenceHeatingNum > 0) {
    9530            0 :                 QToHeatSetPt = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum)
    9531            0 :                                     .SequencedOutputRequiredToHeatingSP(thisFurnace.ZoneSequenceHeatingNum) /
    9532            0 :                                 thisFurnace.ControlZoneMassFlowFrac);
    9533              :             } else {
    9534            0 :                 QToHeatSetPt = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(thisFurnace.ControlZoneNum).OutputRequiredToHeatingSP /
    9535            0 :                                 thisFurnace.ControlZoneMassFlowFrac);
    9536              :             }
    9537              :             //       Cooling mode or floating condition and dehumidification is required
    9538            0 :             if (QToHeatSetPt < 0.0) {
    9539              :                 //         Calculate the reheat coil load wrt the heating setpoint temperature. Reheat coil picks up
    9540              :                 //         the entire excess sensible cooling (DX cooling coil and impact of outdoor air).
    9541            0 :                 ReheatCoilLoad = max(0.0, (QToHeatSetPt - ActualSensibleOutput));
    9542            0 :                 thisFurnace.DehumidInducedHeatingDemandRate = ReheatCoilLoad;
    9543              :                 //       Heating mode and dehumidification is required
    9544              :             } else {
    9545            0 :                 ReheatCoilLoad = max(QToHeatSetPt, QToHeatSetPt - ActualSensibleOutput);
    9546            0 :                 thisFurnace.DehumidInducedHeatingDemandRate = max(0.0, ActualSensibleOutput * (-1.0));
    9547              :             }
    9548              : 
    9549            0 :             SupHeaterLoad = 0.0;
    9550            0 :             CalcVarSpeedHeatPump(state,
    9551              :                                  FurnaceNum,
    9552              :                                  FirstHVACIteration,
    9553              :                                  compressorOp,
    9554              :                                  1,
    9555              :                                  0.0,
    9556              :                                  0.0,
    9557              :                                  NoCompOutput,
    9558              :                                  QLatUnitOut,
    9559              :                                  0.0,
    9560              :                                  0.0,
    9561              :                                  OnOffAirFlowRatio,
    9562              :                                  SupHeaterLoad);
    9563              : 
    9564            0 :             if (NoCompOutput > SystemSensibleLoad && SystemSensibleLoad > 0.0 && ReheatCoilLoad > 0.0) {
    9565              :                 // Reduce reheat coil load if you are controlling high humidity but outside air
    9566              :                 // and/or the supply air fan is providing enough heat to meet the system sensible load.
    9567              :                 // This will bring the zone temp closer to the heating setpoint temp.
    9568            0 :                 ReheatCoilLoad = max(0.0, ReheatCoilLoad - (NoCompOutput - SystemSensibleLoad));
    9569              :             }
    9570              :         } else {
    9571              :             //       No humidistat installed
    9572            0 :             ReheatCoilLoad = 0.0;
    9573              :         }
    9574              : 
    9575            0 :         TotalZoneSensibleLoad = QZnReq;
    9576            0 :         TotalZoneLatentLoad = QLatReq;
    9577            0 :         if (ReheatCoilLoad > 0.0) {
    9578            0 :             CalcVarSpeedHeatPump(state,
    9579              :                                  FurnaceNum,
    9580              :                                  FirstHVACIteration,
    9581              :                                  compressorOp,
    9582              :                                  SpeedNum,
    9583              :                                  SpeedRatio,
    9584              :                                  PartLoadFrac,
    9585              :                                  QSensUnitOut,
    9586              :                                  QLatUnitOut,
    9587              :                                  TotalZoneSensibleLoad,
    9588              :                                  TotalZoneLatentLoad,
    9589              :                                  OnOffAirFlowRatio,
    9590              :                                  ReheatCoilLoad);
    9591              :         } else {
    9592            0 :             CalcVarSpeedHeatPump(state,
    9593              :                                  FurnaceNum,
    9594              :                                  FirstHVACIteration,
    9595              :                                  compressorOp,
    9596              :                                  SpeedNum,
    9597              :                                  SpeedRatio,
    9598              :                                  PartLoadFrac,
    9599              :                                  QSensUnitOut,
    9600              :                                  QLatUnitOut,
    9601              :                                  TotalZoneSensibleLoad,
    9602              :                                  TotalZoneLatentLoad,
    9603              :                                  OnOffAirFlowRatio,
    9604              :                                  SupHeaterLoad);
    9605              :         }
    9606              : 
    9607              :         // calculate delivered capacity
    9608            0 :         AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    9609              : 
    9610            0 :         thisFurnace.MdotFurnace = AirMassFlow;
    9611              : 
    9612            0 :         QTotUnitOut =
    9613            0 :             AirMassFlow * (state.dataLoopNodes->Node(OutletNode).Enthalpy - state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone).Enthalpy);
    9614              : 
    9615            0 :         state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = AirMassFlow;
    9616            0 :         state.dataLoopNodes->Node(OutletNode).MassFlowRateMaxAvail = AirMassFlow;
    9617              : 
    9618            0 :         if (!FirstHVACIteration && AirMassFlow > 0.0 && AirLoopNum > 0) {
    9619            0 :             int TotBranchNum = state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumOutletBranches;
    9620            0 :             if (TotBranchNum == 1) {
    9621            0 :                 int ZoneSideNodeNum = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum).ZoneEquipSupplyNodeNum(1);
    9622              :                 // THE MASS FLOW PRECISION of the system solver is not enough for some small air flow rate iterations , BY DEBUGGING
    9623              :                 // it may cause mass flow rate oscillations between airloop and zoneequip
    9624              :                 // specify the air flow rate directly for one-to-one system, when the iteration deviation is closing the solver precision level
    9625              :                 // 0.02 is 2 * HVACFlowRateToler, in order to accommodate the system solver precision level
    9626            0 :                 if (std::abs(AirMassFlow - state.dataLoopNodes->Node(ZoneSideNodeNum).MassFlowRate) < 0.02) {
    9627            0 :                     state.dataLoopNodes->Node(ZoneSideNodeNum).MassFlowRateMaxAvail = AirMassFlow;
    9628              :                 }
    9629            0 :                 state.dataLoopNodes->Node(ZoneSideNodeNum).MassFlowRate = AirMassFlow;
    9630              :             }
    9631              : 
    9632              :             // the below might be useful if more divergences occur
    9633              :             // Node(PrimaryAirSystem(AirLoopNumber)%Branch(1)%NodeNumIn)%MassFlowRateMaxAvail = AirMassFlow
    9634              :             // Node(PrimaryAirSystem(AirLoopNumber)%Branch(1)%NodeNumIn)%MassFlowRate = AirMassFlow
    9635              :         }
    9636              : 
    9637              :         // report variables
    9638            0 :         thisFurnace.DehumidInducedHeatingDemandRate = ReheatCoilLoad;
    9639            0 :         if (QZnReq > HVAC::SmallLoad) { // HEATING LOAD
    9640            0 :             thisFurnace.CoolingCoilSensDemand = 0.0;
    9641            0 :             thisFurnace.HeatingCoilSensDemand = QZnReq;
    9642              :         } else {
    9643            0 :             thisFurnace.CoolingCoilSensDemand = std::abs(QZnReq);
    9644            0 :             thisFurnace.HeatingCoilSensDemand = 0.0;
    9645              :         }
    9646              : 
    9647            0 :         thisFurnace.CompPartLoadRatio = state.dataFurnaces->SaveCompressorPLR;
    9648            0 :         if (thisFurnace.fanOp == HVAC::FanOp::Cycling) {
    9649            0 :             if (SupHeaterLoad > 0.0) {
    9650            0 :                 thisFurnace.FanPartLoadRatio = 1.0;
    9651              :             } else {
    9652            0 :                 if (SpeedNum < 2) {
    9653            0 :                     thisFurnace.FanPartLoadRatio = PartLoadFrac;
    9654              :                 } else {
    9655            0 :                     thisFurnace.FanPartLoadRatio = 1.0;
    9656              :                 }
    9657              :             }
    9658              :         } else {
    9659            0 :             if (UnitOn) {
    9660            0 :                 thisFurnace.FanPartLoadRatio = 1.0;
    9661              :             } else {
    9662            0 :                 if (SpeedNum < 2) {
    9663            0 :                     thisFurnace.FanPartLoadRatio = PartLoadFrac;
    9664              :                 } else {
    9665            0 :                     thisFurnace.FanPartLoadRatio = 1.0;
    9666              :                 }
    9667              :             }
    9668              :         }
    9669            0 :     }
    9670              : 
    9671              :     //******************************************************************************
    9672              : 
    9673            0 :     void ControlVSHPOutput(EnergyPlusData &state,
    9674              :                            int const FurnaceNum,                  // Unit index of engine driven heat pump
    9675              :                            bool const FirstHVACIteration,         // flag for 1st HVAC iteration in the time step
    9676              :                            HVAC::CompressorOp const compressorOp, // compressor operation; 1=on, 0=off
    9677              :                            HVAC::FanOp const fanOp,               // operating mode: FanOp::Cycling | FanOp::Continuous
    9678              :                            Real64 &QZnReq,                        // cooling or heating output needed by zone [W]
    9679              :                            Real64 QLatReq,                        // latent cooling output needed by zone [W]
    9680              :                            int &SpeedNum,                         // Speed number
    9681              :                            Real64 &SpeedRatio,                    // unit speed ratio for DX coils
    9682              :                            Real64 &PartLoadFrac,                  // unit part load fraction
    9683              :                            Real64 &OnOffAirFlowRatio,             // ratio of compressor ON airflow to AVERAGE airflow over timestep
    9684              :                            Real64 &SupHeaterLoad                  // Supplemental heater load [W]
    9685              :     )
    9686              :     {
    9687              : 
    9688              :         // SUBROUTINE INFORMATION:
    9689              :         //       AUTHOR         Bo Shen, based on HVACMultiSpeedHeatPump:ControlMSHPOutput
    9690              :         //       DATE WRITTEN   March,  2012
    9691              : 
    9692              :         // PURPOSE OF THIS SUBROUTINE:
    9693              :         // Determine the part load fraction at low speed, and speed ratio at high speed for this time step.
    9694              : 
    9695              :         // METHODOLOGY EMPLOYED:
    9696              :         // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
    9697              : 
    9698              :         // SUBROUTINE PARAMETER DEFINITIONS:
    9699            0 :         int constexpr MaxIte(500); // maximum number of iterations
    9700              : 
    9701              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    9702              :         Real64 FullOutput;   // unit full output when compressor is operating [W]
    9703              :         Real64 LowOutput;    // unit full output at low speed [W]
    9704              :         Real64 TempOutput;   // unit output when iteration limit exceeded [W]
    9705              :         Real64 NoCompOutput; // output when no active compressor [W]
    9706              :         int SolFla;          // Flag of RegulaFalsi solver
    9707              :         Real64 QCoilActual;  // coil load actually delivered returned to calling component
    9708              :         int i;               // Speed index
    9709            0 :         IntegratedHeatPump::IHPOperationMode IHPMode(IntegratedHeatPump::IHPOperationMode::Idle);
    9710              : 
    9711            0 :         SupHeaterLoad = 0.0;
    9712            0 :         PartLoadFrac = 0.0;
    9713            0 :         SpeedRatio = 0.0;
    9714            0 :         SpeedNum = 1;
    9715            0 :         Real64 LatOutput = 0.0;
    9716            0 :         Real64 noLatOutput = 0.0;
    9717            0 :         Real64 ErrorToler = 0.001; // Error tolerance for convergence from input deck
    9718              : 
    9719            0 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
    9720            0 :         if (thisFurnace.availSched->getCurrentVal() == 0.0) {
    9721            0 :             return;
    9722              :         }
    9723              : 
    9724              :         // Get result when DX coil is off
    9725            0 :         SupHeaterLoad = 0.0;
    9726            0 :         CalcVarSpeedHeatPump(state,
    9727              :                              FurnaceNum,
    9728              :                              FirstHVACIteration,
    9729              :                              compressorOp,
    9730              :                              SpeedNum,
    9731              :                              SpeedRatio,
    9732              :                              PartLoadFrac,
    9733              :                              NoCompOutput,
    9734              :                              noLatOutput,
    9735              :                              0.0,
    9736              :                              0.0,
    9737              :                              OnOffAirFlowRatio,
    9738              :                              SupHeaterLoad);
    9739              : 
    9740            0 :         if (thisFurnace.bIsIHP) {
    9741            0 :             IHPMode = IntegratedHeatPump::GetCurWorkMode(state, thisFurnace.CoolingCoilIndex);
    9742            0 :             if ((IntegratedHeatPump::IHPOperationMode::DedicatedWaterHtg == IHPMode) ||
    9743              :                 (IntegratedHeatPump::IHPOperationMode::SCWHMatchWH == IHPMode)) { // cooling capacity is a resultant
    9744            0 :                 return;
    9745              :             }
    9746              :         }
    9747              : 
    9748              :         // If cooling and NoCompOutput < QZnReq, the coil needs to be off
    9749              :         // If heating and NoCompOutput > QZnReq, the coil needs to be off
    9750              :         // If no cooling or heating and no latent load, the coil needs to be off
    9751            0 :         if (QZnReq < -HVAC::SmallLoad) {
    9752            0 :             if (NoCompOutput < QZnReq && QLatReq >= -HVAC::SmallLoad) {
    9753            0 :                 return;
    9754              :             }
    9755            0 :         } else if (QZnReq > HVAC::SmallLoad) {
    9756            0 :             if (NoCompOutput > QZnReq && QLatReq >= -HVAC::SmallLoad) {
    9757            0 :                 return;
    9758              :             }
    9759            0 :             if (QLatReq <= -HVAC::SmallLoad) {
    9760            0 :                 QZnReq = 0.0; // Zero heating load to allow dehumidification
    9761              :             }
    9762              :         } else {
    9763            0 :             if (QLatReq >= -HVAC::SmallLoad) {
    9764            0 :                 return;
    9765              :             }
    9766              :         }
    9767              : 
    9768              :         // Get full load result
    9769            0 :         PartLoadFrac = 1.0;
    9770            0 :         SpeedRatio = 1.0;
    9771            0 :         if (thisFurnace.HeatCoolMode == Furnaces::ModeOfOperation::HeatingMode) {
    9772            0 :             SpeedNum = thisFurnace.NumOfSpeedHeating;
    9773            0 :         } else if (thisFurnace.HeatCoolMode == Furnaces::ModeOfOperation::CoolingMode) {
    9774            0 :             SpeedNum = thisFurnace.NumOfSpeedCooling;
    9775            0 :         } else if (QLatReq < -HVAC::SmallLoad) {
    9776            0 :             SpeedNum = thisFurnace.NumOfSpeedCooling;
    9777              :         } else {
    9778            0 :             SpeedNum = 1;
    9779            0 :             PartLoadFrac = 0.0;
    9780              :         }
    9781              : 
    9782            0 :         if (thisFurnace.bIsIHP) {
    9783            0 :             SpeedNum = IntegratedHeatPump::GetMaxSpeedNumIHP(state, thisFurnace.CoolingCoilIndex);
    9784              :         }
    9785              : 
    9786            0 :         CalcVarSpeedHeatPump(state,
    9787              :                              FurnaceNum,
    9788              :                              FirstHVACIteration,
    9789              :                              compressorOp,
    9790              :                              SpeedNum,
    9791              :                              SpeedRatio,
    9792              :                              PartLoadFrac,
    9793              :                              FullOutput,
    9794              :                              LatOutput,
    9795              :                              QZnReq,
    9796              :                              QLatReq,
    9797              :                              OnOffAirFlowRatio,
    9798              :                              SupHeaterLoad);
    9799              : 
    9800            0 :         if (QLatReq < (-1.0 * HVAC::SmallLoad)) { // dehumidification mode
    9801            0 :             if (QLatReq <= LatOutput || (QZnReq < -HVAC::SmallLoad && QZnReq <= FullOutput) || (QZnReq > HVAC::SmallLoad && QZnReq >= FullOutput)) {
    9802            0 :                 PartLoadFrac = 1.0;
    9803            0 :                 SpeedRatio = 1.0;
    9804            0 :                 thisFurnace.CompPartLoadRatio = PartLoadFrac;
    9805            0 :                 thisFurnace.CompSpeedRatio = SpeedRatio;
    9806            0 :                 thisFurnace.CompSpeedNum = SpeedNum;
    9807            0 :                 return;
    9808              :             }
    9809            0 :         } else if (QZnReq < -HVAC::SmallLoad) {
    9810            0 :             if (QZnReq <= FullOutput) {
    9811            0 :                 PartLoadFrac = 1.0;
    9812            0 :                 SpeedRatio = 1.0;
    9813            0 :                 thisFurnace.CompPartLoadRatio = PartLoadFrac;
    9814            0 :                 thisFurnace.CompSpeedRatio = SpeedRatio;
    9815            0 :                 thisFurnace.CompSpeedNum = SpeedNum;
    9816            0 :                 return;
    9817              :             }
    9818              :         } else {
    9819            0 :             if (QZnReq >= FullOutput) {
    9820            0 :                 PartLoadFrac = 1.0;
    9821            0 :                 SpeedRatio = 1.0;
    9822              :                 // may need supplemental heating so don't return in heating mode
    9823              :             }
    9824              :         }
    9825              : 
    9826            0 :         if ((QZnReq < -HVAC::SmallLoad && NoCompOutput - QZnReq > HVAC::SmallLoad) ||
    9827            0 :             (QZnReq > HVAC::SmallLoad && QZnReq - NoCompOutput > HVAC::SmallLoad)) {
    9828            0 :             if ((QZnReq > HVAC::SmallLoad && QZnReq < FullOutput) || (QZnReq < (-1.0 * HVAC::SmallLoad) && QZnReq > FullOutput)) {
    9829              :                 // Check whether the low speed coil can meet the load or not
    9830            0 :                 CalcVarSpeedHeatPump(state,
    9831              :                                      FurnaceNum,
    9832              :                                      FirstHVACIteration,
    9833              :                                      compressorOp,
    9834              :                                      1,
    9835              :                                      0.0,
    9836              :                                      1.0,
    9837              :                                      LowOutput,
    9838              :                                      LatOutput,
    9839              :                                      QZnReq,
    9840              :                                      QLatReq,
    9841              :                                      OnOffAirFlowRatio,
    9842              :                                      SupHeaterLoad);
    9843            0 :                 if ((QZnReq > HVAC::SmallLoad && QZnReq <= LowOutput) || (QZnReq < (-HVAC::SmallLoad) && QZnReq >= LowOutput)) {
    9844              :                     // Calculate the part load fraction
    9845            0 :                     SpeedRatio = 0.0;
    9846            0 :                     SpeedNum = 1;
    9847              :                     auto f = // (AUTO_OK_LAMBDA)
    9848            0 :                         [&state, FurnaceNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, compressorOp](Real64 const PartLoadFrac) {
    9849            0 :                             return VSHPCyclingResidual(
    9850            0 :                                 state, PartLoadFrac, FurnaceNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, compressorOp, 1.0);
    9851            0 :                         };
    9852            0 :                     General::SolveRoot(state, ErrorToler, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
    9853            0 :                     if (SolFla == -1) {
    9854            0 :                         if (!state.dataGlobal->WarmupFlag) {
    9855            0 :                             if (thisFurnace.ErrCountCyc == 0) {
    9856            0 :                                 ++thisFurnace.ErrCountCyc;
    9857            0 :                                 ShowWarningError(
    9858            0 :                                     state, format("Iteration limit exceeded calculating VS WSHP unit cycling ratio, for unit={}", thisFurnace.Name));
    9859            0 :                                 ShowContinueErrorTimeStamp(state, format("Cycling ratio returned={:.2R}", PartLoadFrac));
    9860              :                             } else {
    9861            0 :                                 ShowRecurringWarningErrorAtEnd(
    9862              :                                     state,
    9863            0 :                                     thisFurnace.Name + "\": Iteration limit warning exceeding calculating DX unit cycling ratio  continues...",
    9864            0 :                                     thisFurnace.ErrIndexCyc,
    9865              :                                     PartLoadFrac,
    9866              :                                     PartLoadFrac);
    9867              :                             }
    9868              :                         }
    9869            0 :                     } else if (SolFla == -2) {
    9870            0 :                         ShowFatalError(
    9871            0 :                             state, format("VS WSHP unit cycling ratio calculation failed: cycling limits exceeded, for unit={}", thisFurnace.Name));
    9872              :                     }
    9873            0 :                 } else {
    9874              :                     // Check to see which speed to meet the load
    9875            0 :                     PartLoadFrac = 1.0;
    9876            0 :                     SpeedRatio = 1.0;
    9877            0 :                     if (QZnReq < -HVAC::SmallLoad) { // Cooling
    9878            0 :                         for (i = 2; i <= thisFurnace.NumOfSpeedCooling; ++i) {
    9879            0 :                             CalcVarSpeedHeatPump(state,
    9880              :                                                  FurnaceNum,
    9881              :                                                  FirstHVACIteration,
    9882              :                                                  compressorOp,
    9883              :                                                  i,
    9884              :                                                  SpeedRatio,
    9885              :                                                  PartLoadFrac,
    9886              :                                                  TempOutput,
    9887              :                                                  LatOutput,
    9888              :                                                  QZnReq,
    9889              :                                                  QLatReq,
    9890              :                                                  OnOffAirFlowRatio,
    9891              :                                                  SupHeaterLoad);
    9892              : 
    9893            0 :                             if (QZnReq >= TempOutput) {
    9894            0 :                                 SpeedNum = i;
    9895            0 :                                 break;
    9896              :                             }
    9897              :                         }
    9898              :                     } else {
    9899            0 :                         for (i = 2; i <= thisFurnace.NumOfSpeedHeating; ++i) {
    9900            0 :                             CalcVarSpeedHeatPump(state,
    9901              :                                                  FurnaceNum,
    9902              :                                                  FirstHVACIteration,
    9903              :                                                  compressorOp,
    9904              :                                                  i,
    9905              :                                                  SpeedRatio,
    9906              :                                                  PartLoadFrac,
    9907              :                                                  TempOutput,
    9908              :                                                  LatOutput,
    9909              :                                                  QZnReq,
    9910              :                                                  QLatReq,
    9911              :                                                  OnOffAirFlowRatio,
    9912              :                                                  SupHeaterLoad);
    9913            0 :                             if (QZnReq <= TempOutput) {
    9914            0 :                                 SpeedNum = i;
    9915            0 :                                 break;
    9916              :                             }
    9917              :                         }
    9918              :                     }
    9919            0 :                     auto f = [&state, FurnaceNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, SpeedNum, compressorOp](
    9920              :                                  Real64 const SpeedRatio) {
    9921            0 :                         return VSHPSpeedResidual(
    9922            0 :                             state, SpeedRatio, FurnaceNum, FirstHVACIteration, QZnReq, OnOffAirFlowRatio, SupHeaterLoad, SpeedNum, compressorOp, 1.0);
    9923            0 :                     };
    9924            0 :                     General::SolveRoot(state, ErrorToler, MaxIte, SolFla, SpeedRatio, f, 1.0e-10, 1.0);
    9925            0 :                     if (SolFla == -1) {
    9926            0 :                         if (!state.dataGlobal->WarmupFlag) {
    9927            0 :                             if (thisFurnace.ErrCountVar == 0) {
    9928            0 :                                 ++thisFurnace.ErrCountVar;
    9929            0 :                                 ShowWarningError(
    9930            0 :                                     state, format("Iteration limit exceeded calculating VS WSHP unit speed ratio, for unit={}", thisFurnace.Name));
    9931            0 :                                 ShowContinueErrorTimeStamp(state, format("Speed ratio returned=[{:.2R}], Speed number ={}", SpeedRatio, SpeedNum));
    9932              :                             } else {
    9933            0 :                                 ShowRecurringWarningErrorAtEnd(
    9934              :                                     state,
    9935            0 :                                     thisFurnace.Name + "\": Iteration limit warning exceeding calculating DX unit speed ratio continues...",
    9936            0 :                                     thisFurnace.ErrIndexVar,
    9937              :                                     SpeedRatio,
    9938              :                                     SpeedRatio);
    9939              :                             }
    9940              :                         }
    9941            0 :                     } else if (SolFla == -2) {
    9942            0 :                         ShowFatalError(
    9943            0 :                             state, format("VS WSHP unit compressor speed calculation failed: speed limits exceeded, for unit={}", thisFurnace.Name));
    9944              :                     }
    9945              :                 }
    9946            0 :             } else {
    9947            0 :                 LatOutput = noLatOutput; // reset full output if not needed for sensible load
    9948            0 :                 SpeedNum = 1;            // reset speed from full output test
    9949              :             }
    9950            0 :         } else {
    9951            0 :             LatOutput = noLatOutput; // reset full output if not needed for sensible load
    9952            0 :             SpeedNum = 1;            // reset speed from full output test
    9953              :         }
    9954              :         // meet the latent load
    9955            0 :         if (QLatReq < -HVAC::SmallLoad && QLatReq < LatOutput) {
    9956            0 :             PartLoadFrac = 1.0;
    9957            0 :             SpeedRatio = 1.0;
    9958            0 :             for (i = SpeedNum; i <= thisFurnace.NumOfSpeedCooling; ++i) {
    9959            0 :                 CalcVarSpeedHeatPump(state,
    9960              :                                      FurnaceNum,
    9961              :                                      FirstHVACIteration,
    9962              :                                      compressorOp,
    9963              :                                      i,
    9964              :                                      SpeedRatio,
    9965              :                                      PartLoadFrac,
    9966              :                                      TempOutput,
    9967              :                                      LatOutput,
    9968              :                                      QZnReq,
    9969              :                                      QLatReq,
    9970              :                                      OnOffAirFlowRatio,
    9971              :                                      SupHeaterLoad);
    9972              : 
    9973            0 :                 if (QLatReq > LatOutput) {
    9974            0 :                     SpeedNum = i;
    9975            0 :                     break;
    9976              :                 }
    9977              :             }
    9978            0 :             if (QLatReq - LatOutput > HVAC::SmallLoad) {
    9979            0 :                 if (SpeedNum < 2) {
    9980              :                     auto f = // (AUTO_OK_LAMBDA)
    9981            0 :                         [&state, FurnaceNum, FirstHVACIteration, QLatReq, OnOffAirFlowRatio, SupHeaterLoad, compressorOp](Real64 const PartLoadFrac) {
    9982            0 :                             return VSHPCyclingResidual(
    9983            0 :                                 state, PartLoadFrac, FurnaceNum, FirstHVACIteration, QLatReq, OnOffAirFlowRatio, SupHeaterLoad, compressorOp, 0.0);
    9984            0 :                         };
    9985            0 :                     General::SolveRoot(state, ErrorToler, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
    9986              :                 } else {
    9987            0 :                     auto f = [&state, FurnaceNum, FirstHVACIteration, QLatReq, OnOffAirFlowRatio, SupHeaterLoad, SpeedNum, compressorOp](
    9988              :                                  Real64 const SpeedRatio) {
    9989            0 :                         return VSHPSpeedResidual(state,
    9990              :                                                  SpeedRatio,
    9991              :                                                  FurnaceNum,
    9992              :                                                  FirstHVACIteration,
    9993              :                                                  QLatReq,
    9994              :                                                  OnOffAirFlowRatio,
    9995              :                                                  SupHeaterLoad,
    9996              :                                                  SpeedNum,
    9997              :                                                  compressorOp,
    9998            0 :                                                  0.0);
    9999            0 :                     };
   10000            0 :                     General::SolveRoot(state, ErrorToler, MaxIte, SolFla, SpeedRatio, f, 1.0e-10, 1.0);
   10001              :                 }
   10002            0 :                 if (SolFla == -1) {
   10003            0 :                     if (!state.dataGlobal->WarmupFlag) {
   10004            0 :                         if (thisFurnace.ErrCountVar2 == 0) {
   10005            0 :                             ++thisFurnace.ErrCountVar2;
   10006            0 :                             ShowWarningError(state,
   10007            0 :                                              format("Iteration limit exceeded calculating VS WSHP unit speed ratio, for unit={}", thisFurnace.Name));
   10008            0 :                             ShowContinueErrorTimeStamp(state, format("Speed ratio returned=[{:.2R}], Speed number ={}", SpeedRatio, SpeedNum));
   10009              :                         } else {
   10010            0 :                             ShowRecurringWarningErrorAtEnd(state,
   10011            0 :                                                            thisFurnace.Name +
   10012              :                                                                "\": Iteration limit warning exceeding calculating DX unit speed ratio continues...",
   10013            0 :                                                            thisFurnace.ErrIndexVar,
   10014              :                                                            SpeedRatio,
   10015              :                                                            SpeedRatio);
   10016              :                         }
   10017              :                     }
   10018            0 :                 } else if (SolFla == -2) {
   10019            0 :                     ShowFatalError(state,
   10020            0 :                                    format("VS WSHP unit compressor speed calculation failed: speed limits exceeded, for unit={}", thisFurnace.Name));
   10021              :                 }
   10022              :             }
   10023              :         }
   10024              :         // end meet the latent load
   10025              : 
   10026              :         // if the heating coil cannot meet the load, trim with supplemental heater
   10027              :         // occurs with constant fan mode when compressor is on or off
   10028              :         // occurs with cycling fan mode when compressor PLR is equal to 1
   10029            0 :         if ((QZnReq > HVAC::SmallLoad && QZnReq > FullOutput) && (thisFurnace.SuppHeatCoilIndex != 0)) {
   10030            0 :             PartLoadFrac = 1.0;
   10031            0 :             SpeedRatio = 1.0;
   10032            0 :             if (thisFurnace.NumOfSpeedHeating > 0) {
   10033            0 :                 SpeedNum = thisFurnace.NumOfSpeedHeating; // maximum heating speed, avoid zero for cooling only mode
   10034              :             }
   10035              : 
   10036            0 :             if (state.dataEnvrn->OutDryBulbTemp <= thisFurnace.MaxOATSuppHeat) {
   10037            0 :                 SupHeaterLoad = QZnReq - FullOutput;
   10038              :             } else {
   10039            0 :                 SupHeaterLoad = 0.0;
   10040              :             }
   10041            0 :             CalcVarSpeedHeatPump(state,
   10042              :                                  FurnaceNum,
   10043              :                                  FirstHVACIteration,
   10044              :                                  compressorOp,
   10045              :                                  SpeedNum,
   10046              :                                  SpeedRatio,
   10047              :                                  PartLoadFrac,
   10048              :                                  TempOutput,
   10049              :                                  LatOutput,
   10050              :                                  QZnReq,
   10051              :                                  QLatReq,
   10052              :                                  OnOffAirFlowRatio,
   10053              :                                  SupHeaterLoad);
   10054              :         }
   10055              : 
   10056              :         // check the outlet of the supplemental heater to be lower than the maximum supplemental heater supply air temperature
   10057            0 :         if (state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).Temp > thisFurnace.DesignMaxOutletTemp && SupHeaterLoad > 0.0) {
   10058              : 
   10059              :             //   If the supply air temperature is to high, turn off the supplemental heater to recalculate the outlet temperature
   10060            0 :             CalcNonDXHeatingCoils(state, FurnaceNum, true, FirstHVACIteration, 0.0, fanOp, QCoilActual);
   10061              :             //   If the outlet temperature is below the maximum supplemental heater supply air temperature, reduce the load passed to
   10062              :             //   the supplemental heater, otherwise leave the supplemental heater off. If the supplemental heater is to be turned on,
   10063              :             //   use the outlet conditions when the supplemental heater was off (CALL above) as the inlet conditions for the calculation
   10064              :             //   of supplemental heater load to just meet the maximum supply air temperature from the supplemental heater.
   10065            0 :             if (state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).Temp < thisFurnace.DesignMaxOutletTemp) {
   10066            0 :                 Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).HumRat);
   10067            0 :                 SupHeaterLoad = state.dataLoopNodes->Node(thisFurnace.FurnaceInletNodeNum).MassFlowRate * CpAir *
   10068            0 :                                 (thisFurnace.DesignMaxOutletTemp - state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).Temp);
   10069              : 
   10070              :             } else {
   10071            0 :                 SupHeaterLoad = 0.0;
   10072              :             }
   10073              :         }
   10074              : 
   10075              :         // prepare module level output
   10076            0 :         thisFurnace.CompPartLoadRatio = PartLoadFrac;
   10077            0 :         thisFurnace.CompSpeedRatio = SpeedRatio;
   10078            0 :         thisFurnace.CompSpeedNum = SpeedNum;
   10079            0 :         thisFurnace.CoolingCoilLatentDemand = std::abs(QLatReq);
   10080              : 
   10081            0 :         if (thisFurnace.fanOp == HVAC::FanOp::Continuous) {
   10082            0 :             thisFurnace.FanPartLoadRatio = 1.0;
   10083              :         } else {
   10084            0 :             thisFurnace.FanPartLoadRatio = PartLoadFrac;
   10085              :         }
   10086              :     }
   10087              : 
   10088              :     //******************************************************************************
   10089              : 
   10090            0 :     void CalcVarSpeedHeatPump(EnergyPlusData &state,
   10091              :                               int const FurnaceNum,                  // Variable speed heat pump number
   10092              :                               bool const FirstHVACIteration,         // Flag for 1st HVAC iteration
   10093              :                               HVAC::CompressorOp const compressorOp, // Compressor on/off; 1=on, 0=off
   10094              :                               int const SpeedNum,                    // Speed number
   10095              :                               Real64 const SpeedRatio,               // Compressor speed ratio
   10096              :                               Real64 const PartLoadFrac,             // Compressor part load fraction
   10097              :                               Real64 &SensibleLoadMet,               // Sensible cooling load met (furnace outlet with respect to control zone temp)
   10098              :                               Real64 &LatentLoadMet,     // Latent cooling load met (furnace outlet with respect to control zone humidity ratio)
   10099              :                               Real64 const QZnReq,       // Zone load (W)
   10100              :                               Real64 const QLatReq,      // Zone latent load []
   10101              :                               Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to AVERAGE airflow over timestep
   10102              :                               Real64 const SupHeaterLoad // supplemental heater load (W)
   10103              :     )
   10104              :     {
   10105              :         // SUBROUTINE INFORMATION:
   10106              :         //       AUTHOR:          Bo Shen, based on HVACMultiSpeedHeatPump:CalcMSHeatPump
   10107              :         //       DATE WRITTEN:    March 2012
   10108              : 
   10109              :         // PURPOSE OF THIS SUBROUTINE:
   10110              :         //  This routine will calculates MSHP performance based on given system load
   10111              : 
   10112            0 :         Real64 SavePartloadRatio = 0.0; // part-load ratio
   10113            0 :         Real64 SaveSpeedRatio = 0.0;    // speed ratio
   10114            0 :         Real64 QCoilActual = 0.0;       // coil load actually delivered returned to calling component
   10115            0 :         Real64 HeatCoilLoad = 0.0;      // required heating coil load
   10116              : 
   10117            0 :         state.dataFurnaces->SaveCompressorPLR = 0.0;
   10118              : 
   10119              :         // Set inlet air mass flow rate based on PLR and compressor on/off air flow rates
   10120            0 :         SetVSHPAirFlow(state, FurnaceNum, PartLoadFrac, OnOffAirFlowRatio, SpeedNum, SpeedRatio);
   10121              : 
   10122            0 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
   10123              : 
   10124            0 :         if ((SupHeaterLoad > 1.0e-10) && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool) && (thisFurnace.SuppHeatCoilIndex == 0)) {
   10125              :             // ONLY HEATING COIL, NO SUPPLEMENTAL COIL, USED FOR REHEAT DURING DUHMI
   10126            0 :             HeatCoilLoad = thisFurnace.DesignHeatingCapacity * PartLoadFrac; // REHEAT IN FAN ON TIME
   10127              : 
   10128            0 :             if (HeatCoilLoad > SupHeaterLoad) {
   10129            0 :                 HeatCoilLoad = SupHeaterLoad; // HEATING COIL RUN TIME < FAN ON TIME
   10130              :             }
   10131              : 
   10132            0 :         } else if ((QZnReq > HVAC::SmallLoad) && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10133            0 :             HeatCoilLoad = thisFurnace.DesignHeatingCapacity * PartLoadFrac;
   10134              :         } else {
   10135            0 :             HeatCoilLoad = 0.0;
   10136              :         }
   10137              : 
   10138            0 :         Real64 AirMassFlow = state.dataLoopNodes->Node(thisFurnace.FurnaceInletNodeNum).MassFlowRate;
   10139              :         // if blow through, simulate fan then coils
   10140            0 :         if (thisFurnace.fanPlace == HVAC::FanPlace::BlowThru) {
   10141            0 :             state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
   10142              : 
   10143            0 :             if ((!thisFurnace.CoolingCoilUpstream) && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10144              :                 // simulate thisFurnace heating coil
   10145            0 :                 bool SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
   10146            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, thisFurnace.fanOp, QCoilActual);
   10147              :             }
   10148              : 
   10149            0 :             if ((QZnReq < -HVAC::SmallLoad || (QLatReq < -HVAC::SmallLoad)) &&
   10150            0 :                 (state.dataEnvrn->OutDryBulbTemp >= thisFurnace.MinOATCompressorCooling)) { // COOLING MODE or dehumidification mode
   10151              : 
   10152            0 :                 if (thisFurnace.bIsIHP) {
   10153            0 :                     IntegratedHeatPump::SimIHP(state,
   10154              :                                                BlankString,
   10155            0 :                                                thisFurnace.CoolingCoilIndex,
   10156              :                                                thisFurnace.fanOp,
   10157              :                                                compressorOp,
   10158              :                                                PartLoadFrac,
   10159              :                                                SpeedNum,
   10160              :                                                SpeedRatio,
   10161              :                                                QZnReq,
   10162              :                                                QLatReq,
   10163              :                                                false,
   10164              :                                                false,
   10165              :                                                OnOffAirFlowRatio);
   10166              :                 } else {
   10167            0 :                     VariableSpeedCoils::SimVariableSpeedCoils(state,
   10168              :                                                               BlankString,
   10169            0 :                                                               thisFurnace.CoolingCoilIndex,
   10170              :                                                               thisFurnace.fanOp,
   10171              :                                                               compressorOp,
   10172              :                                                               PartLoadFrac,
   10173              :                                                               SpeedNum,
   10174              :                                                               SpeedRatio,
   10175              :                                                               QZnReq,
   10176              :                                                               QLatReq,
   10177              :                                                               OnOffAirFlowRatio);
   10178              :                 }
   10179              : 
   10180            0 :                 SavePartloadRatio = PartLoadFrac;
   10181            0 :                 SaveSpeedRatio = SpeedRatio;
   10182              : 
   10183            0 :                 state.dataFurnaces->SaveCompressorPLR = state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.CoolingCoilIndex).PartLoadRatio;
   10184              :             } else {
   10185            0 :                 if (thisFurnace.bIsIHP) {
   10186            0 :                     IntegratedHeatPump::SimIHP(state,
   10187              :                                                BlankString,
   10188            0 :                                                thisFurnace.CoolingCoilIndex,
   10189              :                                                thisFurnace.fanOp,
   10190              :                                                compressorOp,
   10191              :                                                PartLoadFrac,
   10192              :                                                SpeedNum,
   10193              :                                                SpeedRatio,
   10194              :                                                QZnReq,
   10195              :                                                QLatReq,
   10196              :                                                false,
   10197              :                                                false,
   10198              :                                                OnOffAirFlowRatio);
   10199              :                 } else {
   10200            0 :                     VariableSpeedCoils::SimVariableSpeedCoils(
   10201            0 :                         state, BlankString, thisFurnace.CoolingCoilIndex, thisFurnace.fanOp, compressorOp, 0.0, 1, 0.0, 0.0, 0.0, OnOffAirFlowRatio);
   10202              :                 }
   10203              :             }
   10204              : 
   10205            0 :             if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatCool) {
   10206            0 :                 if ((QZnReq > HVAC::SmallLoad) && state.dataFurnaces->HeatingLoad) {
   10207            0 :                     if (thisFurnace.bIsIHP) {
   10208            0 :                         IntegratedHeatPump::SimIHP(state,
   10209              :                                                    BlankString,
   10210            0 :                                                    thisFurnace.HeatingCoilIndex,
   10211              :                                                    thisFurnace.fanOp,
   10212              :                                                    compressorOp,
   10213              :                                                    PartLoadFrac,
   10214              :                                                    SpeedNum,
   10215              :                                                    SpeedRatio,
   10216              :                                                    QZnReq,
   10217              :                                                    QLatReq,
   10218              :                                                    false,
   10219              :                                                    false,
   10220              :                                                    OnOffAirFlowRatio);
   10221              :                     } else {
   10222            0 :                         VariableSpeedCoils::SimVariableSpeedCoils(state,
   10223              :                                                                   BlankString,
   10224            0 :                                                                   thisFurnace.HeatingCoilIndex,
   10225              :                                                                   thisFurnace.fanOp,
   10226              :                                                                   compressorOp,
   10227              :                                                                   PartLoadFrac,
   10228              :                                                                   SpeedNum,
   10229              :                                                                   SpeedRatio,
   10230              :                                                                   QZnReq,
   10231              :                                                                   QLatReq,
   10232              :                                                                   OnOffAirFlowRatio);
   10233              :                     }
   10234              : 
   10235            0 :                     SavePartloadRatio = PartLoadFrac;
   10236            0 :                     SaveSpeedRatio = SpeedRatio;
   10237              : 
   10238            0 :                     state.dataFurnaces->SaveCompressorPLR = state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.HeatingCoilIndex).PartLoadRatio;
   10239              :                 } else {
   10240            0 :                     if (thisFurnace.bIsIHP) {
   10241            0 :                         IntegratedHeatPump::SimIHP(state,
   10242              :                                                    BlankString,
   10243            0 :                                                    thisFurnace.CoolingCoilIndex,
   10244              :                                                    thisFurnace.fanOp,
   10245              :                                                    compressorOp,
   10246              :                                                    PartLoadFrac,
   10247              :                                                    SpeedNum,
   10248              :                                                    SpeedRatio,
   10249              :                                                    QZnReq,
   10250              :                                                    QLatReq,
   10251              :                                                    false,
   10252              :                                                    false,
   10253              :                                                    OnOffAirFlowRatio);
   10254              :                     } else {
   10255            0 :                         VariableSpeedCoils::SimVariableSpeedCoils(state,
   10256              :                                                                   BlankString,
   10257            0 :                                                                   thisFurnace.HeatingCoilIndex,
   10258              :                                                                   thisFurnace.fanOp,
   10259              :                                                                   compressorOp,
   10260              :                                                                   0.0,
   10261              :                                                                   1,
   10262              :                                                                   0.0,
   10263              :                                                                   0.0,
   10264              :                                                                   0.0,
   10265              :                                                                   OnOffAirFlowRatio);
   10266              :                     }
   10267              :                 }
   10268            0 :             } else if (thisFurnace.CoolingCoilUpstream && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10269              :                 // simulate thisFurnace heating coil
   10270            0 :                 bool SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
   10271            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, thisFurnace.fanOp, QCoilActual);
   10272              :             }
   10273              : 
   10274              :             // Call twice to ensure the fan outlet conditions are updated
   10275            0 :             state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
   10276              : 
   10277            0 :             if ((!thisFurnace.CoolingCoilUpstream) && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10278              :                 // simulate thisFurnace heating coil
   10279            0 :                 bool SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
   10280            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, thisFurnace.fanOp, QCoilActual);
   10281              :             }
   10282              : 
   10283            0 :             if ((QZnReq < -HVAC::SmallLoad || (QLatReq < -HVAC::SmallLoad)) &&
   10284            0 :                 (state.dataEnvrn->OutDryBulbTemp >= thisFurnace.MinOATCompressorCooling)) {
   10285              : 
   10286            0 :                 if (thisFurnace.bIsIHP) {
   10287            0 :                     IntegratedHeatPump::SimIHP(state,
   10288              :                                                BlankString,
   10289            0 :                                                thisFurnace.CoolingCoilIndex,
   10290              :                                                thisFurnace.fanOp,
   10291              :                                                compressorOp,
   10292              :                                                PartLoadFrac,
   10293              :                                                SpeedNum,
   10294              :                                                SpeedRatio,
   10295              :                                                QZnReq,
   10296              :                                                QLatReq,
   10297              :                                                false,
   10298              :                                                false,
   10299              :                                                OnOffAirFlowRatio);
   10300              :                 } else {
   10301            0 :                     VariableSpeedCoils::SimVariableSpeedCoils(state,
   10302              :                                                               BlankString,
   10303            0 :                                                               thisFurnace.CoolingCoilIndex,
   10304              :                                                               thisFurnace.fanOp,
   10305              :                                                               compressorOp,
   10306              :                                                               PartLoadFrac,
   10307              :                                                               SpeedNum,
   10308              :                                                               SpeedRatio,
   10309              :                                                               QZnReq,
   10310              :                                                               QLatReq,
   10311              :                                                               OnOffAirFlowRatio);
   10312              :                 }
   10313              : 
   10314            0 :                 SavePartloadRatio = PartLoadFrac;
   10315            0 :                 SaveSpeedRatio = SpeedRatio;
   10316            0 :                 state.dataFurnaces->SaveCompressorPLR = state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.CoolingCoilIndex).PartLoadRatio;
   10317              :             } else {
   10318              : 
   10319            0 :                 if (thisFurnace.bIsIHP) {
   10320            0 :                     IntegratedHeatPump::SimIHP(state,
   10321              :                                                BlankString,
   10322            0 :                                                thisFurnace.CoolingCoilIndex,
   10323              :                                                thisFurnace.fanOp,
   10324              :                                                compressorOp,
   10325              :                                                PartLoadFrac,
   10326              :                                                SpeedNum,
   10327              :                                                SpeedRatio,
   10328              :                                                QZnReq,
   10329              :                                                QLatReq,
   10330              :                                                false,
   10331              :                                                false,
   10332              :                                                OnOffAirFlowRatio);
   10333              :                 } else {
   10334            0 :                     VariableSpeedCoils::SimVariableSpeedCoils(
   10335            0 :                         state, BlankString, thisFurnace.CoolingCoilIndex, thisFurnace.fanOp, compressorOp, 0.0, 1, 0.0, 0.0, 0.0, OnOffAirFlowRatio);
   10336              :                 }
   10337              :             }
   10338              : 
   10339            0 :             if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatCool) {
   10340            0 :                 if ((QZnReq > HVAC::SmallLoad) && state.dataFurnaces->HeatingLoad) {
   10341            0 :                     if (thisFurnace.bIsIHP) {
   10342            0 :                         IntegratedHeatPump::SimIHP(state,
   10343              :                                                    BlankString,
   10344            0 :                                                    thisFurnace.HeatingCoilIndex,
   10345              :                                                    thisFurnace.fanOp,
   10346              :                                                    compressorOp,
   10347              :                                                    PartLoadFrac,
   10348              :                                                    SpeedNum,
   10349              :                                                    SpeedRatio,
   10350              :                                                    QZnReq,
   10351              :                                                    QLatReq,
   10352              :                                                    false,
   10353              :                                                    false,
   10354              :                                                    OnOffAirFlowRatio);
   10355              :                     } else {
   10356            0 :                         VariableSpeedCoils::SimVariableSpeedCoils(state,
   10357              :                                                                   BlankString,
   10358            0 :                                                                   thisFurnace.HeatingCoilIndex,
   10359              :                                                                   thisFurnace.fanOp,
   10360              :                                                                   compressorOp,
   10361              :                                                                   PartLoadFrac,
   10362              :                                                                   SpeedNum,
   10363              :                                                                   SpeedRatio,
   10364              :                                                                   QZnReq,
   10365              :                                                                   QLatReq,
   10366              :                                                                   OnOffAirFlowRatio);
   10367              :                     }
   10368              : 
   10369            0 :                     SavePartloadRatio = PartLoadFrac;
   10370            0 :                     SaveSpeedRatio = SpeedRatio;
   10371            0 :                     state.dataFurnaces->SaveCompressorPLR = state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.HeatingCoilIndex).PartLoadRatio;
   10372              :                 } else {
   10373            0 :                     if (thisFurnace.bIsIHP) {
   10374            0 :                         IntegratedHeatPump::SimIHP(state,
   10375              :                                                    BlankString,
   10376            0 :                                                    thisFurnace.CoolingCoilIndex,
   10377              :                                                    thisFurnace.fanOp,
   10378              :                                                    compressorOp,
   10379              :                                                    PartLoadFrac,
   10380              :                                                    SpeedNum,
   10381              :                                                    SpeedRatio,
   10382              :                                                    QZnReq,
   10383              :                                                    QLatReq,
   10384              :                                                    false,
   10385              :                                                    false,
   10386              :                                                    OnOffAirFlowRatio);
   10387              :                     } else {
   10388            0 :                         VariableSpeedCoils::SimVariableSpeedCoils(state,
   10389              :                                                                   BlankString,
   10390            0 :                                                                   thisFurnace.HeatingCoilIndex,
   10391              :                                                                   thisFurnace.fanOp,
   10392              :                                                                   compressorOp,
   10393              :                                                                   0.0,
   10394              :                                                                   1,
   10395              :                                                                   0.0,
   10396              :                                                                   0.0,
   10397              :                                                                   0.0,
   10398              :                                                                   OnOffAirFlowRatio);
   10399              :                     }
   10400              :                 }
   10401            0 :             } else if (thisFurnace.CoolingCoilUpstream && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10402              :                 // simulate thisFurnace heating coil
   10403            0 :                 bool SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
   10404            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, thisFurnace.fanOp, QCoilActual);
   10405              :             }
   10406              : 
   10407              :             //  Simulate supplemental heating coil for blow through fan
   10408            0 :             if (thisFurnace.SuppHeatCoilIndex > 0) {
   10409            0 :                 bool SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
   10410            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, SupHeaterLoad, thisFurnace.fanOp, QCoilActual);
   10411              :             }
   10412              :         } else { // otherwise simulate DX coils then fan then supplemental heater
   10413              : 
   10414            0 :             if ((!thisFurnace.CoolingCoilUpstream) && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10415              :                 // simulate thisFurnace heating coil
   10416            0 :                 bool SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
   10417            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, thisFurnace.fanOp, QCoilActual);
   10418              :             }
   10419              : 
   10420            0 :             if ((QZnReq < -HVAC::SmallLoad || (QLatReq < -HVAC::SmallLoad)) &&
   10421            0 :                 (state.dataEnvrn->OutDryBulbTemp >= thisFurnace.MinOATCompressorCooling)) {
   10422              : 
   10423            0 :                 if (thisFurnace.bIsIHP) {
   10424            0 :                     IntegratedHeatPump::SimIHP(state,
   10425              :                                                BlankString,
   10426            0 :                                                thisFurnace.CoolingCoilIndex,
   10427              :                                                thisFurnace.fanOp,
   10428              :                                                compressorOp,
   10429              :                                                PartLoadFrac,
   10430              :                                                SpeedNum,
   10431              :                                                SpeedRatio,
   10432              :                                                QZnReq,
   10433              :                                                QLatReq,
   10434              :                                                false,
   10435              :                                                false,
   10436              :                                                OnOffAirFlowRatio);
   10437              :                 } else {
   10438            0 :                     VariableSpeedCoils::SimVariableSpeedCoils(state,
   10439              :                                                               BlankString,
   10440            0 :                                                               thisFurnace.CoolingCoilIndex,
   10441              :                                                               thisFurnace.fanOp,
   10442              :                                                               compressorOp,
   10443              :                                                               PartLoadFrac,
   10444              :                                                               SpeedNum,
   10445              :                                                               SpeedRatio,
   10446              :                                                               QZnReq,
   10447              :                                                               QLatReq,
   10448              :                                                               OnOffAirFlowRatio);
   10449              :                 }
   10450              : 
   10451            0 :                 SavePartloadRatio = PartLoadFrac;
   10452            0 :                 SaveSpeedRatio = SpeedRatio;
   10453              : 
   10454            0 :                 state.dataFurnaces->SaveCompressorPLR = state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.CoolingCoilIndex).PartLoadRatio;
   10455              :             } else {
   10456            0 :                 if (thisFurnace.bIsIHP) {
   10457            0 :                     IntegratedHeatPump::SimIHP(state,
   10458              :                                                BlankString,
   10459            0 :                                                thisFurnace.CoolingCoilIndex,
   10460              :                                                thisFurnace.fanOp,
   10461              :                                                compressorOp,
   10462              :                                                PartLoadFrac,
   10463              :                                                SpeedNum,
   10464              :                                                SpeedRatio,
   10465              :                                                QZnReq,
   10466              :                                                QLatReq,
   10467              :                                                false,
   10468              :                                                false,
   10469              :                                                OnOffAirFlowRatio);
   10470              :                 } else {
   10471            0 :                     VariableSpeedCoils::SimVariableSpeedCoils(
   10472            0 :                         state, BlankString, thisFurnace.CoolingCoilIndex, thisFurnace.fanOp, compressorOp, 0.0, 1, 0.0, 0.0, 0.0, OnOffAirFlowRatio);
   10473              :                 }
   10474              :             }
   10475              : 
   10476            0 :             if (thisFurnace.type != HVAC::UnitarySysType::Unitary_HeatCool) {
   10477            0 :                 if (QZnReq > HVAC::SmallLoad && (state.dataEnvrn->OutDryBulbTemp >= thisFurnace.MinOATCompressorCooling)) {
   10478              : 
   10479            0 :                     if (thisFurnace.bIsIHP) {
   10480            0 :                         IntegratedHeatPump::SimIHP(state,
   10481              :                                                    BlankString,
   10482            0 :                                                    thisFurnace.HeatingCoilIndex,
   10483              :                                                    thisFurnace.fanOp,
   10484              :                                                    compressorOp,
   10485              :                                                    PartLoadFrac,
   10486              :                                                    SpeedNum,
   10487              :                                                    SpeedRatio,
   10488              :                                                    QZnReq,
   10489              :                                                    QLatReq,
   10490              :                                                    false,
   10491              :                                                    false,
   10492              :                                                    OnOffAirFlowRatio);
   10493              :                     } else {
   10494            0 :                         VariableSpeedCoils::SimVariableSpeedCoils(state,
   10495              :                                                                   BlankString,
   10496            0 :                                                                   thisFurnace.HeatingCoilIndex,
   10497              :                                                                   thisFurnace.fanOp,
   10498              :                                                                   compressorOp,
   10499              :                                                                   PartLoadFrac,
   10500              :                                                                   SpeedNum,
   10501              :                                                                   SpeedRatio,
   10502              :                                                                   QZnReq,
   10503              :                                                                   QLatReq,
   10504              :                                                                   OnOffAirFlowRatio);
   10505              :                     }
   10506              : 
   10507            0 :                     SavePartloadRatio = PartLoadFrac;
   10508            0 :                     SaveSpeedRatio = SpeedRatio;
   10509            0 :                     state.dataFurnaces->SaveCompressorPLR = state.dataVariableSpeedCoils->VarSpeedCoil(thisFurnace.HeatingCoilIndex).PartLoadRatio;
   10510              :                 } else {
   10511            0 :                     if (thisFurnace.bIsIHP) {
   10512            0 :                         IntegratedHeatPump::SimIHP(state,
   10513              :                                                    BlankString,
   10514            0 :                                                    thisFurnace.CoolingCoilIndex,
   10515              :                                                    thisFurnace.fanOp,
   10516              :                                                    compressorOp,
   10517              :                                                    PartLoadFrac,
   10518              :                                                    SpeedNum,
   10519              :                                                    SpeedRatio,
   10520              :                                                    QZnReq,
   10521              :                                                    QLatReq,
   10522              :                                                    false,
   10523              :                                                    false,
   10524              :                                                    OnOffAirFlowRatio);
   10525              :                     } else {
   10526            0 :                         VariableSpeedCoils::SimVariableSpeedCoils(state,
   10527              :                                                                   BlankString,
   10528            0 :                                                                   thisFurnace.HeatingCoilIndex,
   10529              :                                                                   thisFurnace.fanOp,
   10530              :                                                                   compressorOp,
   10531              :                                                                   0.0,
   10532              :                                                                   1,
   10533              :                                                                   0.0,
   10534              :                                                                   0.0,
   10535              :                                                                   0.0,
   10536              :                                                                   OnOffAirFlowRatio);
   10537              :                     }
   10538              :                 }
   10539            0 :             } else if (thisFurnace.CoolingCoilUpstream && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10540              :                 // simulate thisFurnace heating coil
   10541            0 :                 bool SuppHeatingCoilFlag = false; // if true simulates supplemental heating coil
   10542            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, HeatCoilLoad, thisFurnace.fanOp, QCoilActual);
   10543              :             }
   10544              : 
   10545            0 :             state.dataFans->fans(thisFurnace.FanIndex)->simulate(state, FirstHVACIteration, state.dataFurnaces->FanSpeedRatio);
   10546              :             //  Simulate supplemental heating coil for draw through fan
   10547            0 :             if (thisFurnace.SuppHeatCoilIndex > 0) {
   10548            0 :                 bool SuppHeatingCoilFlag = true; // if true simulates supplemental heating coil
   10549            0 :                 CalcNonDXHeatingCoils(state, FurnaceNum, SuppHeatingCoilFlag, FirstHVACIteration, SupHeaterLoad, thisFurnace.fanOp, QCoilActual);
   10550              :             }
   10551              :         }
   10552              : 
   10553              :         // If the fan runs continually do not allow coils to set OnOffFanPartLoadRatio.
   10554            0 :         if (thisFurnace.fanOp == HVAC::FanOp::Continuous) {
   10555            0 :             state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
   10556              :         }
   10557              : 
   10558            0 :         auto &outNode = state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum);
   10559            0 :         auto &zoneNode = state.dataLoopNodes->Node(thisFurnace.NodeNumOfControlledZone);
   10560            0 :         Real64 zoneEnthalpy = Psychrometrics::PsyHFnTdbW(zoneNode.Temp, zoneNode.HumRat);
   10561            0 :         Real64 outletEnthalpy = Psychrometrics::PsyHFnTdbW(outNode.Temp, outNode.HumRat);
   10562            0 :         Real64 totalLoadMet = AirMassFlow * (outletEnthalpy - zoneEnthalpy);
   10563            0 :         SensibleLoadMet =
   10564            0 :             AirMassFlow * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(outNode.Temp, outNode.HumRat, zoneNode.Temp, zoneNode.HumRat); // sensible {W};
   10565            0 :         LatentLoadMet = totalLoadMet - SensibleLoadMet;
   10566            0 :         thisFurnace.LatentLoadMet = LatentLoadMet;
   10567            0 :     }
   10568              : 
   10569              :     //******************************************************************************
   10570              : 
   10571            0 :     Real64 VSHPCyclingResidual(EnergyPlusData &state,
   10572              :                                Real64 const PartLoadFrac, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
   10573              :                                int FurnaceNum,
   10574              :                                // int ZoneNum,
   10575              :                                bool FirstHVACIteration,
   10576              :                                // int fanOp,
   10577              :                                Real64 LoadToBeMet,
   10578              :                                Real64 OnOffAirFlowRatio,
   10579              :                                Real64 SupHeaterLoad,
   10580              :                                HVAC::CompressorOp compressorOp,
   10581              :                                Real64 par9_SensLatFlag)
   10582              :     {
   10583              :         // FUNCTION INFORMATION:
   10584              :         //       AUTHOR         Bo Shen, based on HVACMultiSpeedHeatPump:MSHPCyclingResidual
   10585              :         //       DATE WRITTEN   March, 2012
   10586              : 
   10587              :         // PURPOSE OF THIS FUNCTION:
   10588              :         //  Calculates residual function ((ActualOutput - QZnReq)/QZnReq)
   10589              :         //  MSHP output depends on the part load ratio which is being varied to zero the residual.
   10590              : 
   10591              :         // METHODOLOGY EMPLOYED:
   10592              :         //  Calls CalcMSHeatPump to get ActualOutput at the given part load ratio
   10593              :         //  and calculates the residual as defined above
   10594              : 
   10595              :         // int FurnaceNum = int(Par[0]);
   10596              :         // int ZoneNum = int(Par[1]);
   10597              :         // bool FirstHVACIteration = (Par[2] == 1.0);
   10598              :         // int fanOp = int(Par[3]);
   10599              :         // Real64 LoadToBeMet = Par[4];
   10600              :         // Real64 OnOffAirFlowRatio = Par[5];
   10601              :         // Real64 SupHeaterLoad = Par[6];
   10602              :         // CompressorOperation CompressorOp = static_cast<CompressorOperation>(Par[8]);
   10603              :         // Real64 par9_SensLatFlag = Par[9];
   10604              : 
   10605              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
   10606              :         Real64 ZoneSensLoadMet; // delivered sensible capacity of MSHP
   10607              :         Real64 ZoneLatLoadMet;  // delivered latent capacity of MSHP
   10608              : 
   10609            0 :         Real64 QZnReq = 0.0;
   10610            0 :         Real64 QZnLat = 0.0;
   10611            0 :         if (par9_SensLatFlag == 1.0) {
   10612            0 :             QZnReq = LoadToBeMet;
   10613              :         } else {
   10614            0 :             QZnLat = LoadToBeMet;
   10615              :         }
   10616              : 
   10617            0 :         CalcVarSpeedHeatPump(state,
   10618              :                              FurnaceNum,
   10619              :                              FirstHVACIteration,
   10620              :                              compressorOp,
   10621              :                              1,
   10622              :                              0.0,
   10623              :                              PartLoadFrac,
   10624              :                              ZoneSensLoadMet,
   10625              :                              ZoneLatLoadMet,
   10626              :                              QZnReq,
   10627              :                              QZnLat,
   10628              :                              OnOffAirFlowRatio,
   10629              :                              SupHeaterLoad);
   10630              : 
   10631            0 :         Real64 ResScale = std::abs(LoadToBeMet);
   10632            0 :         if (ResScale < 100.0) {
   10633            0 :             ResScale = 100.0;
   10634              :         } else {
   10635            0 :             ResScale = LoadToBeMet;
   10636              :         }
   10637              : 
   10638              :         // Calculate residual based on output calculation flag
   10639            0 :         if (par9_SensLatFlag == 1.0) {
   10640            0 :             return (ZoneSensLoadMet - LoadToBeMet) / ResScale;
   10641              :         } else {
   10642            0 :             return (ZoneLatLoadMet - LoadToBeMet) / ResScale;
   10643              :         }
   10644              :     }
   10645              : 
   10646              :     //******************************************************************************
   10647              : 
   10648            0 :     Real64 VSHPSpeedResidual(EnergyPlusData &state,
   10649              :                              Real64 const SpeedRatio, // compressor cycling ratio (1.0 is continuous, 0.0 is off)
   10650              :                              int FurnaceNum,
   10651              :                              // int ZoneNum,
   10652              :                              bool FirstHVACIteration,
   10653              :                              // int fanOp
   10654              :                              Real64 LoadToBeMet,
   10655              :                              Real64 OnOffAirFlowRatio,
   10656              :                              Real64 SupHeaterLoad,
   10657              :                              int SpeedNum,
   10658              :                              HVAC::CompressorOp compressorOp,
   10659              :                              Real64 par9_SensLatFlag)
   10660              :     {
   10661              :         // FUNCTION INFORMATION:
   10662              :         //       AUTHOR         Bo Shen, , based on HVACMultiSpeedHeatPump:MSHPVarSpeedgResidual
   10663              :         //       DATE WRITTEN   March, 2012
   10664              : 
   10665              :         // PURPOSE OF THIS FUNCTION:
   10666              :         //  Calculates residual function ((ActualOutput - QZnReq)/QZnReq)
   10667              :         //  MSHP output depends on the part load ratio which is being varied to zero the residual.
   10668              : 
   10669              :         // METHODOLOGY EMPLOYED:
   10670              :         //  Calls CalcMSHeatPump to get ActualOutput at the given speed ratio (partload ratio for high speed)
   10671              :         //  and calculates the residual as defined above
   10672              : 
   10673            0 :         Real64 QZnReq = 0.0;
   10674            0 :         Real64 QZnLat = 0.0;
   10675            0 :         if (par9_SensLatFlag == 1.0) {
   10676            0 :             QZnReq = LoadToBeMet;
   10677              :         } else {
   10678            0 :             QZnLat = LoadToBeMet;
   10679              :         }
   10680              : 
   10681              :         Real64 ZoneSensLoadMet; // delivered sensible capacity of MSHP
   10682              :         Real64 ZoneLatLoadMet;  // delivered latent capacity of MSHP
   10683            0 :         CalcVarSpeedHeatPump(state,
   10684              :                              FurnaceNum,
   10685              :                              FirstHVACIteration,
   10686              :                              compressorOp,
   10687              :                              SpeedNum,
   10688              :                              SpeedRatio,
   10689              :                              1.0,
   10690              :                              ZoneSensLoadMet,
   10691              :                              ZoneLatLoadMet,
   10692              :                              QZnReq,
   10693              :                              QZnLat,
   10694              :                              OnOffAirFlowRatio,
   10695              :                              SupHeaterLoad);
   10696              : 
   10697            0 :         Real64 ResScale = std::abs(LoadToBeMet);
   10698            0 :         if (ResScale < 100.0) {
   10699            0 :             ResScale = 100.0;
   10700              :         } else {
   10701            0 :             ResScale = LoadToBeMet;
   10702              :         }
   10703              : 
   10704              :         // Calculate residual based on output calculation flag
   10705            0 :         if (par9_SensLatFlag == 1.0) {
   10706            0 :             return (ZoneSensLoadMet - LoadToBeMet) / ResScale;
   10707              :         } else {
   10708            0 :             return (ZoneLatLoadMet - LoadToBeMet) / ResScale;
   10709              :         }
   10710              :     }
   10711              : 
   10712            9 :     void SetVSHPAirFlow(EnergyPlusData &state,
   10713              :                         int const FurnaceNum,                        // Unit index
   10714              :                         Real64 const PartLoadRatio,                  // unit part load ratio
   10715              :                         Real64 &OnOffAirFlowRatio,                   // ratio of compressor ON airflow to average airflow over timestep
   10716              :                         ObjexxFCL::Optional_int_const SpeedNum,      // Speed number
   10717              :                         ObjexxFCL::Optional<Real64 const> SpeedRatio // Speed ratio
   10718              :     )
   10719              :     {
   10720              : 
   10721              :         // SUBROUTINE INFORMATION:
   10722              :         //       AUTHOR         Bo Shen, based on HVACMultiSpeedHeatPump:SetAverageAirFlow
   10723              :         //       DATE WRITTEN   March, 2012
   10724              : 
   10725              :         // PURPOSE OF THIS SUBROUTINE:
   10726              :         // Set the average air mass flow rates using the part load fraction of the heat pump for this time step
   10727              :         // Set OnOffAirFlowRatio to be used by DX coils
   10728              : 
   10729              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
   10730              :         Real64 AverageUnitMassFlow; // average supply air mass flow rate over time step
   10731              : 
   10732            9 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
   10733              : 
   10734            9 :         state.dataHVACGlobal->MSHPMassFlowRateLow = 0.0;  // Mass flow rate at low speed
   10735            9 :         state.dataHVACGlobal->MSHPMassFlowRateHigh = 0.0; // Mass flow rate at high speed
   10736              : 
   10737            9 :         if (thisFurnace.fanOp == HVAC::FanOp::Continuous) {
   10738            1 :             state.dataFurnaces->CompOffMassFlow = thisFurnace.IdleMassFlowRate;
   10739            1 :             state.dataFurnaces->CompOffFlowRatio = thisFurnace.IdleSpeedRatio;
   10740              :         } else {
   10741            8 :             state.dataFurnaces->CompOffMassFlow = 0.0;
   10742            8 :             state.dataFurnaces->CompOffFlowRatio = 0.0;
   10743              :         }
   10744              : 
   10745            9 :         if (state.dataFurnaces->CoolingLoad && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10746            3 :             if (thisFurnace.NumOfSpeedCooling > 0) {
   10747            3 :                 state.dataFurnaces->CompOnMassFlow = thisFurnace.CoolMassFlowRate(thisFurnace.NumOfSpeedCooling);
   10748            3 :                 state.dataFurnaces->CompOnFlowRatio = thisFurnace.MSCoolingSpeedRatio(thisFurnace.NumOfSpeedCooling);
   10749            3 :                 state.dataHVACGlobal->MSHPMassFlowRateLow = thisFurnace.CoolMassFlowRate(thisFurnace.NumOfSpeedCooling);
   10750            3 :                 state.dataHVACGlobal->MSHPMassFlowRateHigh = thisFurnace.CoolMassFlowRate(thisFurnace.NumOfSpeedCooling);
   10751              :             } else {
   10752            0 :                 state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxCoolAirMassFlow;
   10753            0 :                 state.dataFurnaces->CompOnFlowRatio = thisFurnace.CoolingSpeedRatio;
   10754              :             }
   10755            3 :             AverageUnitMassFlow = (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
   10756            3 :             if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
   10757            0 :                 state.dataFurnaces->FanSpeedRatio =
   10758            0 :                     (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
   10759              :             } else {
   10760            3 :                 state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
   10761              :             }
   10762            6 :         } else if (state.dataFurnaces->HeatingLoad && (thisFurnace.type == HVAC::UnitarySysType::Unitary_HeatCool)) {
   10763            6 :             if (thisFurnace.NumOfSpeedHeating > 0) {
   10764            4 :                 state.dataFurnaces->CompOnMassFlow = thisFurnace.HeatMassFlowRate(thisFurnace.NumOfSpeedHeating);
   10765            4 :                 state.dataFurnaces->CompOnFlowRatio = thisFurnace.MSHeatingSpeedRatio(thisFurnace.NumOfSpeedHeating);
   10766            4 :                 state.dataHVACGlobal->MSHPMassFlowRateLow = thisFurnace.HeatMassFlowRate(thisFurnace.NumOfSpeedHeating);
   10767            4 :                 state.dataHVACGlobal->MSHPMassFlowRateHigh = thisFurnace.HeatMassFlowRate(thisFurnace.NumOfSpeedHeating);
   10768              :             } else {
   10769            2 :                 state.dataFurnaces->CompOnMassFlow = thisFurnace.MaxHeatAirMassFlow;
   10770            2 :                 state.dataFurnaces->CompOnFlowRatio = thisFurnace.HeatingSpeedRatio;
   10771              :             }
   10772            6 :             AverageUnitMassFlow = (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
   10773            6 :             if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
   10774            1 :                 state.dataFurnaces->FanSpeedRatio =
   10775            1 :                     (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
   10776              :             } else {
   10777            5 :                 state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
   10778              :             }
   10779            0 :         } else if (thisFurnace.bIsIHP) {
   10780            0 :             if (!state.dataZoneEnergyDemand->CurDeadBandOrSetback(thisFurnace.ControlZoneNum) && present(SpeedNum)) {
   10781              :                 // if(present(SpeedNum)) {
   10782            0 :                 state.dataFurnaces->CompOnMassFlow =
   10783            0 :                     IntegratedHeatPump::GetAirMassFlowRateIHP(state, thisFurnace.CoolingCoilIndex, SpeedNum, SpeedRatio, false);
   10784            0 :                 state.dataFurnaces->CompOnFlowRatio =
   10785            0 :                     state.dataFurnaces->CompOnMassFlow /
   10786            0 :                     IntegratedHeatPump::GetAirMassFlowRateIHP(
   10787              :                         state, thisFurnace.CoolingCoilIndex, IntegratedHeatPump::GetMaxSpeedNumIHP(state, thisFurnace.CoolingCoilIndex), 1.0, false);
   10788            0 :                 state.dataHVACGlobal->MSHPMassFlowRateLow =
   10789            0 :                     IntegratedHeatPump::GetAirMassFlowRateIHP(state, thisFurnace.CoolingCoilIndex, SpeedNum, 0.0, false);
   10790            0 :                 state.dataHVACGlobal->MSHPMassFlowRateHigh =
   10791            0 :                     IntegratedHeatPump::GetAirMassFlowRateIHP(state, thisFurnace.CoolingCoilIndex, SpeedNum, 1.0, false);
   10792              :             }
   10793              : 
   10794              :             // Set up fan flow rate during compressor off time
   10795            0 :             if (thisFurnace.fanOp == HVAC::FanOp::Continuous && present(SpeedNum)) {
   10796            0 :                 if (thisFurnace.AirFlowControl == AirFlowControlConstFan::UseCompressorOnFlow && state.dataFurnaces->CompOnMassFlow > 0.0) {
   10797            0 :                     state.dataFurnaces->CompOffMassFlow =
   10798            0 :                         IntegratedHeatPump::GetAirMassFlowRateIHP(state, thisFurnace.CoolingCoilIndex, SpeedNum, 1.0, false);
   10799            0 :                     state.dataFurnaces->CompOffFlowRatio =
   10800            0 :                         state.dataFurnaces->CompOffMassFlow /
   10801            0 :                         IntegratedHeatPump::GetAirMassFlowRateIHP(state,
   10802              :                                                                   thisFurnace.CoolingCoilIndex,
   10803              :                                                                   IntegratedHeatPump::GetMaxSpeedNumIHP(state, thisFurnace.CoolingCoilIndex),
   10804              :                                                                   1.0,
   10805              :                                                                   false);
   10806              :                 }
   10807              :             }
   10808              : 
   10809            0 :             if (present(SpeedNum)) {
   10810            0 :                 if (SpeedNum > 1) {
   10811            0 :                     AverageUnitMassFlow = state.dataFurnaces->CompOnMassFlow;
   10812            0 :                     state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
   10813              :                 } else {
   10814            0 :                     AverageUnitMassFlow =
   10815            0 :                         (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
   10816            0 :                     if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
   10817            0 :                         state.dataFurnaces->FanSpeedRatio =
   10818            0 :                             (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
   10819              :                     } else {
   10820            0 :                         state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
   10821              :                     }
   10822              :                 }
   10823              :             } else {
   10824            0 :                 AverageUnitMassFlow =
   10825            0 :                     (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
   10826            0 :                 if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
   10827            0 :                     state.dataFurnaces->FanSpeedRatio =
   10828            0 :                         (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
   10829              :                 } else {
   10830            0 :                     state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
   10831              :                 }
   10832              :             }
   10833              : 
   10834            0 :             if (IntegratedHeatPump::IHPOperationMode::SCWHMatchWH ==
   10835            0 :                 state.dataIntegratedHP->IntegratedHeatPumps(thisFurnace.CoolingCoilIndex).CurMode) {
   10836            0 :                 state.dataFurnaces->CompOnMassFlow =
   10837            0 :                     IntegratedHeatPump::GetAirMassFlowRateIHP(state, thisFurnace.CoolingCoilIndex, SpeedNum, SpeedRatio, false);
   10838            0 :                 AverageUnitMassFlow = state.dataFurnaces->CompOnMassFlow;
   10839              :             }
   10840              :         } else {
   10841            0 :             if (!state.dataZoneEnergyDemand->CurDeadBandOrSetback(thisFurnace.ControlZoneNum) && present(SpeedNum)) {
   10842            0 :                 if (thisFurnace.HeatCoolMode == Furnaces::ModeOfOperation::HeatingMode) {
   10843            0 :                     if (SpeedNum == 1) {
   10844            0 :                         state.dataFurnaces->CompOnMassFlow = thisFurnace.HeatMassFlowRate(SpeedNum);
   10845            0 :                         state.dataFurnaces->CompOnFlowRatio = thisFurnace.MSHeatingSpeedRatio(SpeedNum);
   10846            0 :                         state.dataHVACGlobal->MSHPMassFlowRateLow = thisFurnace.HeatMassFlowRate(1);
   10847            0 :                         state.dataHVACGlobal->MSHPMassFlowRateHigh = thisFurnace.HeatMassFlowRate(1);
   10848            0 :                     } else if (SpeedNum > 1) {
   10849            0 :                         state.dataFurnaces->CompOnMassFlow =
   10850            0 :                             SpeedRatio * thisFurnace.HeatMassFlowRate(SpeedNum) + (1.0 - SpeedRatio) * thisFurnace.HeatMassFlowRate(SpeedNum - 1);
   10851            0 :                         state.dataFurnaces->CompOnFlowRatio = SpeedRatio * thisFurnace.MSHeatingSpeedRatio(SpeedNum) +
   10852            0 :                                                               (1.0 - SpeedRatio) * thisFurnace.MSHeatingSpeedRatio(SpeedNum - 1);
   10853            0 :                         state.dataHVACGlobal->MSHPMassFlowRateLow = thisFurnace.HeatMassFlowRate(SpeedNum - 1);
   10854            0 :                         state.dataHVACGlobal->MSHPMassFlowRateHigh = thisFurnace.HeatMassFlowRate(SpeedNum);
   10855              :                     }
   10856            0 :                 } else if (thisFurnace.HeatCoolMode == Furnaces::ModeOfOperation::CoolingMode) {
   10857            0 :                     if (SpeedNum == 1) {
   10858            0 :                         state.dataFurnaces->CompOnMassFlow = thisFurnace.CoolMassFlowRate(SpeedNum);
   10859            0 :                         state.dataFurnaces->CompOnFlowRatio = thisFurnace.MSCoolingSpeedRatio(SpeedNum);
   10860            0 :                         state.dataHVACGlobal->MSHPMassFlowRateLow = thisFurnace.CoolMassFlowRate(1);
   10861            0 :                         state.dataHVACGlobal->MSHPMassFlowRateHigh = thisFurnace.CoolMassFlowRate(1);
   10862            0 :                     } else if (SpeedNum > 1) {
   10863            0 :                         state.dataFurnaces->CompOnMassFlow =
   10864            0 :                             SpeedRatio * thisFurnace.CoolMassFlowRate(SpeedNum) + (1.0 - SpeedRatio) * thisFurnace.CoolMassFlowRate(SpeedNum - 1);
   10865            0 :                         state.dataFurnaces->CompOnFlowRatio = SpeedRatio * thisFurnace.MSCoolingSpeedRatio(SpeedNum) +
   10866            0 :                                                               (1.0 - SpeedRatio) * thisFurnace.MSCoolingSpeedRatio(SpeedNum - 1);
   10867            0 :                         state.dataHVACGlobal->MSHPMassFlowRateLow = thisFurnace.CoolMassFlowRate(SpeedNum - 1);
   10868            0 :                         state.dataHVACGlobal->MSHPMassFlowRateHigh = thisFurnace.CoolMassFlowRate(SpeedNum);
   10869              :                     }
   10870              :                 }
   10871              :             }
   10872              : 
   10873              :             // Set up fan flow rate during compressor off time
   10874            0 :             if (thisFurnace.fanOp == HVAC::FanOp::Continuous && present(SpeedNum)) {
   10875            0 :                 if (thisFurnace.AirFlowControl == AirFlowControlConstFan::UseCompressorOnFlow && state.dataFurnaces->CompOnMassFlow > 0.0) {
   10876            0 :                     if (SpeedNum == 1) { // LOWEST SPEED USE IDLE FLOW
   10877            0 :                         state.dataFurnaces->CompOffMassFlow = thisFurnace.IdleMassFlowRate;
   10878            0 :                         state.dataFurnaces->CompOffFlowRatio = thisFurnace.IdleSpeedRatio;
   10879            0 :                     } else if (thisFurnace.LastMode == Furnaces::ModeOfOperation::HeatingMode) {
   10880            0 :                         state.dataFurnaces->CompOffMassFlow = thisFurnace.HeatMassFlowRate(SpeedNum);
   10881            0 :                         state.dataFurnaces->CompOffFlowRatio = thisFurnace.MSHeatingSpeedRatio(SpeedNum);
   10882              :                     } else {
   10883            0 :                         state.dataFurnaces->CompOffMassFlow = thisFurnace.CoolMassFlowRate(SpeedNum);
   10884            0 :                         state.dataFurnaces->CompOffFlowRatio = thisFurnace.MSCoolingSpeedRatio(SpeedNum);
   10885              :                     }
   10886              :                 }
   10887              :             }
   10888              : 
   10889            0 :             if (present(SpeedNum)) {
   10890            0 :                 if (SpeedNum > 1) {
   10891            0 :                     AverageUnitMassFlow = state.dataFurnaces->CompOnMassFlow;
   10892            0 :                     state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
   10893              :                 } else {
   10894            0 :                     AverageUnitMassFlow =
   10895            0 :                         (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
   10896            0 :                     if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
   10897            0 :                         state.dataFurnaces->FanSpeedRatio =
   10898            0 :                             (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
   10899              :                     } else {
   10900            0 :                         state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
   10901              :                     }
   10902              :                 }
   10903              :             } else {
   10904            0 :                 AverageUnitMassFlow =
   10905            0 :                     (PartLoadRatio * state.dataFurnaces->CompOnMassFlow) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffMassFlow);
   10906            0 :                 if (state.dataFurnaces->CompOffFlowRatio > 0.0) {
   10907            0 :                     state.dataFurnaces->FanSpeedRatio =
   10908            0 :                         (PartLoadRatio * state.dataFurnaces->CompOnFlowRatio) + ((1 - PartLoadRatio) * state.dataFurnaces->CompOffFlowRatio);
   10909              :                 } else {
   10910            0 :                     state.dataFurnaces->FanSpeedRatio = state.dataFurnaces->CompOnFlowRatio;
   10911              :                 }
   10912              :             }
   10913              :         }
   10914              : 
   10915           17 :         if ((thisFurnace.availSched->getCurrentVal() == 0.0) || state.dataHVACGlobal->TurnFansOff ||
   10916            8 :             (thisFurnace.fanAvailSched->getCurrentVal() == 0.0 && !state.dataHVACGlobal->TurnFansOn)) {
   10917            1 :             state.dataLoopNodes->Node(thisFurnace.FurnaceInletNodeNum).MassFlowRate = 0.0;
   10918            1 :             OnOffAirFlowRatio = 0.0;
   10919              :         } else {
   10920            8 :             state.dataLoopNodes->Node(thisFurnace.FurnaceInletNodeNum).MassFlowRate = AverageUnitMassFlow;
   10921            8 :             state.dataLoopNodes->Node(thisFurnace.FurnaceInletNodeNum).MassFlowRateMaxAvail = AverageUnitMassFlow;
   10922            8 :             if (AverageUnitMassFlow > 0.0) {
   10923            8 :                 OnOffAirFlowRatio = state.dataFurnaces->CompOnMassFlow / AverageUnitMassFlow;
   10924              :             } else {
   10925            0 :                 OnOffAirFlowRatio = 0.0;
   10926              :             }
   10927              :         }
   10928              : 
   10929            9 :         state.dataLoopNodes->Node(thisFurnace.FurnaceOutletNodeNum).MassFlowRate =
   10930            9 :             state.dataLoopNodes->Node(thisFurnace.FurnaceInletNodeNum).MassFlowRate;
   10931            9 :     }
   10932              : 
   10933            7 :     void SetMinOATCompressor(EnergyPlusData &state,
   10934              :                              int const FurnaceNum,                    // index to furnace
   10935              :                              std::string const &cCurrentModuleObject, // type of furnace
   10936              :                              bool &ErrorsFound                        // GetInput logical that errors were found
   10937              :     )
   10938              :     {
   10939            7 :         bool errFlag = false;
   10940            7 :         auto &thisFurnace = state.dataFurnaces->Furnace(FurnaceNum);
   10941              : 
   10942              :         // Set minimum OAT for heat pump compressor operation in heating mode
   10943            7 :         if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingSingleSpeed) {
   10944            5 :             thisFurnace.MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, thisFurnace.CoolingCoilIndex, errFlag);
   10945            2 :         } else if (thisFurnace.CoolingCoilType_Num == HVAC::CoilDX_CoolingHXAssisted) {
   10946            1 :             std::string ChildCoolingCoilType = state.dataHVACAssistedCC->HXAssistedCoil(thisFurnace.CoolingCoilIndex).CoolingCoilType;
   10947            1 :             std::string ChildCoolingCoilName = state.dataHVACAssistedCC->HXAssistedCoil(thisFurnace.CoolingCoilIndex).CoolingCoilName;
   10948              : 
   10949            1 :             if (Util::SameString(ChildCoolingCoilType, "COIL:COOLING:DX")) {
   10950            1 :                 int childCCIndex_DX = CoilCoolingDX::factory(state, ChildCoolingCoilName);
   10951            1 :                 if (childCCIndex_DX < 0) {
   10952            0 :                     ShowContinueError(state, format("Occurs in {} = {}", cCurrentModuleObject, thisFurnace.Name));
   10953            0 :                     errFlag = true;
   10954            0 :                     ErrorsFound = true;
   10955              :                 }
   10956            1 :                 auto const &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[childCCIndex_DX];
   10957            1 :                 thisFurnace.MinOATCompressorCooling = newCoil.performance.minOutdoorDrybulb;
   10958            0 :             } else if (Util::SameString(ChildCoolingCoilType, "Coil:Cooling:DX:VariableSpeed")) {
   10959            0 :                 int childCCIndex_VS = state.dataHVACAssistedCC->HXAssistedCoil(thisFurnace.CoolingCoilIndex).CoolingCoilIndex;
   10960            0 :                 thisFurnace.MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, childCCIndex_VS, errFlag);
   10961              :             } else { // Single speed
   10962            0 :                 int childCCIndex_SP = state.dataHVACAssistedCC->HXAssistedCoil(thisFurnace.CoolingCoilIndex).CoolingCoilIndex;
   10963            0 :                 thisFurnace.MinOATCompressorCooling = DXCoils::GetMinOATCompressor(state, childCCIndex_SP, errFlag);
   10964              :             }
   10965            2 :         } else if (thisFurnace.CoolingCoilType_Num == HVAC::Coil_CoolingAirToAirVariableSpeed) {
   10966            1 :             thisFurnace.MinOATCompressorCooling = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, thisFurnace.CoolingCoilIndex, errFlag);
   10967              :         } else {
   10968            0 :             thisFurnace.MinOATCompressorCooling = -1000.0;
   10969              :         }
   10970            7 :         if (errFlag) {
   10971            0 :             ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, thisFurnace.Name));
   10972            0 :             ErrorsFound = true;
   10973              :         }
   10974              : 
   10975              :         // Set minimum OAT for heat pump compressor operation in heating mode
   10976            7 :         errFlag = false;
   10977            7 :         if (thisFurnace.HeatingCoilType_Num == HVAC::Coil_HeatingAirToAirVariableSpeed) {
   10978            1 :             thisFurnace.MinOATCompressorHeating = VariableSpeedCoils::GetVSCoilMinOATCompressor(state, thisFurnace.HeatingCoilIndex, errFlag);
   10979            6 :         } else if (thisFurnace.HeatingCoilType_Num == HVAC::CoilDX_HeatingEmpirical) {
   10980            3 :             thisFurnace.MinOATCompressorHeating = DXCoils::GetMinOATCompressor(state, thisFurnace.HeatingCoilIndex, errFlag);
   10981              :         } else {
   10982            3 :             thisFurnace.MinOATCompressorHeating = -1000.0;
   10983              :         }
   10984            7 :         if (errFlag) {
   10985            0 :             ShowContinueError(state, format("...occurs in {} = {}", cCurrentModuleObject, thisFurnace.Name));
   10986            0 :             ErrorsFound = true;
   10987              :         }
   10988            7 :     }
   10989              : 
   10990              : } // namespace Furnaces
   10991              : 
   10992              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1