LCOV - code coverage report
Current view: top level - EnergyPlus - HeatingCoils.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1142 1688 67.7 %
Date: 2023-01-17 19:17:23 Functions: 26 27 96.3 %

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

Generated by: LCOV version 1.13