LCOV - code coverage report
Current view: top level - EnergyPlus - SteamCoils.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 52.7 % 844 445
Test Date: 2025-05-22 16:09:37 Functions: 58.3 % 24 14

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cmath>
      50              : 
      51              : // ObjexxFCL Headers
      52              : #include <ObjexxFCL/Array.functions.hh>
      53              : 
      54              : // EnergyPlus Headers
      55              : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
      56              : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
      57              : #include <EnergyPlus/BranchNodeConnections.hh>
      58              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      59              : #include <EnergyPlus/DataContaminantBalance.hh>
      60              : #include <EnergyPlus/DataEnvironment.hh>
      61              : #include <EnergyPlus/DataHVACGlobals.hh>
      62              : #include <EnergyPlus/DataLoopNode.hh>
      63              : #include <EnergyPlus/DataSizing.hh>
      64              : #include <EnergyPlus/Fans.hh>
      65              : #include <EnergyPlus/FaultsManager.hh>
      66              : #include <EnergyPlus/FluidProperties.hh>
      67              : #include <EnergyPlus/GeneralRoutines.hh>
      68              : #include <EnergyPlus/GlobalNames.hh>
      69              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      70              : #include <EnergyPlus/NodeInputManager.hh>
      71              : #include <EnergyPlus/OutputProcessor.hh>
      72              : #include <EnergyPlus/Plant/DataPlant.hh>
      73              : #include <EnergyPlus/PlantUtilities.hh>
      74              : #include <EnergyPlus/Psychrometrics.hh>
      75              : #include <EnergyPlus/ReportCoilSelection.hh>
      76              : #include <EnergyPlus/ScheduleManager.hh>
      77              : #include <EnergyPlus/SteamCoils.hh>
      78              : #include <EnergyPlus/UtilityRoutines.hh>
      79              : 
      80              : namespace EnergyPlus {
      81              : 
      82              : namespace SteamCoils {
      83              : 
      84              :     // Module containing the SteamCoil simulation routines
      85              : 
      86              :     // MODULE INFORMATION:
      87              :     //   AUTHOR         Rahul Chillar
      88              :     //   DATE WRITTEN   Jan 2005
      89              :     //   MODIFIED       na
      90              :     //   RE-ENGINEERED  na
      91              : 
      92              :     // PURPOSE OF THIS MODULE:
      93              :     // To encapsulate the data and algorithms required to
      94              :     // manage the SteamCoil System Component.
      95              : 
      96              :     using namespace DataLoopNode;
      97              :     using namespace Psychrometrics;
      98              : 
      99              :     using PlantUtilities::MyPlantSizingIndex;
     100              :     using PlantUtilities::ScanPlantLoopsForObject;
     101              : 
     102              :     constexpr std::array<std::string_view, static_cast<int>(CoilControlType::Num)> coilControlTypeNames = {"TEMPERATURESETPOINTCONTROL",
     103              :                                                                                                            "ZONELOADCONTROL"};
     104              : 
     105            3 :     void SimulateSteamCoilComponents(EnergyPlusData &state,
     106              :                                      std::string_view CompName,
     107              :                                      bool const FirstHVACIteration,
     108              :                                      int &CompIndex,
     109              :                                      ObjexxFCL::Optional<Real64 const> QCoilReq, // coil load to be met
     110              :                                      ObjexxFCL::Optional<Real64> QCoilActual,    // coil load actually delivered returned to calling component
     111              :                                      ObjexxFCL::Optional<HVAC::FanOp const> fanOpMode,
     112              :                                      ObjexxFCL::Optional<Real64 const> PartLoadRatio)
     113              :     {
     114              : 
     115              :         // SUBROUTINE INFORMATION:
     116              :         //   AUTHOR         Rahul Chillar
     117              :         //   DATE WRITTEN   Jan 2005
     118              :         //   MODIFIED       na
     119              :         //   RE-ENGINEERED  na
     120              : 
     121              :         // PURPOSE OF THIS SUBROUTINE:
     122              :         // This subroutine manages SteamCoil component simulation.
     123              : 
     124              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     125              :         Real64 QCoilActualTemp; // coil load actually delivered returned to calling component
     126              :         int CoilNum;            // The SteamCoil that you are currently loading input into
     127              :         HVAC::FanOp fanOp;      // fan operating mode
     128              :         Real64 PartLoadFrac;    // part-load fraction of heating coil
     129              :         Real64 QCoilReqLocal;   // local required heating load optional
     130              : 
     131              :         // Obtains and Allocates SteamCoil related parameters from input file
     132            3 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
     133            0 :             GetSteamCoilInput(state);
     134            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
     135              :         }
     136              : 
     137              :         // Find the correct SteamCoilNumber with the Coil Name
     138            3 :         if (CompIndex == 0) {
     139            0 :             CoilNum = Util::FindItemInList(CompName, state.dataSteamCoils->SteamCoil);
     140            0 :             if (CoilNum == 0) {
     141            0 :                 ShowFatalError(state, format("SimulateSteamCoilComponents: Coil not found={}", CompName));
     142              :             }
     143            0 :             CompIndex = CoilNum;
     144              :         } else {
     145            3 :             CoilNum = CompIndex;
     146            3 :             if (CoilNum > state.dataSteamCoils->NumSteamCoils || CoilNum < 1) {
     147            0 :                 ShowFatalError(state,
     148            0 :                                format("SimulateSteamCoilComponents: Invalid CompIndex passed={}, Number of Steam Coils={}, Coil name={}",
     149              :                                       CoilNum,
     150            0 :                                       state.dataSteamCoils->NumSteamCoils,
     151              :                                       CompName));
     152              :             }
     153            3 :             if (state.dataSteamCoils->CheckEquipName(CoilNum)) {
     154            2 :                 if (CompName != state.dataSteamCoils->SteamCoil(CoilNum).Name) {
     155            0 :                     ShowFatalError(
     156              :                         state,
     157            0 :                         format("SimulateSteamCoilComponents: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
     158              :                                CoilNum,
     159              :                                CompName,
     160            0 :                                state.dataSteamCoils->SteamCoil(CoilNum).Name));
     161              :                 }
     162            2 :                 state.dataSteamCoils->CheckEquipName(CoilNum) = false;
     163              :             }
     164              :         }
     165              : 
     166              :         // With the correct CoilNum Initialize
     167            3 :         InitSteamCoil(state, CoilNum, FirstHVACIteration); // Initialize all SteamCoil related parameters
     168              : 
     169            3 :         if (present(fanOpMode)) {
     170            2 :             fanOp = fanOpMode;
     171              :         } else {
     172            1 :             fanOp = HVAC::FanOp::Continuous;
     173              :         }
     174            3 :         if (present(PartLoadRatio)) {
     175            2 :             PartLoadFrac = PartLoadRatio;
     176              :         } else {
     177            1 :             PartLoadFrac = 1.0;
     178              :         }
     179            3 :         if (present(QCoilReq)) {
     180            2 :             QCoilReqLocal = QCoilReq;
     181              :         } else {
     182            1 :             QCoilReqLocal = 0.0;
     183              :         }
     184              : 
     185            3 :         CalcSteamAirCoil(
     186              :             state, CoilNum, QCoilReqLocal, QCoilActualTemp, fanOp, PartLoadFrac); // Autodesk:OPTIONAL QCoilReq used without PRESENT check
     187            3 :         if (present(QCoilActual)) QCoilActual = QCoilActualTemp;
     188              : 
     189              :         // Update the current SteamCoil to the outlet nodes
     190            3 :         UpdateSteamCoil(state, CoilNum);
     191              : 
     192              :         // Report the current SteamCoil
     193            3 :         ReportSteamCoil(state, CoilNum);
     194            3 :     }
     195              : 
     196              :     // Get Input Section of the Module
     197              : 
     198            2 :     void GetSteamCoilInput(EnergyPlusData &state)
     199              :     {
     200              :         // SUBROUTINE INFORMATION:
     201              :         //   AUTHOR         Rahul Chillar
     202              :         //   DATE WRITTEN   Jan 2005
     203              :         //   MODIFIED       na
     204              :         //   RE-ENGINEERED  na
     205              : 
     206              :         // PURPOSE OF THIS SUBROUTINE:
     207              :         // Obtains input data for coils and stores it in coil data structures
     208              : 
     209              :         // METHODOLOGY EMPLOYED:
     210              :         // Uses "Get" routines to read in data.
     211              : 
     212              :         // Using/Aliasing
     213              :         using BranchNodeConnections::TestCompSet;
     214              :         using GlobalNames::VerifyUniqueCoilName;
     215              :         using NodeInputManager::GetOnlySingleNode;
     216              : 
     217              :         // SUBROUTINE PARAMETER DEFINITIONS:
     218              :         static constexpr std::string_view RoutineName("GetSteamCoilInput: "); // include trailing blank space
     219              :         static constexpr std::string_view routineName = "GetSteamCoilInput";
     220              : 
     221              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     222              :         int CoilNum; // The SteamCoil that you are currently loading input into
     223              :         int NumStmHeat;
     224              :         int StmHeatNum;
     225              :         int NumAlphas;
     226              :         int NumNums;
     227              :         int IOStat;
     228            2 :         bool ErrorsFound(false);         // If errors detected in input
     229            2 :         std::string CurrentModuleObject; // for ease in getting objects
     230            2 :         Array1D_string AlphArray;        // Alpha input items for object
     231            2 :         Array1D_string cAlphaFields;     // Alpha field names
     232            2 :         Array1D_string cNumericFields;   // Numeric field names
     233            2 :         Array1D<Real64> NumArray;        // Numeric input items for object
     234            2 :         Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     235            2 :         Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     236            2 :         int TotalArgs(0);                // Total number of alpha and numeric arguments (max) for a
     237              :                                          //  certain object in the input file
     238              : 
     239            2 :         CurrentModuleObject = "Coil:Heating:Steam";
     240            2 :         NumStmHeat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     241            2 :         state.dataSteamCoils->NumSteamCoils = NumStmHeat;
     242            2 :         if (state.dataSteamCoils->NumSteamCoils > 0) {
     243            2 :             state.dataSteamCoils->SteamCoil.allocate(state.dataSteamCoils->NumSteamCoils);
     244            2 :             state.dataSteamCoils->CheckEquipName.dimension(state.dataSteamCoils->NumSteamCoils, true);
     245              :         }
     246              : 
     247            2 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, TotalArgs, NumAlphas, NumNums);
     248            2 :         AlphArray.allocate(NumAlphas);
     249            2 :         cAlphaFields.allocate(NumAlphas);
     250            2 :         cNumericFields.allocate(NumNums);
     251            2 :         NumArray.dimension(NumNums, 0.0);
     252            2 :         lAlphaBlanks.dimension(NumAlphas, true);
     253            2 :         lNumericBlanks.dimension(NumNums, true);
     254              : 
     255              :         // Get the data for steam heating coils
     256            4 :         for (StmHeatNum = 1; StmHeatNum <= NumStmHeat; ++StmHeatNum) {
     257              : 
     258            2 :             CoilNum = StmHeatNum;
     259              : 
     260            2 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     261              :                                                                      CurrentModuleObject,
     262              :                                                                      StmHeatNum,
     263              :                                                                      AlphArray,
     264              :                                                                      NumAlphas,
     265              :                                                                      NumArray,
     266              :                                                                      NumNums,
     267              :                                                                      IOStat,
     268              :                                                                      lNumericBlanks,
     269              :                                                                      lAlphaBlanks,
     270              :                                                                      cAlphaFields,
     271              :                                                                      cNumericFields);
     272              : 
     273            2 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, AlphArray(1)};
     274            2 :             Util::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, ErrorsFound);
     275              : 
     276              :             // ErrorsFound will be set to True if problem was found, left untouched otherwise
     277            2 :             VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
     278              : 
     279            2 :             state.dataSteamCoils->SteamCoil(CoilNum).Name = AlphArray(1);
     280              : 
     281            2 :             if (lAlphaBlanks(2)) {
     282            0 :                 state.dataSteamCoils->SteamCoil(CoilNum).availSched = Sched::GetScheduleAlwaysOn(state);
     283            2 :             } else if ((state.dataSteamCoils->SteamCoil(CoilNum).availSched = Sched::GetSchedule(state, AlphArray(2))) == nullptr) {
     284            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), AlphArray(2));
     285            0 :                 ErrorsFound = true;
     286              :             }
     287              : 
     288            2 :             state.dataSteamCoils->SteamCoil(CoilNum).SteamCoilTypeA = "Heating";
     289            2 :             state.dataSteamCoils->SteamCoil(CoilNum).CoilType = DataPlant::PlantEquipmentType::CoilSteamAirHeating;
     290            2 :             state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate = NumArray(1);
     291            2 :             state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling = NumArray(2);
     292            2 :             state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn = NumArray(3);
     293              : 
     294            4 :             state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum = GetOnlySingleNode(state,
     295            2 :                                                                                            AlphArray(3),
     296              :                                                                                            ErrorsFound,
     297              :                                                                                            DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
     298            2 :                                                                                            AlphArray(1),
     299              :                                                                                            DataLoopNode::NodeFluidType::Steam,
     300              :                                                                                            DataLoopNode::ConnectionType::Inlet,
     301              :                                                                                            NodeInputManager::CompFluidStream::Secondary,
     302              :                                                                                            ObjectIsNotParent);
     303            4 :             state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum = GetOnlySingleNode(state,
     304            2 :                                                                                             AlphArray(4),
     305              :                                                                                             ErrorsFound,
     306              :                                                                                             DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
     307            2 :                                                                                             AlphArray(1),
     308              :                                                                                             DataLoopNode::NodeFluidType::Steam,
     309              :                                                                                             DataLoopNode::ConnectionType::Outlet,
     310              :                                                                                             NodeInputManager::CompFluidStream::Secondary,
     311              :                                                                                             ObjectIsNotParent);
     312            4 :             state.dataSteamCoils->SteamCoil(CoilNum).AirInletNodeNum = GetOnlySingleNode(state,
     313            2 :                                                                                          AlphArray(5),
     314              :                                                                                          ErrorsFound,
     315              :                                                                                          DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
     316            2 :                                                                                          AlphArray(1),
     317              :                                                                                          DataLoopNode::NodeFluidType::Air,
     318              :                                                                                          DataLoopNode::ConnectionType::Inlet,
     319              :                                                                                          NodeInputManager::CompFluidStream::Primary,
     320              :                                                                                          ObjectIsNotParent);
     321            4 :             state.dataSteamCoils->SteamCoil(CoilNum).AirOutletNodeNum = GetOnlySingleNode(state,
     322            2 :                                                                                           AlphArray(6),
     323              :                                                                                           ErrorsFound,
     324              :                                                                                           DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
     325            2 :                                                                                           AlphArray(1),
     326              :                                                                                           DataLoopNode::NodeFluidType::Air,
     327              :                                                                                           DataLoopNode::ConnectionType::Outlet,
     328              :                                                                                           NodeInputManager::CompFluidStream::Primary,
     329              :                                                                                           ObjectIsNotParent);
     330              : 
     331            2 :             std::string controlMode = Util::makeUPPER(AlphArray(7));
     332            2 :             state.dataSteamCoils->SteamCoil(CoilNum).TypeOfCoil = static_cast<CoilControlType>(getEnumValue(coilControlTypeNames, controlMode));
     333              : 
     334            2 :             switch (state.dataSteamCoils->SteamCoil(CoilNum).TypeOfCoil) {
     335            0 :             case CoilControlType::TemperatureSetPoint:
     336            0 :                 state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum = GetOnlySingleNode(state,
     337            0 :                                                                                                  AlphArray(8),
     338              :                                                                                                  ErrorsFound,
     339              :                                                                                                  DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
     340            0 :                                                                                                  AlphArray(1),
     341              :                                                                                                  DataLoopNode::NodeFluidType::Air,
     342              :                                                                                                  DataLoopNode::ConnectionType::Sensor,
     343              :                                                                                                  NodeInputManager::CompFluidStream::Primary,
     344              :                                                                                                  ObjectIsNotParent);
     345            0 :                 if (state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum == 0) {
     346            0 :                     ShowSevereError(state, format("{}{} not found for {} = {}", RoutineName, cAlphaFields(8), CurrentModuleObject, AlphArray(1)));
     347            0 :                     ShowContinueError(state, "..required for Temperature Setpoint Controlled Coils.");
     348            0 :                     ErrorsFound = true;
     349              :                 }
     350            0 :                 break;
     351            2 :             case CoilControlType::ZoneLoadControl:
     352            2 :                 if (!lAlphaBlanks(8)) {
     353            0 :                     ShowWarningError(state, format("{}ZoneLoad Controlled Coil, so {} not needed", RoutineName, cAlphaFields(8)));
     354            0 :                     ShowContinueError(state, format("for {} = {}", CurrentModuleObject, AlphArray(1)));
     355            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum = 0;
     356              :                 }
     357            2 :                 break;
     358            0 :             default:
     359            0 :                 ShowSevereError(
     360              :                     state,
     361            0 :                     format("{}Invalid {} [{}] specified for {} = {}", RoutineName, cAlphaFields(7), AlphArray(7), CurrentModuleObject, AlphArray(1)));
     362            0 :                 ErrorsFound = true;
     363              :             }
     364              : 
     365            4 :             TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(3), AlphArray(4), "Steam Nodes");
     366            2 :             TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(5), AlphArray(6), "Air Nodes");
     367              : 
     368            2 :             state.dataSteamCoils->SteamCoil(CoilNum).steam = Fluid::GetSteam(state);
     369            2 :             if (state.dataSteamCoils->SteamCoil(CoilNum).steam == nullptr && CoilNum == 1) {
     370            0 :                 ShowSevereError(state, format("{}Steam Properties for {} not found.", RoutineName, AlphArray(1)));
     371            0 :                 ShowContinueError(state, "Steam Fluid Properties should have been included in the input file.");
     372            0 :                 ErrorsFound = true;
     373              :             }
     374            2 :         }
     375              : 
     376            4 :         for (CoilNum = 1; CoilNum <= NumStmHeat; ++CoilNum) {
     377              : 
     378              :             // Setup the Simple Heating Coil reporting variables
     379              :             // CurrentModuleObject = "Coil:Heating:Steam"
     380            4 :             SetupOutputVariable(state,
     381              :                                 "Heating Coil Heating Energy",
     382              :                                 Constant::Units::J,
     383            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilEnergy,
     384              :                                 OutputProcessor::TimeStepType::System,
     385              :                                 OutputProcessor::StoreType::Sum,
     386            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).Name,
     387              :                                 Constant::eResource::EnergyTransfer,
     388              :                                 OutputProcessor::Group::HVAC,
     389              :                                 OutputProcessor::EndUseCat::HeatingCoils);
     390            4 :             SetupOutputVariable(state,
     391              :                                 "Heating Coil Heating Rate",
     392              :                                 Constant::Units::W,
     393            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate,
     394              :                                 OutputProcessor::TimeStepType::System,
     395              :                                 OutputProcessor::StoreType::Average,
     396            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).Name);
     397            4 :             SetupOutputVariable(state,
     398              :                                 "Heating Coil Steam Mass Flow Rate",
     399              :                                 Constant::Units::kg_s,
     400            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate,
     401              :                                 OutputProcessor::TimeStepType::System,
     402              :                                 OutputProcessor::StoreType::Average,
     403            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).Name);
     404            4 :             SetupOutputVariable(state,
     405              :                                 "Heating Coil Steam Inlet Temperature",
     406              :                                 Constant::Units::C,
     407            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).InletSteamTemp,
     408              :                                 OutputProcessor::TimeStepType::System,
     409              :                                 OutputProcessor::StoreType::Average,
     410            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).Name);
     411            4 :             SetupOutputVariable(state,
     412              :                                 "Heating Coil Steam Outlet Temperature",
     413              :                                 Constant::Units::C,
     414            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamTemp,
     415              :                                 OutputProcessor::TimeStepType::System,
     416              :                                 OutputProcessor::StoreType::Average,
     417            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).Name);
     418            4 :             SetupOutputVariable(state,
     419              :                                 "Heating Coil Steam Trap Loss Rate",
     420              :                                 Constant::Units::W,
     421            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss,
     422              :                                 OutputProcessor::TimeStepType::System,
     423              :                                 OutputProcessor::StoreType::Average,
     424            2 :                                 state.dataSteamCoils->SteamCoil(CoilNum).Name);
     425              :         }
     426              : 
     427            2 :         if (ErrorsFound) {
     428            0 :             ShowFatalError(state, format("{}Errors found in getting input.", RoutineName));
     429              :         }
     430              : 
     431            2 :         AlphArray.deallocate();
     432            2 :         cAlphaFields.deallocate();
     433            2 :         cNumericFields.deallocate();
     434            2 :         NumArray.deallocate();
     435            2 :         lAlphaBlanks.deallocate();
     436            2 :         lNumericBlanks.deallocate();
     437            2 :     }
     438              : 
     439              :     // End of Get Input subroutines for the HB Module
     440              : 
     441              :     // Beginning Initialization Section of the Module
     442              : 
     443            3 :     void InitSteamCoil(EnergyPlusData &state, int const CoilNum, bool const FirstHVACIteration)
     444              :     {
     445              :         // SUBROUTINE INFORMATION:
     446              :         //   AUTHOR         Rahul Chillar
     447              :         //   DATE WRITTEN   Jan 2005
     448              :         //   MODIFIED       na
     449              :         //   RE-ENGINEERED  na
     450              : 
     451              :         // PURPOSE OF THIS SUBROUTINE:
     452              :         // This subroutine is for initializations of the SteamCoil Components.
     453              : 
     454              :         // METHODOLOGY EMPLOYED:
     455              :         // Uses the status flags to trigger initializations.
     456              : 
     457              :         // REFERENCES:
     458              :         // na
     459              : 
     460              :         // Using/Aliasing
     461              :         using PlantUtilities::InitComponentNodes;
     462              : 
     463              :         // Locals
     464              :         // SUBROUTINE ARGUMENT DEFINITIONS:
     465              : 
     466              :         // SUBROUTINE PARAMETER DEFINITIONS:
     467              :         static constexpr std::string_view RoutineName("InitSteamCoil");
     468              : 
     469              :         // INTERFACE BLOCK SPECIFICATIONS
     470              :         // na
     471              : 
     472              :         // DERIVED TYPE DEFINITIONS
     473              :         // na
     474              : 
     475              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     476              :         int AirInletNode;
     477              :         int SteamInletNode;
     478              :         int ControlNode;
     479              :         int AirOutletNode;
     480              :         Real64 SteamDensity;
     481              :         Real64 StartEnthSteam;
     482              :         bool errFlag;
     483              : 
     484            3 :         if (state.dataSteamCoils->MyOneTimeFlag) {
     485              :             // initialize the environment and sizing flags
     486            2 :             state.dataSteamCoils->MyEnvrnFlag.dimension(state.dataSteamCoils->NumSteamCoils, true);
     487            2 :             state.dataSteamCoils->MySizeFlag.dimension(state.dataSteamCoils->NumSteamCoils, true);
     488            2 :             state.dataSteamCoils->CoilWarningOnceFlag.dimension(state.dataSteamCoils->NumSteamCoils, true);
     489            2 :             state.dataSteamCoils->MyPlantScanFlag.dimension(state.dataSteamCoils->NumSteamCoils, true);
     490            2 :             state.dataSteamCoils->MyOneTimeFlag = false;
     491              :         }
     492              : 
     493            3 :         if (state.dataSteamCoils->MyPlantScanFlag(CoilNum) && allocated(state.dataPlnt->PlantLoop)) {
     494            2 :             errFlag = false;
     495            4 :             ScanPlantLoopsForObject(state,
     496            2 :                                     state.dataSteamCoils->SteamCoil(CoilNum).Name,
     497            2 :                                     state.dataSteamCoils->SteamCoil(CoilNum).CoilType,
     498            2 :                                     state.dataSteamCoils->SteamCoil(CoilNum).plantLoc,
     499              :                                     errFlag,
     500              :                                     _,
     501              :                                     _,
     502              :                                     _,
     503              :                                     _,
     504              :                                     _);
     505            2 :             if (errFlag) {
     506            0 :                 ShowFatalError(state, "InitSteamCoil: Program terminated for previous conditions.");
     507              :             }
     508            2 :             state.dataSteamCoils->MyPlantScanFlag(CoilNum) = false;
     509              :         }
     510              : 
     511            3 :         if (!state.dataGlobal->SysSizingCalc && state.dataSteamCoils->MySizeFlag(CoilNum)) {
     512              :             // for each coil, do the sizing once.
     513            1 :             SizeSteamCoil(state, CoilNum);
     514            1 :             state.dataSteamCoils->MySizeFlag(CoilNum) = false;
     515              :         }
     516              : 
     517              :         // Do the Begin Environment initializations
     518            3 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataSteamCoils->MyEnvrnFlag(CoilNum)) {
     519              :             // Initialize all report variables to a known state at beginning of simulation
     520            2 :             state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilEnergy = 0.0;
     521            2 :             state.dataSteamCoils->SteamCoil(CoilNum).TotSteamCoolingCoilEnergy = 0.0;
     522            2 :             state.dataSteamCoils->SteamCoil(CoilNum).SenSteamCoolingCoilEnergy = 0.0;
     523            2 :             state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate = 0.0;
     524            2 :             state.dataSteamCoils->SteamCoil(CoilNum).TotSteamCoolingCoilRate = 0.0;
     525            2 :             state.dataSteamCoils->SteamCoil(CoilNum).SenSteamCoolingCoilRate = 0.0;
     526              :             // Initialize other module level variables
     527            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate = 0.0;
     528            2 :             state.dataSteamCoils->SteamCoil(CoilNum).OutletAirMassFlowRate = 0.0;
     529            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletAirTemp = 0.0;
     530            2 :             state.dataSteamCoils->SteamCoil(CoilNum).OutletAirTemp = 0.0;
     531            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletAirHumRat = 0.0;
     532            2 :             state.dataSteamCoils->SteamCoil(CoilNum).OutletAirHumRat = 0.0;
     533            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletAirEnthalpy = 0.0;
     534            2 :             state.dataSteamCoils->SteamCoil(CoilNum).OutletAirEnthalpy = 0.0;
     535            2 :             state.dataSteamCoils->SteamCoil(CoilNum).TotSteamCoilLoad = 0.0;
     536            2 :             state.dataSteamCoils->SteamCoil(CoilNum).SenSteamCoilLoad = 0.0;
     537            2 :             state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = 0.0;
     538            2 :             state.dataSteamCoils->SteamCoil(CoilNum).LeavingRelHum = 0.0;
     539            2 :             state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp = 0.0;
     540            2 :             state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletHumRat = 0.0;
     541            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletSteamTemp = 0.0;
     542            2 :             state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamTemp = 0.0;
     543            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = 0.0;
     544            2 :             state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = 0.0;
     545            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy = 0.0;
     546            2 :             state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = 0.0;
     547            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletSteamPress = 0.0;
     548            2 :             state.dataSteamCoils->SteamCoil(CoilNum).InletSteamQuality = 0.0;
     549            2 :             state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality = 0.0;
     550              : 
     551              :             // More Environment initializations
     552            2 :             AirInletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirInletNodeNum;
     553            2 :             SteamInletNode = state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum;
     554            2 :             ControlNode = state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum;
     555            2 :             AirOutletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirOutletNodeNum;
     556              : 
     557            2 :             state.dataLoopNodes->Node(SteamInletNode).Temp = 100.0;
     558            2 :             state.dataLoopNodes->Node(SteamInletNode).Press = 101325.0;
     559            2 :             auto *steam = Fluid::GetSteam(state);
     560            2 :             SteamDensity = steam->getSatDensity(state, state.dataLoopNodes->Node(SteamInletNode).Temp, 1.0, RoutineName);
     561            2 :             StartEnthSteam = steam->getSatEnthalpy(state, state.dataLoopNodes->Node(SteamInletNode).Temp, 1.0, RoutineName);
     562            2 :             state.dataLoopNodes->Node(SteamInletNode).Enthalpy = StartEnthSteam;
     563            2 :             state.dataLoopNodes->Node(SteamInletNode).Quality = 1.0;
     564            2 :             state.dataLoopNodes->Node(SteamInletNode).HumRat = 0.0;
     565            2 :             state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate =
     566            2 :                 SteamDensity * state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate;
     567              :             //     Node(SteamInletNode)%MassFlowRate         = SteamCoil(CoilNum)%MaxSteamMassFlowRate
     568              :             //     Node(SteamInletNode)%MassFlowRateMinAvail = 0.0
     569              :             //     Node(SteamInletNode)%MassFlowRateMaxAvail = SteamCoil(CoilNum)%MaxSteamMassFlowRate
     570            6 :             InitComponentNodes(state,
     571              :                                0.0,
     572            2 :                                state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate,
     573            2 :                                state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
     574            2 :                                state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum);
     575            2 :             state.dataSteamCoils->MyEnvrnFlag(CoilNum) = false;
     576              :         } // End If for the Begin Environment initializations
     577              : 
     578            3 :         if (!state.dataGlobal->BeginEnvrnFlag) {
     579            0 :             state.dataSteamCoils->MyEnvrnFlag(CoilNum) = true;
     580              :         }
     581              : 
     582              :         // Do the Begin Day initializations
     583              :         // NONE
     584              : 
     585              :         // Do the begin HVAC time step initializations
     586              :         // NONE
     587              : 
     588              :         // Do the following initializations (every time step): This should be the info from
     589              :         // the previous components outlets or the node data in this section.
     590              : 
     591            3 :         AirInletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirInletNodeNum;
     592            3 :         SteamInletNode = state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum;
     593            3 :         ControlNode = state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum;
     594            3 :         AirOutletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirOutletNodeNum;
     595              : 
     596              :         // First set the conditions for the air into the coil model
     597              : 
     598              :         // If a temperature setpoint controlled coil must set the desired outlet temp everytime
     599            3 :         if (ControlNode == 0) {
     600            3 :             state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp = 0.0;
     601            0 :         } else if (ControlNode == AirOutletNode) {
     602            0 :             state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint;
     603              :         } else {
     604            0 :             state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp =
     605            0 :                 state.dataLoopNodes->Node(ControlNode).TempSetPoint -
     606            0 :                 (state.dataLoopNodes->Node(ControlNode).Temp - state.dataLoopNodes->Node(AirOutletNode).Temp);
     607              :         }
     608              : 
     609            3 :         state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
     610            3 :         state.dataSteamCoils->SteamCoil(CoilNum).InletAirTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
     611            3 :         state.dataSteamCoils->SteamCoil(CoilNum).InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
     612            3 :         state.dataSteamCoils->SteamCoil(CoilNum).InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
     613            3 :         if (FirstHVACIteration) {
     614            3 :             state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate;
     615              :         } else {
     616            0 :             state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = state.dataLoopNodes->Node(SteamInletNode).MassFlowRate;
     617              :         }
     618            3 :         state.dataSteamCoils->SteamCoil(CoilNum).InletSteamTemp = state.dataLoopNodes->Node(SteamInletNode).Temp;
     619            3 :         state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy = state.dataLoopNodes->Node(SteamInletNode).Enthalpy;
     620            3 :         state.dataSteamCoils->SteamCoil(CoilNum).InletSteamPress = state.dataLoopNodes->Node(SteamInletNode).Press;
     621            3 :         state.dataSteamCoils->SteamCoil(CoilNum).InletSteamQuality = state.dataLoopNodes->Node(SteamInletNode).Quality;
     622            3 :         state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate = 0.0;
     623            3 :         state.dataSteamCoils->SteamCoil(CoilNum).TotSteamCoolingCoilRate = 0.0;
     624            3 :         state.dataSteamCoils->SteamCoil(CoilNum).SenSteamCoolingCoilRate = 0.0;
     625              :         //   Node(SteamInletNode)%MassFlowRateMaxAvail = MIN(Node(SteamInletNode)%MassFlowRateMaxAvail,&
     626              :         //                                                   SteamCoil(CoilNum)%MaxSteamMassFlowRate)
     627            3 :     }
     628              : 
     629            1 :     void SizeSteamCoil(EnergyPlusData &state, int const CoilNum)
     630              :     {
     631              :         // SUBROUTINE INFORMATION:
     632              :         //       AUTHOR         Rahul Chillar
     633              :         //       DATE WRITTEN   Jan 2005
     634              :         //       MODIFIED       na
     635              :         //       RE-ENGINEERED  na
     636              : 
     637              :         // PURPOSE OF THIS SUBROUTINE:
     638              :         // This subroutine is for sizing Steam Coil Components for which flow rates have not been
     639              :         // specified in the input.
     640              : 
     641              :         // METHODOLOGY EMPLOYED:
     642              :         // Obtains flow rates from the zone or system sizing arrays and plant sizing data.
     643              : 
     644              :         // Using/Aliasing
     645              :         using namespace DataSizing;
     646              :         using PlantUtilities::RegisterPlantCompDesignFlow;
     647              : 
     648              :         // SUBROUTINE PARAMETER DEFINITIONS:
     649              :         static constexpr std::string_view RoutineName("SizeSteamCoil");
     650              : 
     651              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     652              :         int PltSizNum;      // do loop index for plant sizing
     653              :         int PltSizSteamNum; // index of plant sizing object for 1st steam loop
     654              :         bool ErrorsFound;   // If errors detected in input
     655              :         Real64 CoilInTemp;
     656              :         Real64 CoilOutTemp;
     657              :         Real64 CoilOutHumRat;
     658              :         Real64 CoilInHumRat;
     659              :         Real64 DesCoilLoad;
     660              :         Real64 DesMassFlow;
     661              :         Real64 DesVolFlow;
     662              :         Real64 MinFlowFrac;
     663              :         Real64 OutAirFrac;
     664            1 :         Real64 TempSteamIn(100.0);
     665              :         Real64 EnthSteamInDry;
     666              :         Real64 EnthSteamOutWet;
     667              :         Real64 LatentHeatSteam;
     668              :         Real64 SteamDensity;
     669              :         Real64 RhoAirStd; // density of air at standard conditions
     670              :         Real64 CpAirStd;  // specific heat of air at std conditions
     671              :         Real64 CpWater;   // specific heat of water (condensed steam)
     672              : 
     673            1 :         std::string CompName;     // component name
     674            1 :         std::string CompType;     // component type
     675            1 :         std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
     676            1 :         bool bPRINT = false;      // TRUE if sizing is reported to output (eio)
     677              :         Real64 TempSize;          // autosized value
     678              : 
     679            1 :         ErrorsFound = false;
     680            1 :         PltSizSteamNum = 0;
     681            1 :         PltSizNum = 0;
     682            1 :         CoilInTemp = 0.0;
     683            1 :         CoilInHumRat = 0.0;
     684            1 :         CoilOutTemp = 0.0;
     685            1 :         DesCoilLoad = 0.0;
     686            1 :         MinFlowFrac = 0.0;
     687            1 :         DesMassFlow = 0.0;
     688            1 :         DesVolFlow = 0.0;
     689            1 :         CpWater = 0.0;
     690            1 :         RhoAirStd = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, 20.0, 0.0);
     691            1 :         CpAirStd = PsyCpAirFnW(0.0);
     692            1 :         bool coilWasAutosized(false); // coil report
     693              : 
     694            1 :         auto &OASysEqSizing = state.dataSize->OASysEqSizing;
     695            1 :         auto &TermUnitSizing = state.dataSize->TermUnitSizing;
     696              : 
     697              :         // If this is a steam coil
     698              :         // Find the appropriate steam Plant Sizing object
     699            1 :         if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == AutoSize) {
     700            1 :             coilWasAutosized = true; // coil report
     701            1 :             PltSizSteamNum = MyPlantSizingIndex(state,
     702              :                                                 "steam heating coil",
     703            1 :                                                 state.dataSteamCoils->SteamCoil(CoilNum).Name,
     704            1 :                                                 state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
     705            1 :                                                 state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
     706              :                                                 ErrorsFound);
     707              :         }
     708              : 
     709            1 :         if (PltSizSteamNum > 0) {
     710              :             // If this is a central air system heating coil
     711            1 :             if (state.dataSize->CurSysNum > 0) {
     712            0 :                 auto &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
     713              : 
     714              :                 // If the coil water volume flow rate needs autosizing, then do it
     715            0 :                 if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == AutoSize) {
     716            0 :                     CheckSysSizing(state, "Coil:Heating:Steam", state.dataSteamCoils->SteamCoil(CoilNum).Name);
     717              : 
     718            0 :                     if (state.dataSteamCoils->SteamCoil(CoilNum).DesiccantRegenerationCoil) {
     719              : 
     720            0 :                         state.dataSize->DataDesicRegCoil = true;
     721            0 :                         state.dataSize->DataDesicDehumNum = state.dataSteamCoils->SteamCoil(CoilNum).DesiccantDehumNum;
     722            0 :                         CompType = state.dataSteamCoils->SteamCoil(CoilNum).SteamCoilType; // this is casting an int to a string
     723            0 :                         CompName = state.dataSteamCoils->SteamCoil(CoilNum).Name;
     724            0 :                         bPRINT = false;
     725            0 :                         HeatingCoilDesAirInletTempSizer sizerHeatingDesInletTemp;
     726            0 :                         bool ErrorsFound = false;
     727            0 :                         sizerHeatingDesInletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
     728            0 :                         state.dataSize->DataDesInletAirTemp = sizerHeatingDesInletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
     729              : 
     730            0 :                         HeatingCoilDesAirOutletTempSizer sizerHeatingDesOutletTemp;
     731            0 :                         ErrorsFound = false;
     732            0 :                         sizerHeatingDesOutletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
     733            0 :                         state.dataSize->DataDesOutletAirTemp = sizerHeatingDesOutletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
     734              : 
     735            0 :                         if (state.dataSize->CurOASysNum > 0) {
     736            0 :                             OASysEqSizing(state.dataSize->CurOASysNum).AirFlow = true;
     737            0 :                             OASysEqSizing(state.dataSize->CurOASysNum).AirVolFlow = finalSysSizing.DesOutAirVolFlow;
     738              :                         }
     739            0 :                         TempSize = AutoSize; // reset back
     740            0 :                     }
     741              : 
     742              :                     // Set the duct flow rate
     743            0 :                     switch (state.dataSize->CurDuctType) {
     744            0 :                     case HVAC::AirDuctType::Main:
     745            0 :                         DesVolFlow = finalSysSizing.SysAirMinFlowRat * finalSysSizing.DesMainVolFlow;
     746            0 :                         break;
     747            0 :                     case HVAC::AirDuctType::Cooling:
     748            0 :                         DesVolFlow = finalSysSizing.SysAirMinFlowRat * finalSysSizing.DesCoolVolFlow;
     749            0 :                         break;
     750            0 :                     case HVAC::AirDuctType::Heating:
     751            0 :                         DesVolFlow = finalSysSizing.DesHeatVolFlow;
     752            0 :                         break;
     753            0 :                     case HVAC::AirDuctType::Other:
     754            0 :                         DesVolFlow = finalSysSizing.DesMainVolFlow;
     755            0 :                         break;
     756            0 :                     default:
     757            0 :                         DesVolFlow = finalSysSizing.DesMainVolFlow;
     758              :                     }
     759            0 :                     if (state.dataSize->DataDesicRegCoil) {
     760            0 :                         bPRINT = false;
     761            0 :                         TempSize = AutoSize;
     762            0 :                         bool errorsFound = false;
     763            0 :                         HeatingAirFlowSizer sizingHeatingAirFlow;
     764            0 :                         sizingHeatingAirFlow.overrideSizingString(SizingString);
     765              :                         // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
     766            0 :                         sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
     767            0 :                         DesVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
     768            0 :                     }
     769            0 :                     DesMassFlow = RhoAirStd * DesVolFlow;
     770              :                     // get the outside air fraction
     771            0 :                     if (finalSysSizing.HeatOAOption == DataSizing::OAControl::MinOA) {
     772            0 :                         if (DesVolFlow > 0.0) {
     773            0 :                             OutAirFrac = finalSysSizing.DesOutAirVolFlow / DesVolFlow;
     774              :                         } else {
     775            0 :                             OutAirFrac = 1.0;
     776              :                         }
     777            0 :                         OutAirFrac = min(1.0, max(0.0, OutAirFrac));
     778              :                     } else {
     779            0 :                         OutAirFrac = 1.0;
     780              :                     }
     781              : 
     782            0 :                     if (state.dataSize->DataDesicRegCoil) {
     783            0 :                         DesCoilLoad = CpAirStd * DesMassFlow * (state.dataSize->DataDesOutletAirTemp - state.dataSize->DataDesInletAirTemp);
     784              :                     } else {
     785              :                         // mixed air temp
     786            0 :                         CoilInTemp = OutAirFrac * finalSysSizing.HeatOutTemp + (1.0 - OutAirFrac) * finalSysSizing.HeatRetTemp;
     787              :                         // coil load
     788            0 :                         DesCoilLoad = CpAirStd * DesMassFlow * (finalSysSizing.HeatSupTemp - CoilInTemp);
     789              :                     }
     790              :                     // AUTOSTEAMCOIL
     791            0 :                     if (DesCoilLoad >= HVAC::SmallLoad) {
     792              :                         // TempSteamIn=SteamCoil(CoilNum)%InletSteamTemp
     793              :                         // TempSteamIn=PlantSizData(PltSizSteamNum)%ExitTemp
     794            0 :                         TempSteamIn = 100.0; // Should be from the PlantSizing object (ExitTemp) instead of hardwired to 100?
     795              :                         // RefrigIndex is set during GetInput for this module
     796            0 :                         EnthSteamInDry = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 1.0, RoutineName);
     797            0 :                         EnthSteamOutWet = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 0.0, RoutineName);
     798            0 :                         LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
     799            0 :                         SteamDensity = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
     800              :                         // SteamCoil(CoilNum)%MaxSteamVolFlowRate = DesCoilLoad/(SteamDensity * LatentHeatSteam)
     801              :                         //            CpWater  =  GetSpecificHeatGlycol('WATER',  &
     802              :                         //                                              TempSteamIn, &
     803              :                         //                                              PlantLoop(SteamCoil(CoilNum)%LoopNum)%FluidIndex, &
     804              :                         //                                             'SizeSteamCoil')
     805            0 :                         CpWater = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatSpecificHeat(state, TempSteamIn, 0.0, RoutineName);
     806              : 
     807            0 :                         state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate =
     808            0 :                             DesCoilLoad / (SteamDensity * (LatentHeatSteam + state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling * CpWater));
     809              :                         //             PlantSizData(PltSizSteamNum)%DeltaT*CPHW(PlantSizData(PltSizSteamNum)%ExitTemp)))
     810              :                     } else {
     811            0 :                         state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate = 0.0;
     812            0 :                         ShowWarningError(
     813            0 :                             state, format("The design coil load is zero for COIL:Heating:Steam {}", state.dataSteamCoils->SteamCoil(CoilNum).Name));
     814              :                     }
     815            0 :                     BaseSizer::reportSizerOutput(state,
     816              :                                                  "Coil:Heating:Steam",
     817            0 :                                                  state.dataSteamCoils->SteamCoil(CoilNum).Name,
     818              :                                                  "Maximum Steam Flow Rate [m3/s]",
     819            0 :                                                  state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate);
     820              :                 }
     821            0 :                 state.dataSize->DataDesicRegCoil = false; // reset all globals to 0 to ensure correct sizing for other child components
     822              :                 // Coil report, set fan info for airloopnum
     823              : 
     824            0 :                 if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum > 0) {
     825            0 :                     state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
     826              :                         state,
     827            0 :                         state.dataSteamCoils->SteamCoil(CoilNum).Name,
     828              :                         "Coil:Heating:Steam",
     829            0 :                         state.dataFans->fans(state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum)->Name,
     830            0 :                         state.dataFans->fans(state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum)->type,
     831            0 :                         state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum);
     832              :                 }
     833              : 
     834              :                 // if this is a zone coil
     835            1 :             } else if (state.dataSize->CurZoneEqNum > 0) {
     836            1 :                 CheckZoneSizing(state, "Coil:Heating:Steam", state.dataSteamCoils->SteamCoil(CoilNum).Name);
     837              :                 // autosize the coil steam volume flow rate if needed
     838            1 :                 if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == AutoSize) {
     839              :                     // if coil is part of a terminal unit just use the terminal unit value
     840            1 :                     if (state.dataSize->TermUnitSingDuct || state.dataSize->TermUnitPIU || state.dataSize->TermUnitIU) {
     841            0 :                         if (state.dataSize->CurTermUnitSizingNum > 0) {
     842            0 :                             state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate =
     843            0 :                                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).MaxSTVolFlow;
     844              :                         } else {
     845            0 :                             state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate = 0.0;
     846              :                         }
     847              :                         // if coil is part of a zonal unit, calc coil load to get hot Steam flow rate
     848            0 :                         DesCoilLoad = TermUnitSizing(state.dataSize->CurTermUnitSizingNum).DesHeatingLoad; // coil report
     849            0 :                         DesVolFlow = TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow *
     850            0 :                                      TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult; // coil report
     851              :                     } else {
     852            1 :                         CoilInTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp;
     853            1 :                         CoilOutTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).HeatDesTemp;
     854            1 :                         CoilOutHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).HeatDesHumRat;
     855            1 :                         DesMassFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatMassFlow;
     856            1 :                         DesVolFlow = DesMassFlow / RhoAirStd;
     857            1 :                         DesCoilLoad = PsyCpAirFnW(CoilOutHumRat) * DesMassFlow * (CoilOutTemp - CoilInTemp);
     858            1 :                         if (DesCoilLoad >= HVAC::SmallLoad) {
     859            1 :                             TempSteamIn = 100.0;
     860              :                             // RefrigIndex is set during GetInput for this module
     861            1 :                             EnthSteamInDry = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 1.0, RoutineName);
     862            1 :                             EnthSteamOutWet = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 0.0, RoutineName);
     863            1 :                             LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
     864            1 :                             SteamDensity = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
     865              :                             // SteamCoil(CoilNum)%MaxSteamVolFlowRate = DesCoilLoad/(SteamDensity * LatentHeatSteam)
     866              :                             //           CpWater  =  GetSpecificHeatGlycol('WATER',  &
     867              :                             //                                             TempSteamIn, &
     868              :                             //                                             PlantLoop(SteamCoil(CoilNum)%LoopNum)%FluidIndex, &
     869              :                             //                                            'SizeSteamCoil')
     870            1 :                             CpWater = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatSpecificHeat(state, TempSteamIn, 0.0, RoutineName);
     871              : 
     872            1 :                             state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate =
     873            1 :                                 DesCoilLoad / (SteamDensity * (LatentHeatSteam + state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling * CpWater));
     874              :                             //             PlantSizData(PltSizSteamNum)%DeltaT*CPHW(PlantSizData(PltSizSteamNum)%ExitTemp)))
     875              :                         } else {
     876            0 :                             state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate = 0.0;
     877              :                         }
     878              :                     }
     879              :                     // issue warning if hw coil has zero flow
     880            1 :                     if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == 0.0) {
     881            0 :                         ShowWarningError(
     882            0 :                             state, format("The design coil load is zero for COIL:Heating:Steam {}", state.dataSteamCoils->SteamCoil(CoilNum).Name));
     883            0 :                         ShowContinueError(state, "The autosize value for max Steam flow rate is zero");
     884              :                     }
     885            2 :                     BaseSizer::reportSizerOutput(state,
     886              :                                                  "Coil:Heating:Steam",
     887            1 :                                                  state.dataSteamCoils->SteamCoil(CoilNum).Name,
     888              :                                                  "Maximum Steam Flow Rate [m3/s]",
     889            1 :                                                  state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate);
     890              :                 }
     891              :             } // end zone coil ELSE - IF
     892              : 
     893              :         } else {
     894              :             // if there is no heating Plant Sizing object and autosizng was requested, issue an error message
     895            0 :             if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == AutoSize) {
     896            0 :                 ShowSevereError(state, "Autosizing of Steam coil requires a heating loop Sizing:Plant object");
     897            0 :                 ShowContinueError(state, format("Occurs in Steam coil object= {}", state.dataSteamCoils->SteamCoil(CoilNum).Name));
     898            0 :                 ErrorsFound = true;
     899              :             }
     900              :         } // end of heating Plant Sizing existence IF - ELSE
     901              : 
     902              :         // save the design Steam volumetric flow rate for use by the Steam loop sizing algorithms
     903            2 :         RegisterPlantCompDesignFlow(
     904            1 :             state, state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum, state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate);
     905              : 
     906            4 :         state.dataRptCoilSelection->coilSelectionReportObj->setCoilHeatingCapacity(state,
     907            1 :                                                                                    state.dataSteamCoils->SteamCoil(CoilNum).Name,
     908              :                                                                                    "Coil:Heating:Steam",
     909              :                                                                                    DesCoilLoad,
     910              :                                                                                    coilWasAutosized,
     911            1 :                                                                                    state.dataSize->CurSysNum,
     912            1 :                                                                                    state.dataSize->CurZoneEqNum,
     913            1 :                                                                                    state.dataSize->CurOASysNum,
     914              :                                                                                    0.0,
     915              :                                                                                    1.0,
     916              :                                                                                    -999.0,
     917              :                                                                                    -999.0);
     918            3 :         state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterFlowNodeNums(state,
     919            1 :                                                                                      state.dataSteamCoils->SteamCoil(CoilNum).Name,
     920              :                                                                                      "Coil:Heating:Steam",
     921            1 :                                                                                      state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate,
     922              :                                                                                      coilWasAutosized,
     923            1 :                                                                                      state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
     924            1 :                                                                                      state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
     925            1 :                                                                                      state.dataSteamCoils->SteamCoil(CoilNum).plantLoc.loopNum);
     926            3 :         state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterHeaterCapacityNodeNums(
     927              :             state,
     928            1 :             state.dataSteamCoils->SteamCoil(CoilNum).Name,
     929              :             "Coil:Heating:Steam",
     930              :             DesCoilLoad,
     931              :             coilWasAutosized,
     932            1 :             state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
     933            1 :             state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
     934            1 :             state.dataSteamCoils->SteamCoil(CoilNum).plantLoc.loopNum);
     935            3 :         state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntWaterTemp(
     936            1 :             state, state.dataSteamCoils->SteamCoil(CoilNum).Name, "Coil:Heating:Steam", TempSteamIn); // coil  report
     937            3 :         state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgWaterTemp(
     938              :             state,
     939            1 :             state.dataSteamCoils->SteamCoil(CoilNum).Name,
     940              :             "Coil:Heating:Steam",
     941            1 :             TempSteamIn - state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling); // coil report
     942            3 :         state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterDeltaT(
     943              :             state,
     944            1 :             state.dataSteamCoils->SteamCoil(CoilNum).Name,
     945              :             "Coil:Heating:Steam",
     946            1 :             state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling); // coil report
     947            1 :         state.dataSteamCoils->SteamCoil(CoilNum).DesCoilCapacity = DesCoilLoad;
     948            1 :         state.dataSteamCoils->SteamCoil(CoilNum).DesAirVolFlow = DesVolFlow;
     949            1 :         if (ErrorsFound) {
     950            0 :             ShowFatalError(state, "Preceding Steam coil sizing errors cause program termination");
     951              :         }
     952              : 
     953              :         // There is no standard rating for heating coils at this point, so fill with dummy flag values
     954            3 :         state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(state,
     955            1 :                                                                                    state.dataSteamCoils->SteamCoil(CoilNum).Name,
     956              :                                                                                    "Coil:Heating:Steam",
     957              :                                                                                    -999.0,
     958              :                                                                                    -999.0,
     959              :                                                                                    -999.0,
     960              :                                                                                    -999.0,
     961              :                                                                                    -999.0,
     962              :                                                                                    -999.0,
     963              :                                                                                    -999.0,
     964              :                                                                                    -999.0,
     965              :                                                                                    -999.0,
     966              :                                                                                    -999.0,
     967              :                                                                                    -999.0,
     968              :                                                                                    -999.0,
     969              :                                                                                    -999.0);
     970            1 :     }
     971              : 
     972              :     // End Initialization Section of the Module
     973              : 
     974              :     // Begin Algorithm Section of the Module
     975              : 
     976            3 :     void CalcSteamAirCoil(EnergyPlusData &state,
     977              :                           int const CoilNum,
     978              :                           Real64 const QCoilRequested, // requested coil load
     979              :                           Real64 &QCoilActual,         // coil load actually delivered
     980              :                           HVAC::FanOp const fanOp,     // fan operating mode
     981              :                           Real64 const PartLoadRatio   // part-load ratio of heating coil
     982              :     )
     983              :     {
     984              :         // SUBROUTINE INFORMATION:
     985              :         //   AUTHOR         Rahul Chillar
     986              :         //   DATE WRITTEN   Jan 2005
     987              :         //   MODIFIED       Sep. 2012, B. Griffith, add calls to SetComponentFlowRate for plant interactions
     988              :         //                  Jul. 2016, R. Zhang, Applied the coil supply air temperature sensor offset fault model
     989              :         //   RE-ENGINEERED  na
     990              : 
     991              :         // PURPOSE OF THIS SUBROUTINE:
     992              :         // Simple Steam to air heat exchanger which,
     993              :         // serves as an interface for distributing heat from boiler to zones.
     994              : 
     995              :         // METHODOLOGY EMPLOYED:
     996              :         // Steam coils are different, All of steam condenses in heat exchanger
     997              :         // Steam traps allow only water to leave the coil,the degree of subcooling
     998              :         // desired is input by the user, which is used to calculate water outlet temp.
     999              :         // Heat exchange is = Latent Heat + Sensible heat,coil effectivness is 1.0
    1000              : 
    1001              :         using HVAC::TempControlTol;
    1002              :         using PlantUtilities::SetComponentFlowRate;
    1003              : 
    1004              :         static constexpr std::string_view RoutineName("CalcSteamAirCoil");
    1005              :         static constexpr std::string_view RoutineNameSizeSteamCoil("SizeSteamCoil");
    1006              : 
    1007            3 :         Real64 SteamMassFlowRate(0.0);
    1008            3 :         Real64 AirMassFlow(0.0); // [kg/sec]
    1009            3 :         Real64 TempAirIn(0.0);   // [C]
    1010            3 :         Real64 TempAirOut(0.0);  // [C]
    1011            3 :         Real64 Win(0.0);
    1012            3 :         Real64 TempSteamIn(0.0);
    1013            3 :         Real64 TempWaterOut(0.0);
    1014            3 :         Real64 CapacitanceAir(0.0);
    1015            3 :         Real64 HeatingCoilLoad(0.0);
    1016            3 :         Real64 CoilPress(0.0);
    1017            3 :         Real64 EnthSteamInDry(0.0);
    1018            3 :         Real64 EnthSteamOutWet(0.0);
    1019            3 :         Real64 LatentHeatSteam(0.0);
    1020            3 :         Real64 SubcoolDeltaTemp(0.0);
    1021            3 :         Real64 TempSetPoint(0.0);
    1022            3 :         Real64 QCoilReq(0.0);
    1023            3 :         Real64 QCoilCap(0.0);
    1024            3 :         Real64 QSteamCoilMaxHT(0.0);
    1025            3 :         Real64 TempWaterAtmPress(0.0);
    1026            3 :         Real64 TempLoopOutToPump(0.0);
    1027            3 :         Real64 EnergyLossToEnvironment(0.0);
    1028            3 :         Real64 EnthCoilOutlet(0.0);
    1029            3 :         Real64 EnthPumpInlet(0.0);
    1030            3 :         Real64 EnthAtAtmPress(0.0);
    1031            3 :         Real64 CpWater(0.0);
    1032              : 
    1033            3 :         QCoilReq = QCoilRequested;
    1034            3 :         TempAirIn = state.dataSteamCoils->SteamCoil(CoilNum).InletAirTemp;
    1035            3 :         Win = state.dataSteamCoils->SteamCoil(CoilNum).InletAirHumRat;
    1036            3 :         TempSteamIn = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamTemp;
    1037            3 :         CoilPress = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamPress;
    1038            3 :         SubcoolDeltaTemp = state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling;
    1039            3 :         TempSetPoint = state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp;
    1040              : 
    1041              :         // If there is a fault of coil SAT Sensor
    1042            3 :         if (state.dataSteamCoils->SteamCoil(CoilNum).FaultyCoilSATFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    1043            0 :             (!state.dataGlobal->KickOffSimulation)) {
    1044              :             // calculate the sensor offset using fault information
    1045            0 :             int FaultIndex = state.dataSteamCoils->SteamCoil(CoilNum).FaultyCoilSATIndex;
    1046            0 :             state.dataSteamCoils->SteamCoil(CoilNum).FaultyCoilSATOffset =
    1047            0 :                 state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
    1048              :             // update the TempSetPoint
    1049            0 :             TempSetPoint -= state.dataSteamCoils->SteamCoil(CoilNum).FaultyCoilSATOffset;
    1050              :         }
    1051              : 
    1052              :         //  adjust mass flow rates for cycling fan cycling coil operation
    1053            3 :         if (fanOp == HVAC::FanOp::Cycling) {
    1054            0 :             if (PartLoadRatio > 0.0) {
    1055            0 :                 AirMassFlow = state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate / PartLoadRatio;
    1056            0 :                 SteamMassFlowRate = min(state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate / PartLoadRatio,
    1057            0 :                                         state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate);
    1058            0 :                 QCoilReq /= PartLoadRatio;
    1059              :             } else {
    1060            0 :                 AirMassFlow = 0.0;
    1061            0 :                 SteamMassFlowRate = 0.0;
    1062              :             }
    1063              :         } else {
    1064            3 :             AirMassFlow = state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate;
    1065            3 :             SteamMassFlowRate = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate;
    1066              :         }
    1067              : 
    1068            3 :         if (AirMassFlow > 0.0) { // If the coil is operating
    1069            2 :             CapacitanceAir = PsyCpAirFnW(Win) * AirMassFlow;
    1070              :         } else {
    1071            1 :             CapacitanceAir = 0.0;
    1072              :         }
    1073              : 
    1074              :         // If the coil is operating there should be some heating capacitance
    1075              :         //  across the coil, so do the simulation. If not set outlet to inlet and no load.
    1076              :         //  Also the coil has to be scheduled to be available
    1077              :         //  Control output to meet load QCoilReq. Load Controlled Coil.
    1078            3 :         switch (state.dataSteamCoils->SteamCoil(CoilNum).TypeOfCoil) {
    1079              : 
    1080            3 :         case CoilControlType::ZoneLoadControl:
    1081            4 :             if ((CapacitanceAir > 0.0) && ((state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate) > 0.0) &&
    1082            7 :                 (state.dataSteamCoils->SteamCoil(CoilNum).availSched->getCurrentVal() > 0.0 || state.dataSteamCoils->MySizeFlag(CoilNum)) &&
    1083              :                 (QCoilReq > 0.0)) {
    1084              : 
    1085              :                 // Steam heat exchangers would not have effectivness, since all of the steam is
    1086              :                 // converted to water and only then the steam trap allows it to leave the heat
    1087              :                 // exchanger, subsequently heat exchange is latent heat + subcooling.
    1088            2 :                 EnthSteamInDry = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 1.0, RoutineName);
    1089            2 :                 EnthSteamOutWet = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 0.0, RoutineName);
    1090              : 
    1091            2 :                 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
    1092              : 
    1093              :                 //          CpWater = GetSpecificHeatGlycol('WATER',  &
    1094              :                 //                                           TempSteamIn, &
    1095              :                 //                                           PlantLoop(SteamCoil(CoilNum)%LoopNum)%FluidIndex, &
    1096              :                 //                                           'CalcSteamAirCoil')
    1097              : 
    1098            2 :                 CpWater = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatSpecificHeat(state, TempSteamIn, 0.0, RoutineNameSizeSteamCoil);
    1099              : 
    1100              :                 // Max Heat Transfer
    1101            2 :                 QSteamCoilMaxHT = state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
    1102            2 :                 state.dataSteamCoils->SteamCoil(CoilNum).OperatingCapacity = QSteamCoilMaxHT;
    1103              : 
    1104              :                 // Determine the Max coil capacity and check for the same.
    1105            2 :                 if (QCoilReq > QSteamCoilMaxHT) {
    1106            1 :                     QCoilCap = QSteamCoilMaxHT;
    1107              :                 } else {
    1108            1 :                     QCoilCap = QCoilReq;
    1109              :                 }
    1110              : 
    1111              :                 // Steam Mass Flow Rate Required
    1112            2 :                 SteamMassFlowRate = QCoilCap / (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
    1113              : 
    1114            4 :                 SetComponentFlowRate(state,
    1115              :                                      SteamMassFlowRate,
    1116            2 :                                      state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
    1117            2 :                                      state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
    1118            2 :                                      state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
    1119              : 
    1120              :                 // recalculate if mass flow rate changed in previous call.
    1121            2 :                 QCoilCap = SteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
    1122              : 
    1123              :                 // In practice Sensible & Superheated heat transfer is negligible compared to latent part.
    1124              :                 // This is required for outlet water temperature, otherwise it will be saturation temperature.
    1125              :                 // Steam Trap drains off all the Water formed.
    1126              :                 // Here Degree of Subcooling is used to calculate hot water return temperature.
    1127              : 
    1128              :                 // Calculating Water outlet temperature
    1129            2 :                 TempWaterOut = TempSteamIn - SubcoolDeltaTemp;
    1130              : 
    1131              :                 // Total Heat Transfer to air
    1132            2 :                 HeatingCoilLoad = QCoilCap;
    1133              : 
    1134              :                 // Temperature of air at outlet
    1135            2 :                 TempAirOut = TempAirIn + QCoilCap / (AirMassFlow * PsyCpAirFnW(Win));
    1136              : 
    1137            2 :                 state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = SteamMassFlowRate;
    1138            2 :                 state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = SteamMassFlowRate;
    1139              : 
    1140              :                 //************************* Loop Losses *****************************
    1141              :                 // Loop pressure return considerations included in steam coil since the pipes are
    1142              :                 // perfect and do not account for losses.
    1143              :                 // Return water is condensate at atmoshperic pressure
    1144              :                 // Process is considered constant enthalpy expansion
    1145              :                 // No quality function in EnergyPlus hence no option left apart from
    1146              :                 // considering saturated state.
    1147              :                 //              StdBaroPress=101325
    1148              : 
    1149              :                 TempWaterAtmPress =
    1150            2 :                     state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatTemperature(state, state.dataEnvrn->StdBaroPress, RoutineName);
    1151              : 
    1152              :                 // Point 4 at atm - loop delta subcool during return journery back to pump
    1153            2 :                 TempLoopOutToPump = TempWaterAtmPress - state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn;
    1154              : 
    1155              :                 // Actual Steam Coil Outlet Enthalpy
    1156            2 :                 EnthCoilOutlet =
    1157            2 :                     state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 0.0, RoutineName) - CpWater * SubcoolDeltaTemp;
    1158              : 
    1159              :                 // Enthalpy at Point 4
    1160            2 :                 EnthAtAtmPress = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempWaterAtmPress, 0.0, RoutineName);
    1161              : 
    1162              :                 // Reported value of coil outlet enthalpy at the node to match the node outlet temperature
    1163            2 :                 CpWater = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatSpecificHeat(state, TempLoopOutToPump, 0.0, RoutineNameSizeSteamCoil);
    1164              : 
    1165            2 :                 EnthPumpInlet = EnthAtAtmPress - CpWater * state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn;
    1166              : 
    1167            2 :                 state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = EnthPumpInlet;
    1168              : 
    1169              :                 // Point 3-Point 5,
    1170            2 :                 EnergyLossToEnvironment = SteamMassFlowRate * (EnthCoilOutlet - EnthPumpInlet);
    1171              : 
    1172              :                 // Loss to enviornment due to pressure drop
    1173            2 :                 state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = EnergyLossToEnvironment;
    1174              :                 //************************* Loop Losses *****************************
    1175              :             } else { // Coil is not running.
    1176              : 
    1177            1 :                 TempAirOut = TempAirIn;
    1178            1 :                 TempWaterOut = TempSteamIn;
    1179            1 :                 HeatingCoilLoad = 0.0;
    1180            1 :                 state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy;
    1181            1 :                 state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = 0.0;
    1182            1 :                 state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality = 0.0;
    1183            1 :                 state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = 0.0;
    1184            1 :                 TempLoopOutToPump = TempWaterOut;
    1185              :             }
    1186            3 :             break;
    1187            0 :         case CoilControlType::TemperatureSetPoint:
    1188              :             // Control coil output to meet a Setpoint Temperature.
    1189            0 :             if ((CapacitanceAir > 0.0) && ((state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate) > 0.0) &&
    1190            0 :                 (state.dataSteamCoils->SteamCoil(CoilNum).availSched->getCurrentVal() > 0.0 || state.dataSteamCoils->MySizeFlag(CoilNum)) &&
    1191            0 :                 (std::abs(TempSetPoint - TempAirIn) > TempControlTol)) {
    1192              : 
    1193              :                 // Steam heat exchangers would not have effectivness, since all of the steam is
    1194              :                 // converted to water and only then the steam trap allows it to leave the heat
    1195              :                 // exchanger, subsequently heat exchange is latent heat + subcooling.
    1196            0 :                 EnthSteamInDry = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 1.0, RoutineName);
    1197            0 :                 EnthSteamOutWet = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 0.0, RoutineName);
    1198            0 :                 LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
    1199              : 
    1200              :                 //          CpWater = GetSpecificHeatGlycol('WATER',  &
    1201              :                 //                                           TempSteamIn, &
    1202              :                 //                                           PlantLoop(SteamCoil(CoilNum)%LoopNum)%FluidIndex, &
    1203              :                 //                                           'CalcSteamAirCoil')
    1204            0 :                 CpWater = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatSpecificHeat(state, TempSteamIn, 0.0, RoutineNameSizeSteamCoil);
    1205              : 
    1206              :                 // Max Heat Transfer
    1207            0 :                 QSteamCoilMaxHT = state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
    1208              : 
    1209              :                 // Coil Load in case of temperature setpoint
    1210            0 :                 QCoilCap = CapacitanceAir * (TempSetPoint - TempAirIn);
    1211              : 
    1212              :                 // Check to see if setpoint above enetering temperature. If not, set
    1213              :                 // output to zero.
    1214            0 :                 if (QCoilCap <= 0.0) {
    1215            0 :                     QCoilCap = 0.0;
    1216            0 :                     TempAirOut = TempAirIn;
    1217              : 
    1218              :                     // Steam Mass Flow Rate Required
    1219            0 :                     SteamMassFlowRate = 0.0;
    1220            0 :                     SetComponentFlowRate(state,
    1221              :                                          SteamMassFlowRate,
    1222            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
    1223            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
    1224            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
    1225              :                     // Inlet equal to outlet when not required to run.
    1226            0 :                     TempWaterOut = TempSteamIn;
    1227              : 
    1228              :                     // Total Heat Transfer to air
    1229            0 :                     HeatingCoilLoad = QCoilCap;
    1230              : 
    1231              :                     // The HeatingCoilLoad is the change in the enthalpy of the water
    1232            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy;
    1233              : 
    1234              :                     // Outlet flow rate set to inlet
    1235            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = SteamMassFlowRate;
    1236            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = SteamMassFlowRate;
    1237              : 
    1238            0 :                 } else if (QCoilCap > QSteamCoilMaxHT) {
    1239              :                     // Setting to Maximum Coil Capacity
    1240            0 :                     QCoilCap = QSteamCoilMaxHT;
    1241              : 
    1242              :                     // Temperature of air at outlet
    1243            0 :                     TempAirOut = TempAirIn + QCoilCap / (AirMassFlow * PsyCpAirFnW(Win));
    1244              : 
    1245              :                     // In practice Sensible & Superheated heat transfer is negligible compared to latent part.
    1246              :                     // This is required for outlet water temperature, otherwise it will be saturation temperature.
    1247              :                     // Steam Trap drains off all the Water formed.
    1248              :                     // Here Degree of Subcooling is used to calculate hot water return temperature.
    1249              : 
    1250              :                     // Calculating Water outlet temperature
    1251            0 :                     TempWaterOut = TempSteamIn - SubcoolDeltaTemp;
    1252              : 
    1253              :                     // Steam Mass Flow Rate Required
    1254            0 :                     SteamMassFlowRate = QCoilCap / (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
    1255            0 :                     SetComponentFlowRate(state,
    1256              :                                          SteamMassFlowRate,
    1257            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
    1258            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
    1259            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
    1260              : 
    1261              :                     // recalculate in case previous call changed mass flow rate
    1262            0 :                     QCoilCap = SteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
    1263            0 :                     TempAirOut = TempAirIn + QCoilCap / (AirMassFlow * PsyCpAirFnW(Win));
    1264              : 
    1265              :                     // Total Heat Transfer to air
    1266            0 :                     HeatingCoilLoad = QCoilCap;
    1267              : 
    1268              :                     // The HeatingCoilLoad is the change in the enthalpy of the water
    1269            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy =
    1270            0 :                         state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy - HeatingCoilLoad / SteamMassFlowRate;
    1271            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = SteamMassFlowRate;
    1272            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = SteamMassFlowRate;
    1273              : 
    1274              :                 } else {
    1275              :                     // Temp air out is temperature Setpoint
    1276            0 :                     TempAirOut = TempSetPoint;
    1277              : 
    1278              :                     // In practice Sensible & Superheated heat transfer is negligible compared to latent part.
    1279              :                     // This is required for outlet water temperature, otherwise it will be saturation temperature.
    1280              :                     // Steam Trap drains off all the Water formed.
    1281              :                     // Here Degree of Subcooling is used to calculate hot water return temperature.
    1282              : 
    1283              :                     // Calculating Water outlet temperature
    1284            0 :                     TempWaterOut = TempSteamIn - SubcoolDeltaTemp;
    1285              : 
    1286              :                     // Steam Mass Flow Rate Required
    1287            0 :                     SteamMassFlowRate = QCoilCap / (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
    1288            0 :                     SetComponentFlowRate(state,
    1289              :                                          SteamMassFlowRate,
    1290            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
    1291            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
    1292            0 :                                          state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
    1293              : 
    1294              :                     // recalculate in case previous call changed mass flow rate
    1295            0 :                     QCoilCap = SteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
    1296            0 :                     TempAirOut = TempAirIn + QCoilCap / (AirMassFlow * PsyCpAirFnW(Win));
    1297              : 
    1298              :                     // Total Heat Transfer to air
    1299            0 :                     HeatingCoilLoad = QCoilCap;
    1300              : 
    1301            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = SteamMassFlowRate;
    1302            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = SteamMassFlowRate;
    1303              : 
    1304              :                     //************************* Loop Losses *****************************
    1305              :                     // Loop pressure return considerations included in steam coil since the pipes are
    1306              :                     // perfect and do not account for losses.
    1307              : 
    1308              :                     // Return water is condensate at atmoshperic pressure
    1309              :                     // Process is considered constant enthalpy expansion
    1310              :                     // No quality function in EnergyPlus hence no option left apart from
    1311              :                     // considering saturated state.
    1312              :                     //              StdBaroPress=101325
    1313              : 
    1314              :                     TempWaterAtmPress =
    1315            0 :                         state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatTemperature(state, state.dataEnvrn->StdBaroPress, RoutineName);
    1316              : 
    1317              :                     // Point 4 at atm - loop delta subcool during return journery back to pump
    1318            0 :                     TempLoopOutToPump = TempWaterAtmPress - state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn;
    1319              : 
    1320              :                     // Actual Steam Coil Outlet Enthalpy
    1321            0 :                     EnthCoilOutlet = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempSteamIn, 0.0, RoutineName) -
    1322            0 :                                      CpWater * SubcoolDeltaTemp;
    1323              : 
    1324              :                     // Enthalpy at Point 4
    1325            0 :                     EnthAtAtmPress = state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatEnthalpy(state, TempWaterAtmPress, 0.0, RoutineName);
    1326              : 
    1327              :                     CpWater =
    1328            0 :                         state.dataSteamCoils->SteamCoil(CoilNum).steam->getSatSpecificHeat(state, TempLoopOutToPump, 0.0, RoutineNameSizeSteamCoil);
    1329              : 
    1330              :                     // Reported value of coil outlet enthalpy at the node to match the node outlet temperature
    1331            0 :                     EnthPumpInlet = EnthAtAtmPress - CpWater * state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn;
    1332              : 
    1333            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = EnthPumpInlet;
    1334              : 
    1335              :                     // Point 3-Point 5,
    1336            0 :                     EnergyLossToEnvironment = SteamMassFlowRate * (EnthCoilOutlet - EnthPumpInlet);
    1337              : 
    1338              :                     // Loss to enviornment due to pressure drop
    1339            0 :                     state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = EnergyLossToEnvironment;
    1340              :                     //************************* Loop Losses *****************************
    1341              :                 }
    1342              : 
    1343              :             } else { // If not running Conditions do not change across coil from inlet to outlet
    1344            0 :                 SteamMassFlowRate = 0.0;
    1345            0 :                 SetComponentFlowRate(state,
    1346              :                                      SteamMassFlowRate,
    1347            0 :                                      state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
    1348            0 :                                      state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
    1349            0 :                                      state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
    1350            0 :                 TempAirOut = TempAirIn;
    1351            0 :                 TempWaterOut = TempSteamIn;
    1352            0 :                 HeatingCoilLoad = 0.0;
    1353            0 :                 state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy;
    1354            0 :                 state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = 0.0;
    1355            0 :                 state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality = 0.0;
    1356            0 :                 state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = 0.0;
    1357            0 :                 TempLoopOutToPump = TempWaterOut;
    1358              :             }
    1359            0 :             break;
    1360            0 :         default:
    1361            0 :             assert(false);
    1362              :         }
    1363              : 
    1364            3 :         if (fanOp == HVAC::FanOp::Cycling) {
    1365            0 :             HeatingCoilLoad *= PartLoadRatio;
    1366              :         }
    1367              : 
    1368              :         // Set the outlet conditions
    1369            3 :         state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate = HeatingCoilLoad;
    1370            3 :         state.dataSteamCoils->SteamCoil(CoilNum).OutletAirTemp = TempAirOut;
    1371            3 :         state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamTemp = TempLoopOutToPump;
    1372            3 :         state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality = 0.0;
    1373            3 :         QCoilActual = HeatingCoilLoad;
    1374              : 
    1375              :         // This SteamCoil does not change the moisture or Mass Flow across the component
    1376            3 :         state.dataSteamCoils->SteamCoil(CoilNum).OutletAirHumRat = state.dataSteamCoils->SteamCoil(CoilNum).InletAirHumRat;
    1377            3 :         state.dataSteamCoils->SteamCoil(CoilNum).OutletAirMassFlowRate = state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate;
    1378              :         // Set the outlet enthalpys for air and water
    1379            3 :         state.dataSteamCoils->SteamCoil(CoilNum).OutletAirEnthalpy =
    1380            3 :             PsyHFnTdbW(state.dataSteamCoils->SteamCoil(CoilNum).OutletAirTemp, state.dataSteamCoils->SteamCoil(CoilNum).OutletAirHumRat);
    1381            3 :     }
    1382              : 
    1383              :     // Beginning of Update subroutines for the SteamCoil Module
    1384              : 
    1385            3 :     void UpdateSteamCoil(EnergyPlusData &state, int const CoilNum)
    1386              :     {
    1387              :         // SUBROUTINE INFORMATION:
    1388              :         //   AUTHOR         Rahul Chillar
    1389              :         //   DATE WRITTEN   Jan 2005
    1390              :         //   MODIFIED       na
    1391              :         //   RE-ENGINEERED  na
    1392              : 
    1393              :         // PURPOSE OF THIS SUBROUTINE:
    1394              :         // This subroutine updates the coil outlet nodes.
    1395              : 
    1396              :         // METHODOLOGY EMPLOYED:
    1397              :         // Data is moved from the coil data structure to the coil outlet nodes.
    1398              : 
    1399              :         using PlantUtilities::SafeCopyPlantNode;
    1400              : 
    1401              :         int AirInletNode;
    1402              :         int SteamInletNode;
    1403              :         int AirOutletNode;
    1404              :         int SteamOutletNode;
    1405              : 
    1406            3 :         AirInletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirInletNodeNum;
    1407            3 :         SteamInletNode = state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum;
    1408            3 :         AirOutletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirOutletNodeNum;
    1409            3 :         SteamOutletNode = state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum;
    1410              : 
    1411              :         // Set the outlet air nodes of the SteamCoil
    1412            3 :         state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = state.dataSteamCoils->SteamCoil(CoilNum).OutletAirMassFlowRate;
    1413            3 :         state.dataLoopNodes->Node(AirOutletNode).Temp = state.dataSteamCoils->SteamCoil(CoilNum).OutletAirTemp;
    1414            3 :         state.dataLoopNodes->Node(AirOutletNode).HumRat = state.dataSteamCoils->SteamCoil(CoilNum).OutletAirHumRat;
    1415            3 :         state.dataLoopNodes->Node(AirOutletNode).Enthalpy = state.dataSteamCoils->SteamCoil(CoilNum).OutletAirEnthalpy;
    1416              : 
    1417            3 :         SafeCopyPlantNode(state, SteamInletNode, SteamOutletNode);
    1418              : 
    1419              :         // Set the outlet Steam nodes for the Coil
    1420              :         //   Node(SteamOutletNode)%MassFlowRate = SteamCoil(CoilNum)%OutletSteamMassFlowRate
    1421            3 :         state.dataLoopNodes->Node(SteamOutletNode).Temp = state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamTemp;
    1422            3 :         state.dataLoopNodes->Node(SteamOutletNode).Enthalpy = state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy;
    1423            3 :         state.dataLoopNodes->Node(SteamOutletNode).Quality = state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality;
    1424              :         // Node(SteamInletNode)%MassFlowRate  = SteamCoil(CoilNum)%OutletSteamMassFlowRate
    1425              : 
    1426              :         // Set the outlet nodes for properties that just pass through & not used
    1427            3 :         state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
    1428            3 :         state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
    1429            3 :         state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
    1430            3 :         state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
    1431            3 :         state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
    1432            3 :         state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
    1433              : 
    1434              :         // Set the outlet nodes for properties that just pass through & not used
    1435              : 
    1436              :         // Node(SteamOutletNode)%Press              = Node(SteamInletNode)%Press
    1437              :         //   Node(SteamOutletNode)%Press               = StdBaroPress  ! Water out at atm pressure
    1438              :         //   Node(SteamOutletNode)%HumRat              = Node(SteamInletNode)%HumRat
    1439              :         //   Node(SteamOutletNode)%MassFlowRateMin     = Node(SteamInletNode)%MassFlowRateMin
    1440              :         //   Node(SteamOutletNode)%MassFlowRateMax     = Node(SteamInletNode)%MassFlowRateMax
    1441              :         //   Node(SteamOutletNode)%MassFlowRateMinAvail= Node(SteamInletNode)%MassFlowRateMinAvail
    1442              :         //   Node(SteamOutletNode)%MassFlowRateMaxAvail= Node(SteamInletNode)%MassFlowRateMaxAvail
    1443              : 
    1444              :         //   IF (SteamCoil(CoilNum)%InletSteamMassFlowRate.EQ.0.0) THEN
    1445              :         //     Node(SteamInletNode)%MassFlowRate         = 0.0
    1446              :         //     Node(SteamInletNode)%MassFlowRateMinAvail = 0.0
    1447              :         //     Node(SteamOutletNode)%MassFlowRateMinAvail= 0.0
    1448              :         //   END IF
    1449              : 
    1450            3 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1451            0 :             state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
    1452              :         }
    1453            3 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    1454            0 :             state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
    1455              :         }
    1456            3 :     }
    1457              : 
    1458              :     // End of Update subroutines for the SteamCoil Module
    1459              : 
    1460              :     // Beginning of Reporting subroutines for the SteamCoil Module
    1461              : 
    1462            3 :     void ReportSteamCoil(EnergyPlusData &state, int const CoilNum)
    1463              :     {
    1464              :         // SUBROUTINE INFORMATION:
    1465              :         //   AUTHOR         Rahul Chillar
    1466              :         //   DATE WRITTEN   Jan 2005
    1467              :         //   MODIFIED       na
    1468              :         //   RE-ENGINEERED  na
    1469              : 
    1470              :         // PURPOSE OF THIS SUBROUTINE:
    1471              :         // This subroutine updates the report variable for the coils.
    1472              : 
    1473              :         // Report the SteamCoil energy from this component
    1474            3 :         state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilEnergy =
    1475            3 :             state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate * state.dataHVACGlobal->TimeStepSysSec;
    1476            3 :     }
    1477              : 
    1478              :     // End of Reporting subroutines for the SteamCoil Module
    1479              : 
    1480              :     // Utility subroutines for the SteamCoil Module
    1481              : 
    1482            2 :     int GetSteamCoilIndex(EnergyPlusData &state,
    1483              :                           std::string_view CoilType,   // must match coil types in this module
    1484              :                           std::string const &CoilName, // must match coil names for the coil type
    1485              :                           bool &ErrorsFound            // set to true if problem
    1486              :     )
    1487              :     {
    1488              : 
    1489              :         // FUNCTION INFORMATION:
    1490              :         //       AUTHOR         R. Raustad
    1491              :         //       DATE WRITTEN   August 2007
    1492              :         //       MODIFIED       na
    1493              :         //       RE-ENGINEERED  na
    1494              : 
    1495              :         // PURPOSE OF THIS FUNCTION:
    1496              :         // This function looks up the index for the given coil and returns it.  If
    1497              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1498              :         // as zero.
    1499              : 
    1500              :         // Return value
    1501              :         int IndexNum; // returned air inlet node number of matched coil
    1502              : 
    1503              :         // Obtains and Allocates SteamCoil related parameters from input file
    1504            2 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1505            2 :             GetSteamCoilInput(state);
    1506            2 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1507              :         }
    1508              : 
    1509            2 :         if (CoilType == "COIL:HEATING:STEAM") {
    1510            2 :             IndexNum = Util::FindItemInList(CoilName, state.dataSteamCoils->SteamCoil);
    1511              :         } else {
    1512            0 :             IndexNum = 0;
    1513              :         }
    1514              : 
    1515            2 :         if (IndexNum == 0) {
    1516            0 :             ShowSevereError(state, format(R"(GetSteamCoilIndex: Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
    1517            0 :             ErrorsFound = true;
    1518              :         }
    1519              : 
    1520            2 :         return IndexNum;
    1521              :     }
    1522              : 
    1523            0 :     int GetCompIndex(EnergyPlusData &state, std::string_view const coilName)
    1524              :     {
    1525            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1526            0 :             GetSteamCoilInput(state);
    1527            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1528              :         }
    1529              : 
    1530            0 :         int indexNum = Util::FindItemInList(coilName, state.dataSteamCoils->SteamCoil);
    1531              : 
    1532            0 :         if (indexNum == 0) { // may not find coil name
    1533            0 :             ShowSevereError(state, format("GetSteamCoilIndex: Could not find CoilType = Coil:Heating:Steam with Name = \"{}\"", coilName));
    1534              :         }
    1535              : 
    1536            0 :         return indexNum;
    1537              :     }
    1538              : 
    1539            0 :     void CheckSteamCoilSchedule(
    1540              :         EnergyPlusData &state, [[maybe_unused]] std::string const &CompType, std::string_view CompName, Real64 &Value, int &CompIndex)
    1541              :     {
    1542              : 
    1543              :         // SUBROUTINE INFORMATION:
    1544              :         //       AUTHOR         Linda Lawrie
    1545              :         //       DATE WRITTEN   March 2006
    1546              :         //       MODIFIED       na
    1547              :         //       RE-ENGINEERED  na
    1548              : 
    1549              :         // PURPOSE OF THIS SUBROUTINE:
    1550              :         // Gets the correct schedule value for this coil
    1551              : 
    1552              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1553              :         int CoilNum;
    1554              : 
    1555              :         // Obtains and Allocates SteamCoil related parameters from input file
    1556            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1557            0 :             GetSteamCoilInput(state);
    1558            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1559              :         }
    1560              : 
    1561              :         // Find the correct Coil number
    1562            0 :         if (CompIndex == 0) {
    1563            0 :             CoilNum = Util::FindItemInList(CompName, state.dataSteamCoils->SteamCoil);
    1564            0 :             if (CoilNum == 0) {
    1565            0 :                 ShowFatalError(state, format("CheckSteamCoilSchedule: Coil not found={}", CompName));
    1566              :             }
    1567            0 :             CompIndex = CoilNum;
    1568            0 :             Value = state.dataSteamCoils->SteamCoil(CoilNum).availSched->getCurrentVal(); // not scheduled?
    1569              :         } else {
    1570            0 :             CoilNum = CompIndex;
    1571            0 :             if (CoilNum > state.dataSteamCoils->NumSteamCoils || CoilNum < 1) {
    1572            0 :                 ShowFatalError(state,
    1573            0 :                                format("SimulateSteamCoilComponents: Invalid CompIndex passed={}, Number of Steam Coils={}, Coil name={}",
    1574              :                                       CoilNum,
    1575            0 :                                       state.dataSteamCoils->NumSteamCoils,
    1576              :                                       CompName));
    1577              :             }
    1578            0 :             if (CompName != state.dataSteamCoils->SteamCoil(CoilNum).Name) {
    1579            0 :                 ShowFatalError(state,
    1580            0 :                                format("SimulateSteamCoilComponents: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
    1581              :                                       CoilNum,
    1582              :                                       CompName,
    1583            0 :                                       state.dataSteamCoils->SteamCoil(CoilNum).Name));
    1584              :             }
    1585            0 :             Value = state.dataSteamCoils->SteamCoil(CoilNum).availSched->getCurrentVal(); // not scheduled?
    1586              :         }
    1587            0 :     }
    1588              : 
    1589            0 :     Real64 GetCoilMaxWaterFlowRate(EnergyPlusData &state,
    1590              :                                    std::string const &CoilType, // must match coil types in this module
    1591              :                                    std::string const &CoilName, // must match coil names for the coil type
    1592              :                                    bool &ErrorsFound            // set to true if problem
    1593              :     )
    1594              :     {
    1595              : 
    1596              :         // FUNCTION INFORMATION:
    1597              :         //       AUTHOR         Linda Lawrie
    1598              :         //       DATE WRITTEN   November 2006
    1599              :         //       MODIFIED       na
    1600              :         //       RE-ENGINEERED  na
    1601              : 
    1602              :         // PURPOSE OF THIS FUNCTION:
    1603              :         // This function looks up the max water flow rate for the given coil and returns it.  If
    1604              :         // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
    1605              :         // as negative.
    1606              : 
    1607              :         // Return value
    1608              :         Real64 MaxWaterFlowRate; // returned max water flow rate of matched coil
    1609              : 
    1610              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    1611              :         int WhichCoil;
    1612              : 
    1613              :         // Obtains and Allocates SteamCoil related parameters from input file
    1614            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1615            0 :             GetSteamCoilInput(state);
    1616            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1617              :         }
    1618              : 
    1619            0 :         if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
    1620            0 :             WhichCoil = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
    1621            0 :             if (WhichCoil != 0) {
    1622              :                 // coil does not specify MaxWaterFlowRate
    1623            0 :                 MaxWaterFlowRate = 0.0;
    1624            0 :                 ShowRecurringWarningErrorAtEnd(state, "Requested Max Water Flow Rate from COIL:Heating:Steam N/A", state.dataSteamCoils->ErrCount);
    1625              :             }
    1626              :         } else {
    1627            0 :             WhichCoil = 0;
    1628              :         }
    1629              : 
    1630            0 :         if (WhichCoil == 0) {
    1631            0 :             ShowSevereError(state, format("GetCoilMaxWaterFlowRate: Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
    1632            0 :             ErrorsFound = true;
    1633            0 :             MaxWaterFlowRate = -1000.0;
    1634              :         }
    1635              : 
    1636            0 :         return MaxWaterFlowRate;
    1637              :     }
    1638              : 
    1639            3 :     Real64 GetCoilMaxSteamFlowRate(EnergyPlusData &state,
    1640              :                                    int const CoilIndex, // must match coil types in this module
    1641              :                                    bool &ErrorsFound    // set to true if problem
    1642              :     )
    1643              :     {
    1644              : 
    1645              :         // FUNCTION INFORMATION:
    1646              :         //       AUTHOR         R. Raustad
    1647              :         //       DATE WRITTEN   August 2007
    1648              :         //       MODIFIED       na
    1649              :         //       RE-ENGINEERED  na
    1650              : 
    1651              :         // PURPOSE OF THIS FUNCTION:
    1652              :         // This function looks up the max steam flow rate for the given coil and returns it.  If
    1653              :         // incorrect coil type or name is given, ErrorsFound is returned as true and flow rate is returned
    1654              :         // as zero.
    1655              : 
    1656              :         // Return value
    1657              :         Real64 MaxSteamFlowRate; // returned max steam flow rate of matched coil
    1658              : 
    1659              :         // Obtains and Allocates SteamCoil related parameters from input file
    1660            3 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1661            0 :             GetSteamCoilInput(state);
    1662            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1663              :         }
    1664              : 
    1665            3 :         if (CoilIndex == 0) {
    1666            0 :             ShowSevereError(state, "GetCoilMaxSteamFlowRate: Could not find CoilType = \"Coil:Heating:Steam\"");
    1667            0 :             ErrorsFound = true;
    1668            0 :             MaxSteamFlowRate = 0.0;
    1669              :         } else {
    1670            3 :             MaxSteamFlowRate = state.dataSteamCoils->SteamCoil(CoilIndex).MaxSteamVolFlowRate;
    1671              :         }
    1672              : 
    1673            3 :         return MaxSteamFlowRate;
    1674              :     }
    1675              : 
    1676            2 :     int GetCoilAirInletNode(EnergyPlusData &state,
    1677              :                             int const CoilIndex,         // must match coil types in this module
    1678              :                             std::string const &CoilName, // must match coil names for the coil type
    1679              :                             bool &ErrorsFound            // set to true if problem
    1680              :     )
    1681              :     {
    1682              : 
    1683              :         // FUNCTION INFORMATION:
    1684              :         //       AUTHOR         R. Raustad
    1685              :         //       DATE WRITTEN   July 2007
    1686              :         //       MODIFIED       na
    1687              :         //       RE-ENGINEERED  na
    1688              : 
    1689              :         // PURPOSE OF THIS FUNCTION:
    1690              :         // This function looks up the air inlet node number for the given coil and returns it.  If
    1691              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1692              :         // as zero.
    1693              : 
    1694              :         // Return value
    1695              :         int NodeNumber; // returned air inlet node number of matched coil
    1696              : 
    1697              :         // Obtains and Allocates SteamCoil related parameters from input file
    1698            2 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1699            0 :             GetSteamCoilInput(state);
    1700            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1701              :         }
    1702              : 
    1703            2 :         if (CoilIndex == 0) {
    1704            0 :             ShowSevereError(state, format("GetCoilAirInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
    1705            0 :             ErrorsFound = true;
    1706            0 :             NodeNumber = 0;
    1707              :         } else {
    1708            2 :             NodeNumber = state.dataSteamCoils->SteamCoil(CoilIndex).AirInletNodeNum;
    1709              :         }
    1710              : 
    1711            2 :         return NodeNumber;
    1712              :     }
    1713              : 
    1714            2 :     int GetCoilAirOutletNode(EnergyPlusData &state,
    1715              :                              int const CoilIndex,         // must match coil types in this module
    1716              :                              std::string const &CoilName, // must match coil names for the coil type
    1717              :                              bool &ErrorsFound            // set to true if problem
    1718              :     )
    1719              :     {
    1720              : 
    1721              :         // FUNCTION INFORMATION:
    1722              :         //       AUTHOR         R. Raustad
    1723              :         //       DATE WRITTEN   July 2007
    1724              :         //       MODIFIED       na
    1725              :         //       RE-ENGINEERED  na
    1726              : 
    1727              :         // PURPOSE OF THIS FUNCTION:
    1728              :         // This function looks up the air outlet node number for the given coil and returns it.  If
    1729              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1730              :         // as zero.
    1731              : 
    1732              :         // METHODOLOGY EMPLOYED:
    1733              :         // na
    1734              : 
    1735              :         // REFERENCES:
    1736              :         // na
    1737              : 
    1738              :         // USE STATEMENTS:
    1739              :         // na
    1740              : 
    1741              :         // Return value
    1742              :         int NodeNumber; // returned air inlet node number of matched coil
    1743              : 
    1744              :         // Obtains and Allocates SteamCoil related parameters from input file
    1745            2 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1746            0 :             GetSteamCoilInput(state);
    1747            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1748              :         }
    1749              : 
    1750            2 :         if (CoilIndex == 0) {
    1751            0 :             ShowSevereError(state, format("GetCoilAirOutletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
    1752            0 :             ErrorsFound = true;
    1753            0 :             NodeNumber = 0;
    1754              :         } else {
    1755            2 :             NodeNumber = state.dataSteamCoils->SteamCoil(CoilIndex).AirOutletNodeNum;
    1756              :         }
    1757              : 
    1758            2 :         return NodeNumber;
    1759              :     }
    1760              : 
    1761            0 :     int GetCoilAirOutletNode(EnergyPlusData &state,
    1762              :                              std::string const &CoilType,       // must match coil types in this module
    1763              :                              std::string const &CoilName,       // must match coil names for the coil type
    1764              :                              [[maybe_unused]] bool &ErrorsFound // set to true if problem
    1765              :     )
    1766              :     {
    1767              : 
    1768              :         // FUNCTION INFORMATION:
    1769              :         //       AUTHOR         R. Raustad
    1770              :         //       DATE WRITTEN   July 2007
    1771              :         //       MODIFIED       na
    1772              :         //       RE-ENGINEERED  na
    1773              : 
    1774              :         // PURPOSE OF THIS FUNCTION:
    1775              :         // This function looks up the air outlet node number for the given coil and returns it.  If
    1776              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1777              :         // as zero.
    1778              : 
    1779              :         // Return value
    1780              :         int NodeNumber; // returned air inlet node number of matched coil
    1781              : 
    1782              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    1783              :         int IndexNum; // returned air inlet node number of matched coil
    1784              : 
    1785              :         // Obtains and Allocates SteamCoil related parameters from input file
    1786            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1787            0 :             GetSteamCoilInput(state);
    1788            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1789              :         }
    1790              : 
    1791            0 :         if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
    1792            0 :             IndexNum = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
    1793              :         } else {
    1794            0 :             IndexNum = 0;
    1795              :         }
    1796              : 
    1797            0 :         if (IndexNum == 0) {
    1798            0 :             NodeNumber = 0;
    1799              :         } else {
    1800            0 :             NodeNumber = state.dataSteamCoils->SteamCoil(IndexNum).AirOutletNodeNum;
    1801              :         }
    1802              : 
    1803            0 :         return NodeNumber;
    1804              :     }
    1805              : 
    1806            1 :     int GetCoilSteamInletNode(EnergyPlusData &state,
    1807              :                               int const CoilIndex,         // must match coil types in this module
    1808              :                               std::string const &CoilName, // must match coil names for the coil type
    1809              :                               bool &ErrorsFound            // set to true if problem
    1810              :     )
    1811              :     {
    1812              : 
    1813              :         // FUNCTION INFORMATION:
    1814              :         //       AUTHOR         R. Raustad
    1815              :         //       DATE WRITTEN   July 2007
    1816              :         //       MODIFIED       na
    1817              :         //       RE-ENGINEERED  na
    1818              : 
    1819              :         // PURPOSE OF THIS FUNCTION:
    1820              :         // This function looks up the steam inlet node number for the given coil and returns it.  If
    1821              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1822              :         // as zero.
    1823              : 
    1824              :         // Return value
    1825              :         int NodeNumber; // returned air inlet node number of matched coil
    1826              : 
    1827              :         // Obtains and Allocates SteamCoil related parameters from input file
    1828            1 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1829            0 :             GetSteamCoilInput(state);
    1830            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1831              :         }
    1832              : 
    1833            1 :         if (CoilIndex == 0) {
    1834            0 :             ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
    1835            0 :             ErrorsFound = true;
    1836            0 :             NodeNumber = 0;
    1837              :         } else {
    1838            1 :             NodeNumber = state.dataSteamCoils->SteamCoil(CoilIndex).SteamInletNodeNum;
    1839              :         }
    1840              : 
    1841            1 :         return NodeNumber;
    1842              :     }
    1843              : 
    1844            1 :     int GetCoilSteamInletNode(EnergyPlusData &state,
    1845              :                               std::string const &CoilType, // must match coil types in this module
    1846              :                               std::string const &CoilName, // must match coil names for the coil type
    1847              :                               bool &ErrorsFound            // set to true if problem
    1848              :     )
    1849              :     {
    1850              : 
    1851              :         // FUNCTION INFORMATION:
    1852              :         //       AUTHOR         L. Lawrie (based on R. Raustad)
    1853              :         //       DATE WRITTEN   June 2008
    1854              :         //       MODIFIED       na
    1855              :         //       RE-ENGINEERED  na
    1856              : 
    1857              :         // PURPOSE OF THIS FUNCTION:
    1858              :         // This function looks up the steam inlet node number for the given coil and returns it.  If
    1859              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1860              :         // as zero.
    1861              : 
    1862              :         // Return value
    1863              :         int NodeNumber; // returned air inlet node number of matched coil
    1864              : 
    1865              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    1866              :         int IndexNum; // returned air inlet node number of matched coil
    1867              : 
    1868              :         // Obtains and Allocates SteamCoil related parameters from input file
    1869            1 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1870            0 :             GetSteamCoilInput(state);
    1871            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1872              :         }
    1873              : 
    1874            1 :         if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
    1875            1 :             IndexNum = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
    1876              :         } else {
    1877            0 :             IndexNum = 0;
    1878              :         }
    1879              : 
    1880            1 :         if (IndexNum == 0) {
    1881            0 :             ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
    1882            0 :             ErrorsFound = true;
    1883            0 :             NodeNumber = 0;
    1884              :         } else {
    1885            1 :             NodeNumber = state.dataSteamCoils->SteamCoil(IndexNum).SteamInletNodeNum;
    1886              :         }
    1887              : 
    1888            1 :         return NodeNumber;
    1889              :     }
    1890              : 
    1891            0 :     int GetCoilSteamOutletNode(EnergyPlusData &state,
    1892              :                                int const CoilIndex,         // must match coil types in this module
    1893              :                                std::string const &CoilName, // must match coil names for the coil type
    1894              :                                bool &ErrorsFound            // set to true if problem
    1895              :     )
    1896              :     {
    1897              : 
    1898              :         // FUNCTION INFORMATION:
    1899              :         //       AUTHOR         R. Raustad
    1900              :         //       DATE WRITTEN   July 2007
    1901              :         //       MODIFIED       na
    1902              :         //       RE-ENGINEERED  na
    1903              : 
    1904              :         // PURPOSE OF THIS FUNCTION:
    1905              :         // This function looks up the steam inlet node number for the given coil and returns it.  If
    1906              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1907              :         // as zero.
    1908              : 
    1909              :         // Return value
    1910              :         int NodeNumber; // returned air inlet node number of matched coil
    1911              : 
    1912              :         // Obtains and Allocates SteamCoil related parameters from input file
    1913            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1914            0 :             GetSteamCoilInput(state);
    1915            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1916              :         }
    1917              : 
    1918            0 :         if (CoilIndex == 0) {
    1919            0 :             ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
    1920            0 :             ErrorsFound = true;
    1921            0 :             NodeNumber = 0;
    1922              :         } else {
    1923            0 :             NodeNumber = state.dataSteamCoils->SteamCoil(CoilIndex).SteamOutletNodeNum;
    1924              :         }
    1925              : 
    1926            0 :         return NodeNumber;
    1927              :     }
    1928              : 
    1929            1 :     int GetCoilSteamOutletNode(EnergyPlusData &state,
    1930              :                                std::string_view CoilType,   // must match coil types in this module
    1931              :                                std::string const &CoilName, // must match coil names for the coil type
    1932              :                                bool &ErrorsFound            // set to true if problem
    1933              :     )
    1934              :     {
    1935              : 
    1936              :         // FUNCTION INFORMATION:
    1937              :         //       AUTHOR         L. Lawrie (based on R. Raustad)
    1938              :         //       DATE WRITTEN   June 2008
    1939              :         //       MODIFIED       na
    1940              :         //       RE-ENGINEERED  na
    1941              : 
    1942              :         // PURPOSE OF THIS FUNCTION:
    1943              :         // This function looks up the steam inlet node number for the given coil and returns it.  If
    1944              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1945              :         // as zero.
    1946              : 
    1947              :         // Return value
    1948              :         int NodeNumber; // returned air inlet node number of matched coil
    1949              : 
    1950              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    1951              :         int IndexNum; // returned air inlet node number of matched coil
    1952              : 
    1953              :         // Obtains and Allocates SteamCoil related parameters from input file
    1954            1 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    1955            0 :             GetSteamCoilInput(state);
    1956            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    1957              :         }
    1958              : 
    1959            1 :         if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
    1960            1 :             IndexNum = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
    1961              :         } else {
    1962            0 :             IndexNum = 0;
    1963              :         }
    1964              : 
    1965            1 :         if (IndexNum == 0) {
    1966            0 :             ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
    1967            0 :             ErrorsFound = true;
    1968            0 :             NodeNumber = 0;
    1969              :         } else {
    1970            1 :             NodeNumber = state.dataSteamCoils->SteamCoil(IndexNum).SteamOutletNodeNum;
    1971              :         }
    1972              : 
    1973            1 :         return NodeNumber;
    1974              :     }
    1975              : 
    1976            0 :     Real64 GetCoilCapacity(EnergyPlusData &state,
    1977              :                            std::string const &CoilType, // must match coil types in this module
    1978              :                            std::string const &CoilName, // must match coil names for the coil type
    1979              :                            bool &ErrorsFound            // set to true if problem
    1980              :     )
    1981              :     {
    1982              : 
    1983              :         // FUNCTION INFORMATION:
    1984              :         //       AUTHOR         R. Raustad
    1985              :         //       DATE WRITTEN   July 2007
    1986              :         //       MODIFIED       na
    1987              :         //       RE-ENGINEERED  na
    1988              : 
    1989              :         // PURPOSE OF THIS FUNCTION:
    1990              :         // This function looks up the steam coils operating capacity and returns it.  If
    1991              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    1992              :         // as zero.
    1993              : 
    1994              :         // Return value
    1995              :         Real64 Capacity; // returned operating capacity of matched coil (W)
    1996              : 
    1997              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    1998              :         int WhichCoil;
    1999              : 
    2000              :         // Obtains and Allocates SteamCoil related parameters from input file
    2001            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    2002            0 :             GetSteamCoilInput(state);
    2003            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    2004              :         }
    2005              : 
    2006            0 :         if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
    2007            0 :             WhichCoil = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
    2008            0 :             if (WhichCoil != 0) {
    2009              :                 // coil does not specify MaxWaterFlowRate
    2010            0 :                 Capacity = state.dataSteamCoils->SteamCoil(WhichCoil).OperatingCapacity;
    2011              :             }
    2012              :         } else {
    2013            0 :             WhichCoil = 0;
    2014              :         }
    2015              : 
    2016            0 :         if (WhichCoil == 0) {
    2017            0 :             ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
    2018            0 :             ErrorsFound = true;
    2019            0 :             Capacity = 0.0;
    2020              :         }
    2021              : 
    2022            0 :         return Capacity;
    2023              :     }
    2024              : 
    2025            0 :     CoilControlType GetTypeOfCoil(EnergyPlusData &state,
    2026              :                                   int const CoilIndex,         // must match coil types in this module
    2027              :                                   std::string const &CoilName, // must match coil names for the coil type
    2028              :                                   bool &ErrorsFound            // set to true if problem
    2029              :     )
    2030              :     {
    2031              : 
    2032              :         // FUNCTION INFORMATION:
    2033              :         //       AUTHOR         R. Raustad
    2034              :         //       DATE WRITTEN   July 2007
    2035              :         //       MODIFIED       na
    2036              :         //       RE-ENGINEERED  na
    2037              : 
    2038              :         // PURPOSE OF THIS FUNCTION:
    2039              :         // This function looks up the steam coils operating capacity and returns it.  If
    2040              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    2041              :         // as zero.
    2042              : 
    2043              :         // Obtains and Allocates SteamCoil related parameters from input file
    2044            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    2045            0 :             GetSteamCoilInput(state);
    2046            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    2047              :         }
    2048              : 
    2049            0 :         if (CoilIndex == 0) {
    2050            0 :             ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
    2051            0 :             ErrorsFound = true;
    2052            0 :             return CoilControlType::Invalid;
    2053              :         } else {
    2054            0 :             return state.dataSteamCoils->SteamCoil(CoilIndex).TypeOfCoil;
    2055              :         }
    2056              :     }
    2057              : 
    2058            0 :     int GetSteamCoilControlNodeNum(EnergyPlusData &state,
    2059              :                                    std::string const &CoilType, // must match coil types in this module
    2060              :                                    std::string const &CoilName, // must match coil names for the coil type
    2061              :                                    bool &ErrorFlag              // set to true if problem
    2062              :     )
    2063              :     {
    2064              : 
    2065              :         // FUNCTION INFORMATION:
    2066              :         //       AUTHOR         B. Nigusse, FSEC
    2067              :         //       DATE WRITTEN   January 2012
    2068              :         //       MODIFIED       na
    2069              :         //       RE-ENGINEERED  na
    2070              : 
    2071              :         // PURPOSE OF THIS FUNCTION:
    2072              :         // This function looks up the steam coils and returns the steam control node number.  If
    2073              :         // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    2074              :         // as zero.
    2075              : 
    2076              :         // Return value
    2077              :         int NodeNumber; // returned node number of matched coil
    2078              : 
    2079              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    2080              :         int WhichCoil;
    2081              : 
    2082              :         // Obtains and Allocates SteamCoil related parameters from input file
    2083            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    2084            0 :             GetSteamCoilInput(state);
    2085            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    2086              :         }
    2087              : 
    2088            0 :         WhichCoil = 0;
    2089            0 :         NodeNumber = 0;
    2090            0 :         if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
    2091            0 :             WhichCoil = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
    2092            0 :             if (WhichCoil != 0) {
    2093            0 :                 NodeNumber = state.dataSteamCoils->SteamCoil(WhichCoil).TempSetPointNodeNum;
    2094              :             }
    2095              :         } else {
    2096            0 :             WhichCoil = 0;
    2097              :         }
    2098              : 
    2099            0 :         if (WhichCoil == 0) {
    2100            0 :             ShowSevereError(state, format("GetSteamCoilControlNodeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    2101            0 :             ErrorFlag = true;
    2102            0 :             NodeNumber = 0;
    2103              :         }
    2104              : 
    2105            0 :         return NodeNumber;
    2106              :     }
    2107              : 
    2108            0 :     int GetSteamCoilAvailScheduleIndex(EnergyPlusData &state,
    2109              :                                        std::string const &CoilType, // must match coil types in this module
    2110              :                                        std::string const &CoilName, // must match coil names for the coil type
    2111              :                                        bool &ErrorsFound            // set to true if problem
    2112              :     )
    2113              :     {
    2114              : 
    2115              :         // FUNCTION INFORMATION:
    2116              :         //       AUTHOR         Chandan Sharma, FSEC
    2117              :         //       DATE WRITTEN   February 2013
    2118              :         //       MODIFIED       na
    2119              :         //       RE-ENGINEERED  na
    2120              : 
    2121              :         // PURPOSE OF THIS FUNCTION:
    2122              :         // This function looks up the given coil and returns the availability schedule index.  If
    2123              :         // incorrect coil type or name is given, ErrorsFound is returned as true and index is returned
    2124              :         // as zero.
    2125              : 
    2126              :         // Return value
    2127              :         int AvailSchIndex; // returned availability schedule of matched coil
    2128              : 
    2129              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    2130              :         int WhichCoil;
    2131              : 
    2132              :         // Obtains and Allocates HeatingCoil related parameters from input file
    2133            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
    2134            0 :             GetSteamCoilInput(state);
    2135            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    2136              :         }
    2137              : 
    2138            0 :         WhichCoil = 0;
    2139            0 :         AvailSchIndex = 0;
    2140              : 
    2141            0 :         if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
    2142            0 :             WhichCoil = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
    2143            0 :             if (WhichCoil != 0) {
    2144            0 :                 AvailSchIndex = state.dataSteamCoils->SteamCoil(WhichCoil).availSched->Num;
    2145              :             }
    2146              :         } else {
    2147            0 :             WhichCoil = 0;
    2148              :         }
    2149              : 
    2150            0 :         if (WhichCoil == 0) {
    2151            0 :             ShowSevereError(state, format("GetCoilAvailScheduleIndex: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    2152            0 :             ErrorsFound = true;
    2153            0 :             AvailSchIndex = 0;
    2154              :         }
    2155              : 
    2156            0 :         return AvailSchIndex;
    2157              :     }
    2158              : 
    2159            0 :     void SetSteamCoilData(EnergyPlusData &state,
    2160              :                           int const CoilNum,                                  // Number of hot water heating Coil
    2161              :                           bool &ErrorsFound,                                  // Set to true if certain errors found
    2162              :                           ObjexxFCL::Optional_bool DesiccantRegenerationCoil, // Flag that this coil is used as regeneration air heating coil
    2163              :                           ObjexxFCL::Optional_int DesiccantDehumIndex         // Index for the desiccant dehum system where this caoil is used
    2164              :     )
    2165              :     {
    2166              : 
    2167              :         // FUNCTION INFORMATION:
    2168              :         //       AUTHOR         Bereket Nigusse
    2169              :         //       DATE WRITTEN   February 2016
    2170              :         //       MODIFIED       na
    2171              :         //       RE-ENGINEERED  na
    2172              : 
    2173              :         // PURPOSE OF THIS FUNCTION:
    2174              :         // This function sets data to water Heating Coil using the coil index and arguments passed
    2175              : 
    2176            0 :         if (state.dataSteamCoils->GetSteamCoilsInputFlag) {
    2177            0 :             GetSteamCoilInput(state);
    2178            0 :             state.dataSteamCoils->GetSteamCoilsInputFlag = false;
    2179              :         }
    2180              : 
    2181            0 :         if (CoilNum <= 0 || CoilNum > state.dataSteamCoils->NumSteamCoils) {
    2182            0 :             ShowSevereError(state,
    2183            0 :                             format("SetHeatingCoilData: called with heating coil Number out of range={} should be >0 and <{}",
    2184              :                                    CoilNum,
    2185            0 :                                    state.dataSteamCoils->NumSteamCoils));
    2186            0 :             ErrorsFound = true;
    2187            0 :             return;
    2188              :         }
    2189              : 
    2190            0 :         if (present(DesiccantRegenerationCoil)) {
    2191            0 :             state.dataSteamCoils->SteamCoil(CoilNum).DesiccantRegenerationCoil = DesiccantRegenerationCoil;
    2192              :         }
    2193              : 
    2194            0 :         if (present(DesiccantDehumIndex)) {
    2195            0 :             state.dataSteamCoils->SteamCoil(CoilNum).DesiccantDehumNum = DesiccantDehumIndex;
    2196              :         }
    2197              :     }
    2198              :     // End of Utility subroutines for the SteamCoil Module
    2199              : 
    2200              : } // namespace SteamCoils
    2201              : 
    2202              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1