LCOV - code coverage report
Current view: top level - EnergyPlus - HeatingCoils.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1134 1687 67.2 %
Date: 2024-08-23 23:50:59 Functions: 24 25 96.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cmath>
      50             : 
      51             : // ObjexxFCL Headers
      52             : #include <ObjexxFCL/Array.functions.hh>
      53             : #include <ObjexxFCL/Fmath.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
      57             : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
      58             : #include <EnergyPlus/BranchNodeConnections.hh>
      59             : #include <EnergyPlus/Coils/CoilCoolingDX.hh>
      60             : #include <EnergyPlus/CurveManager.hh>
      61             : #include <EnergyPlus/DXCoils.hh>
      62             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      63             : #include <EnergyPlus/DataContaminantBalance.hh>
      64             : #include <EnergyPlus/DataEnvironment.hh>
      65             : #include <EnergyPlus/DataGlobalConstants.hh>
      66             : #include <EnergyPlus/DataHVACGlobals.hh>
      67             : #include <EnergyPlus/DataHeatBalance.hh>
      68             : #include <EnergyPlus/DataLoopNode.hh>
      69             : #include <EnergyPlus/DataSizing.hh>
      70             : #include <EnergyPlus/EMSManager.hh>
      71             : #include <EnergyPlus/FaultsManager.hh>
      72             : #include <EnergyPlus/General.hh>
      73             : #include <EnergyPlus/GlobalNames.hh>
      74             : #include <EnergyPlus/HeatingCoils.hh>
      75             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      76             : #include <EnergyPlus/NodeInputManager.hh>
      77             : #include <EnergyPlus/OutputProcessor.hh>
      78             : #include <EnergyPlus/OutputReportPredefined.hh>
      79             : #include <EnergyPlus/Psychrometrics.hh>
      80             : #include <EnergyPlus/RefrigeratedCase.hh>
      81             : #include <EnergyPlus/ScheduleManager.hh>
      82             : #include <EnergyPlus/UtilityRoutines.hh>
      83             : #include <EnergyPlus/VariableSpeedCoils.hh>
      84             : 
      85             : namespace EnergyPlus { // NOLINT(modernize-concat-nested-namespaces) // TODO: Take out this lint when we want to apply formatting for nested
      86             :                        // namespacing
      87             : 
      88             : namespace HeatingCoils {
      89             :     // Module containing the HeatingCoil simulation routines other than the Water coils
      90             : 
      91             :     // MODULE INFORMATION:
      92             :     //       AUTHOR         Richard J. Liesen
      93             :     //       DATE WRITTEN   May 2000
      94             :     //       MODIFIED       Therese Stovall June 2008 to add references to refrigeration condensers
      95             : 
      96             :     // PURPOSE OF THIS MODULE:
      97             :     // To encapsulate the data and algorithms required to
      98             :     // manage the HeatingCoil System Component
      99             : 
     100   108011617 :     void SimulateHeatingCoilComponents(EnergyPlusData &state,
     101             :                                        std::string_view CompName,
     102             :                                        bool const FirstHVACIteration,
     103             :                                        ObjexxFCL::Optional<Real64 const> QCoilReq, // coil load to be met
     104             :                                        ObjexxFCL::Optional_int CompIndex,
     105             :                                        ObjexxFCL::Optional<Real64> QCoilActual, // coil load actually delivered returned to calling component
     106             :                                        ObjexxFCL::Optional_bool_const SuppHeat, // True if current heating coil is a supplemental heating coil
     107             :                                        ObjexxFCL::Optional<HVAC::FanOp const> fanOpMode, // fan operating mode, FanOp::Cycling or FanOp::Continuous
     108             :                                        ObjexxFCL::Optional<Real64 const> PartLoadRatio,  // part-load ratio of heating coil
     109             :                                        ObjexxFCL::Optional_int StageNum,
     110             :                                        ObjexxFCL::Optional<Real64 const> SpeedRatio // Speed ratio of MultiStage heating coil
     111             :     )
     112             :     {
     113             : 
     114             :         // SUBROUTINE INFORMATION:
     115             :         //       AUTHOR         Richard Liesen
     116             :         //       DATE WRITTEN   May 2000
     117             : 
     118             :         // PURPOSE OF THIS SUBROUTINE:
     119             :         // This subroutine manages HeatingCoil component simulation.
     120             : 
     121             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     122   108011617 :         int CoilNum(0);       // The HeatingCoil that you are currently loading input into
     123             :         Real64 QCoilActual2;  // coil load actually delivered returned from specific coil
     124             :         HVAC::FanOp fanOp;    // fan operating mode
     125             :         Real64 PartLoadFrac;  // part-load fraction of heating coil
     126             :         Real64 QCoilRequired; // local variable for optional argument
     127             : 
     128             :         // Obtains and Allocates HeatingCoil related parameters from input file
     129   108011617 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
     130         110 :             GetHeatingCoilInput(state);
     131         110 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
     132             :         }
     133             : 
     134             :         // Find the correct HeatingCoilNumber with the Coil Name
     135   108011617 :         if (present(CompIndex)) {
     136   108011617 :             if (CompIndex == 0) {
     137     8769413 :                 CoilNum = Util::FindItemInList(CompName, state.dataHeatingCoils->HeatingCoil);
     138     8769413 :                 if (CoilNum == 0) {
     139           0 :                     ShowFatalError(state, format("SimulateHeatingCoilComponents: Coil not found={}", CompName));
     140             :                 }
     141             :                 //    CompIndex=CoilNum
     142             :             } else {
     143    99242204 :                 CoilNum = CompIndex;
     144    99242204 :                 if (CoilNum > state.dataHeatingCoils->NumHeatingCoils || CoilNum < 1) {
     145           0 :                     ShowFatalError(state,
     146           0 :                                    format("SimulateHeatingCoilComponents: Invalid CompIndex passed={}, Number of Heating Coils={}, Coil name={}",
     147             :                                           CoilNum,
     148           0 :                                           state.dataHeatingCoils->NumHeatingCoils,
     149             :                                           CompName));
     150             :                 }
     151    99242204 :                 if (state.dataHeatingCoils->CheckEquipName(CoilNum)) {
     152         724 :                     if (!CompName.empty() && CompName != state.dataHeatingCoils->HeatingCoil(CoilNum).Name) {
     153           0 :                         ShowFatalError(
     154             :                             state,
     155           0 :                             format("SimulateHeatingCoilComponents: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
     156             :                                    CoilNum,
     157             :                                    CompName,
     158           0 :                                    state.dataHeatingCoils->HeatingCoil(CoilNum).Name));
     159             :                     }
     160         724 :                     state.dataHeatingCoils->CheckEquipName(CoilNum) = false;
     161             :                 }
     162             :             }
     163             :         } else {
     164           0 :             ShowSevereError(state, "SimulateHeatingCoilComponents: CompIndex argument not used.");
     165           0 :             ShowContinueError(state, format("..CompName = {}", CompName));
     166           0 :             ShowFatalError(state, "Preceding conditions cause termination.");
     167             :         }
     168             : 
     169   108011617 :         if (present(SuppHeat)) {
     170    98653406 :             state.dataHeatingCoils->CoilIsSuppHeater = SuppHeat;
     171             :         } else {
     172     9358211 :             state.dataHeatingCoils->CoilIsSuppHeater = false;
     173             :         }
     174             : 
     175   108011617 :         if (present(fanOpMode)) {
     176    99362294 :             fanOp = fanOpMode;
     177             :         } else {
     178     8649323 :             fanOp = HVAC::FanOp::Continuous;
     179             :         }
     180             : 
     181   108011617 :         if (present(PartLoadRatio)) {
     182    29994029 :             PartLoadFrac = PartLoadRatio;
     183             :         } else {
     184    78017588 :             PartLoadFrac = 1.0;
     185             :         }
     186             : 
     187   108011617 :         if (present(QCoilReq)) {
     188   104086046 :             QCoilRequired = QCoilReq;
     189             :         } else {
     190     3925571 :             QCoilRequired = DataLoopNode::SensedLoadFlagValue;
     191             :         }
     192             : 
     193             :         // With the correct CoilNum Initialize
     194   108011617 :         InitHeatingCoil(state, CoilNum, FirstHVACIteration, QCoilRequired); // Initialize all HeatingCoil related parameters
     195             : 
     196             :         // Calculate the Correct HeatingCoil Model with the current CoilNum
     197   108011617 :         switch (state.dataHeatingCoils->HeatingCoil(CoilNum).HCoilType_Num) {
     198    33898164 :         case HVAC::Coil_HeatingElectric: {
     199    33898164 :             CalcElectricHeatingCoil(state, CoilNum, QCoilRequired, QCoilActual2, fanOp, PartLoadFrac);
     200    33898164 :         } break;
     201     1063066 :         case HVAC::Coil_HeatingElectric_MultiStage: {
     202     1063066 :             CalcMultiStageElectricHeatingCoil(
     203             :                 state,
     204             :                 CoilNum,
     205             :                 SpeedRatio,
     206             :                 PartLoadRatio,
     207             :                 StageNum,
     208             :                 fanOp,
     209             :                 QCoilActual2,
     210     1063066 :                 state.dataHeatingCoils->CoilIsSuppHeater); // Autodesk:OPTIONAL SpeedRatio, PartLoadRatio, StageNum used without PRESENT check
     211     1063066 :         } break;
     212    72562154 :         case HVAC::Coil_HeatingGasOrOtherFuel: {
     213    72562154 :             CalcFuelHeatingCoil(state, CoilNum, QCoilRequired, QCoilActual2, fanOp, PartLoadFrac);
     214    72562154 :         } break;
     215      382010 :         case HVAC::Coil_HeatingGas_MultiStage: {
     216      382010 :             CalcMultiStageGasHeatingCoil(state,
     217             :                                          CoilNum,
     218             :                                          SpeedRatio,
     219             :                                          PartLoadRatio,
     220             :                                          StageNum,
     221             :                                          fanOp); // Autodesk:OPTIONAL SpeedRatio, PartLoadRatio, StageNum used without PRESENT check
     222      382010 :         } break;
     223      106223 :         case HVAC::Coil_HeatingDesuperheater: {
     224      106223 :             CalcDesuperheaterHeatingCoil(state, CoilNum, QCoilRequired, QCoilActual2);
     225      106223 :         } break;
     226           0 :         default:
     227           0 :             QCoilActual2 = 0.0;
     228           0 :             break;
     229             :         }
     230             : 
     231             :         // Update the current HeatingCoil to the outlet nodes
     232   108011617 :         UpdateHeatingCoil(state, CoilNum);
     233             : 
     234             :         // Report the current HeatingCoil
     235   108011617 :         ReportHeatingCoil(state, CoilNum, state.dataHeatingCoils->CoilIsSuppHeater);
     236             : 
     237   108011617 :         if (present(QCoilActual)) {
     238    72795117 :             QCoilActual = QCoilActual2;
     239             :         }
     240   108011617 :     }
     241             : 
     242         288 :     void GetHeatingCoilInput(EnergyPlusData &state)
     243             :     {
     244             : 
     245             :         // SUBROUTINE INFORMATION:
     246             :         //       AUTHOR         Richard Liesen
     247             :         //       DATE WRITTEN   May 2000
     248             : 
     249             :         // PURPOSE OF THIS SUBROUTINE:
     250             :         // Obtains input data for coils and stores it in coil data structures
     251             : 
     252             :         // METHODOLOGY EMPLOYED:
     253             :         // Uses "Get" routines to read in data.
     254             : 
     255             :         // SUBROUTINE PARAMETER DEFINITIONS:
     256             :         static constexpr std::string_view RoutineName = "GetHeatingCoilInput: "; // include trailing blank space
     257             : 
     258             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     259         288 :         std::string CurrentModuleObject; // for ease in getting objects
     260         288 :         Array1D_string Alphas;           // Alpha input items for object
     261         288 :         Array1D_string cAlphaFields;     // Alpha field names
     262         288 :         Array1D_string cNumericFields;   // Numeric field names
     263         288 :         Array1D<Real64> Numbers;         // Numeric input items for object
     264         288 :         Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     265         288 :         Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     266             :         int NumAlphas;
     267             :         int NumNums;
     268             :         int IOStat;
     269             :         int StageNum;
     270             :         bool DXCoilErrFlag; // Used in GetDXCoil mining functions
     271             :         bool errFlag;
     272             : 
     273         288 :         state.dataHeatingCoils->NumElecCoil = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:Electric");
     274         576 :         state.dataHeatingCoils->NumElecCoilMultiStage =
     275         288 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:Electric:MultiStage");
     276         288 :         state.dataHeatingCoils->NumFuelCoil = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:Fuel");
     277         576 :         state.dataHeatingCoils->NumGasCoilMultiStage =
     278         288 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:Gas:MultiStage");
     279         576 :         state.dataHeatingCoils->NumDesuperheaterCoil =
     280         288 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:Desuperheater");
     281         288 :         state.dataHeatingCoils->NumHeatingCoils = state.dataHeatingCoils->NumElecCoil + state.dataHeatingCoils->NumElecCoilMultiStage +
     282         288 :                                                   state.dataHeatingCoils->NumFuelCoil + state.dataHeatingCoils->NumGasCoilMultiStage +
     283         288 :                                                   state.dataHeatingCoils->NumDesuperheaterCoil;
     284         288 :         if (state.dataHeatingCoils->NumHeatingCoils > 0) {
     285         288 :             state.dataHeatingCoils->HeatingCoil.allocate(state.dataHeatingCoils->NumHeatingCoils);
     286         288 :             state.dataHeatingCoils->HeatingCoilNumericFields.allocate(state.dataHeatingCoils->NumHeatingCoils);
     287         288 :             state.dataHeatingCoils->ValidSourceType.dimension(state.dataHeatingCoils->NumHeatingCoils, false);
     288         288 :             state.dataHeatingCoils->CheckEquipName.dimension(state.dataHeatingCoils->NumHeatingCoils, true);
     289             :         }
     290             : 
     291         576 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     292         288 :             state, "Coil:Heating:Electric", state.dataHeatingCoils->TotalArgs, NumAlphas, NumNums);
     293         288 :         state.dataHeatingCoils->MaxNums = max(state.dataHeatingCoils->MaxNums, NumNums);
     294         288 :         state.dataHeatingCoils->MaxAlphas = max(state.dataHeatingCoils->MaxAlphas, NumAlphas);
     295         576 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     296         288 :             state, "Coil:Heating:Electric:MultiStage", state.dataHeatingCoils->TotalArgs, NumAlphas, NumNums);
     297         288 :         state.dataHeatingCoils->MaxNums = max(state.dataHeatingCoils->MaxNums, NumNums);
     298         288 :         state.dataHeatingCoils->MaxAlphas = max(state.dataHeatingCoils->MaxAlphas, NumAlphas);
     299         576 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     300         288 :             state, "Coil:Heating:Fuel", state.dataHeatingCoils->TotalArgs, NumAlphas, NumNums);
     301         288 :         state.dataHeatingCoils->MaxNums = max(state.dataHeatingCoils->MaxNums, NumNums);
     302         288 :         state.dataHeatingCoils->MaxAlphas = max(state.dataHeatingCoils->MaxAlphas, NumAlphas);
     303         576 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     304         288 :             state, "Coil:Heating:Gas:MultiStage", state.dataHeatingCoils->TotalArgs, NumAlphas, NumNums);
     305         288 :         state.dataHeatingCoils->MaxNums = max(state.dataHeatingCoils->MaxNums, NumNums);
     306         288 :         state.dataHeatingCoils->MaxAlphas = max(state.dataHeatingCoils->MaxAlphas, NumAlphas);
     307         576 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     308         288 :             state, "Coil:Heating:Desuperheater", state.dataHeatingCoils->TotalArgs, NumAlphas, NumNums);
     309         288 :         state.dataHeatingCoils->MaxNums = max(state.dataHeatingCoils->MaxNums, NumNums);
     310         288 :         state.dataHeatingCoils->MaxAlphas = max(state.dataHeatingCoils->MaxAlphas, NumAlphas);
     311             : 
     312         288 :         Alphas.allocate(state.dataHeatingCoils->MaxAlphas);
     313         288 :         cAlphaFields.allocate(state.dataHeatingCoils->MaxAlphas);
     314         288 :         cNumericFields.allocate(state.dataHeatingCoils->MaxNums);
     315         288 :         Numbers.dimension(state.dataHeatingCoils->MaxNums, 0.0);
     316         288 :         lAlphaBlanks.dimension(state.dataHeatingCoils->MaxAlphas, true);
     317         288 :         lNumericBlanks.dimension(state.dataHeatingCoils->MaxNums, true);
     318             : 
     319             :         // Get the data for electric heating coils
     320         943 :         for (int ElecCoilNum = 1; ElecCoilNum <= state.dataHeatingCoils->NumElecCoil; ++ElecCoilNum) {
     321             : 
     322         655 :             auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(ElecCoilNum);
     323         655 :             auto &heatingCoilNumericFields = state.dataHeatingCoils->HeatingCoilNumericFields(ElecCoilNum);
     324             : 
     325         655 :             CurrentModuleObject = "Coil:Heating:Electric";
     326         655 :             heatingCoil.FuelType = Constant::eFuel::Electricity;
     327             : 
     328         655 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     329             :                                                                      CurrentModuleObject,
     330             :                                                                      ElecCoilNum,
     331             :                                                                      Alphas,
     332             :                                                                      NumAlphas,
     333             :                                                                      Numbers,
     334             :                                                                      NumNums,
     335             :                                                                      IOStat,
     336             :                                                                      lNumericBlanks,
     337             :                                                                      lAlphaBlanks,
     338             :                                                                      cAlphaFields,
     339             :                                                                      cNumericFields);
     340             : 
     341         655 :             heatingCoilNumericFields.FieldNames.allocate(state.dataHeatingCoils->MaxNums);
     342         655 :             heatingCoilNumericFields.FieldNames = cNumericFields;
     343             : 
     344             :             // InputErrorsFound will be set to True if problem was found, left untouched otherwise
     345         655 :             GlobalNames::VerifyUniqueCoilName(
     346         655 :                 state, CurrentModuleObject, Alphas(1), state.dataHeatingCoils->InputErrorsFound, CurrentModuleObject + " Name");
     347             : 
     348         655 :             heatingCoil.Name = Alphas(1);
     349         655 :             heatingCoil.Schedule = Alphas(2);
     350         655 :             if (lAlphaBlanks(2)) {
     351          60 :                 heatingCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
     352             :             } else {
     353         595 :                 heatingCoil.SchedPtr = ScheduleManager::GetScheduleIndex(state, Alphas(2));
     354         595 :                 if (heatingCoil.SchedPtr == 0) {
     355           0 :                     ShowSevereError(state,
     356           0 :                                     format("{}{}: Invalid {} entered ={} for {}={}",
     357             :                                            RoutineName,
     358             :                                            CurrentModuleObject,
     359             :                                            cAlphaFields(2),
     360             :                                            Alphas(2),
     361             :                                            cAlphaFields(1),
     362             :                                            Alphas(1)));
     363           0 :                     state.dataHeatingCoils->InputErrorsFound = true;
     364             :                 }
     365             :             }
     366             : 
     367         655 :             heatingCoil.HeatingCoilType = "Heating";
     368         655 :             heatingCoil.HeatingCoilModel = "Electric";
     369         655 :             heatingCoil.HCoilType_Num = HVAC::Coil_HeatingElectric;
     370             : 
     371         655 :             heatingCoil.Efficiency = Numbers(1);
     372         655 :             heatingCoil.NominalCapacity = Numbers(2);
     373         655 :             errFlag = false;
     374         655 :             heatingCoil.AirInletNodeNum = GetOnlySingleNode(state,
     375         655 :                                                             Alphas(3),
     376             :                                                             errFlag,
     377             :                                                             DataLoopNode::ConnectionObjectType::CoilHeatingElectric,
     378         655 :                                                             Alphas(1),
     379             :                                                             DataLoopNode::NodeFluidType::Air,
     380             :                                                             DataLoopNode::ConnectionType::Inlet,
     381             :                                                             NodeInputManager::CompFluidStream::Primary,
     382             :                                                             DataLoopNode::ObjectIsNotParent);
     383         655 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     384         655 :             errFlag = false;
     385         655 :             heatingCoil.AirOutletNodeNum = GetOnlySingleNode(state,
     386         655 :                                                              Alphas(4),
     387             :                                                              errFlag,
     388             :                                                              DataLoopNode::ConnectionObjectType::CoilHeatingElectric,
     389         655 :                                                              Alphas(1),
     390             :                                                              DataLoopNode::NodeFluidType::Air,
     391             :                                                              DataLoopNode::ConnectionType::Outlet,
     392             :                                                              NodeInputManager::CompFluidStream::Primary,
     393             :                                                              DataLoopNode::ObjectIsNotParent);
     394         655 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     395             : 
     396         655 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
     397             : 
     398         655 :             errFlag = false;
     399         655 :             heatingCoil.TempSetPointNodeNum = GetOnlySingleNode(state,
     400         655 :                                                                 Alphas(5),
     401             :                                                                 errFlag,
     402             :                                                                 DataLoopNode::ConnectionObjectType::CoilHeatingElectric,
     403         655 :                                                                 Alphas(1),
     404             :                                                                 DataLoopNode::NodeFluidType::Air,
     405             :                                                                 DataLoopNode::ConnectionType::Sensor,
     406             :                                                                 NodeInputManager::CompFluidStream::Primary,
     407             :                                                                 DataLoopNode::ObjectIsNotParent);
     408         655 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     409             : 
     410             :             // Setup Report variables for the Electric Coils
     411             :             // CurrentModuleObject = "Coil:Heating:Electric"
     412        1310 :             SetupOutputVariable(state,
     413             :                                 "Heating Coil Heating Energy",
     414             :                                 Constant::Units::J,
     415         655 :                                 heatingCoil.HeatingCoilLoad,
     416             :                                 OutputProcessor::TimeStepType::System,
     417             :                                 OutputProcessor::StoreType::Sum,
     418         655 :                                 heatingCoil.Name,
     419             :                                 Constant::eResource::EnergyTransfer,
     420             :                                 OutputProcessor::Group::HVAC,
     421             :                                 OutputProcessor::EndUseCat::HeatingCoils);
     422        1310 :             SetupOutputVariable(state,
     423             :                                 "Heating Coil Heating Rate",
     424             :                                 Constant::Units::W,
     425         655 :                                 heatingCoil.HeatingCoilRate,
     426             :                                 OutputProcessor::TimeStepType::System,
     427             :                                 OutputProcessor::StoreType::Average,
     428         655 :                                 heatingCoil.Name);
     429        1310 :             SetupOutputVariable(state,
     430             :                                 "Heating Coil Electricity Energy",
     431             :                                 Constant::Units::J,
     432         655 :                                 heatingCoil.ElecUseLoad,
     433             :                                 OutputProcessor::TimeStepType::System,
     434             :                                 OutputProcessor::StoreType::Sum,
     435         655 :                                 heatingCoil.Name,
     436             :                                 Constant::eResource::Electricity,
     437             :                                 OutputProcessor::Group::HVAC,
     438             :                                 OutputProcessor::EndUseCat::Heating);
     439        1310 :             SetupOutputVariable(state,
     440             :                                 "Heating Coil Electricity Rate",
     441             :                                 Constant::Units::W,
     442         655 :                                 heatingCoil.ElecUseRate,
     443             :                                 OutputProcessor::TimeStepType::System,
     444             :                                 OutputProcessor::StoreType::Average,
     445         655 :                                 heatingCoil.Name);
     446             :         }
     447             : 
     448             :         // Get the data for electric heating coils
     449         293 :         for (int ElecCoilNum = 1; ElecCoilNum <= state.dataHeatingCoils->NumElecCoilMultiStage; ++ElecCoilNum) {
     450             : 
     451           5 :             int CoilNum = state.dataHeatingCoils->NumElecCoil + ElecCoilNum;
     452           5 :             auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
     453           5 :             auto &heatingCoilNumericFields = state.dataHeatingCoils->HeatingCoilNumericFields(CoilNum);
     454             : 
     455           5 :             CurrentModuleObject = "Coil:Heating:Electric:MultiStage";
     456           5 :             heatingCoil.FuelType = Constant::eFuel::Electricity;
     457             : 
     458           5 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     459             :                                                                      CurrentModuleObject,
     460             :                                                                      ElecCoilNum,
     461             :                                                                      Alphas,
     462             :                                                                      NumAlphas,
     463             :                                                                      Numbers,
     464             :                                                                      NumNums,
     465             :                                                                      IOStat,
     466             :                                                                      lNumericBlanks,
     467             :                                                                      lAlphaBlanks,
     468             :                                                                      cAlphaFields,
     469             :                                                                      cNumericFields);
     470             : 
     471           5 :             heatingCoilNumericFields.FieldNames.allocate(state.dataHeatingCoils->MaxNums);
     472           5 :             heatingCoilNumericFields.FieldNames = cNumericFields;
     473             : 
     474             :             // InputErrorsFound will be set to True if problem was found, left untouched otherwise
     475           5 :             GlobalNames::VerifyUniqueCoilName(
     476           5 :                 state, CurrentModuleObject, Alphas(1), state.dataHeatingCoils->InputErrorsFound, CurrentModuleObject + " Name");
     477           5 :             heatingCoil.Name = Alphas(1);
     478           5 :             heatingCoil.Schedule = Alphas(2);
     479           5 :             if (lAlphaBlanks(2)) {
     480           0 :                 heatingCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
     481             :             } else {
     482           5 :                 heatingCoil.SchedPtr = ScheduleManager::GetScheduleIndex(state, Alphas(2));
     483           5 :                 if (heatingCoil.SchedPtr == 0) {
     484           0 :                     ShowSevereError(state,
     485           0 :                                     format("{}{}: Invalid {} entered ={} for {}={}",
     486             :                                            RoutineName,
     487             :                                            CurrentModuleObject,
     488             :                                            cAlphaFields(2),
     489             :                                            Alphas(2),
     490             :                                            cAlphaFields(1),
     491             :                                            Alphas(1)));
     492           0 :                     state.dataHeatingCoils->InputErrorsFound = true;
     493             :                 }
     494             :             }
     495             : 
     496           5 :             heatingCoil.HeatingCoilType = "Heating";
     497           5 :             heatingCoil.HeatingCoilModel = "ElectricMultiStage";
     498           5 :             heatingCoil.HCoilType_Num = HVAC::Coil_HeatingElectric_MultiStage;
     499             : 
     500           5 :             heatingCoil.NumOfStages = static_cast<int>(Numbers(1));
     501             : 
     502           5 :             heatingCoil.MSEfficiency.allocate(heatingCoil.NumOfStages);
     503           5 :             heatingCoil.MSNominalCapacity.allocate(heatingCoil.NumOfStages);
     504             : 
     505          16 :             for (StageNum = 1; StageNum <= heatingCoil.NumOfStages; ++StageNum) {
     506             : 
     507          11 :                 heatingCoil.MSEfficiency(StageNum) = Numbers(StageNum * 2);
     508          11 :                 heatingCoil.MSNominalCapacity(StageNum) = Numbers(StageNum * 2 + 1);
     509             :             }
     510             : 
     511           5 :             errFlag = false;
     512           5 :             heatingCoil.AirInletNodeNum = GetOnlySingleNode(state,
     513           5 :                                                             Alphas(3),
     514             :                                                             errFlag,
     515             :                                                             DataLoopNode::ConnectionObjectType::CoilHeatingElectricMultiStage,
     516           5 :                                                             Alphas(1),
     517             :                                                             DataLoopNode::NodeFluidType::Air,
     518             :                                                             DataLoopNode::ConnectionType::Inlet,
     519             :                                                             NodeInputManager::CompFluidStream::Primary,
     520             :                                                             DataLoopNode::ObjectIsNotParent);
     521           5 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     522           5 :             errFlag = false;
     523           5 :             heatingCoil.AirOutletNodeNum = GetOnlySingleNode(state,
     524           5 :                                                              Alphas(4),
     525             :                                                              errFlag,
     526             :                                                              DataLoopNode::ConnectionObjectType::CoilHeatingElectricMultiStage,
     527           5 :                                                              Alphas(1),
     528             :                                                              DataLoopNode::NodeFluidType::Air,
     529             :                                                              DataLoopNode::ConnectionType::Outlet,
     530             :                                                              NodeInputManager::CompFluidStream::Primary,
     531             :                                                              DataLoopNode::ObjectIsNotParent);
     532           5 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     533             : 
     534           5 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
     535             : 
     536           5 :             errFlag = false;
     537           5 :             heatingCoil.TempSetPointNodeNum = GetOnlySingleNode(state,
     538           5 :                                                                 Alphas(5),
     539             :                                                                 errFlag,
     540             :                                                                 DataLoopNode::ConnectionObjectType::CoilHeatingElectricMultiStage,
     541           5 :                                                                 Alphas(1),
     542             :                                                                 DataLoopNode::NodeFluidType::Air,
     543             :                                                                 DataLoopNode::ConnectionType::Sensor,
     544             :                                                                 NodeInputManager::CompFluidStream::Primary,
     545             :                                                                 DataLoopNode::ObjectIsNotParent);
     546           5 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     547             : 
     548             :             // Setup Report variables for the Electric Coils
     549             :             // CurrentModuleObject = "Coil:Heating:Electric:MultiStage"
     550          10 :             SetupOutputVariable(state,
     551             :                                 "Heating Coil Heating Energy",
     552             :                                 Constant::Units::J,
     553           5 :                                 heatingCoil.HeatingCoilLoad,
     554             :                                 OutputProcessor::TimeStepType::System,
     555             :                                 OutputProcessor::StoreType::Sum,
     556           5 :                                 heatingCoil.Name,
     557             :                                 Constant::eResource::EnergyTransfer,
     558             :                                 OutputProcessor::Group::HVAC,
     559             :                                 OutputProcessor::EndUseCat::HeatingCoils);
     560          10 :             SetupOutputVariable(state,
     561             :                                 "Heating Coil Heating Rate",
     562             :                                 Constant::Units::W,
     563           5 :                                 heatingCoil.HeatingCoilRate,
     564             :                                 OutputProcessor::TimeStepType::System,
     565             :                                 OutputProcessor::StoreType::Average,
     566           5 :                                 heatingCoil.Name);
     567          10 :             SetupOutputVariable(state,
     568             :                                 "Heating Coil Electricity Energy",
     569             :                                 Constant::Units::J,
     570           5 :                                 heatingCoil.ElecUseLoad,
     571             :                                 OutputProcessor::TimeStepType::System,
     572             :                                 OutputProcessor::StoreType::Sum,
     573           5 :                                 heatingCoil.Name,
     574             :                                 Constant::eResource::Electricity,
     575             :                                 OutputProcessor::Group::HVAC,
     576             :                                 OutputProcessor::EndUseCat::Heating);
     577          10 :             SetupOutputVariable(state,
     578             :                                 "Heating Coil Electricity Rate",
     579             :                                 Constant::Units::W,
     580           5 :                                 heatingCoil.ElecUseRate,
     581             :                                 OutputProcessor::TimeStepType::System,
     582             :                                 OutputProcessor::StoreType::Average,
     583           5 :                                 heatingCoil.Name);
     584             :         }
     585             : 
     586             :         // Get the data for for fuel heating coils
     587        1062 :         for (int FuelCoilNum = 1; FuelCoilNum <= state.dataHeatingCoils->NumFuelCoil; ++FuelCoilNum) {
     588             : 
     589         774 :             int CoilNum = state.dataHeatingCoils->NumElecCoil + state.dataHeatingCoils->NumElecCoilMultiStage + FuelCoilNum;
     590         774 :             auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
     591         774 :             auto &heatingCoilNumericFields = state.dataHeatingCoils->HeatingCoilNumericFields(CoilNum);
     592             : 
     593         774 :             CurrentModuleObject = "Coil:Heating:Fuel";
     594             : 
     595         774 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     596             :                                                                      CurrentModuleObject,
     597             :                                                                      FuelCoilNum,
     598             :                                                                      Alphas,
     599             :                                                                      NumAlphas,
     600             :                                                                      Numbers,
     601             :                                                                      NumNums,
     602             :                                                                      IOStat,
     603             :                                                                      lNumericBlanks,
     604             :                                                                      lAlphaBlanks,
     605             :                                                                      cAlphaFields,
     606             :                                                                      cNumericFields);
     607             : 
     608         774 :             heatingCoilNumericFields.FieldNames.allocate(state.dataHeatingCoils->MaxNums);
     609         774 :             heatingCoilNumericFields.FieldNames = cNumericFields;
     610             : 
     611             :             // InputErrorsFound will be set to True if problem was found, left untouched otherwise
     612         774 :             GlobalNames::VerifyUniqueCoilName(
     613         774 :                 state, CurrentModuleObject, Alphas(1), state.dataHeatingCoils->InputErrorsFound, CurrentModuleObject + " Name");
     614         774 :             heatingCoil.Name = Alphas(1);
     615         774 :             heatingCoil.Schedule = Alphas(2);
     616         774 :             if (lAlphaBlanks(2)) {
     617          84 :                 heatingCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
     618             :             } else {
     619         690 :                 heatingCoil.SchedPtr = ScheduleManager::GetScheduleIndex(state, Alphas(2));
     620         690 :                 if (heatingCoil.SchedPtr == 0) {
     621           0 :                     ShowSevereError(state,
     622           0 :                                     format("{}{}: Invalid {} entered ={} for {}={}",
     623             :                                            RoutineName,
     624             :                                            CurrentModuleObject,
     625             :                                            cAlphaFields(2),
     626             :                                            Alphas(2),
     627             :                                            cAlphaFields(1),
     628             :                                            Alphas(1)));
     629           0 :                     state.dataHeatingCoils->InputErrorsFound = true;
     630             :                 }
     631             :             }
     632             : 
     633         774 :             heatingCoil.HeatingCoilType = "Heating";
     634         774 :             heatingCoil.HeatingCoilModel = "Fuel";
     635         774 :             heatingCoil.HCoilType_Num = HVAC::Coil_HeatingGasOrOtherFuel;
     636             : 
     637         774 :             heatingCoil.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, Alphas(3)));
     638         774 :             if (!(heatingCoil.FuelType == Constant::eFuel::NaturalGas || heatingCoil.FuelType == Constant::eFuel::Propane ||
     639           1 :                   heatingCoil.FuelType == Constant::eFuel::Diesel || heatingCoil.FuelType == Constant::eFuel::Gasoline ||
     640           1 :                   heatingCoil.FuelType == Constant::eFuel::FuelOilNo1 || heatingCoil.FuelType == Constant::eFuel::FuelOilNo2 ||
     641           0 :                   heatingCoil.FuelType == Constant::eFuel::OtherFuel1 || heatingCoil.FuelType == Constant::eFuel::OtherFuel2 ||
     642           0 :                   heatingCoil.FuelType == Constant::eFuel::Coal)) {
     643           0 :                 ShowSevereError(state,
     644           0 :                                 format("{}{}: Invalid {} entered ={} for {}={}",
     645             :                                        RoutineName,
     646             :                                        CurrentModuleObject,
     647             :                                        cAlphaFields(3),
     648             :                                        Alphas(3),
     649             :                                        cAlphaFields(1),
     650             :                                        Alphas(1)));
     651           0 :                 state.dataHeatingCoils->InputErrorsFound = true;
     652             :             }
     653         774 :             std::string const sFuelType(Constant::eFuelNames[static_cast<int>(heatingCoil.FuelType)]);
     654             : 
     655         774 :             heatingCoil.Efficiency = Numbers(1);
     656         774 :             heatingCoil.NominalCapacity = Numbers(2);
     657         774 :             errFlag = false;
     658         774 :             heatingCoil.AirInletNodeNum = GetOnlySingleNode(state,
     659         774 :                                                             Alphas(4),
     660             :                                                             errFlag,
     661             :                                                             DataLoopNode::ConnectionObjectType::CoilHeatingFuel,
     662         774 :                                                             Alphas(1),
     663             :                                                             DataLoopNode::NodeFluidType::Air,
     664             :                                                             DataLoopNode::ConnectionType::Inlet,
     665             :                                                             NodeInputManager::CompFluidStream::Primary,
     666             :                                                             DataLoopNode::ObjectIsNotParent);
     667         774 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     668         774 :             errFlag = false;
     669         774 :             heatingCoil.AirOutletNodeNum = GetOnlySingleNode(state,
     670         774 :                                                              Alphas(5),
     671             :                                                              errFlag,
     672             :                                                              DataLoopNode::ConnectionObjectType::CoilHeatingFuel,
     673         774 :                                                              Alphas(1),
     674             :                                                              DataLoopNode::NodeFluidType::Air,
     675             :                                                              DataLoopNode::ConnectionType::Outlet,
     676             :                                                              NodeInputManager::CompFluidStream::Primary,
     677             :                                                              DataLoopNode::ObjectIsNotParent);
     678         774 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     679             : 
     680         774 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(4), Alphas(5), "Air Nodes");
     681             : 
     682         774 :             errFlag = false;
     683         774 :             heatingCoil.TempSetPointNodeNum = GetOnlySingleNode(state,
     684         774 :                                                                 Alphas(6),
     685             :                                                                 errFlag,
     686             :                                                                 DataLoopNode::ConnectionObjectType::CoilHeatingFuel,
     687         774 :                                                                 Alphas(1),
     688             :                                                                 DataLoopNode::NodeFluidType::Air,
     689             :                                                                 DataLoopNode::ConnectionType::Sensor,
     690             :                                                                 NodeInputManager::CompFluidStream::Primary,
     691             :                                                                 DataLoopNode::ObjectIsNotParent);
     692         774 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     693             : 
     694             :             // parasitic electric load associated with the fuel heating coil
     695         774 :             heatingCoil.ParasiticElecLoad = Numbers(3);
     696             : 
     697         774 :             heatingCoil.PLFCurveIndex = Curve::GetCurveIndex(state, Alphas(7)); // convert curve name to number
     698             : 
     699             :             // parasitic fuel load associated with the gas heating coil (standing pilot light)
     700         774 :             heatingCoil.ParasiticFuelCapacity = Numbers(4);
     701             : 
     702             :             // Setup Report variables for the Fuel Coils
     703             :             // CurrentModuleObject = "Coil:Heating:OtherFuel"
     704             : 
     705        1548 :             SetupOutputVariable(state,
     706             :                                 "Heating Coil Heating Energy",
     707             :                                 Constant::Units::J,
     708         774 :                                 heatingCoil.HeatingCoilLoad,
     709             :                                 OutputProcessor::TimeStepType::System,
     710             :                                 OutputProcessor::StoreType::Sum,
     711         774 :                                 heatingCoil.Name,
     712             :                                 Constant::eResource::EnergyTransfer,
     713             :                                 OutputProcessor::Group::HVAC,
     714             :                                 OutputProcessor::EndUseCat::HeatingCoils);
     715        1548 :             SetupOutputVariable(state,
     716             :                                 "Heating Coil Heating Rate",
     717             :                                 Constant::Units::W,
     718         774 :                                 heatingCoil.HeatingCoilRate,
     719             :                                 OutputProcessor::TimeStepType::System,
     720             :                                 OutputProcessor::StoreType::Average,
     721         774 :                                 heatingCoil.Name);
     722        2322 :             SetupOutputVariable(state,
     723        1548 :                                 format("Heating Coil {} Energy", sFuelType),
     724             :                                 Constant::Units::J,
     725         774 :                                 heatingCoil.FuelUseLoad,
     726             :                                 OutputProcessor::TimeStepType::System,
     727             :                                 OutputProcessor::StoreType::Sum,
     728         774 :                                 heatingCoil.Name,
     729         774 :                                 Constant::eFuel2eResource[(int)heatingCoil.FuelType],
     730             :                                 OutputProcessor::Group::HVAC,
     731             :                                 OutputProcessor::EndUseCat::Heating);
     732        2322 :             SetupOutputVariable(state,
     733        1548 :                                 format("Heating Coil {} Rate", sFuelType),
     734             :                                 Constant::Units::W,
     735         774 :                                 heatingCoil.FuelUseRate,
     736             :                                 OutputProcessor::TimeStepType::System,
     737             :                                 OutputProcessor::StoreType::Average,
     738         774 :                                 heatingCoil.Name);
     739        1548 :             SetupOutputVariable(state,
     740             :                                 "Heating Coil Electricity Energy",
     741             :                                 Constant::Units::J,
     742         774 :                                 heatingCoil.ElecUseLoad,
     743             :                                 OutputProcessor::TimeStepType::System,
     744             :                                 OutputProcessor::StoreType::Sum,
     745         774 :                                 heatingCoil.Name,
     746             :                                 Constant::eResource::Electricity,
     747             :                                 OutputProcessor::Group::HVAC,
     748             :                                 OutputProcessor::EndUseCat::Heating);
     749        1548 :             SetupOutputVariable(state,
     750             :                                 "Heating Coil Electricity Rate",
     751             :                                 Constant::Units::W,
     752         774 :                                 heatingCoil.ElecUseRate,
     753             :                                 OutputProcessor::TimeStepType::System,
     754             :                                 OutputProcessor::StoreType::Average,
     755         774 :                                 heatingCoil.Name);
     756        1548 :             SetupOutputVariable(state,
     757             :                                 "Heating Coil Runtime Fraction",
     758             :                                 Constant::Units::None,
     759         774 :                                 heatingCoil.RTF,
     760             :                                 OutputProcessor::TimeStepType::System,
     761             :                                 OutputProcessor::StoreType::Average,
     762         774 :                                 heatingCoil.Name);
     763        2322 :             SetupOutputVariable(state,
     764        1548 :                                 "Heating Coil Ancillary " + sFuelType + " Rate",
     765             :                                 Constant::Units::W,
     766         774 :                                 heatingCoil.ParasiticFuelRate,
     767             :                                 OutputProcessor::TimeStepType::System,
     768             :                                 OutputProcessor::StoreType::Average,
     769         774 :                                 heatingCoil.Name);
     770        2322 :             SetupOutputVariable(state,
     771        1548 :                                 "Heating Coil Ancillary " + sFuelType + " Energy",
     772             :                                 Constant::Units::J,
     773         774 :                                 heatingCoil.ParasiticFuelConsumption,
     774             :                                 OutputProcessor::TimeStepType::System,
     775             :                                 OutputProcessor::StoreType::Sum,
     776         774 :                                 heatingCoil.Name,
     777         774 :                                 Constant::eFuel2eResource[(int)heatingCoil.FuelType],
     778             :                                 OutputProcessor::Group::HVAC,
     779             :                                 OutputProcessor::EndUseCat::Heating);
     780         774 :         }
     781             : 
     782             :         // Get the data for for gas multistage heating coils
     783         289 :         for (int FuelCoilNum = 1; FuelCoilNum <= state.dataHeatingCoils->NumGasCoilMultiStage; ++FuelCoilNum) {
     784             : 
     785           1 :             int CoilNum = state.dataHeatingCoils->NumElecCoil + state.dataHeatingCoils->NumElecCoilMultiStage + state.dataHeatingCoils->NumFuelCoil +
     786           1 :                           FuelCoilNum;
     787           1 :             auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
     788           1 :             auto &heatingCoilNumericFields = state.dataHeatingCoils->HeatingCoilNumericFields(CoilNum);
     789           1 :             CurrentModuleObject = "Coil:Heating:Gas:MultiStage";
     790           1 :             heatingCoil.FuelType = Constant::eFuel::NaturalGas;
     791             : 
     792           1 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     793             :                                                                      CurrentModuleObject,
     794             :                                                                      FuelCoilNum,
     795             :                                                                      Alphas,
     796             :                                                                      NumAlphas,
     797             :                                                                      Numbers,
     798             :                                                                      NumNums,
     799             :                                                                      IOStat,
     800             :                                                                      lNumericBlanks,
     801             :                                                                      lAlphaBlanks,
     802             :                                                                      cAlphaFields,
     803             :                                                                      cNumericFields);
     804             : 
     805           1 :             heatingCoilNumericFields.FieldNames.allocate(state.dataHeatingCoils->MaxNums);
     806           1 :             heatingCoilNumericFields.FieldNames = cNumericFields;
     807             : 
     808             :             // InputErrorsFound will be set to True if problem was found, left untouched otherwise
     809           1 :             GlobalNames::VerifyUniqueCoilName(
     810           1 :                 state, CurrentModuleObject, Alphas(1), state.dataHeatingCoils->InputErrorsFound, CurrentModuleObject + " Name");
     811           1 :             heatingCoil.Name = Alphas(1);
     812           1 :             heatingCoil.Schedule = Alphas(2);
     813           1 :             if (lAlphaBlanks(2)) {
     814           0 :                 heatingCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
     815             :             } else {
     816           1 :                 heatingCoil.SchedPtr = ScheduleManager::GetScheduleIndex(state, Alphas(2));
     817           1 :                 if (heatingCoil.SchedPtr == 0) {
     818           0 :                     ShowSevereError(state,
     819           0 :                                     format("{}{}: Invalid {} entered ={} for {}={}",
     820             :                                            RoutineName,
     821             :                                            CurrentModuleObject,
     822             :                                            cAlphaFields(2),
     823             :                                            Alphas(2),
     824             :                                            cAlphaFields(1),
     825             :                                            Alphas(1)));
     826           0 :                     state.dataHeatingCoils->InputErrorsFound = true;
     827             :                 }
     828             :             }
     829             : 
     830           1 :             heatingCoil.HeatingCoilType = "Heating";
     831           1 :             heatingCoil.HeatingCoilModel = "GasMultiStage";
     832           1 :             heatingCoil.HCoilType_Num = HVAC::Coil_HeatingGas_MultiStage;
     833             : 
     834           1 :             heatingCoil.ParasiticFuelCapacity = Numbers(1);
     835             : 
     836           1 :             heatingCoil.NumOfStages = static_cast<int>(Numbers(2));
     837             : 
     838           1 :             heatingCoil.MSEfficiency.allocate(heatingCoil.NumOfStages);
     839           1 :             heatingCoil.MSNominalCapacity.allocate(heatingCoil.NumOfStages);
     840           1 :             heatingCoil.MSParasiticElecLoad.allocate(heatingCoil.NumOfStages);
     841             : 
     842           2 :             for (StageNum = 1; StageNum <= heatingCoil.NumOfStages; ++StageNum) {
     843             : 
     844           1 :                 heatingCoil.MSEfficiency(StageNum) = Numbers(StageNum * 3);
     845           1 :                 heatingCoil.MSNominalCapacity(StageNum) = Numbers(StageNum * 3 + 1);
     846           1 :                 heatingCoil.MSParasiticElecLoad(StageNum) = Numbers(StageNum * 3 + 2);
     847             :             }
     848             : 
     849           1 :             errFlag = false;
     850           1 :             heatingCoil.AirInletNodeNum = GetOnlySingleNode(state,
     851           1 :                                                             Alphas(3),
     852             :                                                             errFlag,
     853             :                                                             DataLoopNode::ConnectionObjectType::CoilHeatingGasMultiStage,
     854           1 :                                                             Alphas(1),
     855             :                                                             DataLoopNode::NodeFluidType::Air,
     856             :                                                             DataLoopNode::ConnectionType::Inlet,
     857             :                                                             NodeInputManager::CompFluidStream::Primary,
     858             :                                                             DataLoopNode::ObjectIsNotParent);
     859           1 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     860           1 :             errFlag = false;
     861           1 :             heatingCoil.AirOutletNodeNum = GetOnlySingleNode(state,
     862           1 :                                                              Alphas(4),
     863             :                                                              errFlag,
     864             :                                                              DataLoopNode::ConnectionObjectType::CoilHeatingGasMultiStage,
     865           1 :                                                              Alphas(1),
     866             :                                                              DataLoopNode::NodeFluidType::Air,
     867             :                                                              DataLoopNode::ConnectionType::Outlet,
     868             :                                                              NodeInputManager::CompFluidStream::Primary,
     869             :                                                              DataLoopNode::ObjectIsNotParent);
     870           1 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     871             : 
     872           1 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
     873             : 
     874           1 :             errFlag = false;
     875           1 :             heatingCoil.TempSetPointNodeNum = GetOnlySingleNode(state,
     876           1 :                                                                 Alphas(5),
     877             :                                                                 errFlag,
     878             :                                                                 DataLoopNode::ConnectionObjectType::CoilHeatingGasMultiStage,
     879           1 :                                                                 Alphas(1),
     880             :                                                                 DataLoopNode::NodeFluidType::Air,
     881             :                                                                 DataLoopNode::ConnectionType::Sensor,
     882             :                                                                 NodeInputManager::CompFluidStream::Primary,
     883             :                                                                 DataLoopNode::ObjectIsNotParent);
     884           1 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
     885             : 
     886             :             // parasitic electric load associated with the gas heating coil
     887           1 :             heatingCoil.ParasiticElecLoad = Numbers(10);
     888             : 
     889           1 :             heatingCoil.PLFCurveIndex = Curve::GetCurveIndex(state, Alphas(6)); // convert curve name to number
     890             : 
     891             :             // parasitic gas load associated with the gas heating coil (standing pilot light)
     892             : 
     893             :             // Setup Report variables for the Gas Coils
     894             :             // CurrentModuleObject = "Coil:Heating:Gas:MultiStage"
     895           2 :             SetupOutputVariable(state,
     896             :                                 "Heating Coil Heating Energy",
     897             :                                 Constant::Units::J,
     898           1 :                                 heatingCoil.HeatingCoilLoad,
     899             :                                 OutputProcessor::TimeStepType::System,
     900             :                                 OutputProcessor::StoreType::Sum,
     901           1 :                                 heatingCoil.Name,
     902             :                                 Constant::eResource::EnergyTransfer,
     903             :                                 OutputProcessor::Group::HVAC,
     904             :                                 OutputProcessor::EndUseCat::HeatingCoils);
     905           2 :             SetupOutputVariable(state,
     906             :                                 "Heating Coil Heating Rate",
     907             :                                 Constant::Units::W,
     908           1 :                                 heatingCoil.HeatingCoilRate,
     909             :                                 OutputProcessor::TimeStepType::System,
     910             :                                 OutputProcessor::StoreType::Average,
     911           1 :                                 heatingCoil.Name);
     912           2 :             SetupOutputVariable(state,
     913             :                                 "Heating Coil NaturalGas Energy",
     914             :                                 Constant::Units::J,
     915           1 :                                 heatingCoil.FuelUseLoad,
     916             :                                 OutputProcessor::TimeStepType::System,
     917             :                                 OutputProcessor::StoreType::Sum,
     918           1 :                                 heatingCoil.Name,
     919             :                                 Constant::eResource::NaturalGas,
     920             :                                 OutputProcessor::Group::HVAC,
     921             :                                 OutputProcessor::EndUseCat::Heating);
     922           2 :             SetupOutputVariable(state,
     923             :                                 "Heating Coil NaturalGas Rate",
     924             :                                 Constant::Units::W,
     925           1 :                                 heatingCoil.FuelUseRate,
     926             :                                 OutputProcessor::TimeStepType::System,
     927             :                                 OutputProcessor::StoreType::Average,
     928           1 :                                 heatingCoil.Name);
     929           2 :             SetupOutputVariable(state,
     930             :                                 "Heating Coil Electricity Energy",
     931             :                                 Constant::Units::J,
     932           1 :                                 heatingCoil.ElecUseLoad,
     933             :                                 OutputProcessor::TimeStepType::System,
     934             :                                 OutputProcessor::StoreType::Sum,
     935           1 :                                 heatingCoil.Name,
     936             :                                 Constant::eResource::Electricity,
     937             :                                 OutputProcessor::Group::HVAC,
     938             :                                 OutputProcessor::EndUseCat::Heating);
     939           2 :             SetupOutputVariable(state,
     940             :                                 "Heating Coil Electricity Rate",
     941             :                                 Constant::Units::W,
     942           1 :                                 heatingCoil.ElecUseRate,
     943             :                                 OutputProcessor::TimeStepType::System,
     944             :                                 OutputProcessor::StoreType::Average,
     945           1 :                                 heatingCoil.Name);
     946           2 :             SetupOutputVariable(state,
     947             :                                 "Heating Coil Runtime Fraction",
     948             :                                 Constant::Units::None,
     949           1 :                                 heatingCoil.RTF,
     950             :                                 OutputProcessor::TimeStepType::System,
     951             :                                 OutputProcessor::StoreType::Average,
     952           1 :                                 heatingCoil.Name);
     953           2 :             SetupOutputVariable(state,
     954             :                                 "Heating Coil Ancillary NaturalGas Rate",
     955             :                                 Constant::Units::W,
     956           1 :                                 heatingCoil.ParasiticFuelRate,
     957             :                                 OutputProcessor::TimeStepType::System,
     958             :                                 OutputProcessor::StoreType::Average,
     959           1 :                                 heatingCoil.Name);
     960           2 :             SetupOutputVariable(state,
     961             :                                 "Heating Coil Ancillary NaturalGas Energy",
     962             :                                 Constant::Units::J,
     963           1 :                                 heatingCoil.ParasiticFuelConsumption,
     964             :                                 OutputProcessor::TimeStepType::System,
     965             :                                 OutputProcessor::StoreType::Sum,
     966           1 :                                 heatingCoil.Name,
     967             :                                 Constant::eResource::NaturalGas,
     968             :                                 OutputProcessor::Group::HVAC,
     969             :                                 OutputProcessor::EndUseCat::Heating);
     970             :         }
     971             : 
     972             :         // Get the data for for desuperheater heating coils
     973         291 :         for (int DesuperheaterCoilNum = 1; DesuperheaterCoilNum <= state.dataHeatingCoils->NumDesuperheaterCoil; ++DesuperheaterCoilNum) {
     974             : 
     975           3 :             int CoilNum = state.dataHeatingCoils->NumElecCoil + state.dataHeatingCoils->NumElecCoilMultiStage + state.dataHeatingCoils->NumFuelCoil +
     976           3 :                           state.dataHeatingCoils->NumGasCoilMultiStage + DesuperheaterCoilNum;
     977           3 :             auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
     978           3 :             auto &heatingCoilNumericFields = state.dataHeatingCoils->HeatingCoilNumericFields(CoilNum);
     979           3 :             CurrentModuleObject = "Coil:Heating:Desuperheater";
     980           3 :             heatingCoil.FuelType = Constant::eFuel::Electricity;
     981             : 
     982           3 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     983             :                                                                      CurrentModuleObject,
     984             :                                                                      DesuperheaterCoilNum,
     985             :                                                                      Alphas,
     986             :                                                                      NumAlphas,
     987             :                                                                      Numbers,
     988             :                                                                      NumNums,
     989             :                                                                      IOStat,
     990             :                                                                      lNumericBlanks,
     991             :                                                                      lAlphaBlanks,
     992             :                                                                      cAlphaFields,
     993             :                                                                      cNumericFields);
     994             : 
     995           3 :             heatingCoilNumericFields.FieldNames.allocate(state.dataHeatingCoils->MaxNums);
     996           3 :             heatingCoilNumericFields.FieldNames = cNumericFields;
     997             : 
     998             :             // InputErrorsFound will be set to True if problem was found, left untouched otherwise
     999           3 :             GlobalNames::VerifyUniqueCoilName(
    1000           3 :                 state, CurrentModuleObject, Alphas(1), state.dataHeatingCoils->InputErrorsFound, CurrentModuleObject + " Name");
    1001           3 :             heatingCoil.Name = Alphas(1);
    1002           3 :             heatingCoil.Schedule = Alphas(2);
    1003           3 :             if (lAlphaBlanks(2)) {
    1004           0 :                 heatingCoil.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
    1005             :             } else {
    1006           3 :                 heatingCoil.SchedPtr = ScheduleManager::GetScheduleIndex(state, Alphas(2));
    1007           3 :                 if (heatingCoil.SchedPtr == 0) {
    1008           0 :                     ShowSevereError(state,
    1009           0 :                                     format("{}{}: Invalid {} entered ={} for {}={}",
    1010             :                                            RoutineName,
    1011             :                                            CurrentModuleObject,
    1012             :                                            cAlphaFields(2),
    1013             :                                            Alphas(2),
    1014             :                                            cAlphaFields(1),
    1015             :                                            Alphas(1)));
    1016           0 :                     state.dataHeatingCoils->InputErrorsFound = true;
    1017             :                 }
    1018             :             }
    1019             : 
    1020             :             //       check availability schedule for values between 0 and 1
    1021           3 :             if (heatingCoil.SchedPtr > 0) {
    1022           3 :                 if (!ScheduleManager::CheckScheduleValueMinMax(state, heatingCoil.SchedPtr, ">=", 0.0, "<=", 1.0)) {
    1023           0 :                     ShowSevereError(state, format("{} = \"{}\"", CurrentModuleObject, heatingCoil.Name));
    1024           0 :                     ShowContinueError(state, format("Error found in {} = {}", cAlphaFields(2), Alphas(2)));
    1025           0 :                     ShowContinueError(state, "Schedule values must be (>=0., <=1.)");
    1026           0 :                     state.dataHeatingCoils->InputErrorsFound = true;
    1027             :                 }
    1028             :             }
    1029             : 
    1030           3 :             heatingCoil.HeatingCoilType = "Heating";
    1031           3 :             heatingCoil.HeatingCoilModel = "Desuperheater";
    1032           3 :             heatingCoil.HCoilType_Num = HVAC::Coil_HeatingDesuperheater;
    1033             : 
    1034             :             // HeatingCoil(CoilNum)%Efficiency       = Numbers(1)
    1035             :             //(Numbers(1)) error limits checked and defaults applied on efficiency after
    1036             :             //       identifying souce type.
    1037             : 
    1038           3 :             errFlag = false;
    1039           3 :             heatingCoil.AirInletNodeNum = GetOnlySingleNode(state,
    1040           3 :                                                             Alphas(3),
    1041             :                                                             errFlag,
    1042             :                                                             DataLoopNode::ConnectionObjectType::CoilHeatingDesuperheater,
    1043           3 :                                                             Alphas(1),
    1044             :                                                             DataLoopNode::NodeFluidType::Air,
    1045             :                                                             DataLoopNode::ConnectionType::Inlet,
    1046             :                                                             NodeInputManager::CompFluidStream::Primary,
    1047             :                                                             DataLoopNode::ObjectIsNotParent);
    1048           3 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
    1049           3 :             errFlag = false;
    1050           3 :             heatingCoil.AirOutletNodeNum = GetOnlySingleNode(state,
    1051           3 :                                                              Alphas(4),
    1052             :                                                              errFlag,
    1053             :                                                              DataLoopNode::ConnectionObjectType::CoilHeatingDesuperheater,
    1054           3 :                                                              Alphas(1),
    1055             :                                                              DataLoopNode::NodeFluidType::Air,
    1056             :                                                              DataLoopNode::ConnectionType::Outlet,
    1057             :                                                              NodeInputManager::CompFluidStream::Primary,
    1058             :                                                              DataLoopNode::ObjectIsNotParent);
    1059           3 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
    1060             : 
    1061           3 :             BranchNodeConnections::TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(3), Alphas(4), "Air Nodes");
    1062             : 
    1063           5 :             if ((Util::SameString(Alphas(5), "Refrigeration:Condenser:AirCooled")) ||
    1064           5 :                 (Util::SameString(Alphas(5), "Refrigeration:Condenser:EvaporativeCooled")) ||
    1065           5 :                 (Util::SameString(Alphas(5), "Refrigeration:Condenser:WaterCooled"))) {
    1066           1 :                 if (lNumericBlanks(1)) {
    1067           0 :                     heatingCoil.Efficiency = 0.8;
    1068             :                 } else {
    1069           1 :                     heatingCoil.Efficiency = Numbers(1);
    1070           1 :                     if (Numbers(1) < 0.0 || Numbers(1) > 0.9) {
    1071           0 :                         ShowSevereError(
    1072             :                             state,
    1073           0 :                             format("{}, \"{}\" heat reclaim recovery efficiency must be >= 0 and <=0.9", CurrentModuleObject, heatingCoil.Name));
    1074           0 :                         state.dataHeatingCoils->InputErrorsFound = true;
    1075             :                     }
    1076             :                 }
    1077             :             } else {
    1078           2 :                 if (lNumericBlanks(1)) {
    1079           0 :                     heatingCoil.Efficiency = 0.25;
    1080             :                 } else {
    1081           2 :                     heatingCoil.Efficiency = Numbers(1);
    1082           2 :                     if (Numbers(1) < 0.0 || Numbers(1) > 0.3) {
    1083           0 :                         ShowSevereError(
    1084             :                             state,
    1085           0 :                             format("{}, \"{}\" heat reclaim recovery efficiency must be >= 0 and <=0.3", CurrentModuleObject, heatingCoil.Name));
    1086           0 :                         state.dataHeatingCoils->InputErrorsFound = true;
    1087             :                     }
    1088             :                 }
    1089             :             }
    1090             : 
    1091             :             // Find the DX equipment index associated with the desuperheater heating coil.
    1092             :             // The CoilNum may not be found here when zone heating equip. exists. Check again in InitHeatingCoil.
    1093             :             // (when zone equipment heating coils are included in the input, the air loop DX equipment has not yet been read in)
    1094           3 :             if (Util::SameString(Alphas(5), "Refrigeration:CompressorRack")) {
    1095           1 :                 heatingCoil.ReclaimHeatingSource = HeatObjTypes::COMPRESSORRACK_REFRIGERATEDCASE;
    1096           2 :                 RefrigeratedCase::GetRefrigeratedRackIndex(
    1097           1 :                     state, Alphas(6), heatingCoil.ReclaimHeatingSourceIndexNum, DataHeatBalance::RefrigSystemType::Rack, DXCoilErrFlag, Alphas(5));
    1098           1 :                 if (heatingCoil.ReclaimHeatingSourceIndexNum > 0) {
    1099           1 :                     if (allocated(state.dataHeatBal->HeatReclaimRefrigeratedRack)) {
    1100             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1101           1 :                             state.dataHeatBal->HeatReclaimRefrigeratedRack(heatingCoil.ReclaimHeatingSourceIndexNum);
    1102           1 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1103           1 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1104           1 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1105             :                         }
    1106           1 :                         HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1107           1 :                         if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1108           0 :                             ShowSevereError(
    1109             :                                 state,
    1110           0 :                                 format("{}, \"{}\" sum of heat reclaim recovery efficiencies from the same source coil: \"{} \" cannot be over 0.3",
    1111             :                                        HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1112           0 :                                        heatingCoil.Name,
    1113           0 :                                        heatingCoil.ReclaimHeatingCoilName));
    1114             :                         }
    1115           1 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1116             :                     }
    1117             :                 }
    1118           3 :             } else if ((Util::SameString(Alphas(5), "Refrigeration:Condenser:AirCooled")) ||
    1119           3 :                        (Util::SameString(Alphas(5), "Refrigeration:Condenser:EvaporativeCooled")) ||
    1120           3 :                        (Util::SameString(Alphas(5), "Refrigeration:Condenser:WaterCooled"))) {
    1121           1 :                 heatingCoil.ReclaimHeatingSource = HeatObjTypes::CONDENSER_REFRIGERATION;
    1122           2 :                 RefrigeratedCase::GetRefrigeratedRackIndex(state,
    1123           1 :                                                            Alphas(6),
    1124           1 :                                                            heatingCoil.ReclaimHeatingSourceIndexNum,
    1125             :                                                            DataHeatBalance::RefrigSystemType::Detailed,
    1126             :                                                            DXCoilErrFlag,
    1127           1 :                                                            Alphas(5));
    1128           1 :                 if (heatingCoil.ReclaimHeatingSourceIndexNum > 0) {
    1129           1 :                     if (allocated(state.dataHeatBal->HeatReclaimRefrigCondenser)) {
    1130             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1131           1 :                             state.dataHeatBal->HeatReclaimRefrigCondenser(heatingCoil.ReclaimHeatingSourceIndexNum);
    1132           1 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1133           1 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1134           1 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1135             :                         }
    1136           1 :                         HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1137           1 :                         if (HeatReclaim.ReclaimEfficiencyTotal > 0.9) {
    1138           0 :                             ShowSevereError(
    1139             :                                 state,
    1140           0 :                                 format("{}, \"{}\" sum of heat reclaim recovery efficiencies from the same source coil: \"{} \" cannot be over 0.9",
    1141             :                                        HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1142           0 :                                        heatingCoil.Name,
    1143           0 :                                        heatingCoil.ReclaimHeatingCoilName));
    1144             :                         }
    1145           1 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1146             :                     }
    1147             :                 }
    1148           1 :             } else if (Util::SameString(Alphas(5), "Coil:Cooling:DX:SingleSpeed")) {
    1149           0 :                 heatingCoil.ReclaimHeatingSource = HeatObjTypes::COIL_DX_COOLING;
    1150           0 :                 DXCoils::GetDXCoilIndex(state, Alphas(6), heatingCoil.ReclaimHeatingSourceIndexNum, DXCoilErrFlag, Alphas(5));
    1151           0 :                 if (heatingCoil.ReclaimHeatingSourceIndexNum > 0) {
    1152           0 :                     if (allocated(state.dataHeatBal->HeatReclaimDXCoil)) {
    1153             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1154           0 :                             state.dataHeatBal->HeatReclaimDXCoil(heatingCoil.ReclaimHeatingSourceIndexNum);
    1155           0 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1156           0 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1157           0 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1158             :                         }
    1159           0 :                         HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1160           0 :                         if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1161           0 :                             ShowSevereError(
    1162             :                                 state,
    1163           0 :                                 format("{}, \"{}\" sum of heat reclaim recovery efficiencies from the same source coil: \"{} \" cannot be over 0.3",
    1164             :                                        HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1165           0 :                                        heatingCoil.Name,
    1166           0 :                                        heatingCoil.ReclaimHeatingCoilName));
    1167             :                         }
    1168           0 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1169             :                     }
    1170             :                 }
    1171           0 :                 if (heatingCoil.ReclaimHeatingSourceIndexNum > 0) state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1172           1 :             } else if (Util::SameString(Alphas(5), "Coil:Cooling:DX:VariableSpeed")) {
    1173           0 :                 heatingCoil.ReclaimHeatingSource = HeatObjTypes::COIL_DX_VARIABLE_COOLING;
    1174           0 :                 heatingCoil.ReclaimHeatingSourceIndexNum = VariableSpeedCoils::GetCoilIndexVariableSpeed(state, Alphas(5), Alphas(6), DXCoilErrFlag);
    1175           0 :                 if (heatingCoil.ReclaimHeatingSourceIndexNum > 0) {
    1176           0 :                     if (allocated(state.dataHeatBal->HeatReclaimVS_DXCoil)) {
    1177             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1178           0 :                             state.dataHeatBal->HeatReclaimVS_DXCoil(heatingCoil.ReclaimHeatingSourceIndexNum);
    1179           0 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1180           0 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1181           0 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1182             :                         }
    1183           0 :                         HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1184           0 :                         if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1185           0 :                             ShowSevereError(
    1186             :                                 state,
    1187           0 :                                 format("{}, \"{}\" sum of heat reclaim recovery efficiencies from the same source coil: \"{} \" cannot be over 0.3",
    1188             :                                        HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1189           0 :                                        heatingCoil.Name,
    1190           0 :                                        heatingCoil.ReclaimHeatingCoilName));
    1191             :                         }
    1192           0 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1193             :                     }
    1194             :                 }
    1195           1 :             } else if (Util::SameString(Alphas(5), "Coil:Cooling:DX:TwoSpeed")) {
    1196           0 :                 heatingCoil.ReclaimHeatingSource = HeatObjTypes::COIL_DX_MULTISPEED;
    1197           0 :                 DXCoils::GetDXCoilIndex(state, Alphas(6), heatingCoil.ReclaimHeatingSourceIndexNum, DXCoilErrFlag, Alphas(5));
    1198           0 :                 if (heatingCoil.ReclaimHeatingSourceIndexNum > 0) {
    1199           0 :                     if (allocated(state.dataHeatBal->HeatReclaimDXCoil)) {
    1200             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1201           0 :                             state.dataHeatBal->HeatReclaimDXCoil(heatingCoil.ReclaimHeatingSourceIndexNum);
    1202           0 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1203           0 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1204           0 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1205             :                         }
    1206           0 :                         HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1207           0 :                         if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1208           0 :                             ShowSevereError(
    1209             :                                 state,
    1210           0 :                                 format("{}, \"{}\" sum of heat reclaim recovery efficiencies from the same source coil: \"{} \" cannot be over 0.3",
    1211             :                                        HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1212           0 :                                        heatingCoil.Name,
    1213           0 :                                        heatingCoil.ReclaimHeatingCoilName));
    1214             :                         }
    1215           0 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1216             :                     }
    1217             :                 }
    1218           1 :             } else if (Util::SameString(Alphas(5), "Coil:Cooling:DX:TwoStageWithHumidityControlMode")) {
    1219           0 :                 heatingCoil.ReclaimHeatingSource = HeatObjTypes::COIL_DX_MULTIMODE;
    1220           0 :                 DXCoils::GetDXCoilIndex(state, Alphas(6), heatingCoil.ReclaimHeatingSourceIndexNum, DXCoilErrFlag, Alphas(5));
    1221           0 :                 if (heatingCoil.ReclaimHeatingSourceIndexNum > 0) {
    1222           0 :                     if (allocated(state.dataHeatBal->HeatReclaimDXCoil)) {
    1223             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1224           0 :                             state.dataHeatBal->HeatReclaimDXCoil(heatingCoil.ReclaimHeatingSourceIndexNum);
    1225           0 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1226           0 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1227           0 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1228             :                         }
    1229           0 :                         HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1230           0 :                         if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1231           0 :                             ShowSevereError(
    1232             :                                 state,
    1233           0 :                                 format(R"({}, "{}" sum of heat reclaim recovery efficiencies from the same source coil: "{} " cannot be over 0.3)",
    1234             :                                        HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1235           0 :                                        heatingCoil.Name,
    1236           0 :                                        heatingCoil.ReclaimHeatingCoilName));
    1237             :                         }
    1238           0 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1239             :                     }
    1240             :                 }
    1241           1 :             } else if (Util::SameString(Alphas(5), "Coil:Cooling:DX")) {
    1242           1 :                 heatingCoil.ReclaimHeatingSource = HeatObjTypes::COIL_COOLING_DX_NEW;
    1243           1 :                 heatingCoil.ReclaimHeatingSourceIndexNum = CoilCoolingDX::factory(state, Alphas(6));
    1244           1 :                 if (heatingCoil.ReclaimHeatingSourceIndexNum < 0) {
    1245           0 :                     ShowSevereError(
    1246           0 :                         state, format("{}={}, could not find desuperheater coil {}={}", CurrentModuleObject, heatingCoil.Name, Alphas(5), Alphas(6)));
    1247           0 :                     state.dataHeatingCoils->InputErrorsFound = true;
    1248             :                 }
    1249             :                 DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1250           1 :                     state.dataCoilCooingDX->coilCoolingDXs[heatingCoil.ReclaimHeatingSourceIndexNum].reclaimHeat;
    1251           1 :                 if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1252           1 :                     HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1253           1 :                     std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1254             :                 }
    1255           1 :                 HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1256           1 :                 if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1257           0 :                     ShowSevereError(
    1258             :                         state,
    1259           0 :                         format("{}, \"{}\" sum of heat reclaim recovery efficiencies from the same source coil: \"{}\" cannot be over 0.3",
    1260             :                                HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1261           0 :                                heatingCoil.Name,
    1262           0 :                                heatingCoil.ReclaimHeatingCoilName));
    1263             :                 }
    1264           1 :                 state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1265             :             } else {
    1266           0 :                 ShowSevereError(
    1267             :                     state,
    1268           0 :                     format("{}, \"{}\" valid desuperheater heat source object type not found: {}", CurrentModuleObject, heatingCoil.Name, Alphas(5)));
    1269           0 :                 ShowContinueError(state, "Valid desuperheater heat source objects are:");
    1270           0 :                 ShowContinueError(state,
    1271             :                                   "Refrigeration:CompressorRack, Coil:Cooling:DX:SingleSpeed, Refrigeration:Condenser:AirCooled, "
    1272             :                                   "Refrigeration:Condenser:EvaporativeCooled, Refrigeration:Condenser:WaterCooled,Coil:Cooling:DX:TwoSpeed, and "
    1273             :                                   "Coil:Cooling:DX:TwoStageWithHumidityControlMode");
    1274           0 :                 state.dataHeatingCoils->InputErrorsFound = true;
    1275             :             }
    1276             : 
    1277           3 :             heatingCoil.ReclaimHeatingCoilName = Alphas(6);
    1278             : 
    1279           3 :             errFlag = false;
    1280           3 :             heatingCoil.TempSetPointNodeNum = GetOnlySingleNode(state,
    1281           3 :                                                                 Alphas(7),
    1282             :                                                                 errFlag,
    1283             :                                                                 DataLoopNode::ConnectionObjectType::CoilHeatingDesuperheater,
    1284           3 :                                                                 Alphas(1),
    1285             :                                                                 DataLoopNode::NodeFluidType::Air,
    1286             :                                                                 DataLoopNode::ConnectionType::Sensor,
    1287             :                                                                 NodeInputManager::CompFluidStream::Primary,
    1288             :                                                                 DataLoopNode::ObjectIsNotParent);
    1289           3 :             state.dataHeatingCoils->InputErrorsFound = errFlag || state.dataHeatingCoils->InputErrorsFound;
    1290             : 
    1291             :             // parasitic electric load associated with the desuperheater heating coil
    1292           3 :             heatingCoil.ParasiticElecLoad = Numbers(2);
    1293             : 
    1294           3 :             if (Numbers(2) < 0.0) {
    1295           0 :                 ShowSevereError(state, format("{}, \"{}\" parasitic electric load must be >= 0", CurrentModuleObject, heatingCoil.Name));
    1296           0 :                 state.dataHeatingCoils->InputErrorsFound = true;
    1297             :             }
    1298             : 
    1299             :             // Setup Report variables for the Desuperheater Heating Coils
    1300             :             // CurrentModuleObject = "Coil:Heating:Desuperheater"
    1301           6 :             SetupOutputVariable(state,
    1302             :                                 "Heating Coil Heating Energy",
    1303             :                                 Constant::Units::J,
    1304           3 :                                 heatingCoil.HeatingCoilLoad,
    1305             :                                 OutputProcessor::TimeStepType::System,
    1306             :                                 OutputProcessor::StoreType::Sum,
    1307           3 :                                 heatingCoil.Name,
    1308             :                                 Constant::eResource::EnergyTransfer,
    1309             :                                 OutputProcessor::Group::HVAC,
    1310             :                                 OutputProcessor::EndUseCat::HeatingCoils);
    1311           6 :             SetupOutputVariable(state,
    1312             :                                 "Heating Coil Heating Rate",
    1313             :                                 Constant::Units::W,
    1314           3 :                                 heatingCoil.HeatingCoilRate,
    1315             :                                 OutputProcessor::TimeStepType::System,
    1316             :                                 OutputProcessor::StoreType::Average,
    1317           3 :                                 heatingCoil.Name);
    1318           6 :             SetupOutputVariable(state,
    1319             :                                 "Heating Coil Electricity Energy",
    1320             :                                 Constant::Units::J,
    1321           3 :                                 heatingCoil.ElecUseLoad,
    1322             :                                 OutputProcessor::TimeStepType::System,
    1323             :                                 OutputProcessor::StoreType::Sum,
    1324           3 :                                 heatingCoil.Name,
    1325             :                                 Constant::eResource::Electricity,
    1326             :                                 OutputProcessor::Group::HVAC,
    1327             :                                 OutputProcessor::EndUseCat::Heating);
    1328           6 :             SetupOutputVariable(state,
    1329             :                                 "Heating Coil Electricity Rate",
    1330             :                                 Constant::Units::W,
    1331           3 :                                 heatingCoil.ElecUseRate,
    1332             :                                 OutputProcessor::TimeStepType::System,
    1333             :                                 OutputProcessor::StoreType::Average,
    1334           3 :                                 heatingCoil.Name);
    1335           6 :             SetupOutputVariable(state,
    1336             :                                 "Heating Coil Runtime Fraction",
    1337             :                                 Constant::Units::None,
    1338           3 :                                 heatingCoil.RTF,
    1339             :                                 OutputProcessor::TimeStepType::System,
    1340             :                                 OutputProcessor::StoreType::Average,
    1341           3 :                                 heatingCoil.Name);
    1342             :         }
    1343             : 
    1344         288 :         if (state.dataHeatingCoils->InputErrorsFound) {
    1345           0 :             ShowFatalError(state, format("{}Errors found in input.  Program terminates.", RoutineName));
    1346             :         }
    1347             : 
    1348         288 :         Alphas.deallocate();
    1349         288 :         cAlphaFields.deallocate();
    1350         288 :         cNumericFields.deallocate();
    1351         288 :         Numbers.deallocate();
    1352         288 :         lAlphaBlanks.deallocate();
    1353         288 :         lNumericBlanks.deallocate();
    1354         288 :     }
    1355             : 
    1356   108011617 :     void InitHeatingCoil(EnergyPlusData &state, int const CoilNum, bool const FirstHVACIteration, Real64 const QCoilRequired)
    1357             :     {
    1358             : 
    1359             :         // SUBROUTINE INFORMATION:
    1360             :         //       AUTHOR         Richard J. Liesen
    1361             :         //       DATE WRITTEN   May 2000
    1362             :         //       MODIFIED       B. Griffith, May 2009 added EMS setpoint check
    1363             : 
    1364             :         // PURPOSE OF THIS SUBROUTINE:
    1365             :         // This subroutine is for initializations of the HeatingCoil Components.
    1366             : 
    1367             :         // METHODOLOGY EMPLOYED:
    1368             :         // Uses the status flags to trigger initializations.
    1369             : 
    1370   108011617 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    1371             : 
    1372   108011617 :         if (state.dataHeatingCoils->MyOneTimeFlag) {
    1373             :             // initialize the environment and sizing flags
    1374         288 :             Real64 numHeatingCoils = state.dataHeatingCoils->NumHeatingCoils;
    1375         288 :             state.dataHeatingCoils->MyEnvrnFlag.allocate(numHeatingCoils);
    1376         288 :             state.dataHeatingCoils->MySizeFlag.allocate(numHeatingCoils);
    1377         288 :             state.dataHeatingCoils->ShowSingleWarning.allocate(numHeatingCoils);
    1378         288 :             state.dataHeatingCoils->MySPTestFlag.allocate(numHeatingCoils);
    1379         288 :             state.dataHeatingCoils->MyEnvrnFlag = true;
    1380         288 :             state.dataHeatingCoils->MySizeFlag = true;
    1381         288 :             state.dataHeatingCoils->ShowSingleWarning = true;
    1382         288 :             state.dataHeatingCoils->MyOneTimeFlag = false;
    1383         288 :             state.dataHeatingCoils->MySPTestFlag = true;
    1384             :         }
    1385             : 
    1386   108011617 :         if (!state.dataGlobal->SysSizingCalc && state.dataHeatingCoils->MySizeFlag(CoilNum)) {
    1387             :             // for each coil, do the sizing once.
    1388        1438 :             SizeHeatingCoil(state, CoilNum);
    1389             : 
    1390        1438 :             state.dataHeatingCoils->MySizeFlag(CoilNum) = false;
    1391             :         }
    1392             : 
    1393             :         // Do the following initializations (every time step): This should be the info from
    1394             :         // the previous components outlets or the node data in this section.
    1395             :         // First set the conditions for the air into the coil model
    1396   108011617 :         int AirOutletNodeNum = heatingCoil.AirOutletNodeNum;
    1397   108011617 :         int ControlNodeNum = heatingCoil.TempSetPointNodeNum;
    1398   108011617 :         auto const &airInletNode = state.dataLoopNodes->Node(heatingCoil.AirInletNodeNum);
    1399   108011617 :         auto const &airOutletNode = state.dataLoopNodes->Node(AirOutletNodeNum);
    1400   108011617 :         heatingCoil.InletAirMassFlowRate = airInletNode.MassFlowRate;
    1401   108011617 :         heatingCoil.InletAirTemp = airInletNode.Temp;
    1402   108011617 :         heatingCoil.InletAirHumRat = airInletNode.HumRat;
    1403   108011617 :         heatingCoil.InletAirEnthalpy = airInletNode.Enthalpy;
    1404             : 
    1405             :         // Set the reporting variables to zero at each timestep.
    1406   108011617 :         heatingCoil.HeatingCoilLoad = 0.0;
    1407   108011617 :         heatingCoil.FuelUseLoad = 0.0;
    1408   108011617 :         heatingCoil.ElecUseLoad = 0.0;
    1409   108011617 :         heatingCoil.RTF = 0.0;
    1410             : 
    1411             :         // If a temperature setpoint controlled coil must set the desired outlet temp everytime
    1412   108011617 :         if (ControlNodeNum == 0) {
    1413   104721993 :             heatingCoil.DesiredOutletTemp = 0.0;
    1414             :         } else {
    1415     3289624 :             auto const &controlNode = state.dataLoopNodes->Node(ControlNodeNum);
    1416     3289624 :             heatingCoil.DesiredOutletTemp =
    1417     3289624 :                 controlNode.TempSetPoint - ((ControlNodeNum == AirOutletNodeNum) ? 0 : (controlNode.Temp - airOutletNode.Temp));
    1418             :         }
    1419             : 
    1420     3934150 :         if (QCoilRequired == DataLoopNode::SensedLoadFlagValue && state.dataHeatingCoils->MySPTestFlag(CoilNum) &&
    1421   111945767 :             heatingCoil.HCoilType_Num != HVAC::Coil_HeatingElectric_MultiStage && heatingCoil.HCoilType_Num != HVAC::Coil_HeatingGas_MultiStage) {
    1422             : 
    1423             :             //   If the coil is temperature controlled (QCoilReq == -999.0), both a control node and setpoint are required.
    1424        1356 :             if (!state.dataGlobal->SysSizingCalc && state.dataHVACGlobal->DoSetPointTest) {
    1425             :                 //     3 possibilities here:
    1426             :                 //     1) TempSetPointNodeNum .GT. 0 and TempSetPoint /= SensedNodeFlagValue, this is correct
    1427             :                 //     2) TempSetPointNodeNum .EQ. 0, this is not correct, control node is required
    1428             :                 //     3) TempSetPointNodeNum .GT. 0 and TempSetPoint == SensedNodeFlagValue, this is not correct, missing temperature setpoint
    1429             :                 //     test 2) here (fatal message)
    1430         277 :                 if (ControlNodeNum == 0) {
    1431           0 :                     ShowSevereError(state, format("{} \"{}\"", HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num), heatingCoil.Name));
    1432           0 :                     ShowContinueError(state, "... Missing control node for heating coil.");
    1433           0 :                     ShowContinueError(state, "... enter a control node name in the coil temperature setpoint node field for this heating coil.");
    1434           0 :                     ShowContinueError(state, "... use a Setpoint Manager to establish a setpoint at the coil temperature setpoint node.");
    1435           0 :                     state.dataHeatingCoils->HeatingCoilFatalError = true;
    1436             :                     //     test 3) here (fatal message)
    1437             :                 } else { // IF(ControlNode .GT. 0)THEN
    1438         277 :                     auto const &controlNode = state.dataLoopNodes->Node(ControlNodeNum);
    1439         277 :                     if (controlNode.TempSetPoint == DataLoopNode::SensedNodeFlagValue) {
    1440           0 :                         if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1441           0 :                             ShowSevereError(state, format("{} \"{}\"", HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num), heatingCoil.Name));
    1442           0 :                             ShowContinueError(state, "... Missing temperature setpoint for heating coil.");
    1443           0 :                             ShowContinueError(state, "... use a Setpoint Manager to establish a setpoint at the coil temperature setpoint node.");
    1444           0 :                             state.dataHeatingCoils->HeatingCoilFatalError = true;
    1445             :                         } else {
    1446           0 :                             EMSManager::CheckIfNodeSetPointManagedByEMS(
    1447           0 :                                 state, ControlNodeNum, HVAC::CtrlVarType::Temp, state.dataHeatingCoils->HeatingCoilFatalError);
    1448           0 :                             if (state.dataHeatingCoils->HeatingCoilFatalError) {
    1449           0 :                                 ShowSevereError(state, format("{} \"{}\"", HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num), heatingCoil.Name));
    1450           0 :                                 ShowContinueError(state, "... Missing temperature setpoint for heating coil.");
    1451           0 :                                 ShowContinueError(state, "... use a Setpoint Manager to establish a setpoint at the coil temperature setpoint node.");
    1452           0 :                                 ShowContinueError(state, "... or use an EMS Actuator to establish a setpoint at the coil temperature setpoint node.");
    1453             :                             }
    1454             :                         }
    1455             :                     }
    1456             :                 }
    1457         277 :                 state.dataHeatingCoils->MySPTestFlag(CoilNum) = false;
    1458             :             }
    1459   108010261 :         } else if (state.dataHeatingCoils->MySPTestFlag(CoilNum)) {
    1460             :             //  If QCoilReq /= SensedLoadFlagValue, the coil is load controlled and does not require a control node
    1461             :             //   4 possibilities here:
    1462             :             //   1) TempSetPointNodeNum .EQ. 0 and TempSetPoint == SensedNodeFlagValue, this is correct
    1463             :             //   2) TempSetPointNodeNum .EQ. 0 and TempSetPoint /= SensedNodeFlagValue, this may be correct,
    1464             :             //      (if no control node specified and SP on heating coil outlet do not show warning, other SP managers may be using SP)
    1465             :             //   3) TempSetPointNodeNum .GT. 0 and TempSetPoint == SensedNodeFlagValue, control node not required if load based control
    1466             :             //   4) TempSetPointNodeNum .GT. 0 and TempSetPoint /= SensedNodeFlagValue, control node not required if load based control
    1467             :             //   test 3) and 4) here (warning only)
    1468        1161 :             if (ControlNodeNum > 0) {
    1469           1 :                 ShowWarningError(state, format("{} \"{}\"", HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num), heatingCoil.Name));
    1470           1 :                 ShowContinueError(state, " The \"Temperature Setpoint Node Name\" input is not required for this heating coil.");
    1471           1 :                 ShowContinueError(state, " Leaving the input field \"Temperature Setpoint Node Name\" blank will eliminate this warning.");
    1472             :             }
    1473        1161 :             state.dataHeatingCoils->MySPTestFlag(CoilNum) = false;
    1474             :         }
    1475             : 
    1476             :         // delay fatal error until all coils are called
    1477   108011617 :         if (!FirstHVACIteration && state.dataHeatingCoils->HeatingCoilFatalError) {
    1478           0 :             ShowFatalError(state, "... errors found in heating coil input.");
    1479             :         }
    1480             : 
    1481             :         // Find the heating source index for the desuperheater heating coil if not already found. This occurs when zone heating
    1482             :         // equip. exists. (when zone equipment heating coils are included in the input, the air loop DX equipment has not yet been read)
    1483             :         // Issue a single warning if the coil is not found and continue the simulation
    1484   108011617 :         if (!state.dataHeatingCoils->ValidSourceType(CoilNum) && (heatingCoil.HCoilType_Num == HVAC::Coil_HeatingDesuperheater) &&
    1485           0 :             state.dataHeatingCoils->ShowSingleWarning(CoilNum)) {
    1486           0 :             ++state.dataHeatingCoils->ValidSourceTypeCounter;
    1487           0 :             switch (heatingCoil.ReclaimHeatingSource) {
    1488           0 :             case HeatObjTypes::COMPRESSORRACK_REFRIGERATEDCASE: {
    1489           0 :                 for (int RackNum = 1; RackNum <= state.dataRefrigCase->NumRefrigeratedRacks; ++RackNum) {
    1490           0 :                     if (!Util::SameString(state.dataHeatBal->HeatReclaimRefrigeratedRack(RackNum).Name, heatingCoil.ReclaimHeatingCoilName)) continue;
    1491           0 :                     heatingCoil.ReclaimHeatingSourceIndexNum = RackNum;
    1492           0 :                     if (allocated(state.dataHeatBal->HeatReclaimRefrigeratedRack)) {
    1493             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1494           0 :                             state.dataHeatBal->HeatReclaimRefrigeratedRack(heatingCoil.ReclaimHeatingSourceIndexNum);
    1495           0 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1496           0 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1497           0 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1498           0 :                             HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1499           0 :                             if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1500           0 :                                 ShowSevereError(
    1501             :                                     state,
    1502           0 :                                     format(R"({}, "{}" sum of heat reclaim recovery efficiencies from the same source coil: "{}" cannot be over 0.3)",
    1503             :                                            HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1504           0 :                                            heatingCoil.Name,
    1505           0 :                                            heatingCoil.ReclaimHeatingCoilName));
    1506             :                             }
    1507             :                         }
    1508           0 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1509             :                     }
    1510           0 :                     break;
    1511             :                 }
    1512           0 :             } break;
    1513           0 :             case HeatObjTypes::CONDENSER_REFRIGERATION: {
    1514           0 :                 for (int CondNum = 1; CondNum <= state.dataRefrigCase->NumRefrigCondensers; ++CondNum) {
    1515           0 :                     if (!Util::SameString(state.dataHeatBal->HeatReclaimRefrigCondenser(CondNum).Name, heatingCoil.ReclaimHeatingCoilName)) continue;
    1516           0 :                     heatingCoil.ReclaimHeatingSourceIndexNum = CondNum;
    1517           0 :                     if (allocated(state.dataHeatBal->HeatReclaimRefrigCondenser)) {
    1518             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1519           0 :                             state.dataHeatBal->HeatReclaimRefrigCondenser(heatingCoil.ReclaimHeatingSourceIndexNum);
    1520           0 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1521           0 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1522           0 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1523           0 :                             HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1524           0 :                             if (HeatReclaim.ReclaimEfficiencyTotal > 0.9) {
    1525           0 :                                 ShowSevereError(
    1526             :                                     state,
    1527           0 :                                     format(R"({}, "{}" sum of heat reclaim recovery efficiencies from the same source coil: "{}" cannot be over 0.9)",
    1528             :                                            HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1529           0 :                                            heatingCoil.Name,
    1530           0 :                                            heatingCoil.ReclaimHeatingCoilName));
    1531             :                             }
    1532             :                         }
    1533           0 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1534             :                     }
    1535           0 :                     break;
    1536             :                 }
    1537           0 :             } break;
    1538           0 :             case HeatObjTypes::COIL_DX_COOLING:
    1539             :             case HeatObjTypes::COIL_DX_MULTISPEED:
    1540             :             case HeatObjTypes::COIL_DX_MULTIMODE: {
    1541           0 :                 for (int DXCoilNum = 1; DXCoilNum <= state.dataDXCoils->NumDXCoils; ++DXCoilNum) {
    1542           0 :                     if (!Util::SameString(state.dataHeatBal->HeatReclaimDXCoil(DXCoilNum).Name, heatingCoil.ReclaimHeatingCoilName)) continue;
    1543           0 :                     heatingCoil.ReclaimHeatingSourceIndexNum = DXCoilNum;
    1544           0 :                     if (allocated(state.dataHeatBal->HeatReclaimDXCoil)) {
    1545             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1546           0 :                             state.dataHeatBal->HeatReclaimDXCoil(heatingCoil.ReclaimHeatingSourceIndexNum);
    1547           0 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1548           0 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1549           0 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1550           0 :                             HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1551           0 :                             if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1552           0 :                                 ShowSevereError(
    1553             :                                     state,
    1554           0 :                                     format(R"({}, "{}" sum of heat reclaim recovery efficiencies from the same source coil: "{}" cannot be over 0.3)",
    1555             :                                            HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1556           0 :                                            heatingCoil.Name,
    1557           0 :                                            heatingCoil.ReclaimHeatingCoilName));
    1558             :                             }
    1559             :                         }
    1560           0 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1561             :                     }
    1562           0 :                     break;
    1563             :                 }
    1564           0 :             } break;
    1565           0 :             case HeatObjTypes::COIL_DX_VARIABLE_COOLING: {
    1566           0 :                 for (int DXCoilNum = 1; DXCoilNum <= state.dataVariableSpeedCoils->NumVarSpeedCoils; ++DXCoilNum) {
    1567           0 :                     if (!Util::SameString(state.dataHeatBal->HeatReclaimVS_DXCoil(DXCoilNum).Name, heatingCoil.ReclaimHeatingCoilName)) continue;
    1568           0 :                     heatingCoil.ReclaimHeatingSourceIndexNum = DXCoilNum;
    1569           0 :                     if (allocated(state.dataHeatBal->HeatReclaimVS_DXCoil)) {
    1570             :                         DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1571           0 :                             state.dataHeatBal->HeatReclaimVS_DXCoil(heatingCoil.ReclaimHeatingSourceIndexNum);
    1572           0 :                         if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1573           0 :                             HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1574           0 :                             std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1575           0 :                             HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1576           0 :                             if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1577           0 :                                 ShowSevereError(
    1578             :                                     state,
    1579           0 :                                     format(R"({}, "{}" sum of heat reclaim recovery efficiencies from the same source coil: "{}" cannot be over 0.3)",
    1580             :                                            HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1581           0 :                                            heatingCoil.Name,
    1582           0 :                                            heatingCoil.ReclaimHeatingCoilName));
    1583             :                             }
    1584             :                         }
    1585           0 :                         state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1586             :                     }
    1587           0 :                     break;
    1588             :                 }
    1589             :             case HeatObjTypes::COIL_COOLING_DX_NEW:
    1590             :                 DataHeatBalance::HeatReclaimDataBase &HeatReclaim =
    1591           0 :                     state.dataCoilCooingDX->coilCoolingDXs[heatingCoil.ReclaimHeatingSourceIndexNum].reclaimHeat;
    1592           0 :                 if (!allocated(HeatReclaim.HVACDesuperheaterReclaimedHeat)) {
    1593           0 :                     HeatReclaim.HVACDesuperheaterReclaimedHeat.allocate(state.dataHeatingCoils->NumDesuperheaterCoil);
    1594           0 :                     std::fill(HeatReclaim.HVACDesuperheaterReclaimedHeat.begin(), HeatReclaim.HVACDesuperheaterReclaimedHeat.end(), 0.0);
    1595           0 :                     HeatReclaim.ReclaimEfficiencyTotal += heatingCoil.Efficiency;
    1596           0 :                     if (HeatReclaim.ReclaimEfficiencyTotal > 0.3) {
    1597           0 :                         ShowSevereError(
    1598             :                             state,
    1599           0 :                             format("{}, \"{}\" sum of heat reclaim recovery efficiencies from the same source coil: \"{}\" cannot be over 0.3",
    1600             :                                    HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    1601           0 :                                    heatingCoil.Name,
    1602           0 :                                    heatingCoil.ReclaimHeatingCoilName));
    1603             :                     }
    1604             :                 }
    1605           0 :                 state.dataHeatingCoils->ValidSourceType(CoilNum) = true;
    1606           0 :                 break;
    1607             :             } break;
    1608           0 :             default:
    1609           0 :                 break;
    1610             :             }
    1611           0 :             if ((state.dataHeatingCoils->ValidSourceTypeCounter > state.dataHeatingCoils->NumDesuperheaterCoil * 2) &&
    1612           0 :                 state.dataHeatingCoils->ShowSingleWarning(CoilNum) && !state.dataHeatingCoils->ValidSourceType(CoilNum)) {
    1613           0 :                 ShowWarningError(state,
    1614           0 :                                  format("Coil:Heating:Desuperheater, \"{}\" desuperheater heat source object name not found: {}",
    1615           0 :                                         heatingCoil.Name,
    1616           0 :                                         heatingCoil.ReclaimHeatingCoilName));
    1617           0 :                 ShowContinueError(state, " Desuperheater heating coil is not modeled and simulation continues.");
    1618           0 :                 state.dataHeatingCoils->ShowSingleWarning(CoilNum) = false;
    1619             :             }
    1620             :         }
    1621   108011617 :     }
    1622             : 
    1623        1438 :     void SizeHeatingCoil(EnergyPlusData &state, int const CoilNum)
    1624             :     {
    1625             : 
    1626             :         // SUBROUTINE INFORMATION:
    1627             :         //       AUTHOR         Fred Buhl
    1628             :         //       DATE WRITTEN   January 2002
    1629             :         //       MODIFIED       August 2013 Daeho Kang, add component sizing table entries
    1630             :         //       RE-ENGINEERED  Mar 2014 FSEC, moved calculations to common routine in BaseSizer
    1631             : 
    1632             :         // PURPOSE OF THIS SUBROUTINE:
    1633             :         // This subroutine is for sizing Heating Coil Components for which nominal capcities have not been
    1634             :         // specified in the input.
    1635             : 
    1636             :         // METHODOLOGY EMPLOYED:
    1637             :         // Obtains heating capacities from the zone or system sizing arrays or parent object as necessary.
    1638             :         // heating coil or other routine sets up any required data variables (e.g., DataCoilIsSuppHeater, TermUnitPIU, etc.),
    1639             :         // sizing variable (e.g., HeatingCoil( CoilNum ).NominalCapacity in this routine since it can be multi-staged and new routine
    1640             :         // currently only handles single values) and associated string representing that sizing variable.
    1641             :         // Sizer functions handles the actual sizing and reporting.
    1642             : 
    1643             :         // SUBROUTINE PARAMETER DEFINITIONS:
    1644             :         static constexpr std::string_view RoutineName("SizeHeatingCoil: "); // include trailing blank space
    1645             : 
    1646             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1647        1438 :         std::string CompName;       // component name
    1648        1438 :         std::string CompType;       // component type
    1649        1438 :         std::string SizingString;   // input field sizing description (e.g., Nominal Capacity)
    1650        1438 :         bool bPRINT = true;         // TRUE if sizing is reported to output (eio)
    1651             :         Real64 NominalCapacityDes;  // Autosized nominal capacity for reporting
    1652             :         Real64 NominalCapacityUser; // Hardsized nominal capacity for reporting
    1653             :         Real64 TempCap;             // autosized capacity of heating coil [W]
    1654        1438 :         int FieldNum = 2;           // IDD numeric field number where input field description is found
    1655        1438 :         int NumCoilsSized = 0;      // counter used to deallocate temporary string array after all coils have been sized
    1656             : 
    1657        1438 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    1658             : 
    1659        1438 :         if (heatingCoil.HCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) {
    1660           5 :             FieldNum = 1 + (heatingCoil.NumOfStages * 2);
    1661           5 :             TempCap = heatingCoil.MSNominalCapacity(heatingCoil.NumOfStages);
    1662        1433 :         } else if (heatingCoil.HCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
    1663           1 :             FieldNum = 1 + (heatingCoil.NumOfStages * 3);
    1664           1 :             TempCap = heatingCoil.MSNominalCapacity(heatingCoil.NumOfStages);
    1665        1432 :         } else if (heatingCoil.HCoilType_Num == HVAC::Coil_HeatingDesuperheater) {
    1666           3 :             return; // no autosizable inputs for desupterheater
    1667             :         } else {
    1668        1429 :             FieldNum = 2;
    1669        1429 :             TempCap = heatingCoil.NominalCapacity;
    1670             :         }
    1671        1435 :         SizingString = state.dataHeatingCoils->HeatingCoilNumericFields(CoilNum).FieldNames(FieldNum) + " [W]";
    1672        1435 :         CompType = "Coil:" + heatingCoil.HeatingCoilType + ':' + heatingCoil.HeatingCoilModel;
    1673        1435 :         CompName = heatingCoil.Name;
    1674        1435 :         state.dataSize->DataCoilIsSuppHeater = state.dataHeatingCoils->CoilIsSuppHeater; // set global instead of using optional argument
    1675        1435 :         state.dataSize->DataCoolCoilCap =
    1676             :             0.0; // global only used for heat pump heating coils, non-HP heating coils are sized with other global variables
    1677             : 
    1678        1435 :         if (TempCap == DataSizing::AutoSize) {
    1679        1163 :             if (heatingCoil.DesiccantRegenerationCoil) {
    1680           0 :                 state.dataSize->DataDesicRegCoil = true;
    1681           0 :                 bPRINT = false;
    1682           0 :                 state.dataSize->DataDesicDehumNum = heatingCoil.DesiccantDehumNum;
    1683           0 :                 HeatingCoilDesAirInletTempSizer sizerHeatingDesInletTemp;
    1684           0 :                 bool ErrorsFound = false;
    1685           0 :                 sizerHeatingDesInletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    1686           0 :                 state.dataSize->DataDesInletAirTemp = sizerHeatingDesInletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
    1687             : 
    1688           0 :                 HeatingCoilDesAirOutletTempSizer sizerHeatingDesOutletTemp;
    1689           0 :                 ErrorsFound = false;
    1690           0 :                 sizerHeatingDesOutletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    1691           0 :                 state.dataSize->DataDesOutletAirTemp = sizerHeatingDesOutletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
    1692             : 
    1693           0 :                 if (state.dataSize->CurOASysNum > 0) {
    1694           0 :                     auto &OASysEqSizing(state.dataSize->OASysEqSizing(state.dataSize->CurOASysNum));
    1695           0 :                     OASysEqSizing.AirFlow = true;
    1696           0 :                     OASysEqSizing.AirVolFlow = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesOutAirVolFlow;
    1697             :                 }
    1698           0 :                 state.dataSize->DataDesicDehumNum = 0;
    1699           0 :                 bPRINT = true;
    1700           0 :             }
    1701             :         }
    1702        1435 :         bool errorsFound = false;
    1703        1435 :         HeatingCapacitySizer sizerHeatingCapacity;
    1704        1435 :         sizerHeatingCapacity.overrideSizingString(SizingString);
    1705        1435 :         sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    1706        1435 :         TempCap = sizerHeatingCapacity.size(state, TempCap, errorsFound);
    1707        1435 :         state.dataSize->DataCoilIsSuppHeater = false; // reset global to false so other heating coils are not affected
    1708        1435 :         state.dataSize->DataDesicRegCoil = false;     // reset global to false so other heating coils are not affected
    1709        1435 :         state.dataSize->DataDesInletAirTemp = 0.0;    // reset global data to zero so other heating coils are not
    1710        1435 :         state.dataSize->DataDesOutletAirTemp = 0.0;   // reset global data to zero so other heating coils are not affected
    1711             : 
    1712        1435 :         if (heatingCoil.HCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage || heatingCoil.HCoilType_Num == HVAC::Coil_HeatingGas_MultiStage) {
    1713           6 :             heatingCoil.MSNominalCapacity(heatingCoil.NumOfStages) = TempCap;
    1714           6 :             bool IsAutoSize = false;
    1715             :             int NumOfStages; // total number of stages of multi-stage heating coil
    1716           6 :             if (any_eq(heatingCoil.MSNominalCapacity, DataSizing::AutoSize)) {
    1717           4 :                 IsAutoSize = true;
    1718             :             }
    1719           6 :             if (IsAutoSize) {
    1720           4 :                 NumOfStages = heatingCoil.NumOfStages;
    1721          10 :                 for (int StageNum = NumOfStages - 1; StageNum >= 1; --StageNum) {
    1722           6 :                     bool ThisStageAutoSize = false;
    1723           6 :                     FieldNum = 1 + StageNum * ((heatingCoil.HCoilType_Num == HVAC::Coil_HeatingElectric_MultiStage) ? 2 : 3);
    1724           6 :                     SizingString = state.dataHeatingCoils->HeatingCoilNumericFields(CoilNum).FieldNames(FieldNum) + " [W]";
    1725           6 :                     if (heatingCoil.MSNominalCapacity(StageNum) == DataSizing::AutoSize) {
    1726           6 :                         ThisStageAutoSize = true;
    1727             :                     }
    1728           6 :                     NominalCapacityDes = TempCap * StageNum / NumOfStages;
    1729           6 :                     if (ThisStageAutoSize) {
    1730           6 :                         heatingCoil.MSNominalCapacity(StageNum) = NominalCapacityDes;
    1731           6 :                         BaseSizer::reportSizerOutput(state, CompType, CompName, "Design Size " + SizingString, NominalCapacityDes);
    1732             :                     } else {
    1733           0 :                         if (heatingCoil.MSNominalCapacity(StageNum) > 0.0 && NominalCapacityDes > 0.0) {
    1734           0 :                             NominalCapacityUser = TempCap * StageNum / NumOfStages; // HeatingCoil( CoilNum ).MSNominalCapacity( StageNum );
    1735           0 :                             BaseSizer::reportSizerOutput(state,
    1736             :                                                          CompType,
    1737             :                                                          CompName,
    1738           0 :                                                          "Design Size " + SizingString,
    1739             :                                                          NominalCapacityDes,
    1740           0 :                                                          "User-Specified " + SizingString,
    1741             :                                                          NominalCapacityUser);
    1742           0 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    1743           0 :                                 if ((std::abs(NominalCapacityDes - NominalCapacityUser) / NominalCapacityUser) >
    1744           0 :                                     state.dataSize->AutoVsHardSizingThreshold) {
    1745           0 :                                     ShowMessage(state,
    1746           0 :                                                 format("SizeHeatingCoil: Potential issue with equipment sizing for {}, {}", CompType, CompName));
    1747           0 :                                     ShowContinueError(state, format("User-Specified Nominal Capacity of {:.2R} [W]", NominalCapacityUser));
    1748           0 :                                     ShowContinueError(state, format("differs from Design Size Nominal Capacity of {:.2R} [W]", NominalCapacityDes));
    1749           0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1750           0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1751             :                                 }
    1752             :                             }
    1753             :                         }
    1754             :                     }
    1755             :                 }
    1756             :             } else { // No autosize
    1757           2 :                 NumOfStages = heatingCoil.NumOfStages;
    1758           2 :                 for (int StageNum = NumOfStages - 1; StageNum >= 1; --StageNum) {
    1759           0 :                     if (heatingCoil.MSNominalCapacity(StageNum) > 0.0) {
    1760           0 :                         BaseSizer::reportSizerOutput(
    1761           0 :                             state, CompType, CompName, "User-Specified " + SizingString, heatingCoil.MSNominalCapacity(StageNum));
    1762             :                     }
    1763             :                 }
    1764             :             }
    1765             :             // Ensure capacity at lower Stage must be lower or equal to the capacity at higher Stage.
    1766          12 :             for (int StageNum = 1; StageNum <= heatingCoil.NumOfStages - 1; ++StageNum) {
    1767           6 :                 if (heatingCoil.MSNominalCapacity(StageNum) > heatingCoil.MSNominalCapacity(StageNum + 1)) {
    1768           0 :                     ShowSevereError(state,
    1769           0 :                                     format("SizeHeatingCoil: {} {}, Stage {} Nominal Capacity ({:.2R} W) must be less than or equal to Stage {} "
    1770             :                                            "Nominal Capacity ({:.2R} W).",
    1771           0 :                                            heatingCoil.HeatingCoilType,
    1772           0 :                                            heatingCoil.Name,
    1773             :                                            StageNum,
    1774             :                                            heatingCoil.MSNominalCapacity(StageNum),
    1775           0 :                                            StageNum + 1,
    1776             :                                            heatingCoil.MSNominalCapacity(StageNum + 1)));
    1777           0 :                     ShowFatalError(state, "Preceding conditions cause termination.");
    1778             :                 }
    1779             :             }
    1780           6 :         } else { // not a multi-speed coil
    1781        1429 :             heatingCoil.NominalCapacity = TempCap;
    1782             :         }
    1783             : 
    1784        1435 :         if (++NumCoilsSized == state.dataHeatingCoils->NumHeatingCoils)
    1785          91 :             state.dataHeatingCoils->HeatingCoilNumericFields.deallocate(); // remove temporary array for field names at end of sizing
    1786             : 
    1787             :         // create predefined report entries
    1788        1435 :         switch (heatingCoil.HCoilType_Num) {
    1789         655 :         case HVAC::Coil_HeatingElectric: {
    1790         655 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, heatingCoil.Name, "Coil:Heating:Electric");
    1791        1310 :             OutputReportPredefined::PreDefTableEntry(
    1792         655 :                 state, state.dataOutRptPredefined->pdchHeatCoilNomCap, heatingCoil.Name, heatingCoil.NominalCapacity);
    1793         655 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, heatingCoil.Name, heatingCoil.Efficiency);
    1794         655 :         } break;
    1795           5 :         case HVAC::Coil_HeatingElectric_MultiStage: {
    1796          10 :             OutputReportPredefined::PreDefTableEntry(
    1797           5 :                 state, state.dataOutRptPredefined->pdchHeatCoilType, heatingCoil.Name, "Coil:Heating:Electric:MultiStage");
    1798          10 :             OutputReportPredefined::PreDefTableEntry(
    1799           5 :                 state, state.dataOutRptPredefined->pdchHeatCoilNomCap, heatingCoil.Name, heatingCoil.MSNominalCapacity(heatingCoil.NumOfStages));
    1800          10 :             OutputReportPredefined::PreDefTableEntry(
    1801           5 :                 state, state.dataOutRptPredefined->pdchHeatCoilNomEff, heatingCoil.Name, heatingCoil.MSEfficiency(heatingCoil.NumOfStages));
    1802           5 :         } break;
    1803         774 :         case HVAC::Coil_HeatingGasOrOtherFuel: {
    1804         774 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, heatingCoil.Name, "Coil:Heating:Fuel");
    1805        1548 :             OutputReportPredefined::PreDefTableEntry(
    1806         774 :                 state, state.dataOutRptPredefined->pdchHeatCoilNomCap, heatingCoil.Name, heatingCoil.NominalCapacity);
    1807         774 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, heatingCoil.Name, heatingCoil.Efficiency);
    1808         774 :         } break;
    1809           1 :         case HVAC::Coil_HeatingGas_MultiStage: {
    1810           2 :             OutputReportPredefined::PreDefTableEntry(
    1811           1 :                 state, state.dataOutRptPredefined->pdchHeatCoilType, heatingCoil.Name, "Coil:Heating:Gas:MultiStage");
    1812           2 :             OutputReportPredefined::PreDefTableEntry(
    1813           1 :                 state, state.dataOutRptPredefined->pdchHeatCoilNomCap, heatingCoil.Name, heatingCoil.MSNominalCapacity(heatingCoil.NumOfStages));
    1814           2 :             OutputReportPredefined::PreDefTableEntry(
    1815           1 :                 state, state.dataOutRptPredefined->pdchHeatCoilNomEff, heatingCoil.Name, heatingCoil.MSEfficiency(heatingCoil.NumOfStages));
    1816           1 :         } break;
    1817           0 :         case HVAC::Coil_HeatingDesuperheater: {
    1818           0 :             OutputReportPredefined::PreDefTableEntry(
    1819           0 :                 state, state.dataOutRptPredefined->pdchHeatCoilType, heatingCoil.Name, "Coil:Heating:Desuperheater");
    1820           0 :             OutputReportPredefined::PreDefTableEntry(
    1821           0 :                 state, state.dataOutRptPredefined->pdchHeatCoilNomCap, heatingCoil.Name, heatingCoil.NominalCapacity);
    1822           0 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, heatingCoil.Name, heatingCoil.Efficiency);
    1823           0 :         } break;
    1824           0 :         default:
    1825           0 :             break;
    1826             :         }
    1827             : 
    1828             :         // std 229 heating coils existing table adding new variables:
    1829             :         // pdchHeatCoilUsedAsSupHeat is now reported at coil selection report
    1830             :         // pdchHeatCoilAirloopName is now reported at coil selection report
    1831             :         // std 229 Coil Connections New table: now all reported at coil selection report
    1832        1444 :     }
    1833             : 
    1834    33898164 :     void CalcElectricHeatingCoil(EnergyPlusData &state,
    1835             :                                  int const CoilNum, // index to heating coil
    1836             :                                  Real64 &QCoilReq,
    1837             :                                  Real64 &QCoilActual,       // coil load actually delivered (W)
    1838             :                                  HVAC::FanOp const fanOp,   // fan operating mode
    1839             :                                  Real64 const PartLoadRatio // part-load ratio of heating coil
    1840             :     )
    1841             :     {
    1842             :         // SUBROUTINE INFORMATION:
    1843             :         //       AUTHOR         Rich Liesen
    1844             :         //       DATE WRITTEN   May 2000
    1845             :         //       MODIFIED       Jul. 2016, R. Zhang, Applied the coil supply air temperature sensor offset
    1846             : 
    1847             :         // PURPOSE OF THIS SUBROUTINE:
    1848             :         // Simulates a simple Electric heating coil with an efficiency
    1849             : 
    1850             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1851             :         Real64 AirMassFlow; // [kg/sec]
    1852             :         Real64 TempAirOut;  // [C]
    1853             :         Real64 HeatingCoilLoad;
    1854             :         Real64 QCoilCap;
    1855             : 
    1856    33898164 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    1857             : 
    1858    33898164 :         Real64 Effic = heatingCoil.Efficiency;
    1859    33898164 :         Real64 TempAirIn = heatingCoil.InletAirTemp;
    1860    33898164 :         Real64 Win = heatingCoil.InletAirHumRat;
    1861    33898164 :         Real64 TempSetPoint = heatingCoil.DesiredOutletTemp;
    1862             : 
    1863             :         // If there is a fault of coil SAT Sensor
    1864    33898164 :         if (heatingCoil.FaultyCoilSATFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    1865           0 :             (!state.dataGlobal->KickOffSimulation)) {
    1866             :             // calculate the sensor offset using fault information
    1867           0 :             int FaultIndex = heatingCoil.FaultyCoilSATIndex;
    1868           0 :             heatingCoil.FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
    1869             :             // update the TempSetPoint
    1870           0 :             TempSetPoint -= heatingCoil.FaultyCoilSATOffset;
    1871             :         }
    1872             : 
    1873             :         //  adjust mass flow rates for cycling fan cycling coil operation
    1874    33898164 :         if (fanOp == HVAC::FanOp::Cycling) {
    1875    17840658 :             if (PartLoadRatio > 0.0) {
    1876    11317804 :                 AirMassFlow = heatingCoil.InletAirMassFlowRate / PartLoadRatio;
    1877    11317804 :                 QCoilReq /= PartLoadRatio;
    1878             :             } else {
    1879     6522854 :                 AirMassFlow = 0.0;
    1880             :             }
    1881             :         } else {
    1882    16057506 :             AirMassFlow = heatingCoil.InletAirMassFlowRate;
    1883             :         }
    1884             : 
    1885    33898164 :         Real64 CapacitanceAir = Psychrometrics::PsyCpAirFnW(Win) * AirMassFlow;
    1886             : 
    1887             :         // If the coil is operating there should be some heating capacitance
    1888             :         //  across the coil, so do the simulation. If not set outlet to inlet and no load.
    1889             :         //  Also the coil has to be scheduled to be available.
    1890             : 
    1891             :         // Control output to meet load QCoilReq (QCoilReq is passed in if load controlled, otherwise QCoilReq=-999)
    1892    23874204 :         if ((AirMassFlow > 0.0 && heatingCoil.NominalCapacity > 0.0) &&
    1893    57772368 :             (ScheduleManager::GetCurrentScheduleValue(state, heatingCoil.SchedPtr) > 0.0) && (QCoilReq > 0.0)) {
    1894             : 
    1895             :             // check to see if the Required heating capacity is greater than the user specified capacity.
    1896     4760745 :             if (QCoilReq > heatingCoil.NominalCapacity) {
    1897      255204 :                 QCoilCap = heatingCoil.NominalCapacity;
    1898             :             } else {
    1899     4505541 :                 QCoilCap = QCoilReq;
    1900             :             }
    1901             : 
    1902     4760745 :             TempAirOut = TempAirIn + QCoilCap / CapacitanceAir;
    1903     4760745 :             HeatingCoilLoad = QCoilCap;
    1904             : 
    1905             :             // The HeatingCoilLoad is the change in the enthalpy of the Heating
    1906     4760745 :             heatingCoil.ElecUseLoad = HeatingCoilLoad / Effic;
    1907             : 
    1908             :             // Control coil output to meet a setpoint temperature.
    1909    19113459 :         } else if ((AirMassFlow > 0.0 && heatingCoil.NominalCapacity > 0.0) &&
    1910    48552394 :                    (ScheduleManager::GetCurrentScheduleValue(state, heatingCoil.SchedPtr) > 0.0) && (QCoilReq == DataLoopNode::SensedLoadFlagValue) &&
    1911      301516 :                    (std::abs(TempSetPoint - TempAirIn) > HVAC::TempControlTol)) {
    1912             : 
    1913      263657 :             QCoilCap = CapacitanceAir * (TempSetPoint - TempAirIn);
    1914             :             // check to see if setpoint above enetering temperature. If not, set
    1915             :             // output to zero.
    1916      263657 :             if (QCoilCap <= 0.0) {
    1917       32291 :                 QCoilCap = 0.0;
    1918       32291 :                 TempAirOut = TempAirIn;
    1919             :                 // check to see if the Required heating capacity is greater than the user
    1920             :                 // specified capacity.
    1921      231366 :             } else if (QCoilCap > heatingCoil.NominalCapacity) {
    1922       56093 :                 QCoilCap = heatingCoil.NominalCapacity;
    1923       56093 :                 TempAirOut = TempAirIn + QCoilCap / CapacitanceAir;
    1924             :             } else {
    1925      175273 :                 TempAirOut = TempSetPoint;
    1926             :             }
    1927             : 
    1928      263657 :             HeatingCoilLoad = QCoilCap;
    1929             : 
    1930             :             // The HeatingCoilLoad is the change in the enthalpy of the Heating
    1931      263657 :             heatingCoil.ElecUseLoad = HeatingCoilLoad / Effic;
    1932             : 
    1933             :         } else { // If not running Conditions do not change across coil from inlet to outlet
    1934             : 
    1935    28873762 :             TempAirOut = TempAirIn;
    1936    28873762 :             HeatingCoilLoad = 0.0;
    1937    28873762 :             heatingCoil.ElecUseLoad = 0.0;
    1938             :         }
    1939             : 
    1940    33898164 :         if (fanOp == HVAC::FanOp::Cycling) {
    1941    17840658 :             heatingCoil.ElecUseLoad *= PartLoadRatio;
    1942    17840658 :             HeatingCoilLoad *= PartLoadRatio;
    1943             :         }
    1944             : 
    1945    33898164 :         heatingCoil.HeatingCoilLoad = HeatingCoilLoad;
    1946             : 
    1947             :         // Set the outlet conditions
    1948    33898164 :         heatingCoil.OutletAirTemp = TempAirOut;
    1949             : 
    1950             :         // This HeatingCoil does not change the moisture or Mass Flow across the component
    1951    33898164 :         heatingCoil.OutletAirHumRat = heatingCoil.InletAirHumRat;
    1952    33898164 :         heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    1953             :         // Set the outlet enthalpys for air and Heating
    1954    33898164 :         heatingCoil.OutletAirEnthalpy = Psychrometrics::PsyHFnTdbW(heatingCoil.OutletAirTemp, heatingCoil.OutletAirHumRat);
    1955             : 
    1956    33898164 :         QCoilActual = HeatingCoilLoad;
    1957    33898164 :         if (std::abs(heatingCoil.NominalCapacity) < 1.e-8) {
    1958       90082 :             if (heatingCoil.AirLoopNum > 0) {
    1959           0 :                 state.dataAirLoop->AirLoopAFNInfo(heatingCoil.AirLoopNum).AFNLoopHeatingCoilMaxRTF =
    1960           0 :                     max(state.dataAirLoop->AirLoopAFNInfo(heatingCoil.AirLoopNum).AFNLoopHeatingCoilMaxRTF, 0.0);
    1961             :             }
    1962             :         } else {
    1963    33808082 :             if (heatingCoil.AirLoopNum > 0) {
    1964      681678 :                 state.dataAirLoop->AirLoopAFNInfo(heatingCoil.AirLoopNum).AFNLoopHeatingCoilMaxRTF =
    1965      681678 :                     max(state.dataAirLoop->AirLoopAFNInfo(heatingCoil.AirLoopNum).AFNLoopHeatingCoilMaxRTF,
    1966      681678 :                         HeatingCoilLoad / heatingCoil.NominalCapacity);
    1967             :             }
    1968             :         }
    1969             : 
    1970             :         // set outlet node temp so parent objects can call calc directly without have to simulate entire model
    1971    33898164 :         state.dataLoopNodes->Node(heatingCoil.AirOutletNodeNum).Temp = heatingCoil.OutletAirTemp;
    1972    33898164 :     }
    1973             : 
    1974     1083499 :     void CalcMultiStageElectricHeatingCoil(EnergyPlusData &state,
    1975             :                                            int const CoilNum,       // the number of the electric heating coil to be simulated
    1976             :                                            Real64 const SpeedRatio, // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
    1977             :                                            Real64 const CycRatio,   // cycling part load ratio
    1978             :                                            int const StageNum,      // Stage number
    1979             :                                            HVAC::FanOp const fanOp, // Fan operation mode
    1980             :                                            Real64 &QCoilActual,     // coil load actually delivered (W)
    1981             :                                            bool const SuppHeat)
    1982             :     {
    1983             : 
    1984             :         // SUBROUTINE INFORMATION:
    1985             :         //       AUTHOR         Chandan Sharma, FSEC
    1986             :         //       DATE WRITTEN   January 2013
    1987             : 
    1988             :         // PURPOSE OF THIS SUBROUTINE:
    1989             :         // Calculates the air-side performance and electrical energy use of multistage electric heating coil.
    1990             : 
    1991             :         // METHODOLOGY EMPLOYED:
    1992             :         // Uses the same methodology as the single stage electric heating unit model (SUBROUTINE CalcelectricHeatingCoil).
    1993             :         // In addition it assumes that the unit performance is obtained by interpolating between
    1994             :         // the performance at high stage and that at low stage. If the output needed is below
    1995             :         // that produced at low stage, the coil cycles between off and low stage.
    1996             : 
    1997             :         // SUBROUTINE PARAMETER DEFINITIONS:
    1998             :         static constexpr std::string_view RoutineName = "CalcMultiStageElectricHeatingCoil";
    1999             :         static constexpr std::string_view RoutineNameAverageLoad = "CalcMultiStageElectricHeatingCoil:Averageload";
    2000             :         static constexpr std::string_view RoutineNameFullLoad = "CalcMultiStageElectricHeatingCoil:fullload";
    2001             : 
    2002             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2003             :         Real64 OutletAirEnthalpy;    // outlet air enthalpy [J/kg]
    2004             :         Real64 OutletAirHumRat;      // outlet air humidity ratio [kg/kg]
    2005             :         Real64 TotCapHS;             // total capacity at high stage [W]
    2006             :         Real64 TotCapLS;             // total capacity at low stage [W]
    2007             :         Real64 TotCap;               // total capacity at current stage [W]
    2008             :         Real64 EffHS;                // total capacity at high stage [W]
    2009             :         Real64 EffLS;                // total capacity at low stage [W]
    2010             :         int StageNumHS;              // High stage number
    2011             :         int StageNumLS;              // Low stage number
    2012             :         Real64 FullLoadOutAirEnth;   // Outlet full load enthalpy
    2013             :         Real64 FullLoadOutAirHumRat; // Outlet humidity ratio at full load
    2014             :         Real64 FullLoadOutAirTemp;   // Outlet temperature at full load
    2015             :         Real64 FullLoadOutAirRH;     // Outler relative humidity at full load
    2016             :         Real64 OutletAirTemp;        // Supply ari temperature
    2017             :         Real64 LSElecHeatingPower;   // Full load power at low stage
    2018             :         Real64 HSElecHeatingPower;   // Full load power at high stage
    2019             :         Real64 PartLoadRat;          // part load ratio
    2020             : 
    2021     1083499 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    2022     1083499 :         if (StageNum > 1) {
    2023      209263 :             StageNumLS = StageNum - 1;
    2024      209263 :             StageNumHS = StageNum;
    2025      209263 :             if (StageNum > heatingCoil.NumOfStages) {
    2026       61842 :                 StageNumLS = heatingCoil.NumOfStages - 1;
    2027       61842 :                 StageNumHS = heatingCoil.NumOfStages;
    2028             :             }
    2029             :         } else {
    2030      874236 :             StageNumLS = 1;
    2031      874236 :             StageNumHS = 1;
    2032             :         }
    2033             : 
    2034     1083499 :         Real64 AirMassFlow = heatingCoil.InletAirMassFlowRate;
    2035     1083499 :         Real64 InletAirDryBulbTemp = heatingCoil.InletAirTemp;
    2036     1083499 :         Real64 InletAirEnthalpy = heatingCoil.InletAirEnthalpy;
    2037     1083499 :         Real64 InletAirHumRat = heatingCoil.InletAirHumRat;
    2038             : 
    2039     1083499 :         Real64 OutdoorPressure = state.dataEnvrn->OutBaroPress;
    2040             : 
    2041     1667641 :         if ((AirMassFlow > 0.0) && (ScheduleManager::GetCurrentScheduleValue(state, heatingCoil.SchedPtr) > 0.0) &&
    2042      584142 :             ((CycRatio > 0.0) || (SpeedRatio > 0.0))) {
    2043             : 
    2044      281141 :             if (StageNum > 1) {
    2045             : 
    2046      147421 :                 TotCapLS = heatingCoil.MSNominalCapacity(StageNumLS);
    2047      147421 :                 TotCapHS = heatingCoil.MSNominalCapacity(StageNumHS);
    2048             : 
    2049      147421 :                 EffLS = heatingCoil.MSEfficiency(StageNumLS);
    2050      147421 :                 EffHS = heatingCoil.MSEfficiency(StageNumHS);
    2051             : 
    2052             :                 // Get full load output and power
    2053      147421 :                 LSElecHeatingPower = TotCapLS / EffLS;
    2054      147421 :                 HSElecHeatingPower = TotCapHS / EffHS;
    2055      147421 :                 OutletAirHumRat = InletAirHumRat;
    2056             : 
    2057             :                 // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
    2058             :                 // IF (FanOpMode .EQ. FanOp::Cycling) OnOffFanPartLoadFraction = 1.0d0
    2059             : 
    2060             :                 // Power calculation
    2061      147421 :                 heatingCoil.ElecUseLoad = SpeedRatio * HSElecHeatingPower + (1.0 - SpeedRatio) * LSElecHeatingPower;
    2062             : 
    2063      147421 :                 heatingCoil.HeatingCoilLoad = TotCapHS * SpeedRatio + TotCapLS * (1.0 - SpeedRatio);
    2064             : 
    2065      147421 :                 OutletAirEnthalpy = InletAirEnthalpy + heatingCoil.HeatingCoilLoad / heatingCoil.InletAirMassFlowRate;
    2066      147421 :                 OutletAirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
    2067      147421 :                 FullLoadOutAirRH = Psychrometrics::PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, OutdoorPressure, RoutineNameAverageLoad);
    2068             : 
    2069      147421 :                 if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
    2070           0 :                     OutletAirTemp = Psychrometrics::PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, RoutineName);
    2071           0 :                     OutletAirHumRat = Psychrometrics::PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy, RoutineName);
    2072             :                 }
    2073             : 
    2074      147421 :                 heatingCoil.OutletAirTemp = OutletAirTemp;
    2075      147421 :                 heatingCoil.OutletAirHumRat = OutletAirHumRat;
    2076      147421 :                 heatingCoil.OutletAirEnthalpy = OutletAirEnthalpy;
    2077      147421 :                 heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    2078             : 
    2079             :                 // Stage 1
    2080      133720 :             } else if (CycRatio > 0.0) {
    2081             : 
    2082      106216 :                 PartLoadRat = min(1.0, CycRatio);
    2083             : 
    2084             :                 // for cycling fan, reset mass flow to full on rate
    2085      106216 :                 if (fanOp == HVAC::FanOp::Cycling)
    2086       37168 :                     AirMassFlow /= PartLoadRat;
    2087       69048 :                 else if (fanOp == HVAC::FanOp::Continuous) {
    2088       69048 :                     if (!SuppHeat) {
    2089       66803 :                         AirMassFlow = state.dataHVACGlobal->MSHPMassFlowRateLow;
    2090             :                     }
    2091             :                 }
    2092             : 
    2093      106216 :                 TotCap = heatingCoil.MSNominalCapacity(StageNumLS);
    2094             : 
    2095             :                 // Calculate full load outlet conditions
    2096      106216 :                 FullLoadOutAirEnth = InletAirEnthalpy + TotCap / AirMassFlow;
    2097      106216 :                 FullLoadOutAirHumRat = InletAirHumRat;
    2098      106216 :                 FullLoadOutAirTemp = Psychrometrics::PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
    2099             :                 FullLoadOutAirRH =
    2100      106216 :                     Psychrometrics::PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
    2101             : 
    2102      106216 :                 if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
    2103           0 :                     FullLoadOutAirTemp = Psychrometrics::PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure, RoutineName);
    2104             :                     //  Eventually inlet air conditions will be used in electric Coil, these lines are commented out and marked with this comment
    2105             :                     //  line FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
    2106           0 :                     FullLoadOutAirHumRat = Psychrometrics::PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
    2107             :                 }
    2108             : 
    2109             :                 // Set outlet conditions from the full load calculation
    2110      106216 :                 if (fanOp == HVAC::FanOp::Cycling) {
    2111       37168 :                     OutletAirEnthalpy = FullLoadOutAirEnth;
    2112       37168 :                     OutletAirHumRat = FullLoadOutAirHumRat;
    2113       37168 :                     OutletAirTemp = FullLoadOutAirTemp;
    2114             :                 } else {
    2115       69048 :                     OutletAirEnthalpy = PartLoadRat * FullLoadOutAirEnth + (1.0 - PartLoadRat) * InletAirEnthalpy;
    2116       69048 :                     OutletAirHumRat = PartLoadRat * FullLoadOutAirHumRat + (1.0 - PartLoadRat) * InletAirHumRat;
    2117       69048 :                     OutletAirTemp = PartLoadRat * FullLoadOutAirTemp + (1.0 - PartLoadRat) * InletAirDryBulbTemp;
    2118             :                 }
    2119             : 
    2120      106216 :                 EffLS = heatingCoil.MSEfficiency(StageNumLS);
    2121             : 
    2122             :                 //    HeatingCoil(CoilNum)%HeatingCoilLoad = TotCap
    2123             :                 //   This would require a CR to change
    2124      106216 :                 heatingCoil.HeatingCoilLoad = TotCap * PartLoadRat;
    2125             : 
    2126      106216 :                 heatingCoil.ElecUseLoad = heatingCoil.HeatingCoilLoad / EffLS;
    2127             : 
    2128      106216 :                 heatingCoil.OutletAirTemp = OutletAirTemp;
    2129      106216 :                 heatingCoil.OutletAirHumRat = OutletAirHumRat;
    2130      106216 :                 heatingCoil.OutletAirEnthalpy = OutletAirEnthalpy;
    2131      106216 :                 heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    2132             :                 // this would require a CR to correct (i.e., calculate outputs when coil is off)
    2133             :                 //  ELSE
    2134             :                 //    ! electric coil is off; just pass through conditions
    2135             :                 //    HeatingCoil(CoilNum)%OutletAirEnthalpy = HeatingCoil(CoilNum)%InletAirEnthalpy
    2136             :                 //    HeatingCoil(CoilNum)%OutletAirHumRat   = HeatingCoil(CoilNum)%InletAirHumRat
    2137             :                 //    HeatingCoil(CoilNum)%OutletAirTemp     = HeatingCoil(CoilNum)%InletAirTemp
    2138             :                 //    HeatingCoil(CoilNum)%OutletAirMassFlowRate = HeatingCoil(CoilNum)%InletAirMassFlowRate
    2139             :                 //    HeatingCoil(CoilNum)%ElecUseLoad      = 0.0
    2140             :                 //    HeatingCoil(CoilNum)%HeatingCoilLoad  = 0.0
    2141             :                 //    ElecHeatingCoilPower                  = 0.0
    2142             :             }
    2143             : 
    2144             :         } else {
    2145             : 
    2146             :             // electric coil is off; just pass through conditions
    2147      802358 :             heatingCoil.OutletAirEnthalpy = heatingCoil.InletAirEnthalpy;
    2148      802358 :             heatingCoil.OutletAirHumRat = heatingCoil.InletAirHumRat;
    2149      802358 :             heatingCoil.OutletAirTemp = heatingCoil.InletAirTemp;
    2150      802358 :             heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    2151             : 
    2152             :             // some of these are reset in Init, can be removed to speed up code
    2153      802358 :             heatingCoil.ElecUseLoad = 0.0;
    2154      802358 :             heatingCoil.HeatingCoilLoad = 0.0;
    2155             : 
    2156             :         } // end of on/off if - else
    2157             : 
    2158             :         // set outlet node temp so parent objects can call calc directly without have to simulate entire model
    2159     1083499 :         state.dataLoopNodes->Node(heatingCoil.AirOutletNodeNum).Temp = heatingCoil.OutletAirTemp;
    2160             : 
    2161     1083499 :         QCoilActual = heatingCoil.HeatingCoilLoad;
    2162     1083499 :     }
    2163             : 
    2164    72562154 :     void CalcFuelHeatingCoil(EnergyPlusData &state,
    2165             :                              int const CoilNum, // index to heating coil
    2166             :                              Real64 const QCoilReq,
    2167             :                              Real64 &QCoilActual,                        // coil load actually delivered (W)
    2168             :                              HVAC::FanOp const fanOp,                    // fan operating mode
    2169             :                              [[maybe_unused]] Real64 const PartLoadRatio // part-load ratio of heating coil
    2170             :     )
    2171             :     {
    2172             :         // SUBROUTINE INFORMATION:
    2173             :         //       AUTHOR         Rich Liesen
    2174             :         //       DATE WRITTEN   May 2000
    2175             :         //       MODIFIED       Jul. 2016, R. Zhang, Applied the coil supply air temperature sensor offset
    2176             : 
    2177             :         // PURPOSE OF THIS SUBROUTINE:
    2178             :         // Simulates a simple Gas heating coil with a burner efficiency
    2179             : 
    2180             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2181             :         Real64 TempAirOut; // [C]
    2182             :         Real64 HeatingCoilLoad;
    2183             :         Real64 QCoilCap;
    2184             :         Real64 PartLoadRat;
    2185             :         Real64 PLF;
    2186             : 
    2187    72562154 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    2188             : 
    2189    72562154 :         Real64 Effic = heatingCoil.Efficiency;
    2190    72562154 :         Real64 TempAirIn = heatingCoil.InletAirTemp;
    2191    72562154 :         Real64 Win = heatingCoil.InletAirHumRat;
    2192    72562154 :         Real64 TempSetPoint = heatingCoil.DesiredOutletTemp;
    2193    72562154 :         Real64 AirMassFlow = heatingCoil.InletAirMassFlowRate;
    2194             : 
    2195    72562154 :         Real64 CapacitanceAir = Psychrometrics::PsyCpAirFnW(Win) * AirMassFlow;
    2196             : 
    2197             :         // If there is a fault of coil SAT Sensor
    2198    72562154 :         if (heatingCoil.FaultyCoilSATFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    2199           0 :             (!state.dataGlobal->KickOffSimulation)) {
    2200             :             // calculate the sensor offset using fault information
    2201           0 :             int FaultIndex = heatingCoil.FaultyCoilSATIndex;
    2202           0 :             heatingCoil.FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
    2203             :             // update the TempSetPoint
    2204           0 :             TempSetPoint -= heatingCoil.FaultyCoilSATOffset;
    2205             :         }
    2206             : 
    2207             :         // If the coil is operating there should be some heating capacitance
    2208             :         //  across the coil, so do the simulation. If not set outlet to inlet and no load.
    2209             :         //  Also the coil has to be scheduled to be available.
    2210             : 
    2211             :         // Control output to meet load QCoilReq (QCoilReq is passed in if load controlled, otherwise QCoilReq=-999)
    2212    65835144 :         if ((AirMassFlow > 0.0 && heatingCoil.NominalCapacity > 0.0) &&
    2213   138397298 :             (ScheduleManager::GetCurrentScheduleValue(state, heatingCoil.SchedPtr) > 0.0) && (QCoilReq > 0.0)) {
    2214             : 
    2215             :             // check to see if the Required heating capacity is greater than the user specified capacity.
    2216     8402737 :             if (QCoilReq > heatingCoil.NominalCapacity) {
    2217      105690 :                 QCoilCap = heatingCoil.NominalCapacity;
    2218             :             } else {
    2219     8297047 :                 QCoilCap = QCoilReq;
    2220             :             }
    2221             : 
    2222     8402737 :             TempAirOut = TempAirIn + QCoilCap / CapacitanceAir;
    2223     8402737 :             HeatingCoilLoad = QCoilCap;
    2224             : 
    2225     8402737 :             PartLoadRat = HeatingCoilLoad / heatingCoil.NominalCapacity;
    2226             : 
    2227             :             // The HeatingCoilLoad is the change in the enthalpy of the Heating
    2228     8402737 :             heatingCoil.FuelUseLoad = HeatingCoilLoad / Effic;
    2229     8402737 :             heatingCoil.ElecUseLoad = heatingCoil.ParasiticElecLoad * PartLoadRat;
    2230     8402737 :             heatingCoil.ParasiticFuelRate = heatingCoil.ParasiticFuelCapacity * (1.0 - PartLoadRat);
    2231             : 
    2232             :             // Control coil output to meet a setpoint temperature.
    2233    57432407 :         } else if ((AirMassFlow > 0.0 && heatingCoil.NominalCapacity > 0.0) &&
    2234   123592533 :                    (ScheduleManager::GetCurrentScheduleValue(state, heatingCoil.SchedPtr) > 0.0) && (QCoilReq == DataLoopNode::SensedLoadFlagValue) &&
    2235     2000709 :                    (std::abs(TempSetPoint - TempAirIn) > HVAC::TempControlTol)) {
    2236             : 
    2237     1055405 :             QCoilCap = CapacitanceAir * (TempSetPoint - TempAirIn);
    2238             :             // check to see if setpoint above entering temperature. If not, set
    2239             :             // output to zero.
    2240     1055405 :             if (QCoilCap <= 0.0) {
    2241      200062 :                 QCoilCap = 0.0;
    2242      200062 :                 TempAirOut = TempAirIn;
    2243             :                 // check to see if the Required heating capacity is greater than the user
    2244             :                 // specified capacity.
    2245      855343 :             } else if (QCoilCap > heatingCoil.NominalCapacity) {
    2246      195238 :                 QCoilCap = heatingCoil.NominalCapacity;
    2247      195238 :                 TempAirOut = TempAirIn + QCoilCap / CapacitanceAir;
    2248             :             } else {
    2249      660105 :                 TempAirOut = TempSetPoint;
    2250             :             }
    2251             : 
    2252     1055405 :             HeatingCoilLoad = QCoilCap;
    2253             : 
    2254     1055405 :             PartLoadRat = HeatingCoilLoad / heatingCoil.NominalCapacity;
    2255             : 
    2256             :             // The HeatingCoilLoad is the change in the enthalpy of the Heating
    2257     1055405 :             heatingCoil.FuelUseLoad = HeatingCoilLoad / Effic;
    2258     1055405 :             heatingCoil.ElecUseLoad = heatingCoil.ParasiticElecLoad * PartLoadRat;
    2259     1055405 :             heatingCoil.ParasiticFuelRate = heatingCoil.ParasiticFuelCapacity * (1.0 - PartLoadRat);
    2260             : 
    2261             :         } else { // If not running Conditions do not change across coil from inlet to outlet
    2262             : 
    2263    63104012 :             TempAirOut = TempAirIn;
    2264    63104012 :             HeatingCoilLoad = 0.0;
    2265    63104012 :             PartLoadRat = 0.0;
    2266    63104012 :             heatingCoil.FuelUseLoad = 0.0;
    2267    63104012 :             heatingCoil.ElecUseLoad = 0.0;
    2268    63104012 :             heatingCoil.ParasiticFuelRate = heatingCoil.ParasiticFuelCapacity;
    2269             :         }
    2270             : 
    2271    72562154 :         heatingCoil.RTF = PartLoadRat;
    2272             : 
    2273             :         // If the PLF curve is defined the gas usage needs to be modified
    2274    72562154 :         if (heatingCoil.PLFCurveIndex > 0) {
    2275     8988618 :             if (PartLoadRat == 0) {
    2276     6209864 :                 heatingCoil.FuelUseLoad = 0.0;
    2277             :             } else {
    2278     2778754 :                 PLF = Curve::CurveValue(state, heatingCoil.PLFCurveIndex, PartLoadRat);
    2279     2778754 :                 if (PLF < 0.7) {
    2280           0 :                     if (heatingCoil.PLFErrorCount < 1) {
    2281           0 :                         ++heatingCoil.PLFErrorCount;
    2282           0 :                         ShowWarningError(state,
    2283           0 :                                          format("CalcFuelHeatingCoil: {}=\"{}\", PLF curve values",
    2284             :                                                 HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    2285           0 :                                                 heatingCoil.Name));
    2286           0 :                         ShowContinueError(state, format("The PLF curve value = {:.5T} for part-load ratio = {:.5T}", PLF, PartLoadRat));
    2287           0 :                         ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and the simulation continues...");
    2288           0 :                         ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:Fuel].");
    2289             :                     } else {
    2290           0 :                         ShowRecurringWarningErrorAtEnd(
    2291           0 :                             state, heatingCoil.Name + ", Heating coil PLF curve < 0.7 warning continues... ", heatingCoil.PLFErrorIndex, PLF, PLF);
    2292             :                     }
    2293           0 :                     PLF = 0.7;
    2294             :                 }
    2295             :                 // Modify the Gas Coil Consumption and parasitic loads based on PLF curve
    2296     2778754 :                 heatingCoil.RTF = PartLoadRat / PLF;
    2297     2778754 :                 if (heatingCoil.RTF > 1.0 && std::abs(heatingCoil.RTF - 1.0) > 0.001) {
    2298           0 :                     if (heatingCoil.RTFErrorCount < 1) {
    2299           0 :                         ++heatingCoil.RTFErrorCount;
    2300           0 :                         ShowWarningError(state,
    2301           0 :                                          format("CalcFuelHeatingCoil: {}=\"{}\", runtime fraction",
    2302             :                                                 HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    2303           0 :                                                 heatingCoil.Name));
    2304           0 :                         ShowContinueError(state, format("The runtime fraction exceeded 1.0. [{:.4T}].", heatingCoil.RTF));
    2305           0 :                         ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
    2306           0 :                         ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:Fuel].");
    2307             :                     } else {
    2308           0 :                         ShowRecurringWarningErrorAtEnd(state,
    2309           0 :                                                        format("{}, Heating coil runtime fraction > 1.0 warning continues... ", heatingCoil.Name),
    2310           0 :                                                        heatingCoil.RTFErrorIndex,
    2311           0 :                                                        heatingCoil.RTF,
    2312           0 :                                                        heatingCoil.RTF);
    2313             :                     }
    2314           0 :                     heatingCoil.RTF = 1.0; // Reset coil runtime fraction to 1.0
    2315     2778754 :                 } else if (heatingCoil.RTF > 1.0) {
    2316           0 :                     heatingCoil.RTF = 1.0; // Reset coil runtime fraction to 1.0
    2317             :                 }
    2318     2778754 :                 heatingCoil.ElecUseLoad = heatingCoil.ParasiticElecLoad * heatingCoil.RTF;
    2319     2778754 :                 heatingCoil.FuelUseLoad = heatingCoil.NominalCapacity / Effic * heatingCoil.RTF;
    2320     2778754 :                 heatingCoil.ParasiticFuelRate = heatingCoil.ParasiticFuelCapacity * (1.0 - heatingCoil.RTF);
    2321             :                 // Fan power will also be modified by the heating coil's part load fraction
    2322             :                 // OnOffFanPartLoadFraction passed to fan via DataHVACGlobals (cycling fan only)
    2323     2778754 :                 if (fanOp == HVAC::FanOp::Cycling) {
    2324      168443 :                     state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
    2325             :                 }
    2326             :             }
    2327             :         }
    2328             : 
    2329             :         // Set the outlet conditions
    2330    72562154 :         heatingCoil.HeatingCoilLoad = HeatingCoilLoad;
    2331    72562154 :         heatingCoil.OutletAirTemp = TempAirOut;
    2332             : 
    2333             :         // This HeatingCoil does not change the moisture or Mass Flow across the component
    2334    72562154 :         heatingCoil.OutletAirHumRat = heatingCoil.InletAirHumRat;
    2335    72562154 :         heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    2336             :         // Set the outlet enthalpys for air and Heating
    2337    72562154 :         heatingCoil.OutletAirEnthalpy = Psychrometrics::PsyHFnTdbW(heatingCoil.OutletAirTemp, heatingCoil.OutletAirHumRat);
    2338             : 
    2339    72562154 :         QCoilActual = HeatingCoilLoad;
    2340    72562154 :         if (heatingCoil.AirLoopNum > 0) {
    2341     1062032 :             state.dataAirLoop->AirLoopAFNInfo(heatingCoil.AirLoopNum).AFNLoopHeatingCoilMaxRTF =
    2342     1062032 :                 max(state.dataAirLoop->AirLoopAFNInfo(heatingCoil.AirLoopNum).AFNLoopHeatingCoilMaxRTF, heatingCoil.RTF);
    2343             :         }
    2344    72562154 :         state.dataHVACGlobal->ElecHeatingCoilPower = heatingCoil.ElecUseLoad;
    2345             : 
    2346             :         // set outlet node temp so parent objects can call calc directly without have to simulate entire model
    2347    72562154 :         state.dataLoopNodes->Node(heatingCoil.AirOutletNodeNum).Temp = heatingCoil.OutletAirTemp;
    2348    72562154 :     }
    2349             : 
    2350      382010 :     void CalcMultiStageGasHeatingCoil(EnergyPlusData &state,
    2351             :                                       int const CoilNum,       // the number of the Gas heating coil to be simulated
    2352             :                                       Real64 const SpeedRatio, // SpeedRatio varies between 1.0 (maximum speed) and 0.0 (minimum speed)
    2353             :                                       Real64 const CycRatio,   // cycling part load ratio
    2354             :                                       int const StageNum,      // Speed number
    2355             :                                       HVAC::FanOp const fanOp  // Fan operation mode
    2356             :     )
    2357             :     {
    2358             : 
    2359             :         // SUBROUTINE INFORMATION:
    2360             :         //       AUTHOR         Chandan Sharma, FSEC
    2361             :         //       DATE WRITTEN   January 2013
    2362             : 
    2363             :         // PURPOSE OF THIS SUBROUTINE:
    2364             :         // Calculates the air-side performance and energy use of a multi stage gas heating coil.
    2365             : 
    2366             :         // METHODOLOGY EMPLOYED:
    2367             :         // Uses the same methodology as the single speed Gas heating unit model (SUBROUTINE CalcFuelHeatingCoil).
    2368             :         // In addition it assumes that the unit performance is obtained by interpolating between
    2369             :         // the performance at high stage and that at low stage. If the output needed is below
    2370             :         // that produced at low stage, the coil cycles between off and low stage.
    2371             : 
    2372      382010 :         Real64 const MSHPMassFlowRateHigh = state.dataHVACGlobal->MSHPMassFlowRateHigh;
    2373      382010 :         Real64 const MSHPMassFlowRateLow = state.dataHVACGlobal->MSHPMassFlowRateLow;
    2374             : 
    2375             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2376             :         static constexpr std::string_view RoutineName("CalcMultiStageGasHeatingCoil");
    2377             :         static constexpr std::string_view RoutineNameAverageLoad("CalcMultiStageGasHeatingCoil:Averageload");
    2378             :         static constexpr std::string_view RoutineNameFullLoad("CalcMultiStageGasHeatingCoil:fullload");
    2379             : 
    2380             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2381             :         Real64 OutletAirEnthalpy;    // outlet air enthalpy [J/kg]
    2382             :         Real64 OutletAirHumRat;      // outlet air humidity ratio [kg/kg]
    2383             :         Real64 TotCapHS;             // total capacity at high stage [W]
    2384             :         Real64 TotCapLS;             // total capacity at low stage [W]
    2385             :         Real64 TotCap;               // total capacity at current stage [W]
    2386             :         Real64 EffHS;                // efficiency at high stage
    2387      382010 :         Real64 EffLS(0.0);           // efficiency at low stage
    2388             :         Real64 EffAvg;               // average efficiency
    2389             :         int StageNumHS;              // High stage number
    2390             :         int StageNumLS;              // Low stage number
    2391             :         Real64 FullLoadOutAirEnth;   // Outlet full load enthalpy
    2392             :         Real64 FullLoadOutAirHumRat; // Outlet humidity ratio at full load
    2393             :         Real64 FullLoadOutAirTemp;   // Outlet temperature at full load
    2394             :         Real64 FullLoadOutAirRH;     // Outler relative humidity at full load
    2395             :         Real64 OutletAirTemp;        // Supply ari temperature
    2396             :         Real64 LSFullLoadOutAirEnth; // Outlet full load enthalpy at low stage
    2397             :         Real64 HSFullLoadOutAirEnth; // Outlet full load enthalpy at high stage
    2398             :         Real64 LSGasHeatingPower;    // Full load power at low stage
    2399             :         Real64 HSGasHeatingPower;    // Full load power at high stage
    2400      382010 :         Real64 PartLoadRat(0.0);     // part load ratio
    2401             :         Real64 PLF;                  // part load factor used to calculate RTF
    2402             : 
    2403      382010 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    2404             : 
    2405      382010 :         if (StageNum > 1) {
    2406       61842 :             StageNumLS = StageNum - 1;
    2407       61842 :             StageNumHS = StageNum;
    2408       61842 :             if (StageNum > heatingCoil.NumOfStages) {
    2409       61842 :                 StageNumLS = heatingCoil.NumOfStages - 1;
    2410       61842 :                 StageNumHS = heatingCoil.NumOfStages;
    2411             :             }
    2412             :         } else {
    2413      320168 :             StageNumLS = 1;
    2414      320168 :             StageNumHS = 1;
    2415             :         }
    2416             : 
    2417      382010 :         Real64 AirMassFlow = heatingCoil.InletAirMassFlowRate;
    2418      382010 :         Real64 InletAirEnthalpy = heatingCoil.InletAirEnthalpy;
    2419      382010 :         Real64 InletAirHumRat = heatingCoil.InletAirHumRat;
    2420      382010 :         Real64 OutdoorPressure = state.dataEnvrn->OutBaroPress;
    2421             : 
    2422      532812 :         if ((AirMassFlow > 0.0) && (ScheduleManager::GetCurrentScheduleValue(state, heatingCoil.SchedPtr) > 0.0) &&
    2423      150802 :             ((CycRatio > 0.0) || (SpeedRatio > 0.0))) {
    2424             : 
    2425      200668 :             if (StageNum > 1) {
    2426             : 
    2427           0 :                 TotCapLS = heatingCoil.MSNominalCapacity(StageNumLS);
    2428           0 :                 TotCapHS = heatingCoil.MSNominalCapacity(StageNumHS);
    2429             : 
    2430           0 :                 EffLS = heatingCoil.MSEfficiency(StageNumLS);
    2431           0 :                 EffHS = heatingCoil.MSEfficiency(StageNumHS);
    2432             : 
    2433           0 :                 PartLoadRat = min(1.0, SpeedRatio);
    2434           0 :                 heatingCoil.RTF = 1.0;
    2435             : 
    2436             :                 // Get full load output and power
    2437           0 :                 LSFullLoadOutAirEnth = InletAirEnthalpy + TotCapLS / MSHPMassFlowRateLow;
    2438           0 :                 HSFullLoadOutAirEnth = InletAirEnthalpy + TotCapHS / MSHPMassFlowRateHigh;
    2439           0 :                 LSGasHeatingPower = TotCapLS / EffLS;
    2440           0 :                 HSGasHeatingPower = TotCapHS / EffHS;
    2441           0 :                 OutletAirHumRat = InletAirHumRat;
    2442             : 
    2443             :                 // if cycling fan, send coil part-load fraction to on/off fan via HVACDataGlobals
    2444             :                 // IF (FanOpMode .EQ. FanOp::Cycling) OnOffFanPartLoadFraction = 1.0d0
    2445             : 
    2446             :                 // Power calculation. If PartLoadRat (SpeedRatio) = 0, operate at LS the whole time step
    2447           0 :                 heatingCoil.ElecUseLoad =
    2448           0 :                     PartLoadRat * heatingCoil.MSParasiticElecLoad(StageNumHS) + (1.0 - PartLoadRat) * heatingCoil.MSParasiticElecLoad(StageNumLS);
    2449             : 
    2450           0 :                 state.dataHVACGlobal->ElecHeatingCoilPower = heatingCoil.ElecUseLoad;
    2451           0 :                 heatingCoil.HeatingCoilLoad = MSHPMassFlowRateHigh * (HSFullLoadOutAirEnth - InletAirEnthalpy) * PartLoadRat +
    2452           0 :                                               MSHPMassFlowRateLow * (LSFullLoadOutAirEnth - InletAirEnthalpy) * (1.0 - PartLoadRat);
    2453           0 :                 EffAvg = (EffHS * PartLoadRat) + (EffLS * (1.0 - PartLoadRat));
    2454           0 :                 heatingCoil.FuelUseLoad = heatingCoil.HeatingCoilLoad / EffAvg;
    2455           0 :                 heatingCoil.ParasiticFuelRate = 0.0;
    2456             : 
    2457           0 :                 OutletAirEnthalpy = InletAirEnthalpy + heatingCoil.HeatingCoilLoad / heatingCoil.InletAirMassFlowRate;
    2458           0 :                 OutletAirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
    2459           0 :                 FullLoadOutAirRH = Psychrometrics::PsyRhFnTdbWPb(state, OutletAirTemp, OutletAirHumRat, OutdoorPressure, RoutineNameAverageLoad);
    2460             : 
    2461           0 :                 if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
    2462           0 :                     OutletAirTemp = Psychrometrics::PsyTsatFnHPb(state, OutletAirEnthalpy, OutdoorPressure, RoutineName);
    2463           0 :                     OutletAirHumRat = Psychrometrics::PsyWFnTdbH(state, OutletAirTemp, OutletAirEnthalpy, RoutineName);
    2464             :                 }
    2465             : 
    2466           0 :                 heatingCoil.OutletAirTemp = OutletAirTemp;
    2467           0 :                 heatingCoil.OutletAirHumRat = OutletAirHumRat;
    2468           0 :                 heatingCoil.OutletAirEnthalpy = OutletAirEnthalpy;
    2469           0 :                 heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    2470             : 
    2471             :                 // Stage 1
    2472      200668 :             } else if (CycRatio > 0.0) {
    2473             : 
    2474             :                 // for cycling fan, reset mass flow to full on rate
    2475      200668 :                 if (fanOp == HVAC::FanOp::Cycling)
    2476       28116 :                     AirMassFlow /= CycRatio;
    2477      172552 :                 else if (fanOp == HVAC::FanOp::Continuous)
    2478      172552 :                     AirMassFlow = MSHPMassFlowRateLow;
    2479             : 
    2480      200668 :                 TotCap = heatingCoil.MSNominalCapacity(StageNumLS);
    2481             : 
    2482      200668 :                 PartLoadRat = min(1.0, CycRatio);
    2483      200668 :                 heatingCoil.RTF = PartLoadRat;
    2484             : 
    2485             :                 // Calculate full load outlet conditions
    2486      200668 :                 FullLoadOutAirEnth = InletAirEnthalpy + TotCap / AirMassFlow;
    2487      200668 :                 FullLoadOutAirHumRat = InletAirHumRat;
    2488      200668 :                 FullLoadOutAirTemp = Psychrometrics::PsyTdbFnHW(FullLoadOutAirEnth, FullLoadOutAirHumRat);
    2489             :                 FullLoadOutAirRH =
    2490      200668 :                     Psychrometrics::PsyRhFnTdbWPb(state, FullLoadOutAirTemp, FullLoadOutAirHumRat, OutdoorPressure, RoutineNameFullLoad);
    2491             : 
    2492      200668 :                 if (FullLoadOutAirRH > 1.0) { // Limit to saturated conditions at FullLoadOutAirEnth
    2493           0 :                     FullLoadOutAirTemp = Psychrometrics::PsyTsatFnHPb(state, FullLoadOutAirEnth, OutdoorPressure, RoutineName);
    2494             :                     //  Eventually inlet air conditions will be used in Gas Coil, these lines are commented out and marked with this comment line
    2495             :                     //  FullLoadOutAirTemp = PsyTsatFnHPb(FullLoadOutAirEnth,InletAirPressure)
    2496           0 :                     FullLoadOutAirHumRat = Psychrometrics::PsyWFnTdbH(state, FullLoadOutAirTemp, FullLoadOutAirEnth, RoutineName);
    2497             :                 }
    2498             : 
    2499             :                 // Set outlet conditions from the full load calculation
    2500      200668 :                 if (fanOp == HVAC::FanOp::Cycling) {
    2501       28116 :                     OutletAirEnthalpy = FullLoadOutAirEnth;
    2502       28116 :                     OutletAirHumRat = FullLoadOutAirHumRat;
    2503       28116 :                     OutletAirTemp = FullLoadOutAirTemp;
    2504             :                 } else {
    2505      172552 :                     OutletAirEnthalpy =
    2506      172552 :                         PartLoadRat * AirMassFlow / heatingCoil.InletAirMassFlowRate * (FullLoadOutAirEnth - InletAirEnthalpy) + InletAirEnthalpy;
    2507      172552 :                     OutletAirHumRat =
    2508      172552 :                         PartLoadRat * AirMassFlow / heatingCoil.InletAirMassFlowRate * (FullLoadOutAirHumRat - InletAirHumRat) + InletAirHumRat;
    2509      172552 :                     OutletAirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, OutletAirHumRat);
    2510             :                 }
    2511             : 
    2512      200668 :                 EffLS = heatingCoil.MSEfficiency(StageNumLS);
    2513             : 
    2514      200668 :                 heatingCoil.HeatingCoilLoad = TotCap * PartLoadRat;
    2515             : 
    2516      200668 :                 heatingCoil.FuelUseLoad = heatingCoil.HeatingCoilLoad / EffLS;
    2517             :                 //   parasitics are calculated when the coil is off (1-PLR)
    2518      200668 :                 heatingCoil.ElecUseLoad = heatingCoil.MSParasiticElecLoad(StageNumLS) * (1.0 - PartLoadRat);
    2519      200668 :                 heatingCoil.ParasiticFuelRate = heatingCoil.ParasiticFuelCapacity * (1.0 - PartLoadRat);
    2520      200668 :                 state.dataHVACGlobal->ElecHeatingCoilPower = heatingCoil.ElecUseLoad;
    2521             : 
    2522      200668 :                 heatingCoil.OutletAirTemp = OutletAirTemp;
    2523      200668 :                 heatingCoil.OutletAirHumRat = OutletAirHumRat;
    2524      200668 :                 heatingCoil.OutletAirEnthalpy = OutletAirEnthalpy;
    2525      200668 :                 heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    2526             :             }
    2527             : 
    2528             :             // This requires a CR to correct (i.e., calculate outputs when coil is off)
    2529             :         } else {
    2530             : 
    2531             :             // Gas coil is off; just pass through conditions
    2532      181342 :             heatingCoil.OutletAirEnthalpy = heatingCoil.InletAirEnthalpy;
    2533      181342 :             heatingCoil.OutletAirHumRat = heatingCoil.InletAirHumRat;
    2534      181342 :             heatingCoil.OutletAirTemp = heatingCoil.InletAirTemp;
    2535      181342 :             heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    2536             : 
    2537             :             // some of these are reset in Init, can be removed to speed up code
    2538      181342 :             heatingCoil.ElecUseLoad = 0.0;
    2539      181342 :             heatingCoil.HeatingCoilLoad = 0.0;
    2540      181342 :             heatingCoil.FuelUseLoad = 0.0;
    2541      181342 :             heatingCoil.ParasiticFuelRate = heatingCoil.ParasiticFuelCapacity;
    2542      181342 :             state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
    2543      181342 :             PartLoadRat = 0.0;
    2544             : 
    2545             :         } // end of on/off if - else
    2546             : 
    2547             :         // If the PLF curve is defined the gas usage needs to be modified.
    2548             :         // The PLF curve is only used when the coil cycles.
    2549      382010 :         if (heatingCoil.PLFCurveIndex > 0) {
    2550           0 :             if (PartLoadRat > 0.0 && StageNum < 2) {
    2551           0 :                 PLF = Curve::CurveValue(state, heatingCoil.PLFCurveIndex, PartLoadRat);
    2552           0 :                 if (PLF < 0.7) {
    2553           0 :                     if (heatingCoil.PLFErrorCount < 1) {
    2554           0 :                         ++heatingCoil.PLFErrorCount;
    2555           0 :                         ShowWarningError(state,
    2556           0 :                                          format("CalcFuelHeatingCoil: {}=\"{}\", PLF curve values",
    2557             :                                                 HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    2558           0 :                                                 heatingCoil.Name));
    2559           0 :                         ShowContinueError(state, format("The PLF curve value = {:.5T} for part-load ratio = {:.5T}", PLF, PartLoadRat));
    2560           0 :                         ShowContinueError(state, "PLF curve values must be >= 0.7. PLF has been reset to 0.7 and the simulation continues...");
    2561           0 :                         ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:Fuel].");
    2562             :                     } else {
    2563           0 :                         ShowRecurringWarningErrorAtEnd(state,
    2564           0 :                                                        format("{}, Heating coil PLF curve < 0.7 warning continues... ", heatingCoil.Name),
    2565           0 :                                                        heatingCoil.PLFErrorIndex,
    2566             :                                                        PLF,
    2567             :                                                        PLF);
    2568             :                     }
    2569           0 :                     PLF = 0.7;
    2570             :                 }
    2571             :                 // Modify the Gas Coil Consumption and parasitic loads based on PLF curve
    2572           0 :                 heatingCoil.RTF = PartLoadRat / PLF;
    2573           0 :                 if (heatingCoil.RTF > 1.0 && std::abs(heatingCoil.RTF - 1.0) > 0.001) {
    2574           0 :                     if (heatingCoil.RTFErrorCount < 1) {
    2575           0 :                         ++heatingCoil.RTFErrorCount;
    2576           0 :                         ShowWarningError(state,
    2577           0 :                                          format("CalcFuelHeatingCoil: {}=\"{}\", runtime fraction",
    2578             :                                                 HVAC::cAllCoilTypes(heatingCoil.HCoilType_Num),
    2579           0 :                                                 heatingCoil.Name));
    2580           0 :                         ShowContinueError(state, format("The runtime fraction exceeded 1.0. [{:.4T}].", heatingCoil.RTF));
    2581           0 :                         ShowContinueError(state, "Runtime fraction is set to 1.0 and the simulation continues...");
    2582           0 :                         ShowContinueError(state, "Check the IO reference manual for PLF curve guidance [Coil:Heating:Fuel].");
    2583             :                     } else {
    2584           0 :                         ShowRecurringWarningErrorAtEnd(state,
    2585           0 :                                                        format("{}, Heating coil runtime fraction > 1.0 warning continues... ", heatingCoil.Name),
    2586           0 :                                                        heatingCoil.RTFErrorIndex,
    2587           0 :                                                        heatingCoil.RTF,
    2588           0 :                                                        heatingCoil.RTF);
    2589             :                     }
    2590           0 :                     heatingCoil.RTF = 1.0; // Reset coil runtime fraction to 1.0
    2591           0 :                 } else if (heatingCoil.RTF > 1.0) {
    2592           0 :                     heatingCoil.RTF = 1.0; // Reset coil runtime fraction to 1.0
    2593             :                 }
    2594           0 :                 heatingCoil.ElecUseLoad = heatingCoil.MSParasiticElecLoad(StageNum) * heatingCoil.RTF;
    2595           0 :                 heatingCoil.FuelUseLoad = (heatingCoil.MSNominalCapacity(StageNum) / EffLS) * heatingCoil.RTF;
    2596           0 :                 heatingCoil.ParasiticFuelRate = heatingCoil.ParasiticFuelCapacity * (1.0 - heatingCoil.RTF);
    2597             :                 // Fan power will also be modified by the heating coil's part load fraction
    2598             :                 // OnOffFanPartLoadFraction passed to fan via DataHVACGlobals (cycling fan only)
    2599           0 :                 if (fanOp == HVAC::FanOp::Cycling) {
    2600           0 :                     state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
    2601             :                 }
    2602             :             }
    2603             :         }
    2604             : 
    2605             :         // set outlet node temp so parent objects can call calc directly without have to simulate entire model
    2606      382010 :         state.dataLoopNodes->Node(heatingCoil.AirOutletNodeNum).Temp = heatingCoil.OutletAirTemp;
    2607      382010 :     }
    2608             : 
    2609      106223 :     void CalcDesuperheaterHeatingCoil(EnergyPlusData &state,
    2610             :                                       int const CoilNum,     // index to desuperheater heating coil
    2611             :                                       Real64 const QCoilReq, // load requested by the simulation for load based control [W]
    2612             :                                       Real64 &QCoilActual    // coil load actually delivered
    2613             :     )
    2614             :     {
    2615             :         // SUBROUTINE INFORMATION:
    2616             :         //       AUTHOR         Richard Raustad
    2617             :         //       DATE WRITTEN   January 2005
    2618             :         //       MODIFIED       Jul. 2016, R. Zhang, Applied the coil supply air temperature sensor offset
    2619             : 
    2620             :         // PURPOSE OF THIS SUBROUTINE:
    2621             :         // Simulates a simple desuperheater heating coil with a heat reclaim efficiency
    2622             :         // (eff = ratio of condenser waste heat reclaimed to total condenser waste heat rejected)
    2623             : 
    2624             :         // METHODOLOGY EMPLOYED:
    2625             :         // The available capacity of the desuperheater heating coil is determined by the
    2626             :         // amount of heat rejected at the heating source condenser multiplied by the
    2627             :         // desuperheater heat reclaim efficiency. This capacity is either applied towards
    2628             :         // a requested load (load based control) or applied to the air stream to meet a
    2629             :         // heating setpoint (temperature based control). This subroutine is similar to
    2630             :         // the electric or gas heating coil except that the NominalCapacity is variable
    2631             :         // and based on the runtime fraction and heat rejection of the heat source object.
    2632             : 
    2633             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2634             :         Real64 AvailTemp;       // Lowest temperature available from desuperheater (~T condensing)[C]
    2635             :         Real64 TempAirOut;      // temperature of the air leaving the desuperheater heating coil [C]
    2636             :         Real64 HeatingCoilLoad; // actual load delivered by the desuperheater heating coil [W]
    2637             :         Real64 QCoilCap;        // available capacity of the desuperheater heating coil [W]
    2638             :         int SourceID;           // waste heat source id number
    2639             : 
    2640      106223 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    2641             : 
    2642      106223 :         Real64 Effic = heatingCoil.Efficiency;
    2643      106223 :         Real64 AirMassFlow = heatingCoil.InletAirMassFlowRate;
    2644      106223 :         Real64 TempAirIn = heatingCoil.InletAirTemp;
    2645      106223 :         Real64 Win = heatingCoil.InletAirHumRat;
    2646      106223 :         Real64 CapacitanceAir = Psychrometrics::PsyCpAirFnW(Win) * AirMassFlow;
    2647      106223 :         Real64 TempSetPoint = heatingCoil.DesiredOutletTemp;
    2648             : 
    2649             :         // If there is a fault of coil SAT Sensor
    2650      106223 :         if (heatingCoil.FaultyCoilSATFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    2651           0 :             (!state.dataGlobal->KickOffSimulation)) {
    2652             :             // calculate the sensor offset using fault information
    2653           0 :             int FaultIndex = heatingCoil.FaultyCoilSATIndex;
    2654           0 :             heatingCoil.FaultyCoilSATOffset = state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
    2655             :             // update the TempSetPoint
    2656           0 :             TempSetPoint -= heatingCoil.FaultyCoilSATOffset;
    2657             :         }
    2658             : 
    2659             :         // Access the appropriate structure to find the available heating capacity of the desuperheater heating coil
    2660             :         // The nominal capacity of the desuperheater heating coil varies based on the amount of heat rejected by the source
    2661             :         // Stovall 2011, add comparison to available temperature of heat reclaim source
    2662      106223 :         if (state.dataHeatingCoils->ValidSourceType(CoilNum)) {
    2663      106223 :             SourceID = heatingCoil.ReclaimHeatingSourceIndexNum;
    2664      106223 :             switch (heatingCoil.ReclaimHeatingSource) {
    2665       48924 :             case HeatObjTypes::COMPRESSORRACK_REFRIGERATEDCASE:
    2666             :                 // Added last term to available energy equations to avoid double counting reclaimed energy
    2667             :                 // because refrigeration systems are solved outside the hvac time step iterations
    2668       48924 :                 heatingCoil.RTF = 1.0;
    2669       48924 :                 heatingCoil.NominalCapacity = state.dataHeatBal->HeatReclaimRefrigeratedRack(SourceID).AvailCapacity * Effic -
    2670       48924 :                                               state.dataHeatBal->HeatReclaimRefrigeratedRack(SourceID).WaterHeatingDesuperheaterReclaimedHeatTotal;
    2671       48924 :                 break;
    2672       48866 :             case HeatObjTypes::CONDENSER_REFRIGERATION:
    2673       48866 :                 AvailTemp = state.dataHeatBal->HeatReclaimRefrigCondenser(SourceID).AvailTemperature;
    2674       48866 :                 heatingCoil.RTF = 1.0;
    2675       48866 :                 if (AvailTemp <= TempAirIn) {
    2676         194 :                     heatingCoil.NominalCapacity = 0.0;
    2677         582 :                     ShowRecurringWarningErrorAtEnd(
    2678             :                         state,
    2679         388 :                         format("Coil:Heating:Desuperheater {} - Waste heat source temperature was too low to be useful.", heatingCoil.Name),
    2680         194 :                         heatingCoil.InsuffTemperatureWarn);
    2681             :                 } else {
    2682       48672 :                     heatingCoil.NominalCapacity = state.dataHeatBal->HeatReclaimRefrigCondenser(SourceID).AvailCapacity * Effic -
    2683       48672 :                                                   state.dataHeatBal->HeatReclaimRefrigCondenser(SourceID).WaterHeatingDesuperheaterReclaimedHeatTotal;
    2684             :                 }
    2685       48866 :                 break;
    2686           0 :             case HeatObjTypes::COIL_DX_COOLING:
    2687             :             case HeatObjTypes::COIL_DX_MULTISPEED:
    2688             :             case HeatObjTypes::COIL_DX_MULTIMODE:
    2689           0 :                 heatingCoil.RTF = state.dataDXCoils->DXCoil(SourceID).CoolingCoilRuntimeFraction;
    2690           0 :                 heatingCoil.NominalCapacity = state.dataHeatBal->HeatReclaimDXCoil(SourceID).AvailCapacity * Effic -
    2691           0 :                                               state.dataHeatBal->HeatReclaimDXCoil(SourceID).WaterHeatingDesuperheaterReclaimedHeatTotal;
    2692           0 :                 break;
    2693           0 :             case HeatObjTypes::COIL_DX_VARIABLE_COOLING:
    2694             :                 // condenser heat rejection
    2695           0 :                 heatingCoil.RTF = state.dataVariableSpeedCoils->VarSpeedCoil(SourceID).RunFrac;
    2696           0 :                 heatingCoil.NominalCapacity = state.dataHeatBal->HeatReclaimVS_DXCoil(SourceID).AvailCapacity * Effic -
    2697           0 :                                               state.dataHeatBal->HeatReclaimVS_DXCoil(SourceID).WaterHeatingDesuperheaterReclaimedHeatTotal;
    2698           0 :                 break;
    2699        8433 :             case HeatObjTypes::COIL_COOLING_DX_NEW:
    2700             :                 // get RTF and NominalCapacity from Coil:CoolingDX
    2701             :                 {
    2702        8433 :                     auto const &thisCoolingCoil = state.dataCoilCooingDX->coilCoolingDXs[SourceID];
    2703        8433 :                     heatingCoil.RTF = thisCoolingCoil.runTimeFraction;
    2704        8433 :                     heatingCoil.NominalCapacity =
    2705        8433 :                         thisCoolingCoil.reclaimHeat.AvailCapacity * Effic - thisCoolingCoil.reclaimHeat.WaterHeatingDesuperheaterReclaimedHeatTotal;
    2706             :                 }
    2707        8433 :                 break;
    2708           0 :             default:
    2709           0 :                 assert(false);
    2710             :             }
    2711             : 
    2712             :         } else {
    2713           0 :             heatingCoil.NominalCapacity = 0.0;
    2714             :         }
    2715             : 
    2716             :         // Control output to meet load (QCoilReq)
    2717      106223 :         if ((AirMassFlow > 0.0) && (ScheduleManager::GetCurrentScheduleValue(state, heatingCoil.SchedPtr) > 0.0) && (QCoilReq > 0.0)) {
    2718             : 
    2719             :             // check to see if the Required heating capacity is greater than the available heating capacity.
    2720        2416 :             if (QCoilReq > heatingCoil.NominalCapacity) {
    2721        2336 :                 QCoilCap = heatingCoil.NominalCapacity;
    2722             :             } else {
    2723          80 :                 QCoilCap = QCoilReq;
    2724             :             }
    2725             : 
    2726             :             // report the runtime fraction of the desuperheater heating coil
    2727        2416 :             if (heatingCoil.NominalCapacity > 0.0) {
    2728        2404 :                 heatingCoil.RTF *= (QCoilCap / heatingCoil.NominalCapacity);
    2729        2404 :                 TempAirOut = TempAirIn + QCoilCap / CapacitanceAir;
    2730        2404 :                 HeatingCoilLoad = QCoilCap;
    2731             :             } else {
    2732          12 :                 heatingCoil.RTF = 0.0;
    2733          12 :                 TempAirOut = TempAirIn;
    2734          12 :                 HeatingCoilLoad = 0.0;
    2735             :             }
    2736             : 
    2737             :             // Control coil output to meet a setpoint temperature.
    2738      103801 :         } else if ((AirMassFlow > 0.0 && heatingCoil.NominalCapacity > 0.0) &&
    2739      207608 :                    (ScheduleManager::GetCurrentScheduleValue(state, heatingCoil.SchedPtr) > 0.0) && (QCoilReq == DataLoopNode::SensedLoadFlagValue) &&
    2740           0 :                    (std::abs(TempSetPoint - TempAirIn) > HVAC::TempControlTol)) {
    2741             : 
    2742           0 :             QCoilCap = CapacitanceAir * (TempSetPoint - TempAirIn);
    2743             :             // check to see if setpoint is above entering air temperature. If not, set output to zero.
    2744           0 :             if (QCoilCap <= 0.0) {
    2745           0 :                 QCoilCap = 0.0;
    2746           0 :                 TempAirOut = TempAirIn;
    2747             :                 // check to see if the required heating capacity is greater than the available capacity.
    2748           0 :             } else if (QCoilCap > heatingCoil.NominalCapacity) {
    2749           0 :                 QCoilCap = heatingCoil.NominalCapacity;
    2750           0 :                 TempAirOut = TempAirIn + QCoilCap / CapacitanceAir;
    2751             :             } else {
    2752           0 :                 TempAirOut = TempSetPoint;
    2753             :             }
    2754             : 
    2755           0 :             HeatingCoilLoad = QCoilCap;
    2756             :             //     report the runtime fraction of the desuperheater heating coil
    2757           0 :             heatingCoil.RTF *= (QCoilCap / heatingCoil.NominalCapacity);
    2758             : 
    2759             :         } else { // If not running, conditions do not change across heating coil from inlet to outlet
    2760             : 
    2761      103807 :             TempAirOut = TempAirIn;
    2762      103807 :             HeatingCoilLoad = 0.0;
    2763      103807 :             heatingCoil.ElecUseLoad = 0.0;
    2764      103807 :             heatingCoil.RTF = 0.0;
    2765             :         }
    2766             : 
    2767             :         // Set the outlet conditions
    2768      106223 :         heatingCoil.HeatingCoilLoad = HeatingCoilLoad;
    2769      106223 :         heatingCoil.OutletAirTemp = TempAirOut;
    2770             : 
    2771             :         // This HeatingCoil does not change the moisture or Mass Flow across the component
    2772      106223 :         heatingCoil.OutletAirHumRat = heatingCoil.InletAirHumRat;
    2773      106223 :         heatingCoil.OutletAirMassFlowRate = heatingCoil.InletAirMassFlowRate;
    2774             :         // Set the outlet enthalpy
    2775      106223 :         heatingCoil.OutletAirEnthalpy = Psychrometrics::PsyHFnTdbW(heatingCoil.OutletAirTemp, heatingCoil.OutletAirHumRat);
    2776             : 
    2777      106223 :         heatingCoil.ElecUseLoad = heatingCoil.ParasiticElecLoad * heatingCoil.RTF;
    2778      106223 :         QCoilActual = HeatingCoilLoad;
    2779             : 
    2780             :         // Update remaining waste heat (just in case multiple users of waste heat use same source)
    2781      106223 :         if (state.dataHeatingCoils->ValidSourceType(CoilNum)) {
    2782      106223 :             SourceID = heatingCoil.ReclaimHeatingSourceIndexNum;
    2783             :             //   Refrigerated cases are simulated at the zone time step, do not decrement available capacity
    2784             :             //   (the heat reclaim available capacity will not get reinitialized as the air loop iterates)
    2785      106223 :             int DesuperheaterNum = CoilNum - state.dataHeatingCoils->NumElecCoil - state.dataHeatingCoils->NumElecCoilMultiStage -
    2786      106223 :                                    state.dataHeatingCoils->NumFuelCoil - state.dataHeatingCoils->NumGasCoilMultiStage;
    2787      106223 :             switch (heatingCoil.ReclaimHeatingSource) {
    2788       48924 :             case HeatObjTypes::COMPRESSORRACK_REFRIGERATEDCASE: {
    2789       48924 :                 state.dataHeatBal->HeatReclaimRefrigeratedRack(SourceID).HVACDesuperheaterReclaimedHeat(DesuperheaterNum) = HeatingCoilLoad;
    2790       48924 :                 state.dataHeatBal->HeatReclaimRefrigeratedRack(SourceID).HVACDesuperheaterReclaimedHeatTotal = 0.0;
    2791       97848 :                 for (auto const &num : state.dataHeatBal->HeatReclaimRefrigeratedRack(SourceID).HVACDesuperheaterReclaimedHeat)
    2792       48924 :                     state.dataHeatBal->HeatReclaimRefrigeratedRack(SourceID).HVACDesuperheaterReclaimedHeatTotal += num;
    2793       48924 :             } break;
    2794       48866 :             case HeatObjTypes::CONDENSER_REFRIGERATION: {
    2795       48866 :                 state.dataHeatBal->HeatReclaimRefrigCondenser(SourceID).HVACDesuperheaterReclaimedHeat(DesuperheaterNum) = HeatingCoilLoad;
    2796       48866 :                 state.dataHeatBal->HeatReclaimRefrigCondenser(SourceID).HVACDesuperheaterReclaimedHeatTotal = 0.0;
    2797       97732 :                 for (auto const &num : state.dataHeatBal->HeatReclaimRefrigCondenser(SourceID).HVACDesuperheaterReclaimedHeat)
    2798       48866 :                     state.dataHeatBal->HeatReclaimRefrigCondenser(SourceID).HVACDesuperheaterReclaimedHeatTotal += num;
    2799       48866 :             } break;
    2800           0 :             case HeatObjTypes::COIL_DX_COOLING:
    2801             :             case HeatObjTypes::COIL_DX_MULTISPEED:
    2802             :             case HeatObjTypes::COIL_DX_MULTIMODE: {
    2803           0 :                 state.dataHeatBal->HeatReclaimDXCoil(SourceID).HVACDesuperheaterReclaimedHeat(DesuperheaterNum) = HeatingCoilLoad;
    2804           0 :                 state.dataHeatBal->HeatReclaimDXCoil(SourceID).HVACDesuperheaterReclaimedHeatTotal = 0.0;
    2805           0 :                 for (auto const &num : state.dataHeatBal->HeatReclaimDXCoil(SourceID).HVACDesuperheaterReclaimedHeat)
    2806           0 :                     state.dataHeatBal->HeatReclaimDXCoil(SourceID).HVACDesuperheaterReclaimedHeatTotal += num;
    2807           0 :             } break;
    2808           0 :             case HeatObjTypes::COIL_DX_VARIABLE_COOLING: {
    2809           0 :                 state.dataHeatBal->HeatReclaimVS_DXCoil(SourceID).HVACDesuperheaterReclaimedHeat(DesuperheaterNum) = HeatingCoilLoad;
    2810           0 :                 state.dataHeatBal->HeatReclaimVS_DXCoil(SourceID).HVACDesuperheaterReclaimedHeatTotal = 0.0;
    2811           0 :                 for (auto const &num : state.dataHeatBal->HeatReclaimVS_DXCoil(SourceID).HVACDesuperheaterReclaimedHeat)
    2812           0 :                     state.dataHeatBal->HeatReclaimVS_DXCoil(SourceID).HVACDesuperheaterReclaimedHeatTotal += num;
    2813           0 :             } break;
    2814        8433 :             default:
    2815        8433 :                 break;
    2816             :             }
    2817             :         }
    2818      106223 :     }
    2819             : 
    2820   108011617 :     void UpdateHeatingCoil(EnergyPlusData &state, int const CoilNum)
    2821             :     {
    2822             :         // SUBROUTINE INFORMATION:
    2823             :         //       AUTHOR         Richard Liesen
    2824             :         //       DATE WRITTEN   May 2000
    2825             : 
    2826             :         // PURPOSE OF THIS SUBROUTINE:
    2827             :         // This subroutine updates the coil outlet nodes.
    2828             : 
    2829             :         // METHODOLOGY EMPLOYED:
    2830             :         // Data is moved from the coil data structure to the coil outlet nodes.
    2831             : 
    2832             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2833   108011617 :         auto const &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    2834   108011617 :         auto const &airInletNode = state.dataLoopNodes->Node(heatingCoil.AirInletNodeNum);
    2835   108011617 :         auto &airOuletNode = state.dataLoopNodes->Node(heatingCoil.AirOutletNodeNum);
    2836             : 
    2837             :         // Set the outlet air nodes of the HeatingCoil
    2838   108011617 :         airOuletNode.MassFlowRate = heatingCoil.OutletAirMassFlowRate;
    2839   108011617 :         airOuletNode.Temp = heatingCoil.OutletAirTemp;
    2840   108011617 :         airOuletNode.HumRat = heatingCoil.OutletAirHumRat;
    2841   108011617 :         airOuletNode.Enthalpy = heatingCoil.OutletAirEnthalpy;
    2842             : 
    2843             :         // Set the outlet nodes for properties that just pass through & not used
    2844   108011617 :         airOuletNode.Quality = airInletNode.Quality;
    2845   108011617 :         airOuletNode.Press = airInletNode.Press;
    2846   108011617 :         airOuletNode.MassFlowRateMin = airInletNode.MassFlowRateMin;
    2847   108011617 :         airOuletNode.MassFlowRateMax = airInletNode.MassFlowRateMax;
    2848   108011617 :         airOuletNode.MassFlowRateMinAvail = airInletNode.MassFlowRateMinAvail;
    2849   108011617 :         airOuletNode.MassFlowRateMaxAvail = airInletNode.MassFlowRateMaxAvail;
    2850             : 
    2851   108011617 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2852      723462 :             airOuletNode.CO2 = airInletNode.CO2;
    2853             :         }
    2854             : 
    2855   108011617 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2856      208042 :             airOuletNode.GenContam = airInletNode.GenContam;
    2857             :         }
    2858   108011617 :     }
    2859             : 
    2860   108011617 :     void ReportHeatingCoil(EnergyPlusData &state, int const CoilNum, bool const coilIsSuppHeater)
    2861             :     {
    2862             : 
    2863             :         // SUBROUTINE INFORMATION:
    2864             :         //       AUTHOR         Richard Liesen
    2865             :         //       DATE WRITTEN   May 2000
    2866             : 
    2867             :         // PURPOSE OF THIS SUBROUTINE:
    2868             :         // This subroutine updates the report variable for the coils.
    2869             : 
    2870             :         // Using/Aliasing
    2871   108011617 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    2872   108011617 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    2873             : 
    2874             :         // report the HeatingCoil energy from this component
    2875   108011617 :         heatingCoil.HeatingCoilRate = heatingCoil.HeatingCoilLoad;
    2876   108011617 :         heatingCoil.HeatingCoilLoad *= TimeStepSysSec;
    2877             : 
    2878   108011617 :         heatingCoil.FuelUseRate = heatingCoil.FuelUseLoad;
    2879   108011617 :         heatingCoil.ElecUseRate = heatingCoil.ElecUseLoad;
    2880   108011617 :         if (coilIsSuppHeater) {
    2881    29706985 :             state.dataHVACGlobal->SuppHeatingCoilPower = heatingCoil.ElecUseLoad;
    2882             :         } else {
    2883    78304632 :             state.dataHVACGlobal->ElecHeatingCoilPower = heatingCoil.ElecUseLoad;
    2884             :         }
    2885   108011617 :         heatingCoil.FuelUseLoad *= TimeStepSysSec;
    2886   108011617 :         heatingCoil.ElecUseLoad *= TimeStepSysSec;
    2887             : 
    2888   108011617 :         heatingCoil.ParasiticFuelConsumption = heatingCoil.ParasiticFuelRate * TimeStepSysSec;
    2889             : 
    2890   108011617 :         std::string coilObjClassName;
    2891   108011617 :         switch (heatingCoil.HCoilType_Num) {
    2892    33898164 :         case HVAC::Coil_HeatingElectric: {
    2893    33898164 :             coilObjClassName = "Coil:Heating:Electric";
    2894    33898164 :         } break;
    2895     1063066 :         case HVAC::Coil_HeatingElectric_MultiStage: {
    2896     1063066 :             coilObjClassName = "Coil:Heating:Electric:MultiStage";
    2897     1063066 :         } break;
    2898    72562154 :         case HVAC::Coil_HeatingGasOrOtherFuel: {
    2899    72562154 :             coilObjClassName = "Coil:Heating:Fuel";
    2900    72562154 :         } break;
    2901      382010 :         case HVAC::Coil_HeatingGas_MultiStage: {
    2902      382010 :             coilObjClassName = "Coil:Heating:Gas:MultiStage";
    2903      382010 :         } break;
    2904      106223 :         case HVAC::Coil_HeatingDesuperheater: {
    2905      106223 :             coilObjClassName = "Coil:Heating:Desuperheater";
    2906      106223 :         } break;
    2907           0 :         default:
    2908           0 :             break;
    2909             :         }
    2910   108011617 :         if (heatingCoil.reportCoilFinalSizes) {
    2911    20558695 :             if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
    2912        1433 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
    2913        1433 :                     state, heatingCoil.Name, coilObjClassName, heatingCoil.NominalCapacity, heatingCoil.NominalCapacity, -999.0, -999.0);
    2914        1433 :                 heatingCoil.reportCoilFinalSizes = false;
    2915             :             }
    2916             :         }
    2917   108011617 :     }
    2918             : 
    2919             :     //        End of Reporting subroutines for the HeatingCoil Module
    2920             : 
    2921         610 :     void GetCoilIndex(EnergyPlusData &state, std::string const &HeatingCoilName, int &HeatingCoilIndex, bool &ErrorsFound)
    2922             :     {
    2923             : 
    2924             :         // SUBROUTINE INFORMATION:
    2925             :         //       AUTHOR         Richard Raustad
    2926             :         //       DATE WRITTEN   March 2005
    2927             : 
    2928             :         // PURPOSE OF THIS SUBROUTINE:
    2929             :         // This subroutine sets an index for a given DX Coil -- issues error message if that
    2930             :         // DX Coil is not a legal DX Coil.
    2931             : 
    2932             :         // Obtains and Allocates HeatingCoil related parameters from input file
    2933         610 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    2934           8 :             GetHeatingCoilInput(state);
    2935           8 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    2936             :         }
    2937             : 
    2938         610 :         HeatingCoilIndex = Util::FindItem(HeatingCoilName, state.dataHeatingCoils->HeatingCoil);
    2939         610 :         if (HeatingCoilIndex == 0) {
    2940           0 :             ShowSevereError(state, format("GetCoilIndex: Heating coil not found={}", HeatingCoilName));
    2941           0 :             ErrorsFound = true;
    2942             :         }
    2943         610 :     }
    2944             : 
    2945       98913 :     void CheckHeatingCoilSchedule(EnergyPlusData &state,
    2946             :                                   std::string const &CompType, // unused1208
    2947             :                                   std::string_view CompName,
    2948             :                                   Real64 &Value,
    2949             :                                   int &CompIndex)
    2950             :     {
    2951             : 
    2952             :         // SUBROUTINE INFORMATION:
    2953             :         //       AUTHOR         Linda Lawrie
    2954             :         //       DATE WRITTEN   October 2005
    2955             : 
    2956             :         // PURPOSE OF THIS SUBROUTINE:
    2957             :         // This routine provides a method for outside routines to check if
    2958             :         // the heating coil is scheduled to be on.
    2959             : 
    2960             :         // Obtains and Allocates HeatingCoil related parameters from input file
    2961       98913 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    2962           6 :             GetHeatingCoilInput(state);
    2963           6 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    2964             :         }
    2965             : 
    2966             :         // Find the correct Coil number
    2967       98913 :         if (CompIndex == 0) {
    2968          11 :             int CoilNum = Util::FindItem(CompName, state.dataHeatingCoils->HeatingCoil);
    2969          11 :             if (CoilNum == 0) {
    2970           0 :                 ShowFatalError(state, format("CheckHeatingCoilSchedule: Coil not found=\"{}\".", CompName));
    2971             :             }
    2972          11 :             if (!Util::SameString(CompType, HVAC::cAllCoilTypes(state.dataHeatingCoils->HeatingCoil(CoilNum).HCoilType_Num))) {
    2973           0 :                 ShowSevereError(state, format("CheckHeatingCoilSchedule: Coil=\"{}\"", CompName));
    2974           0 :                 ShowContinueError(state,
    2975           0 :                                   format("...expected type=\"{}\", actual type=\"{}\".",
    2976             :                                          CompType,
    2977           0 :                                          HVAC::cAllCoilTypes(state.dataHeatingCoils->HeatingCoil(CoilNum).HCoilType_Num)));
    2978           0 :                 ShowFatalError(state, "Program terminates due to preceding conditions.");
    2979             :             }
    2980          11 :             CompIndex = CoilNum;
    2981          11 :             Value = ScheduleManager::GetCurrentScheduleValue(state, state.dataHeatingCoils->HeatingCoil(CoilNum).SchedPtr); // not scheduled?
    2982             :         } else {
    2983       98902 :             int CoilNum = CompIndex;
    2984       98902 :             if (CoilNum > state.dataHeatingCoils->NumHeatingCoils || CoilNum < 1) {
    2985           0 :                 ShowFatalError(state,
    2986           0 :                                format("CheckHeatingCoilSchedule: Invalid CompIndex passed={}, Number of Heating Coils={}, Coil name={}",
    2987             :                                       CoilNum,
    2988           0 :                                       state.dataHeatingCoils->NumHeatingCoils,
    2989             :                                       CompName));
    2990             :             }
    2991       98902 :             if (CompName != state.dataHeatingCoils->HeatingCoil(CoilNum).Name) {
    2992           0 :                 ShowSevereError(state,
    2993           0 :                                 format("CheckHeatingCoilSchedule: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
    2994             :                                        CoilNum,
    2995             :                                        CompName,
    2996           0 :                                        state.dataHeatingCoils->HeatingCoil(CoilNum).Name));
    2997           0 :                 ShowContinueError(state,
    2998           0 :                                   format("...expected type=\"{}\", actual type=\"{}\".",
    2999             :                                          CompType,
    3000           0 :                                          HVAC::cAllCoilTypes(state.dataHeatingCoils->HeatingCoil(CoilNum).HCoilType_Num)));
    3001           0 :                 ShowFatalError(state, "Program terminates due to preceding conditions.");
    3002             :             }
    3003       98902 :             Value = ScheduleManager::GetCurrentScheduleValue(state, state.dataHeatingCoils->HeatingCoil(CoilNum).SchedPtr); // not scheduled?
    3004             :         }
    3005       98913 :     }
    3006             : 
    3007         399 :     Real64 GetCoilCapacity(EnergyPlusData &state,
    3008             :                            std::string const &CoilType, // must match coil types in this module
    3009             :                            std::string const &CoilName, // must match coil names for the coil type
    3010             :                            bool &ErrorsFound            // set to true if problem
    3011             :     )
    3012             :     {
    3013             : 
    3014             :         // FUNCTION INFORMATION:
    3015             :         //       AUTHOR         Linda Lawrie
    3016             :         //       DATE WRITTEN   February 2006
    3017             : 
    3018             :         // PURPOSE OF THIS FUNCTION:
    3019             :         // This function looks up the coil capacity for the given coil and returns it.  If
    3020             :         // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
    3021             :         // as negative.
    3022             : 
    3023             :         // Return value
    3024             :         Real64 CoilCapacity; // returned capacity of matched coil
    3025             : 
    3026             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    3027             :         int WhichCoil;
    3028             : 
    3029             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3030         399 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3031           0 :             GetHeatingCoilInput(state);
    3032           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3033             :         }
    3034             : 
    3035         399 :         int FoundType = Util::FindItem(CoilType, HVAC::cAllCoilTypes, HVAC::NumAllCoilTypes);
    3036         399 :         if (FoundType == HVAC::Coil_HeatingElectric || FoundType == HVAC::Coil_HeatingGasOrOtherFuel ||
    3037             :             FoundType == HVAC::Coil_HeatingDesuperheater) {
    3038         399 :             WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3039         399 :             if (WhichCoil != 0) {
    3040         399 :                 CoilCapacity = state.dataHeatingCoils->HeatingCoil(WhichCoil).NominalCapacity;
    3041             :             }
    3042           0 :         } else if (FoundType == HVAC::Coil_HeatingElectric_MultiStage || FoundType == HVAC::Coil_HeatingGas_MultiStage) {
    3043           0 :             WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3044           0 :             if (WhichCoil != 0) {
    3045           0 :                 CoilCapacity =
    3046           0 :                     state.dataHeatingCoils->HeatingCoil(WhichCoil).MSNominalCapacity(state.dataHeatingCoils->HeatingCoil(WhichCoil).NumOfStages);
    3047             :             }
    3048             :         } else {
    3049           0 :             WhichCoil = 0;
    3050             :         }
    3051             : 
    3052         399 :         if (WhichCoil == 0) { // Autodesk:Return Reworked block to assure CoilCapacity is set before return
    3053           0 :             if (FoundType == 0) {
    3054           0 :                 ShowSevereError(state, format("GetCoilCapacity: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3055           0 :             } else if (FoundType > 0) {
    3056           0 :                 ShowSevereError(state, format("GetCoilCapacity: Invalid coil type for capacity, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3057           0 :                 ShowContinueError(state,
    3058           0 :                                   format("...only {}, {} or {} are valid in this context.",
    3059             :                                          HVAC::cAllCoilTypes(HVAC::Coil_HeatingElectric),
    3060             :                                          HVAC::cAllCoilTypes(HVAC::Coil_HeatingGasOrOtherFuel),
    3061             :                                          HVAC::cAllCoilTypes(HVAC::Coil_HeatingDesuperheater)));
    3062             :             }
    3063           0 :             ShowContinueError(state, "... returning Coil Capacity as -1000.");
    3064           0 :             ErrorsFound = true;
    3065           0 :             CoilCapacity = -1000.0;
    3066             :         }
    3067             : 
    3068         399 :         return CoilCapacity;
    3069             :     }
    3070             : 
    3071           0 :     int GetCoilAvailScheduleIndex(EnergyPlusData &state,
    3072             :                                   std::string const &CoilType, // must match coil types in this module
    3073             :                                   std::string const &CoilName, // must match coil names for the coil type
    3074             :                                   bool &ErrorsFound            // set to true if problem
    3075             :     )
    3076             :     {
    3077             : 
    3078             :         // FUNCTION INFORMATION:
    3079             :         //       AUTHOR         Richard Raustad, FSEC
    3080             :         //       DATE WRITTEN   February 2013
    3081             : 
    3082             :         // PURPOSE OF THIS FUNCTION:
    3083             :         // This function looks up the given coil and returns the availability schedule index.  If
    3084             :         // incorrect coil type or name is given, ErrorsFound is returned as true and index is returned
    3085             :         // as zero.
    3086             : 
    3087             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3088           0 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3089           0 :             GetHeatingCoilInput(state);
    3090           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3091             :         }
    3092             : 
    3093           0 :         int WhichCoil = 0;
    3094           0 :         int AvailSchIndex = 0;
    3095           0 :         int FoundType = Util::FindItem(CoilType, HVAC::cAllCoilTypes, HVAC::NumAllCoilTypes);
    3096           0 :         if (FoundType == HVAC::Coil_HeatingElectric || FoundType == HVAC::Coil_HeatingElectric_MultiStage ||
    3097           0 :             FoundType == HVAC::Coil_HeatingGasOrOtherFuel || FoundType == HVAC::Coil_HeatingGas_MultiStage ||
    3098             :             FoundType == HVAC::Coil_HeatingDesuperheater) {
    3099           0 :             WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3100           0 :             if (WhichCoil != 0) {
    3101           0 :                 AvailSchIndex = state.dataHeatingCoils->HeatingCoil(WhichCoil).SchedPtr;
    3102             :             }
    3103             :         } else {
    3104           0 :             WhichCoil = 0;
    3105             :         }
    3106             : 
    3107           0 :         if (WhichCoil == 0) {
    3108           0 :             ShowSevereError(state, format("GetCoilAvailScheduleIndex: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3109           0 :             ErrorsFound = true;
    3110           0 :             AvailSchIndex = 0;
    3111             :         }
    3112             : 
    3113           0 :         return AvailSchIndex;
    3114             :     }
    3115             : 
    3116         411 :     int GetCoilInletNode(EnergyPlusData &state,
    3117             :                          std::string_view CoilType,   // must match coil types in this module
    3118             :                          std::string const &CoilName, // must match coil names for the coil type
    3119             :                          bool &ErrorsFound            // set to true if problem
    3120             :     )
    3121             :     {
    3122             : 
    3123             :         // FUNCTION INFORMATION:
    3124             :         //       AUTHOR         Linda Lawrie
    3125             :         //       DATE WRITTEN   February 2006
    3126             : 
    3127             :         // PURPOSE OF THIS FUNCTION:
    3128             :         // This function looks up the given coil and returns the inlet node number.  If
    3129             :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    3130             :         // as zero.
    3131             : 
    3132             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3133         411 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3134           0 :             GetHeatingCoilInput(state);
    3135           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3136             :         }
    3137             : 
    3138         411 :         int WhichCoil = 0;
    3139         411 :         int NodeNumber = 0;
    3140         411 :         int FoundType = Util::FindItem(CoilType, HVAC::cAllCoilTypes, HVAC::NumAllCoilTypes);
    3141         411 :         if (FoundType == HVAC::Coil_HeatingElectric || FoundType == HVAC::Coil_HeatingElectric_MultiStage ||
    3142           3 :             FoundType == HVAC::Coil_HeatingGasOrOtherFuel || FoundType == HVAC::Coil_HeatingGas_MultiStage ||
    3143             :             FoundType == HVAC::Coil_HeatingDesuperheater) {
    3144         411 :             WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3145         411 :             if (WhichCoil != 0) {
    3146         411 :                 NodeNumber = state.dataHeatingCoils->HeatingCoil(WhichCoil).AirInletNodeNum;
    3147             :             }
    3148             :         } else {
    3149           0 :             WhichCoil = 0;
    3150             :         }
    3151             : 
    3152         411 :         if (WhichCoil == 0) {
    3153           0 :             ShowSevereError(state, format("GetCoilInletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3154           0 :             ErrorsFound = true;
    3155           0 :             NodeNumber = 0;
    3156             :         }
    3157             : 
    3158         411 :         return NodeNumber;
    3159             :     }
    3160             : 
    3161         411 :     int GetCoilOutletNode(EnergyPlusData &state,
    3162             :                           std::string_view CoilType,   // must match coil types in this module
    3163             :                           std::string const &CoilName, // must match coil names for the coil type
    3164             :                           bool &ErrorsFound            // set to true if problem
    3165             :     )
    3166             :     {
    3167             : 
    3168             :         // FUNCTION INFORMATION:
    3169             :         //       AUTHOR         Richard Raustad
    3170             :         //       DATE WRITTEN   August 2006
    3171             : 
    3172             :         // PURPOSE OF THIS FUNCTION:
    3173             :         // This function looks up the given coil and returns the outlet node number.  If
    3174             :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    3175             :         // as zero.
    3176             : 
    3177             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3178         411 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3179           0 :             GetHeatingCoilInput(state);
    3180           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3181             :         }
    3182             : 
    3183         411 :         int WhichCoil = 0;
    3184         411 :         int NodeNumber = 0;
    3185         411 :         int FoundType = Util::FindItem(CoilType, HVAC::cAllCoilTypes, HVAC::NumAllCoilTypes);
    3186         411 :         if (FoundType == HVAC::Coil_HeatingElectric || FoundType == HVAC::Coil_HeatingElectric_MultiStage ||
    3187           3 :             FoundType == HVAC::Coil_HeatingGasOrOtherFuel || FoundType == HVAC::Coil_HeatingGas_MultiStage ||
    3188             :             FoundType == HVAC::Coil_HeatingDesuperheater) {
    3189         411 :             WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3190         411 :             if (WhichCoil != 0) {
    3191         411 :                 NodeNumber = state.dataHeatingCoils->HeatingCoil(WhichCoil).AirOutletNodeNum;
    3192             :             }
    3193             :         } else {
    3194           0 :             WhichCoil = 0;
    3195             :         }
    3196             : 
    3197         411 :         if (WhichCoil == 0) {
    3198           0 :             ShowSevereError(state, format("GetCoilOutletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3199           0 :             ErrorsFound = true;
    3200           0 :             NodeNumber = 0;
    3201             :         }
    3202             : 
    3203         411 :         return NodeNumber;
    3204             :     }
    3205             : 
    3206           2 :     int GetHeatReclaimSourceIndex(EnergyPlusData &state,
    3207             :                                   std::string const &CoilType, // must match coil types in this module
    3208             :                                   std::string const &CoilName, // must match coil names for the coil type
    3209             :                                   bool &ErrorsFound            // set to true if problem
    3210             :     )
    3211             :     {
    3212             : 
    3213             :         // FUNCTION INFORMATION:
    3214             :         //       AUTHOR         Richard Raustad
    3215             :         //       DATE WRITTEN   June 2007
    3216             : 
    3217             :         // PURPOSE OF THIS FUNCTION:
    3218             :         // This function looks up the given coil and returns the heating coil index number if it is a desuperheating coil.
    3219             :         // If incorrect coil type or name is given, ErrorsFound is returned as true and index number is returned
    3220             :         // as zero.
    3221             : 
    3222             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    3223             :         bool GetCoilErrFlag;
    3224             :         int NumCoil;
    3225           2 :         int CoilNum(0);
    3226             : 
    3227             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3228           2 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3229           0 :             GetHeatingCoilInput(state);
    3230           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3231             :         }
    3232             : 
    3233           2 :         int CoilFound = 0;
    3234             : 
    3235             :         // note should eventually get rid of this string comparison
    3236           3 :         if (Util::SameString(CoilType, "COIL:COOLING:DX:SINGLESPEED") || Util::SameString(CoilType, "COIL:COOLING:DX:TWOSPEED") ||
    3237           3 :             Util::SameString(CoilType, "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE")) {
    3238           1 :             bool SuppressWarning = true;
    3239           1 :             DXCoils::GetDXCoilIndex(state, CoilName, CoilNum, GetCoilErrFlag, CoilType, SuppressWarning);
    3240           9 :             for (NumCoil = 1; NumCoil <= state.dataHeatingCoils->NumHeatingCoils; ++NumCoil) {
    3241           8 :                 if (state.dataHeatingCoils->HeatingCoil(NumCoil).ReclaimHeatingSource != HeatObjTypes::COIL_DX_COOLING &&
    3242           8 :                     state.dataHeatingCoils->HeatingCoil(NumCoil).ReclaimHeatingSource != HeatObjTypes::COIL_DX_MULTISPEED &&
    3243          24 :                     state.dataHeatingCoils->HeatingCoil(NumCoil).ReclaimHeatingSource != HeatObjTypes::COIL_DX_MULTIMODE &&
    3244           8 :                     state.dataHeatingCoils->HeatingCoil(NumCoil).ReclaimHeatingCoilName != CoilName)
    3245           8 :                     continue;
    3246           0 :                 CoilFound = CoilNum;
    3247           0 :                 break;
    3248             :             }
    3249           1 :         } else if (Util::SameString(CoilType, "COIL:COOLING:DX:VARIABLESPEED")) {
    3250           1 :             CoilNum = VariableSpeedCoils::GetCoilIndexVariableSpeed(state, CoilType, CoilName, GetCoilErrFlag);
    3251           9 :             for (NumCoil = 1; NumCoil <= state.dataHeatingCoils->NumHeatingCoils; ++NumCoil) {
    3252          16 :                 if (state.dataHeatingCoils->HeatingCoil(NumCoil).ReclaimHeatingSource != HeatObjTypes::COIL_DX_VARIABLE_COOLING &&
    3253           8 :                     state.dataHeatingCoils->HeatingCoil(NumCoil).ReclaimHeatingCoilName != CoilName)
    3254           8 :                     continue;
    3255           0 :                 CoilFound = CoilNum;
    3256           0 :                 break;
    3257             :             }
    3258             :         }
    3259             : 
    3260           2 :         if (CoilNum == 0) {
    3261           0 :             ErrorsFound = true;
    3262             :         }
    3263             : 
    3264           2 :         return CoilFound;
    3265             :     }
    3266             : 
    3267           4 :     int GetCoilControlNodeNum(EnergyPlusData &state,
    3268             :                               std::string const &CoilType, // must match coil types in this module
    3269             :                               std::string const &CoilName, // must match coil names for the coil type
    3270             :                               bool &ErrorsFound            // set to true if problem
    3271             :     )
    3272             :     {
    3273             : 
    3274             :         // FUNCTION INFORMATION:
    3275             :         //       AUTHOR         Richard Raustad
    3276             :         //       DATE WRITTEN   June 2007
    3277             : 
    3278             :         // PURPOSE OF THIS FUNCTION:
    3279             :         // This function looks up the given coil and returns the control node number.  If
    3280             :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    3281             :         // as zero.
    3282             : 
    3283             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3284           4 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3285           0 :             GetHeatingCoilInput(state);
    3286           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3287             :         }
    3288             : 
    3289           4 :         int FoundType = Util::FindItem(CoilType, HVAC::cAllCoilTypes, HVAC::NumAllCoilTypes);
    3290           4 :         if (FoundType == HVAC::Coil_HeatingElectric || FoundType == HVAC::Coil_HeatingElectric_MultiStage ||
    3291           0 :             FoundType == HVAC::Coil_HeatingGasOrOtherFuel || FoundType == HVAC::Coil_HeatingGas_MultiStage ||
    3292             :             FoundType == HVAC::Coil_HeatingDesuperheater) {
    3293           4 :             int WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3294           4 :             if (WhichCoil != 0) {
    3295           4 :                 return state.dataHeatingCoils->HeatingCoil(WhichCoil).TempSetPointNodeNum;
    3296             :             }
    3297             :         }
    3298             : 
    3299           0 :         ShowSevereError(state, format("GetCoilControlNodeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3300           0 :         ErrorsFound = true;
    3301           0 :         return 0;
    3302             :     }
    3303             : 
    3304         700 :     int GetHeatingCoilTypeNum(EnergyPlusData &state,
    3305             :                               std::string const &CoilType, // must match coil types in this module
    3306             :                               std::string const &CoilName, // must match coil names for the coil type
    3307             :                               bool &ErrorsFound            // set to true if problem
    3308             :     )
    3309             :     {
    3310             : 
    3311             :         // FUNCTION INFORMATION:
    3312             :         //       AUTHOR         Richard Raustad
    3313             :         //       DATE WRITTEN   August 2008
    3314             : 
    3315             :         // PURPOSE OF THIS FUNCTION:
    3316             :         // This function looks up the given coil and returns the type number.  If
    3317             :         // incorrect coil type or name is given, ErrorsFound is returned as true and type number is returned
    3318             :         // as zero.
    3319             : 
    3320             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3321         700 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3322         155 :             GetHeatingCoilInput(state);
    3323         155 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3324             :         }
    3325             : 
    3326         700 :         int FoundType = Util::FindItem(CoilType, HVAC::cAllCoilTypes, HVAC::NumAllCoilTypes);
    3327         700 :         if (FoundType == HVAC::Coil_HeatingElectric || FoundType == HVAC::Coil_HeatingElectric_MultiStage ||
    3328           3 :             FoundType == HVAC::Coil_HeatingGasOrOtherFuel || FoundType == HVAC::Coil_HeatingGas_MultiStage ||
    3329             :             FoundType == HVAC::Coil_HeatingDesuperheater) {
    3330         700 :             int WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3331         700 :             if (WhichCoil != 0) {
    3332         700 :                 return state.dataHeatingCoils->HeatingCoil(WhichCoil).HCoilType_Num;
    3333             :             }
    3334             :         }
    3335             : 
    3336           0 :         ShowSevereError(state, format("GetHeatingCoilTypeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3337           0 :         ErrorsFound = true;
    3338           0 :         return 0;
    3339             :     }
    3340             : 
    3341         115 :     int GetHeatingCoilIndex(EnergyPlusData &state,
    3342             :                             std::string const &CoilType, // must match coil types in this module
    3343             :                             std::string const &CoilName, // must match coil names for the coil type
    3344             :                             bool &ErrorsFound            // set to true if problem
    3345             :     )
    3346             :     {
    3347             : 
    3348             :         // FUNCTION INFORMATION:
    3349             :         //       AUTHOR         Linda Lawrie
    3350             :         //       DATE WRITTEN   February 2011
    3351             : 
    3352             :         // PURPOSE OF THIS FUNCTION:
    3353             :         // This function looks up the given coil and returns the index into the structure.  If
    3354             :         // incorrect coil type or name is given, ErrorsFound is returned as true and index is returned
    3355             :         // as zero.
    3356             : 
    3357             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3358         115 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3359           9 :             GetHeatingCoilInput(state);
    3360           9 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3361             :         }
    3362             : 
    3363         115 :         int WhichCoil = 0;
    3364         115 :         int FoundType = Util::FindItem(CoilType, HVAC::cAllCoilTypes, HVAC::NumAllCoilTypes);
    3365         115 :         if (FoundType == HVAC::Coil_HeatingElectric || FoundType == HVAC::Coil_HeatingElectric_MultiStage ||
    3366           1 :             FoundType == HVAC::Coil_HeatingGasOrOtherFuel || FoundType == HVAC::Coil_HeatingGas_MultiStage ||
    3367             :             FoundType == HVAC::Coil_HeatingDesuperheater) {
    3368         115 :             WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3369             :         }
    3370             : 
    3371         115 :         if (WhichCoil == 0) {
    3372           0 :             ShowSevereError(state, format("GetHeatingCoilIndex: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3373           0 :             ErrorsFound = true;
    3374             :         }
    3375             : 
    3376         115 :         return WhichCoil;
    3377             :     }
    3378             : 
    3379         181 :     int GetHeatingCoilPLFCurveIndex(EnergyPlusData &state,
    3380             :                                     std::string const &CoilType, // must match coil types in this module
    3381             :                                     std::string const &CoilName, // must match coil names for the coil type
    3382             :                                     bool &ErrorsFound            // set to true if problem
    3383             :     )
    3384             :     {
    3385             : 
    3386             :         // FUNCTION INFORMATION:
    3387             :         //       AUTHOR         Richard Raustad
    3388             :         //       DATE WRITTEN   December 2008
    3389             : 
    3390             :         // PURPOSE OF THIS FUNCTION:
    3391             :         // This function looks up the given coil and returns the PLF curve index.  If
    3392             :         // incorrect coil name is given for gas or electric heating coils, ErrorsFound
    3393             :         // is returned as true and curve index is returned as zero.
    3394             :         // If not a gas or electric heating coil, ErrorsFound is unchanged and index is 0.
    3395             : 
    3396             :         // Obtains and Allocates HeatingCoil related parameters from input file
    3397         181 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3398           0 :             GetHeatingCoilInput(state);
    3399           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3400             :         }
    3401             : 
    3402         181 :         int FoundType = Util::FindItem(CoilType, HVAC::cAllCoilTypes, HVAC::NumAllCoilTypes);
    3403         181 :         if (FoundType == HVAC::Coil_HeatingElectric || FoundType == HVAC::Coil_HeatingElectric_MultiStage ||
    3404           0 :             FoundType == HVAC::Coil_HeatingGasOrOtherFuel || FoundType == HVAC::Coil_HeatingGas_MultiStage ||
    3405             :             FoundType == HVAC::Coil_HeatingDesuperheater) {
    3406         181 :             int WhichCoil = Util::FindItem(CoilName, state.dataHeatingCoils->HeatingCoil);
    3407         181 :             if (WhichCoil != 0) {
    3408         181 :                 return state.dataHeatingCoils->HeatingCoil(WhichCoil).PLFCurveIndex;
    3409             :             } else {
    3410           0 :                 ShowSevereError(state, format("GetHeatingCoilPLFCurveIndex: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3411           0 :                 ErrorsFound = true;
    3412           0 :                 return 0;
    3413             :             }
    3414             :         } else {
    3415           0 :             return 0;
    3416             :         }
    3417             :     }
    3418             : 
    3419           2 :     int GetHeatingCoilNumberOfStages(EnergyPlusData &state,
    3420             :                                      std::string const &CoilType, // must match coil types in this module
    3421             :                                      std::string const &CoilName, // must match coil names for the coil type
    3422             :                                      bool &ErrorsFound            // set to true if problem
    3423             :     )
    3424             :     {
    3425             : 
    3426             :         // FUNCTION INFORMATION:
    3427             :         //       AUTHOR         Chandan Sharma
    3428             :         //       DATE WRITTEN   February 2013
    3429             : 
    3430             :         // PURPOSE OF THIS FUNCTION:
    3431             :         // This function looks up the given coil and returns the number of speeds for multistage coils.
    3432             :         // If incorrect coil type or name is given, ErrorsFound is returned as true.
    3433             : 
    3434             :         // Obtains and Allocates HeatingCoils
    3435           2 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3436           0 :             GetHeatingCoilInput(state);
    3437           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3438             :         }
    3439             : 
    3440           2 :         int WhichCoil = Util::FindItemInList(CoilName, state.dataHeatingCoils->HeatingCoil);
    3441           2 :         if (WhichCoil != 0) {
    3442           2 :             return state.dataHeatingCoils->HeatingCoil(WhichCoil).NumOfStages;
    3443             :         } else {
    3444           0 :             ShowSevereError(state, format("GetHeatingCoilNumberOfSpeeds: Invalid Heating Coil Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    3445           0 :             ErrorsFound = true;
    3446           0 :             return 0;
    3447             :         }
    3448             :     }
    3449             : 
    3450           4 :     void SetHeatingCoilData(EnergyPlusData &state,
    3451             :                             int const CoilNum,                                  // Number of electric or gas heating Coil
    3452             :                             bool &ErrorsFound,                                  // Set to true if certain errors found
    3453             :                             ObjexxFCL::Optional_bool DesiccantRegenerationCoil, // Flag that this coil is used as regeneration air heating coil
    3454             :                             ObjexxFCL::Optional_int DesiccantDehumIndex         // Index for the desiccant dehum system where this coil is used
    3455             :     )
    3456             :     {
    3457             : 
    3458             :         // FUNCTION INFORMATION:
    3459             :         //       AUTHOR         Bereket Nigusse
    3460             :         //       DATE WRITTEN   February 2016
    3461             : 
    3462             :         // PURPOSE OF THIS FUNCTION:
    3463             :         // This function sets data to Heating Coil using the coil index and arguments passed
    3464             : 
    3465           4 :         auto &heatingCoil = state.dataHeatingCoils->HeatingCoil(CoilNum);
    3466           4 :         if (state.dataHeatingCoils->GetCoilsInputFlag) {
    3467           0 :             GetHeatingCoilInput(state);
    3468           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3469             :         }
    3470             : 
    3471           4 :         if (CoilNum <= 0 || CoilNum > state.dataHeatingCoils->NumHeatingCoils) {
    3472           0 :             ShowSevereError(state,
    3473           0 :                             format("SetHeatingCoilData: called with heating coil Number out of range={} should be >0 and <{}",
    3474             :                                    CoilNum,
    3475           0 :                                    state.dataHeatingCoils->NumHeatingCoils));
    3476           0 :             ErrorsFound = true;
    3477           0 :             return;
    3478             :         }
    3479             : 
    3480           4 :         if (present(DesiccantRegenerationCoil)) {
    3481           4 :             heatingCoil.DesiccantRegenerationCoil = DesiccantRegenerationCoil;
    3482             :         }
    3483             : 
    3484           4 :         if (present(DesiccantDehumIndex)) {
    3485           4 :             heatingCoil.DesiccantDehumNum = DesiccantDehumIndex;
    3486             :         }
    3487             :     }
    3488             : 
    3489          25 :     void SetHeatingCoilAirLoopNumber(EnergyPlusData &state, std::string const &HeatingCoilName, int AirLoopNum, bool &ErrorsFound)
    3490             :     {
    3491             :         // SUBROUTINE INFORMATION:
    3492             :         //       AUTHOR         L.Gu
    3493             :         //       DATE WRITTEN   March 2018
    3494             : 
    3495             :         // PURPOSE OF THIS SUBROUTINE:
    3496             :         // This subroutine sets an AirLoopNum for a given heating Coil
    3497             : 
    3498             :         int HeatingCoilIndex;
    3499             : 
    3500          25 :         if (state.dataHeatingCoils->GetCoilsInputFlag) { // First time subroutine has been entered
    3501           0 :             GetHeatingCoilInput(state);
    3502           0 :             state.dataHeatingCoils->GetCoilsInputFlag = false;
    3503             :         }
    3504             : 
    3505          25 :         HeatingCoilIndex = Util::FindItem(HeatingCoilName, state.dataHeatingCoils->HeatingCoil);
    3506          25 :         if (HeatingCoilIndex == 0) {
    3507           0 :             ShowSevereError(state, format("GetCoilIndex: Heating coil not found={}", HeatingCoilName));
    3508           0 :             ErrorsFound = true;
    3509             :         } else {
    3510          25 :             state.dataHeatingCoils->HeatingCoil(HeatingCoilIndex).AirLoopNum = AirLoopNum;
    3511             :         }
    3512          25 :     }
    3513             : } // namespace HeatingCoils
    3514             : 
    3515             : } // namespace EnergyPlus

Generated by: LCOV version 1.14