LCOV - code coverage report
Current view: top level - EnergyPlus - WaterCoils.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 2569 3188 80.6 %
Date: 2023-01-17 19:17:23 Functions: 39 44 88.6 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cmath>
      50             : 
      51             : // ObjexxFCL Headers
      52             : #include <ObjexxFCL/Array.functions.hh>
      53             : #include <ObjexxFCL/Fmath.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
      57             : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
      58             : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
      59             : #include <EnergyPlus/Autosizing/CoolingWaterDesAirInletHumRatSizing.hh>
      60             : #include <EnergyPlus/Autosizing/CoolingWaterDesAirInletTempSizing.hh>
      61             : #include <EnergyPlus/Autosizing/CoolingWaterDesAirOutletHumRatSizing.hh>
      62             : #include <EnergyPlus/Autosizing/CoolingWaterDesAirOutletTempSizing.hh>
      63             : #include <EnergyPlus/Autosizing/CoolingWaterDesWaterInletTempSizing.hh>
      64             : #include <EnergyPlus/Autosizing/CoolingWaterNumofTubesPerRowSizing.hh>
      65             : #include <EnergyPlus/Autosizing/CoolingWaterflowSizing.hh>
      66             : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
      67             : #include <EnergyPlus/Autosizing/HeatingAirflowUASizing.hh>
      68             : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
      69             : #include <EnergyPlus/Autosizing/HeatingWaterDesAirInletHumRatSizing.hh>
      70             : #include <EnergyPlus/Autosizing/HeatingWaterDesAirInletTempSizing.hh>
      71             : #include <EnergyPlus/Autosizing/HeatingWaterDesCoilLoadUsedForUASizing.hh>
      72             : #include <EnergyPlus/Autosizing/HeatingWaterDesCoilWaterVolFlowUsedForUASizing.hh>
      73             : #include <EnergyPlus/Autosizing/HeatingWaterflowSizing.hh>
      74             : #include <EnergyPlus/Autosizing/WaterHeatingCapacitySizing.hh>
      75             : #include <EnergyPlus/Autosizing/WaterHeatingCoilUASizing.hh>
      76             : #include <EnergyPlus/BranchNodeConnections.hh>
      77             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      78             : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      79             : #include <EnergyPlus/DataContaminantBalance.hh>
      80             : #include <EnergyPlus/DataEnvironment.hh>
      81             : #include <EnergyPlus/DataHVACGlobals.hh>
      82             : #include <EnergyPlus/DataIPShortCuts.hh>
      83             : #include <EnergyPlus/DataLoopNode.hh>
      84             : #include <EnergyPlus/DataSizing.hh>
      85             : #include <EnergyPlus/DataWater.hh>
      86             : #include <EnergyPlus/EMSManager.hh>
      87             : #include <EnergyPlus/FaultsManager.hh>
      88             : #include <EnergyPlus/FluidProperties.hh>
      89             : #include <EnergyPlus/General.hh>
      90             : #include <EnergyPlus/GeneralRoutines.hh>
      91             : #include <EnergyPlus/GlobalNames.hh>
      92             : #include <EnergyPlus/HVACControllers.hh>
      93             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      94             : #include <EnergyPlus/NodeInputManager.hh>
      95             : #include <EnergyPlus/OutputProcessor.hh>
      96             : #include <EnergyPlus/OutputReportPredefined.hh>
      97             : #include <EnergyPlus/Plant/DataPlant.hh>
      98             : #include <EnergyPlus/PlantUtilities.hh>
      99             : #include <EnergyPlus/Psychrometrics.hh>
     100             : #include <EnergyPlus/ReportCoilSelection.hh>
     101             : #include <EnergyPlus/ScheduleManager.hh>
     102             : #include <EnergyPlus/SetPointManager.hh>
     103             : #include <EnergyPlus/SimAirServingZones.hh>
     104             : #include <EnergyPlus/UtilityRoutines.hh>
     105             : #include <EnergyPlus/WaterCoils.hh>
     106             : #include <EnergyPlus/WaterManager.hh>
     107             : 
     108             : namespace EnergyPlus::WaterCoils {
     109             : // Module containing the WaterCoil simulation routines
     110             : 
     111             : // MODULE INFORMATION:
     112             : //       AUTHOR         Richard J. Liesen
     113             : //       DATE WRITTEN   April 1998
     114             : //       MODIFIED       April 2004: Rahul Chillar
     115             : //                      Feb. 2010, Brent Griffith, Plant Demand Side Update, general fluid properties
     116             : //       RE-ENGINEERED  na
     117             : 
     118             : // PURPOSE OF THIS MODULE:
     119             : // To encapsulate the data and algorithms required to
     120             : // manage the WaterCoil System Component
     121             : 
     122             : using namespace DataLoopNode;
     123             : using namespace DataHVACGlobals;
     124             : 
     125             : using FluidProperties::GetDensityGlycol;
     126             : using FluidProperties::GetSpecificHeatGlycol;
     127             : using Psychrometrics::PsyCpAirFnW;
     128             : using Psychrometrics::PsyHFnTdbRhPb;
     129             : using Psychrometrics::PsyHFnTdbW;
     130             : using Psychrometrics::PsyRhoAirFnPbTdbW;
     131             : using Psychrometrics::PsyTdbFnHW;
     132             : using Psychrometrics::PsyTdpFnWPb;
     133             : using Psychrometrics::PsyTsatFnHPb;
     134             : using Psychrometrics::PsyWFnTdbH;
     135             : using Psychrometrics::PsyWFnTdbRhPb;
     136             : using Psychrometrics::PsyWFnTdbTwbPb;
     137             : using Psychrometrics::PsyWFnTdpPb;
     138             : using namespace ScheduleManager;
     139             : 
     140   137535475 : void SimulateWaterCoilComponents(EnergyPlusData &state,
     141             :                                  std::string_view CompName,
     142             :                                  bool const FirstHVACIteration,
     143             :                                  int &CompIndex,
     144             :                                  Optional<Real64> QActual,
     145             :                                  Optional_int_const FanOpMode,
     146             :                                  Optional<Real64 const> PartLoadRatio)
     147             : {
     148             : 
     149             :     // SUBROUTINE INFORMATION:
     150             :     //       AUTHOR         Richard Liesen
     151             :     //       DATE WRITTEN   February 1998
     152             :     //       MODIFIED       na
     153             :     //       RE-ENGINEERED  na
     154             : 
     155             :     // PURPOSE OF THIS SUBROUTINE:
     156             :     // This subroutine manages WaterCoil component simulation.
     157             : 
     158             :     // Using/Aliasing
     159             : 
     160             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     161             :     int CoilNum;         // The WaterCoil that you are currently loading input into
     162             :     int OpMode;          // fan operating mode
     163             :     Real64 PartLoadFrac; // part-load fraction of heating coil
     164             : 
     165             :     // Obtains and Allocates WaterCoil related parameters from input file
     166   137535475 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) { // First time subroutine has been entered
     167           0 :         GetWaterCoilInput(state);
     168           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
     169             :     }
     170             : 
     171             :     // Find the correct WaterCoilNumber with the Coil Name
     172   137535475 :     if (CompIndex == 0) {
     173      767839 :         CoilNum = UtilityRoutines::FindItemInList(CompName, state.dataWaterCoils->WaterCoil);
     174      767839 :         if (CoilNum == 0) {
     175           0 :             ShowFatalError(state, "SimulateWaterCoilComponents: Coil not found=" + std::string{CompName});
     176             :         }
     177      767839 :         CompIndex = CoilNum;
     178             :     } else {
     179   136767636 :         CoilNum = CompIndex;
     180   136767636 :         if (CoilNum > state.dataWaterCoils->NumWaterCoils || CoilNum < 1) {
     181           0 :             ShowFatalError(state,
     182           0 :                            format("SimulateWaterCoilComponents: Invalid CompIndex passed={}, Number of Water Coils={}, Coil name={}",
     183             :                                   CoilNum,
     184           0 :                                   state.dataWaterCoils->NumWaterCoils,
     185           0 :                                   CompName));
     186             :         }
     187   136767636 :         if (state.dataWaterCoils->CheckEquipName(CoilNum)) {
     188        3092 :             if (CompName != state.dataWaterCoils->WaterCoil(CoilNum).Name) {
     189           0 :                 ShowFatalError(state,
     190           0 :                                format("SimulateWaterCoilComponents: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
     191             :                                       CoilNum,
     192             :                                       CompName,
     193           0 :                                       state.dataWaterCoils->WaterCoil(CoilNum).Name));
     194             :             }
     195        3092 :             state.dataWaterCoils->CheckEquipName(CoilNum) = false;
     196             :         }
     197             :     }
     198             : 
     199             :     // With the correct CoilNum Initialize
     200   137535475 :     InitWaterCoil(state, CoilNum, FirstHVACIteration); // Initialize all WaterCoil related parameters
     201             : 
     202   137535475 :     if (present(FanOpMode)) {
     203     5522026 :         OpMode = FanOpMode;
     204             :     } else {
     205   132013449 :         OpMode = ContFanCycCoil;
     206             :     }
     207   137535475 :     if (present(PartLoadRatio)) {
     208     4127696 :         PartLoadFrac = PartLoadRatio;
     209             :     } else {
     210   133407779 :         PartLoadFrac = 1.0;
     211             :     }
     212             : 
     213             :     // Calculate the Correct WaterCoil Model with the current CoilNum
     214   137535475 :     if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling) {
     215     3336941 :         CalcDetailFlatFinCoolingCoil(state, CoilNum, state.dataWaterCoils->SimCalc, OpMode, PartLoadFrac);
     216     3336941 :         if (present(QActual)) QActual = state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate;
     217   134198534 :     } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) {
     218    22043969 :         CoolingCoil(state, CoilNum, FirstHVACIteration, state.dataWaterCoils->SimCalc, OpMode, PartLoadFrac);
     219    22043969 :         if (present(QActual)) QActual = state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate;
     220             :     }
     221             : 
     222   137535475 :     if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
     223   112154565 :         CalcSimpleHeatingCoil(state, CoilNum, OpMode, PartLoadFrac, state.dataWaterCoils->SimCalc);
     224   112154565 :         if (present(QActual)) QActual = state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate;
     225             :     }
     226             : 
     227             :     // Update the current WaterCoil to the outlet nodes
     228   137535475 :     UpdateWaterCoil(state, CoilNum);
     229             : 
     230             :     // Report the current WaterCoil
     231   137535475 :     ReportWaterCoil(state, CoilNum);
     232   137535475 : }
     233             : 
     234             : // Get Input Section of the Module
     235             : //******************************************************************************
     236             : 
     237         325 : void GetWaterCoilInput(EnergyPlusData &state)
     238             : {
     239             : 
     240             :     // SUBROUTINE INFORMATION:
     241             :     //       AUTHOR         Richard Liesen
     242             :     //       DATE WRITTEN   April 1998
     243             :     //       MODIFIED       April 2004: Rahul Chillar
     244             :     //                      November 2013: Tianzhen Hong for fouling coils
     245             :     //       RE-ENGINEERED  na
     246             : 
     247             :     // PURPOSE OF THIS SUBROUTINE:
     248             :     // Obtains input data for coils and stores it in coil data structures
     249             : 
     250             :     // METHODOLOGY EMPLOYED:
     251             :     // Uses "Get" routines to read in data.
     252             : 
     253             :     // Using/Aliasing
     254             :     using BranchNodeConnections::TestCompSet;
     255             :     using DataSizing::AutoSize;
     256             :     using GlobalNames::VerifyUniqueCoilName;
     257             :     using NodeInputManager::GetOnlySingleNode;
     258             :     using SetPointManager::NodeHasSPMCtrlVarType;
     259             :     using WaterManager::SetupTankSupplyComponent;
     260             :     using namespace FaultsManager;
     261             : 
     262             :     // SUBROUTINE PARAMETER DEFINITIONS:
     263             :     static constexpr std::string_view RoutineName("GetWaterCoilInput: "); // include trailing blank space
     264             : 
     265             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     266             :     int CoilNum; // The WaterCoil that you are currently loading input into
     267         325 :     int NumSimpHeat(0);
     268         325 :     int NumFlatFin(0);
     269         325 :     int NumCooling(0);
     270             :     int SimpHeatNum;
     271             :     int FlatFinNum;
     272             :     int CoolingNum;
     273             :     int NumAlphas;
     274             :     int NumNums;
     275             :     int IOStat;
     276         650 :     std::string CurrentModuleObject; // for ease in getting objects
     277         650 :     Array1D_string AlphArray;        // Alpha input items for object
     278         650 :     Array1D_string cAlphaFields;     // Alpha field names
     279         650 :     Array1D_string cNumericFields;   // Numeric field names
     280         650 :     Array1D<Real64> NumArray;        // Numeric input items for object
     281         650 :     Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     282         650 :     Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     283         325 :     int MaxNums(0);                  // Maximum number of numeric input fields
     284         325 :     int MaxAlphas(0);                // Maximum number of alpha input fields
     285         325 :     int TotalArgs(0);                // Total number of alpha and numeric arguments (max) for a certain object in the input file
     286         325 :     bool ErrorsFound(false);         // If errors detected in input
     287             : 
     288         325 :     NumSimpHeat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:Water");
     289         325 :     NumFlatFin = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:Water:DetailedGeometry");
     290         325 :     NumCooling = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:Water");
     291         325 :     state.dataWaterCoils->NumWaterCoils = NumSimpHeat + NumFlatFin + NumCooling;
     292             : 
     293         325 :     if (state.dataWaterCoils->NumWaterCoils > 0) {
     294         314 :         state.dataWaterCoils->WaterCoil.allocate(state.dataWaterCoils->NumWaterCoils);
     295         314 :         state.dataWaterCoils->WaterCoilNumericFields.allocate(state.dataWaterCoils->NumWaterCoils);
     296         314 :         state.dataWaterCoils->WaterTempCoolCoilErrs.dimension(state.dataWaterCoils->NumWaterCoils, 0);
     297         314 :         state.dataWaterCoils->PartWetCoolCoilErrs.dimension(state.dataWaterCoils->NumWaterCoils, 0);
     298         314 :         state.dataWaterCoils->CheckEquipName.dimension(state.dataWaterCoils->NumWaterCoils, true);
     299             :     }
     300             : 
     301         325 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Heating:Water", TotalArgs, NumAlphas, NumNums);
     302         325 :     MaxNums = max(MaxNums, NumNums);
     303         325 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     304         325 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:Water:DetailedGeometry", TotalArgs, NumAlphas, NumNums);
     305         325 :     MaxNums = max(MaxNums, NumNums);
     306         325 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     307         325 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Coil:Cooling:Water", TotalArgs, NumAlphas, NumNums);
     308         325 :     MaxNums = max(MaxNums, NumNums);
     309         325 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     310             : 
     311         325 :     AlphArray.allocate(MaxAlphas);
     312         325 :     cAlphaFields.allocate(MaxAlphas);
     313         325 :     cNumericFields.allocate(MaxNums);
     314         325 :     NumArray.dimension(MaxNums, 0.0);
     315         325 :     lAlphaBlanks.dimension(MaxAlphas, true);
     316         325 :     lNumericBlanks.dimension(MaxNums, true);
     317         325 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     318         325 :     CurrentModuleObject = "Coil:Heating:Water";
     319             :     // Get the data for simple heating coils
     320        2879 :     for (SimpHeatNum = 1; SimpHeatNum <= NumSimpHeat; ++SimpHeatNum) {
     321             : 
     322        2554 :         CoilNum = SimpHeatNum;
     323             : 
     324        2554 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     325             :                                                                  CurrentModuleObject,
     326             :                                                                  SimpHeatNum,
     327             :                                                                  AlphArray,
     328             :                                                                  NumAlphas,
     329             :                                                                  NumArray,
     330             :                                                                  NumNums,
     331             :                                                                  IOStat,
     332             :                                                                  lNumericBlanks,
     333             :                                                                  lAlphaBlanks,
     334             :                                                                  cAlphaFields,
     335             :                                                                  cNumericFields);
     336             : 
     337        2554 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames.allocate(MaxNums);
     338        2554 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames = "";
     339        2554 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames = cNumericFields;
     340        2554 :         UtilityRoutines::IsNameEmpty(state, AlphArray(1), cCurrentModuleObject, ErrorsFound);
     341             : 
     342             :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
     343        2554 :         VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
     344             : 
     345        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).Name = AlphArray(1);
     346        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).Schedule = AlphArray(2);
     347        2554 :         if (lAlphaBlanks(2)) {
     348          49 :             state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     349             :         } else {
     350        2505 :             state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr = GetScheduleIndex(state, AlphArray(2));
     351        2505 :             if (state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr == 0) {
     352           0 :                 ShowSevereError(state,
     353           0 :                                 CurrentModuleObject + ": invalid " + cAlphaFields(2) + " entered =" + AlphArray(2) + " for " + cAlphaFields(1) + '=' +
     354           0 :                                     AlphArray(1));
     355           0 :                 ErrorsFound = true;
     356             :             }
     357             :         }
     358             : 
     359        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilTypeA = "Heating";
     360        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling; // 'Heating'
     361        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModelA = "SIMPLE";
     362        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel = CoilModel::HeatingSimple; // 'SIMPLE'
     363        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
     364             : 
     365        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).UACoil = NumArray(1);
     366        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable = state.dataWaterCoils->WaterCoil(CoilNum).UACoil;
     367        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = NumArray(2);
     368        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum = GetOnlySingleNode(state,
     369        2554 :                                                                                        AlphArray(3),
     370             :                                                                                        ErrorsFound,
     371             :                                                                                        DataLoopNode::ConnectionObjectType::CoilHeatingWater,
     372        2554 :                                                                                        AlphArray(1),
     373             :                                                                                        DataLoopNode::NodeFluidType::Water,
     374             :                                                                                        DataLoopNode::ConnectionType::Inlet,
     375             :                                                                                        NodeInputManager::CompFluidStream::Secondary,
     376        2554 :                                                                                        ObjectIsNotParent);
     377        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum = GetOnlySingleNode(state,
     378        2554 :                                                                                         AlphArray(4),
     379             :                                                                                         ErrorsFound,
     380             :                                                                                         DataLoopNode::ConnectionObjectType::CoilHeatingWater,
     381        2554 :                                                                                         AlphArray(1),
     382             :                                                                                         DataLoopNode::NodeFluidType::Water,
     383             :                                                                                         DataLoopNode::ConnectionType::Outlet,
     384             :                                                                                         NodeInputManager::CompFluidStream::Secondary,
     385        2554 :                                                                                         ObjectIsNotParent);
     386        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).AirInletNodeNum = GetOnlySingleNode(state,
     387        2554 :                                                                                      AlphArray(5),
     388             :                                                                                      ErrorsFound,
     389             :                                                                                      DataLoopNode::ConnectionObjectType::CoilHeatingWater,
     390        2554 :                                                                                      AlphArray(1),
     391             :                                                                                      DataLoopNode::NodeFluidType::Air,
     392             :                                                                                      DataLoopNode::ConnectionType::Inlet,
     393             :                                                                                      NodeInputManager::CompFluidStream::Primary,
     394        2554 :                                                                                      ObjectIsNotParent);
     395        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).AirOutletNodeNum = GetOnlySingleNode(state,
     396        2554 :                                                                                       AlphArray(6),
     397             :                                                                                       ErrorsFound,
     398             :                                                                                       DataLoopNode::ConnectionObjectType::CoilHeatingWater,
     399        2554 :                                                                                       AlphArray(1),
     400             :                                                                                       DataLoopNode::NodeFluidType::Air,
     401             :                                                                                       DataLoopNode::ConnectionType::Outlet,
     402             :                                                                                       NodeInputManager::CompFluidStream::Primary,
     403        2554 :                                                                                       ObjectIsNotParent);
     404             : 
     405        2554 :         if (AlphArray(7) == "NOMINALCAPACITY") { // not "UFACTORTIMESAREAANDDESIGNWATERFLOWRATE"
     406          52 :             state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth = state.dataWaterCoils->NomCap;
     407             : 
     408             :         } else {
     409             :             // will be caught by input processor
     410        2502 :             state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth = state.dataWaterCoils->UAandFlow;
     411             :         }
     412             : 
     413        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad = NumArray(3);
     414             : 
     415        4802 :         if (state.dataWaterCoils->WaterCoil(CoilNum).UACoil == AutoSize &&
     416        2248 :             state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth == state.dataWaterCoils->UAandFlow)
     417        2200 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     418        2554 :         if (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate == AutoSize)
     419        2248 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     420        5065 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad == AutoSize &&
     421        2511 :             state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth == state.dataWaterCoils->NomCap)
     422           9 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     423             : 
     424        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp = NumArray(4);
     425        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp = NumArray(5);
     426        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).DesOutletWaterTemp = NumArray(6);
     427        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp = NumArray(7);
     428        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).RatioAirSideToWaterSideConvect = NumArray(8);
     429        2554 :         if (!lNumericBlanks(9)) {
     430          93 :             state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp = NumArray(9);
     431          93 :             state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp = true;
     432             :         } else {
     433        2461 :             state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp = false;
     434             :         }
     435        2554 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp <= state.dataWaterCoils->WaterCoil(CoilNum).DesOutletWaterTemp) {
     436           0 :             ShowSevereError(state, "For " + CurrentModuleObject + ", " + AlphArray(1));
     437           0 :             ShowContinueError(state, "  the " + cNumericFields(4) + " must be greater than the " + cNumericFields(6) + '.');
     438           0 :             ErrorsFound = true;
     439             :         }
     440        2554 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp >= state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp) {
     441           0 :             ShowSevereError(state, "For " + CurrentModuleObject + ", " + AlphArray(1));
     442           0 :             ShowContinueError(state, "  the " + cNumericFields(5) + " must be less than the " + cNumericFields(7) + '.');
     443           0 :             ErrorsFound = true;
     444             :         }
     445        2554 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp >= state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp) {
     446           0 :             ShowSevereError(state, "For " + CurrentModuleObject + ", " + AlphArray(1));
     447           0 :             ShowContinueError(state, "  the " + cNumericFields(5) + " must be less than the " + cNumericFields(4) + '.');
     448           0 :             ErrorsFound = true;
     449             :         }
     450             : 
     451        2554 :         TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(3), AlphArray(4), "Water Nodes");
     452        2554 :         TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(5), AlphArray(6), "Air Nodes");
     453             : 
     454             :         // Setup the Simple Heating Coil reporting variables
     455             :         // CurrentModuleObject = "Coil:Heating:Water"
     456       10216 :         SetupOutputVariable(state,
     457             :                             "Heating Coil Heating Energy",
     458             :                             OutputProcessor::Unit::J,
     459        2554 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilEnergy,
     460             :                             OutputProcessor::SOVTimeStepType::System,
     461             :                             OutputProcessor::SOVStoreType::Summed,
     462        2554 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name,
     463             :                             _,
     464             :                             "ENERGYTRANSFER",
     465             :                             "HEATINGCOILS",
     466             :                             _,
     467        2554 :                             "System");
     468       10216 :         SetupOutputVariable(state,
     469             :                             "Heating Coil Source Side Heat Transfer Energy",
     470             :                             OutputProcessor::Unit::J,
     471        2554 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilEnergy,
     472             :                             OutputProcessor::SOVTimeStepType::System,
     473             :                             OutputProcessor::SOVStoreType::Summed,
     474        2554 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name,
     475             :                             _,
     476             :                             "PLANTLOOPHEATINGDEMAND",
     477             :                             "HEATINGCOILS",
     478             :                             _,
     479        2554 :                             "System");
     480       10216 :         SetupOutputVariable(state,
     481             :                             "Heating Coil Heating Rate",
     482             :                             OutputProcessor::Unit::W,
     483        2554 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate,
     484             :                             OutputProcessor::SOVTimeStepType::System,
     485             :                             OutputProcessor::SOVStoreType::Average,
     486        5108 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     487       10216 :         SetupOutputVariable(state,
     488             :                             "Heating Coil U Factor Times Area Value",
     489             :                             OutputProcessor::Unit::W_K,
     490        2554 :                             state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable,
     491             :                             OutputProcessor::SOVTimeStepType::System,
     492             :                             OutputProcessor::SOVStoreType::Average,
     493        5108 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     494             :     }
     495             : 
     496         325 :     CurrentModuleObject = "Coil:Cooling:Water:DetailedGeometry";
     497             :     // Get the data for detailed cooling coils.
     498         468 :     for (FlatFinNum = 1; FlatFinNum <= NumFlatFin; ++FlatFinNum) {
     499             : 
     500         143 :         CoilNum = NumSimpHeat + FlatFinNum;
     501             : 
     502         143 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     503             :                                                                  CurrentModuleObject,
     504             :                                                                  FlatFinNum,
     505             :                                                                  AlphArray,
     506             :                                                                  NumAlphas,
     507             :                                                                  NumArray,
     508             :                                                                  NumNums,
     509             :                                                                  IOStat,
     510             :                                                                  lNumericBlanks,
     511             :                                                                  lAlphaBlanks,
     512             :                                                                  cAlphaFields,
     513             :                                                                  cNumericFields);
     514             : 
     515         143 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames.allocate(MaxNums);
     516         143 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames = "";
     517         143 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames = cNumericFields;
     518         143 :         UtilityRoutines::IsNameEmpty(state, AlphArray(1), cCurrentModuleObject, ErrorsFound);
     519             : 
     520             :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
     521         143 :         VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
     522             : 
     523         143 :         state.dataWaterCoils->WaterCoil(CoilNum).Name = AlphArray(1);
     524         143 :         state.dataWaterCoils->WaterCoil(CoilNum).Schedule = AlphArray(2);
     525         143 :         if (lAlphaBlanks(2)) {
     526           0 :             state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     527             :         } else {
     528         143 :             state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr = GetScheduleIndex(state, AlphArray(2));
     529         143 :             if (state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr == 0) {
     530           0 :                 ShowSevereError(state,
     531           0 :                                 CurrentModuleObject + ": invalid " + cAlphaFields(2) + " entered =" + AlphArray(2) + " for " + cAlphaFields(1) + '=' +
     532           0 :                                     AlphArray(1));
     533           0 :                 ErrorsFound = true;
     534             :             }
     535             :         }
     536             : 
     537         143 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilTypeA = "Cooling";
     538         143 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling; // 'Cooling'
     539         143 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModelA = "DETAILED FLAT FIN";
     540         143 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel = CoilModel::CoolingDetailed; // 'DETAILED FLAT FIN'
     541         143 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
     542             : 
     543         143 :         state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = NumArray(1);
     544         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate == AutoSize)
     545          62 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     546         143 :         state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideSurfArea = NumArray(2);
     547         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideSurfArea == AutoSize)
     548          62 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     549         143 :         state.dataWaterCoils->WaterCoil(CoilNum).TotTubeInsideArea = NumArray(3);
     550         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).TotTubeInsideArea == AutoSize)
     551          62 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     552         143 :         state.dataWaterCoils->WaterCoil(CoilNum).FinSurfArea = NumArray(4);
     553         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).FinSurfArea == AutoSize) state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     554         143 :         state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea = NumArray(5);
     555         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea == AutoSize) state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     556         143 :         state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth = NumArray(6);
     557         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth == AutoSize) state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     558         143 :         state.dataWaterCoils->WaterCoil(CoilNum).FinDiam = NumArray(7);
     559         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).FinDiam == AutoSize) state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     560         143 :         state.dataWaterCoils->WaterCoil(CoilNum).FinThickness = NumArray(8);
     561         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).FinThickness <= 0.0) {
     562           0 :             ShowSevereError(state,
     563           0 :                             CurrentModuleObject + ": " + cNumericFields(8) + " must be > 0.0, for " + cAlphaFields(1) + " = " +
     564           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).Name);
     565           0 :             ErrorsFound = true;
     566             :         }
     567         143 :         state.dataWaterCoils->WaterCoil(CoilNum).TubeInsideDiam = NumArray(9);
     568         143 :         state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideDiam = NumArray(10);
     569         143 :         state.dataWaterCoils->WaterCoil(CoilNum).TubeThermConductivity = NumArray(11);
     570         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).TubeThermConductivity <= 0.0) {
     571           0 :             ShowSevereError(state,
     572           0 :                             CurrentModuleObject + ": " + cNumericFields(11) + " must be > 0.0, for " + cAlphaFields(1) + " = " +
     573           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).Name);
     574           0 :             ErrorsFound = true;
     575             :         }
     576         143 :         state.dataWaterCoils->WaterCoil(CoilNum).FinThermConductivity = NumArray(12);
     577         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).FinThermConductivity <= 0.0) {
     578           0 :             ShowSevereError(state,
     579           0 :                             CurrentModuleObject + ": " + cNumericFields(12) + " must be > 0.0, for " + cAlphaFields(1) + " = " +
     580           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).Name);
     581           0 :             ErrorsFound = true;
     582             :         }
     583         143 :         state.dataWaterCoils->WaterCoil(CoilNum).FinSpacing = NumArray(13);
     584         143 :         state.dataWaterCoils->WaterCoil(CoilNum).TubeDepthSpacing = NumArray(14);
     585         143 :         state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubeRows = NumArray(15);
     586         143 :         state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow = NumArray(16);
     587         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow == AutoSize) state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     588         143 :         if (!lNumericBlanks(17)) {
     589           1 :             state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp = NumArray(17);
     590           1 :             state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp = true;
     591             :         } else {
     592         142 :             state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp = false;
     593             :         }
     594         143 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum =
     595         286 :             GetOnlySingleNode(state,
     596         143 :                               AlphArray(3),
     597             :                               ErrorsFound,
     598             :                               DataLoopNode::ConnectionObjectType::CoilCoolingWaterDetailedGeometry,
     599         143 :                               AlphArray(1),
     600             :                               DataLoopNode::NodeFluidType::Water,
     601             :                               DataLoopNode::ConnectionType::Inlet,
     602             :                               NodeInputManager::CompFluidStream::Secondary,
     603         143 :                               ObjectIsNotParent);
     604         143 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum =
     605         286 :             GetOnlySingleNode(state,
     606         143 :                               AlphArray(4),
     607             :                               ErrorsFound,
     608             :                               DataLoopNode::ConnectionObjectType::CoilCoolingWaterDetailedGeometry,
     609         143 :                               AlphArray(1),
     610             :                               DataLoopNode::NodeFluidType::Water,
     611             :                               DataLoopNode::ConnectionType::Outlet,
     612             :                               NodeInputManager::CompFluidStream::Secondary,
     613         143 :                               ObjectIsNotParent);
     614         143 :         state.dataWaterCoils->WaterCoil(CoilNum).AirInletNodeNum =
     615         286 :             GetOnlySingleNode(state,
     616         143 :                               AlphArray(5),
     617             :                               ErrorsFound,
     618             :                               DataLoopNode::ConnectionObjectType::CoilCoolingWaterDetailedGeometry,
     619         143 :                               AlphArray(1),
     620             :                               DataLoopNode::NodeFluidType::Air,
     621             :                               DataLoopNode::ConnectionType::Inlet,
     622             :                               NodeInputManager::CompFluidStream::Primary,
     623         143 :                               ObjectIsNotParent);
     624         143 :         state.dataWaterCoils->WaterCoil(CoilNum).AirOutletNodeNum =
     625         286 :             GetOnlySingleNode(state,
     626         143 :                               AlphArray(6),
     627             :                               ErrorsFound,
     628             :                               DataLoopNode::ConnectionObjectType::CoilCoolingWaterDetailedGeometry,
     629         143 :                               AlphArray(1),
     630             :                               DataLoopNode::NodeFluidType::Air,
     631             :                               DataLoopNode::ConnectionType::Outlet,
     632             :                               NodeInputManager::CompFluidStream::Primary,
     633         143 :                               ObjectIsNotParent);
     634             : 
     635             :         // A7 ; \field Name of Water Storage Tank for Condensate Collection
     636         143 :         state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectName = AlphArray(7);
     637         143 :         if (lAlphaBlanks(7)) {
     638         143 :             state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectMode = state.dataWaterCoils->CondensateDiscarded;
     639             :         } else {
     640           0 :             state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectMode = state.dataWaterCoils->CondensateToTank;
     641           0 :             SetupTankSupplyComponent(state,
     642           0 :                                      state.dataWaterCoils->WaterCoil(CoilNum).Name,
     643             :                                      CurrentModuleObject,
     644           0 :                                      state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectName,
     645             :                                      ErrorsFound,
     646           0 :                                      state.dataWaterCoils->WaterCoil(CoilNum).CondensateTankID,
     647           0 :                                      state.dataWaterCoils->WaterCoil(CoilNum).CondensateTankSupplyARRID);
     648             :         }
     649             : 
     650         143 :         TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(3), AlphArray(4), "Water Nodes");
     651         143 :         TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(5), AlphArray(6), "Air Nodes");
     652             : 
     653             :         // Setup Report variables for the Detailed Flat Fin Cooling Coils
     654             :         // CurrentModuleObject = "Coil:Cooling:Water:DetailedGeometry"
     655         572 :         SetupOutputVariable(state,
     656             :                             "Cooling Coil Total Cooling Energy",
     657             :                             OutputProcessor::Unit::J,
     658         143 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilEnergy,
     659             :                             OutputProcessor::SOVTimeStepType::System,
     660             :                             OutputProcessor::SOVStoreType::Summed,
     661         143 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name,
     662             :                             _,
     663             :                             "ENERGYTRANSFER",
     664             :                             "COOLINGCOILS",
     665             :                             _,
     666         143 :                             "System");
     667         572 :         SetupOutputVariable(state,
     668             :                             "Cooling Coil Source Side Heat Transfer Energy",
     669             :                             OutputProcessor::Unit::J,
     670         143 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilEnergy,
     671             :                             OutputProcessor::SOVTimeStepType::System,
     672             :                             OutputProcessor::SOVStoreType::Summed,
     673         143 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name,
     674             :                             _,
     675             :                             "PLANTLOOPCOOLINGDEMAND",
     676             :                             "COOLINGCOILS",
     677             :                             _,
     678         143 :                             "System");
     679         572 :         SetupOutputVariable(state,
     680             :                             "Cooling Coil Sensible Cooling Energy",
     681             :                             OutputProcessor::Unit::J,
     682         143 :                             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilEnergy,
     683             :                             OutputProcessor::SOVTimeStepType::System,
     684             :                             OutputProcessor::SOVStoreType::Summed,
     685         286 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     686         572 :         SetupOutputVariable(state,
     687             :                             "Cooling Coil Total Cooling Rate",
     688             :                             OutputProcessor::Unit::W,
     689         143 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate,
     690             :                             OutputProcessor::SOVTimeStepType::System,
     691             :                             OutputProcessor::SOVStoreType::Average,
     692         286 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     693         572 :         SetupOutputVariable(state,
     694             :                             "Cooling Coil Sensible Cooling Rate",
     695             :                             OutputProcessor::Unit::W,
     696         143 :                             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate,
     697             :                             OutputProcessor::SOVTimeStepType::System,
     698             :                             OutputProcessor::SOVStoreType::Average,
     699         286 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     700             : 
     701         143 :         if (state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectMode == state.dataWaterCoils->CondensateToTank) {
     702             : 
     703           0 :             SetupOutputVariable(state,
     704             :                                 "Cooling Coil Condensate Volume Flow Rate",
     705             :                                 OutputProcessor::Unit::m3_s,
     706           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).CondensateVdot,
     707             :                                 OutputProcessor::SOVTimeStepType::System,
     708             :                                 OutputProcessor::SOVStoreType::Average,
     709           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).Name);
     710           0 :             SetupOutputVariable(state,
     711             :                                 "Cooling Coil Condensate Volume",
     712             :                                 OutputProcessor::Unit::m3,
     713           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).CondensateVol,
     714             :                                 OutputProcessor::SOVTimeStepType::System,
     715             :                                 OutputProcessor::SOVStoreType::Summed,
     716           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).Name,
     717             :                                 _,
     718             :                                 "OnSiteWater",
     719             :                                 "Condensate",
     720             :                                 _,
     721           0 :                                 "System");
     722             :         }
     723             :     }
     724             : 
     725         325 :     CurrentModuleObject = "Coil:Cooling:Water";
     726             :     // Get the data for Cooling coils.
     727         728 :     for (CoolingNum = 1; CoolingNum <= NumCooling; ++CoolingNum) {
     728             : 
     729         403 :         CoilNum = NumSimpHeat + NumFlatFin + CoolingNum;
     730             : 
     731         403 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     732             :                                                                  CurrentModuleObject,
     733             :                                                                  CoolingNum,
     734             :                                                                  AlphArray,
     735             :                                                                  NumAlphas,
     736             :                                                                  NumArray,
     737             :                                                                  NumNums,
     738             :                                                                  IOStat,
     739             :                                                                  lNumericBlanks,
     740             :                                                                  lAlphaBlanks,
     741             :                                                                  cAlphaFields,
     742             :                                                                  cNumericFields);
     743             : 
     744         403 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames.allocate(MaxNums);
     745         403 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames = "";
     746         403 :         state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames = cNumericFields;
     747         403 :         UtilityRoutines::IsNameEmpty(state, AlphArray(1), cCurrentModuleObject, ErrorsFound);
     748             : 
     749             :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
     750         403 :         VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
     751             : 
     752         403 :         state.dataWaterCoils->WaterCoil(CoilNum).Name = AlphArray(1);
     753         403 :         state.dataWaterCoils->WaterCoil(CoilNum).Schedule = AlphArray(2);
     754         403 :         if (lAlphaBlanks(2)) {
     755          24 :             state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     756             :         } else {
     757         379 :             state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr = GetScheduleIndex(state, AlphArray(2));
     758         379 :             if (state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr == 0) {
     759           0 :                 ShowSevereError(state,
     760           0 :                                 CurrentModuleObject + ": invalid " + cAlphaFields(2) + " entered =" + AlphArray(2) + " for " + cAlphaFields(1) + '=' +
     761           0 :                                     AlphArray(1));
     762           0 :                 ErrorsFound = true;
     763             :             }
     764             :         }
     765             : 
     766         403 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilTypeA = "Cooling";
     767         403 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling; // 'Cooling'
     768         403 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModelA = "Cooling";
     769         403 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel = CoilModel::CoolingSimple; // 'Cooling'
     770         403 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling;
     771             : 
     772         403 :         state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = NumArray(1); // Liquid mass flow rate at Design  kg/s
     773         403 :         if (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate == AutoSize)
     774         381 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     775         403 :         state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate = NumArray(2); // Dry air mass flow rate at Design (kg/s)
     776         403 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate == AutoSize)
     777         381 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     778         403 :         state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp = NumArray(3); // Entering water temperature at Design C
     779         403 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp == AutoSize)
     780         368 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     781         403 :         state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp = NumArray(4); // Entering air dry bulb temperature at Design(C)
     782         403 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp == AutoSize) state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     783         403 :         state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp = NumArray(5); // Leaving air dry bulb temperature at Design(C)
     784         403 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp == AutoSize) state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     785         403 :         state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat = NumArray(6); // Entering air humidity ratio  at Design
     786         403 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat == AutoSize)
     787         376 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     788         403 :         state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat = NumArray(7); // Leaving air humidity ratio  at Design
     789         403 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat == AutoSize)
     790         376 :             state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize = true;
     791         403 :         if (!lNumericBlanks(8)) {
     792          27 :             state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp = NumArray(8);
     793          27 :             state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp = true;
     794             :         } else {
     795         376 :             state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp = false;
     796             :         }
     797             : 
     798         403 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum = GetOnlySingleNode(state,
     799         403 :                                                                                        AlphArray(3),
     800             :                                                                                        ErrorsFound,
     801             :                                                                                        DataLoopNode::ConnectionObjectType::CoilCoolingWater,
     802         403 :                                                                                        AlphArray(1),
     803             :                                                                                        DataLoopNode::NodeFluidType::Water,
     804             :                                                                                        DataLoopNode::ConnectionType::Inlet,
     805             :                                                                                        NodeInputManager::CompFluidStream::Secondary,
     806         403 :                                                                                        ObjectIsNotParent);
     807         403 :         state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum = GetOnlySingleNode(state,
     808         403 :                                                                                         AlphArray(4),
     809             :                                                                                         ErrorsFound,
     810             :                                                                                         DataLoopNode::ConnectionObjectType::CoilCoolingWater,
     811         403 :                                                                                         AlphArray(1),
     812             :                                                                                         DataLoopNode::NodeFluidType::Water,
     813             :                                                                                         DataLoopNode::ConnectionType::Outlet,
     814             :                                                                                         NodeInputManager::CompFluidStream::Secondary,
     815         403 :                                                                                         ObjectIsNotParent);
     816         403 :         state.dataWaterCoils->WaterCoil(CoilNum).AirInletNodeNum = GetOnlySingleNode(state,
     817         403 :                                                                                      AlphArray(5),
     818             :                                                                                      ErrorsFound,
     819             :                                                                                      DataLoopNode::ConnectionObjectType::CoilCoolingWater,
     820         403 :                                                                                      AlphArray(1),
     821             :                                                                                      DataLoopNode::NodeFluidType::Air,
     822             :                                                                                      DataLoopNode::ConnectionType::Inlet,
     823             :                                                                                      NodeInputManager::CompFluidStream::Primary,
     824         403 :                                                                                      ObjectIsNotParent);
     825         403 :         state.dataWaterCoils->WaterCoil(CoilNum).AirOutletNodeNum = GetOnlySingleNode(state,
     826         403 :                                                                                       AlphArray(6),
     827             :                                                                                       ErrorsFound,
     828             :                                                                                       DataLoopNode::ConnectionObjectType::CoilCoolingWater,
     829         403 :                                                                                       AlphArray(1),
     830             :                                                                                       DataLoopNode::NodeFluidType::Air,
     831             :                                                                                       DataLoopNode::ConnectionType::Outlet,
     832             :                                                                                       NodeInputManager::CompFluidStream::Primary,
     833         403 :                                                                                       ObjectIsNotParent);
     834             : 
     835             :         // The default is SimpleAnalysis = 2.  and DetailedAnalysis   =1
     836         403 :         if (AlphArray(7) == "DETAILEDANALYSIS") { // not "SIMPLEANALYSIS"
     837          54 :             state.dataWaterCoils->WaterCoil(CoilNum).CoolingCoilAnalysisMode = state.dataWaterCoils->DetailedAnalysis;
     838             : 
     839             :         } else {
     840         349 :             state.dataWaterCoils->WaterCoil(CoilNum).CoolingCoilAnalysisMode = state.dataWaterCoils->SimpleAnalysis;
     841             :         }
     842             : 
     843             :         // The default is CrossFlow = 2.  and CounterFlow=1
     844         403 :         if (AlphArray(8) == "COUNTERFLOW") { // not "CROSSFLOW"
     845           1 :             state.dataWaterCoils->WaterCoil(CoilNum).HeatExchType = state.dataWaterCoils->CounterFlow;
     846             : 
     847             :         } else {
     848         402 :             state.dataWaterCoils->WaterCoil(CoilNum).HeatExchType = state.dataWaterCoils->CrossFlow;
     849             :         }
     850             : 
     851             :         // A9; \field Name of Water Storage Tank for Condensate Collection
     852         403 :         state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectName = AlphArray(9);
     853         403 :         if (lAlphaBlanks(9)) {
     854         403 :             state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectMode = state.dataWaterCoils->CondensateDiscarded;
     855             :         } else {
     856           0 :             state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectMode = state.dataWaterCoils->CondensateToTank;
     857           0 :             SetupTankSupplyComponent(state,
     858           0 :                                      state.dataWaterCoils->WaterCoil(CoilNum).Name,
     859             :                                      CurrentModuleObject,
     860           0 :                                      state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectName,
     861             :                                      ErrorsFound,
     862           0 :                                      state.dataWaterCoils->WaterCoil(CoilNum).CondensateTankID,
     863           0 :                                      state.dataWaterCoils->WaterCoil(CoilNum).CondensateTankSupplyARRID);
     864             :         }
     865             : 
     866         403 :         TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(3), AlphArray(4), "Water Nodes");
     867         403 :         TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(5), AlphArray(6), "Air Nodes");
     868             : 
     869             :         // Setup Report variables for the Design input Cooling Coils
     870             :         // CurrentModuleObject = "Coil:Cooling:Water"
     871        1612 :         SetupOutputVariable(state,
     872             :                             "Cooling Coil Total Cooling Energy",
     873             :                             OutputProcessor::Unit::J,
     874         403 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilEnergy,
     875             :                             OutputProcessor::SOVTimeStepType::System,
     876             :                             OutputProcessor::SOVStoreType::Summed,
     877         403 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name,
     878             :                             _,
     879             :                             "ENERGYTRANSFER",
     880             :                             "COOLINGCOILS",
     881             :                             _,
     882         403 :                             "System");
     883        1612 :         SetupOutputVariable(state,
     884             :                             "Cooling Coil Source Side Heat Transfer Energy",
     885             :                             OutputProcessor::Unit::J,
     886         403 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilEnergy,
     887             :                             OutputProcessor::SOVTimeStepType::System,
     888             :                             OutputProcessor::SOVStoreType::Summed,
     889         403 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name,
     890             :                             _,
     891             :                             "PLANTLOOPCOOLINGDEMAND",
     892             :                             "COOLINGCOILS",
     893             :                             _,
     894         403 :                             "System");
     895        1612 :         SetupOutputVariable(state,
     896             :                             "Cooling Coil Sensible Cooling Energy",
     897             :                             OutputProcessor::Unit::J,
     898         403 :                             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilEnergy,
     899             :                             OutputProcessor::SOVTimeStepType::System,
     900             :                             OutputProcessor::SOVStoreType::Summed,
     901         806 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     902        1612 :         SetupOutputVariable(state,
     903             :                             "Cooling Coil Total Cooling Rate",
     904             :                             OutputProcessor::Unit::W,
     905         403 :                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate,
     906             :                             OutputProcessor::SOVTimeStepType::System,
     907             :                             OutputProcessor::SOVStoreType::Average,
     908         806 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     909        1612 :         SetupOutputVariable(state,
     910             :                             "Cooling Coil Sensible Cooling Rate",
     911             :                             OutputProcessor::Unit::W,
     912         403 :                             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate,
     913             :                             OutputProcessor::SOVTimeStepType::System,
     914             :                             OutputProcessor::SOVStoreType::Average,
     915         806 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     916        1612 :         SetupOutputVariable(state,
     917             :                             "Cooling Coil Wetted Area Fraction",
     918             :                             OutputProcessor::Unit::None,
     919         403 :                             state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction,
     920             :                             OutputProcessor::SOVTimeStepType::System,
     921             :                             OutputProcessor::SOVStoreType::Average,
     922         806 :                             state.dataWaterCoils->WaterCoil(CoilNum).Name);
     923             : 
     924         403 :         if (state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectMode == state.dataWaterCoils->CondensateToTank) {
     925             : 
     926           0 :             SetupOutputVariable(state,
     927             :                                 "Cooling Coil Condensate Volume Flow Rate",
     928             :                                 OutputProcessor::Unit::m3_s,
     929           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).CondensateVdot,
     930             :                                 OutputProcessor::SOVTimeStepType::System,
     931             :                                 OutputProcessor::SOVStoreType::Average,
     932           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).Name);
     933           0 :             SetupOutputVariable(state,
     934             :                                 "Cooling Coil Condensate Volume",
     935             :                                 OutputProcessor::Unit::m3,
     936           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).CondensateVol,
     937             :                                 OutputProcessor::SOVTimeStepType::System,
     938             :                                 OutputProcessor::SOVStoreType::Summed,
     939           0 :                                 state.dataWaterCoils->WaterCoil(CoilNum).Name,
     940             :                                 _,
     941             :                                 "OnSiteWater",
     942             :                                 "Condensate",
     943             :                                 _,
     944           0 :                                 "System");
     945             :         }
     946             :     }
     947             : 
     948         325 :     if (ErrorsFound) {
     949           0 :         ShowFatalError(state, std::string{RoutineName} + "Errors found in getting input.");
     950             :     }
     951             : 
     952         325 :     AlphArray.deallocate();
     953         325 :     cAlphaFields.deallocate();
     954         325 :     cNumericFields.deallocate();
     955         325 :     NumArray.deallocate();
     956         325 :     lAlphaBlanks.deallocate();
     957         325 :     lNumericBlanks.deallocate();
     958         325 : }
     959             : 
     960   137535475 : void InitWaterCoil(EnergyPlusData &state, int const CoilNum, bool const FirstHVACIteration)
     961             : {
     962             : 
     963             :     // SUBROUTINE INFORMATION:
     964             :     //       AUTHOR         Richard J. Liesen
     965             :     //       DATE WRITTEN   February 1998
     966             :     //       MODIFIED       April 2004: Rahul Chillar
     967             :     //                      November 2013: XP, Tianzhen Hong to handle fouling coils
     968             :     //       RE-ENGINEERED  na
     969             : 
     970             :     // PURPOSE OF THIS SUBROUTINE:
     971             :     // This subroutine is for initializations of the WaterCoil Components.
     972             : 
     973             :     // METHODOLOGY EMPLOYED:
     974             :     // Uses the status flags to trigger initializations.
     975             : 
     976             :     // REFERENCES:
     977             : 
     978             :     // Using/Aliasing
     979             :     using General::Iterate;
     980             : 
     981             :     using General::SafeDivide;
     982             :     using General::SolveRoot;
     983             :     using namespace OutputReportPredefined;
     984             :     using PlantUtilities::InitComponentNodes;
     985             :     using PlantUtilities::RegisterPlantCompDesignFlow;
     986             :     using PlantUtilities::ScanPlantLoopsForObject;
     987             :     using namespace FaultsManager;
     988             :     using HVACControllers::GetControllerNameAndIndex;
     989             :     using SimAirServingZones::CheckWaterCoilIsOnAirLoop;
     990             : 
     991             :     // SUBROUTINE PARAMETER DEFINITIONS:
     992   137535475 :     constexpr Real64 SmallNo(1.e-9); // SmallNo number in place of zero
     993   137535475 :     constexpr int itmax(10);
     994   137535475 :     constexpr int MaxIte(500); // Maximum number of iterations
     995             :     static constexpr std::string_view RoutineName("InitWaterCoil");
     996             : 
     997             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     998             :     int tempCoilNum;                   // loop variable
     999             :     Real64 DesInletAirEnth;            // Entering air enthalpy at rating (J/kg)
    1000             :     Real64 DesOutletAirEnth;           // Leaving air enthalpy at rating(J/kg)
    1001             :     Real64 DesAirApparatusDewPtEnth;   // Air enthalpy at apparatus dew point at rating(J/kg)
    1002             :     Real64 DesSatEnthAtWaterInTemp;    // Saturated enthalpy at entering liquid temp(J/kg)
    1003             :     Real64 DesHumRatAtWaterInTemp;     // Enthalpy at water inlet temp and entering air HumRat (J/kg)
    1004             :     Real64 CapacitanceAir;             // Air-side capacity rate(W/C)
    1005             :     Real64 DesAirTempApparatusDewPt;   // Temperature apparatus dew point at design capacity
    1006             :     Real64 DesAirHumRatApparatusDewPt; // Humidity Ratio at apparatus dew point at design capacity
    1007             :     Real64 DesBypassFactor;            // ByPass Factor at design condition
    1008             :     Real64 SlopeTempVsHumRatio;        // Ratio temperature difference to humidity difference
    1009             :     // between entering and leaving air states
    1010             :     Real64 TempApparatusDewPtEstimate; // Estimate of TAdp from SlopeTempVsHumRatio
    1011             :     Real64 Y1;                         // Previous values of dependent variable in ITERATE
    1012             :     Real64 X1;                         // Previous values of independent variable in ITERATE
    1013             :     Real64 error;                      // Deviation of dependent variable in iteration
    1014             :     int iter;                          // Iteration counter
    1015             :     int icvg;                          // Iteration convergence flag
    1016             :     Real64 ResultX;                    // Output variable from ITERATE function.
    1017             :     int Ipass;                         // loop index for App_Dewpoint_Loop
    1018             :     int AirInletNode;
    1019             :     int WaterInletNode;
    1020             :     int WaterOutletNode;
    1021             :     Real64 FinDiamVar;
    1022             :     Real64 TubeToFinDiamRatio;
    1023             :     Real64 CpAirStd; // specific heat of air at std conditions
    1024             :     int SolFla;      // Flag of solver
    1025             :     Real64 UA0;      // lower bound for UA
    1026             :     Real64 UA1;      // upper bound for UA
    1027             :     Real64 UA;
    1028             :     Real64 DesUACoilExternalEnth; // enthalpy based UAExternal for wet coil surface {kg/s}
    1029             :     Real64 LogMeanEnthDiff;       // long mean enthalpy difference {J/kg}
    1030             :     Real64 LogMeanTempDiff;       // long mean temperature difference {C}
    1031             :     Real64 DesOutletWaterTemp;
    1032             :     Real64 DesSatEnthAtWaterOutTemp;
    1033             :     Real64 DesEnthAtWaterOutTempAirInHumRat;
    1034             :     Real64 DesEnthWaterOut;
    1035             :     Real64 Cp;  // local fluid specific heat
    1036             :     Real64 rho; // local fluid density
    1037             :     bool errFlag;
    1038   137535475 :     Real64 EnthCorrFrac(0.0); // enthalpy correction factor
    1039   137535475 :     Real64 TempCorrFrac(0.0); // temperature correction factor
    1040             : 
    1041   137535475 :     auto &Node(state.dataLoopNodes->Node);
    1042             : 
    1043   137535475 :     if (state.dataWaterCoils->InitWaterCoilOneTimeFlag) {
    1044             :         // initialize the environment and sizing flags
    1045         314 :         state.dataWaterCoils->MyEnvrnFlag.allocate(state.dataWaterCoils->NumWaterCoils);
    1046         314 :         state.dataWaterCoils->MySizeFlag.allocate(state.dataWaterCoils->NumWaterCoils);
    1047         314 :         state.dataWaterCoils->CoilWarningOnceFlag.allocate(state.dataWaterCoils->NumWaterCoils);
    1048         314 :         state.dataWaterCoils->DesCpAir.allocate(state.dataWaterCoils->NumWaterCoils);
    1049         314 :         state.dataWaterCoils->MyUAAndFlowCalcFlag.allocate(state.dataWaterCoils->NumWaterCoils);
    1050         314 :         state.dataWaterCoils->MyCoilDesignFlag.allocate(state.dataWaterCoils->NumWaterCoils);
    1051         314 :         state.dataWaterCoils->MyCoilReportFlag.allocate(state.dataWaterCoils->NumWaterCoils);
    1052         314 :         state.dataWaterCoils->DesUARangeCheck.allocate(state.dataWaterCoils->NumWaterCoils);
    1053         314 :         state.dataWaterCoils->PlantLoopScanFlag.allocate(state.dataWaterCoils->NumWaterCoils);
    1054             : 
    1055         314 :         state.dataWaterCoils->DesCpAir = 0.0;
    1056         314 :         state.dataWaterCoils->DesUARangeCheck = 0.0;
    1057         314 :         state.dataWaterCoils->MyEnvrnFlag = true;
    1058         314 :         state.dataWaterCoils->MySizeFlag = true;
    1059         314 :         state.dataWaterCoils->CoilWarningOnceFlag = true;
    1060         314 :         state.dataWaterCoils->MyUAAndFlowCalcFlag = true;
    1061         314 :         state.dataWaterCoils->MyCoilDesignFlag = true;
    1062         314 :         state.dataWaterCoils->MyCoilReportFlag = true;
    1063         314 :         state.dataWaterCoils->InitWaterCoilOneTimeFlag = false;
    1064         314 :         state.dataWaterCoils->PlantLoopScanFlag = true;
    1065             : 
    1066        3414 :         for (tempCoilNum = 1; tempCoilNum <= state.dataWaterCoils->NumWaterCoils; ++tempCoilNum) {
    1067        9300 :             GetControllerNameAndIndex(state,
    1068        3100 :                                       state.dataWaterCoils->WaterCoil(tempCoilNum).WaterInletNodeNum,
    1069        3100 :                                       state.dataWaterCoils->WaterCoil(tempCoilNum).ControllerName,
    1070        3100 :                                       state.dataWaterCoils->WaterCoil(tempCoilNum).ControllerIndex,
    1071             :                                       errFlag);
    1072             :         }
    1073             :     }
    1074             : 
    1075   137535475 :     if (state.dataWaterCoils->WaterCoilControllerCheckOneTimeFlag && (state.dataHVACGlobal->GetAirPathDataDone)) {
    1076         314 :         bool ErrorsFound = false;
    1077         314 :         bool WaterCoilOnAirLoop = true;
    1078        3414 :         for (tempCoilNum = 1; tempCoilNum <= state.dataWaterCoils->NumWaterCoils; ++tempCoilNum) {
    1079        3100 :             if (state.dataWaterCoils->WaterCoil(tempCoilNum).ControllerIndex > 0) {
    1080         822 :                 SimAirServingZones::CompType CoilTypeNum(SimAirServingZones::CompType::Invalid);
    1081        1644 :                 std::string CompType;
    1082        1644 :                 std::string CompName = state.dataWaterCoils->WaterCoil(tempCoilNum).Name;
    1083         822 :                 if (state.dataWaterCoils->WaterCoil(tempCoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) {
    1084         293 :                     CoilTypeNum = SimAirServingZones::CompType::WaterCoil_Cooling;
    1085         293 :                     CompType = cAllCoilTypes(DataHVACGlobals::Coil_CoolingWater);
    1086         529 :                 } else if (state.dataWaterCoils->WaterCoil(tempCoilNum).WaterCoilType ==
    1087             :                            DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling) {
    1088         143 :                     CoilTypeNum = SimAirServingZones::CompType::WaterCoil_DetailedCool;
    1089         143 :                     CompType = cAllCoilTypes(DataHVACGlobals::Coil_CoolingWaterDetailed);
    1090         386 :                 } else if (state.dataWaterCoils->WaterCoil(tempCoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
    1091         386 :                     CoilTypeNum = SimAirServingZones::CompType::WaterCoil_SimpleHeat;
    1092         386 :                     CompType = cAllCoilTypes(DataHVACGlobals::Coil_HeatingWater);
    1093             :                 }
    1094         822 :                 WaterCoilOnAirLoop = true;
    1095         822 :                 CheckWaterCoilIsOnAirLoop(state, CoilTypeNum, CompType, CompName, WaterCoilOnAirLoop);
    1096         822 :                 if (!WaterCoilOnAirLoop) {
    1097           0 :                     ShowContinueError(state,
    1098           0 :                                       "Controller:WaterCoil = " + state.dataWaterCoils->WaterCoil(tempCoilNum).ControllerName +
    1099             :                                           ". Invalid water controller entry.");
    1100           0 :                     ErrorsFound = true;
    1101             :                 }
    1102             :             }
    1103             :         }
    1104         314 :         state.dataWaterCoils->WaterCoilControllerCheckOneTimeFlag = false;
    1105         314 :         if (ErrorsFound) {
    1106           0 :             ShowFatalError(state, "Program terminated for previous condition.");
    1107             :         }
    1108             :     }
    1109             : 
    1110   137535475 :     if (state.dataWaterCoils->PlantLoopScanFlag(CoilNum) && allocated(state.dataPlnt->PlantLoop)) {
    1111        3100 :         errFlag = false;
    1112       12400 :         ScanPlantLoopsForObject(state,
    1113        3100 :                                 state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1114        3100 :                                 state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType,
    1115        3100 :                                 state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc,
    1116             :                                 errFlag,
    1117             :                                 _,
    1118             :                                 _,
    1119             :                                 _,
    1120             :                                 _,
    1121             :                                 _);
    1122        3100 :         if (errFlag) {
    1123           0 :             ShowFatalError(state, "InitWaterCoil: Program terminated for previous conditions.");
    1124             :         }
    1125        3100 :         state.dataWaterCoils->PlantLoopScanFlag(CoilNum) = false;
    1126             :     }
    1127   137535475 :     if (!state.dataGlobal->SysSizingCalc && state.dataWaterCoils->MySizeFlag(CoilNum)) {
    1128             :         // for each coil, do the sizing once.
    1129        3100 :         SizeWaterCoil(state, CoilNum);
    1130             : 
    1131        3100 :         state.dataWaterCoils->MySizeFlag(CoilNum) = false;
    1132             :     }
    1133             : 
    1134             :     // Do the Begin Environment initializations
    1135   137535475 :     if (state.dataGlobal->BeginEnvrnFlag && state.dataWaterCoils->MyEnvrnFlag(CoilNum)) {
    1136       41464 :         rho = GetDensityGlycol(state,
    1137       20732 :                                state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    1138             :                                DataGlobalConstants::InitConvTemp,
    1139       20732 :                                state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    1140             :                                RoutineName);
    1141             :         // Initialize all report variables to a known state at beginning of simulation
    1142       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilEnergy = 0.0;
    1143       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilEnergy = 0.0;
    1144       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilEnergy = 0.0;
    1145       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate = 0.0;
    1146       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate = 0.0;
    1147       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate = 0.0;
    1148             : 
    1149             :         // The rest of the one time initializations
    1150       20732 :         AirInletNode = state.dataWaterCoils->WaterCoil(CoilNum).AirInletNodeNum;
    1151       20732 :         WaterInletNode = state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum;
    1152       20732 :         WaterOutletNode = state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum;
    1153             : 
    1154       20732 :         state.dataWaterCoils->DesCpAir(CoilNum) = PsyCpAirFnW(0.0);
    1155       20732 :         state.dataWaterCoils->DesUARangeCheck(CoilNum) = (-1568.6 * state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat + 20.157);
    1156             : 
    1157       38767 :         if ((state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) ||
    1158       18035 :             (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling)) { // 'Cooling'
    1159        3569 :             Node(WaterInletNode).Temp = 5.0;
    1160             : 
    1161       10707 :             Cp = GetSpecificHeatGlycol(state,
    1162        3569 :                                        state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    1163        3569 :                                        Node(WaterInletNode).Temp,
    1164        3569 :                                        state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    1165             :                                        RoutineName);
    1166             : 
    1167        3569 :             Node(WaterInletNode).Enthalpy = Cp * Node(WaterInletNode).Temp;
    1168        3569 :             Node(WaterInletNode).Quality = 0.0;
    1169        3569 :             Node(WaterInletNode).Press = 0.0;
    1170        3569 :             Node(WaterInletNode).HumRat = 0.0;
    1171             :         }
    1172             : 
    1173       20732 :         if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) { // 'Heating'
    1174       17163 :             Node(WaterInletNode).Temp = 60.0;
    1175             : 
    1176       51489 :             Cp = GetSpecificHeatGlycol(state,
    1177       17163 :                                        state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    1178       17163 :                                        Node(WaterInletNode).Temp,
    1179       17163 :                                        state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    1180             :                                        RoutineName);
    1181             : 
    1182       17163 :             Node(WaterInletNode).Enthalpy = Cp * Node(WaterInletNode).Temp;
    1183       17163 :             Node(WaterInletNode).Quality = 0.0;
    1184       17163 :             Node(WaterInletNode).Press = 0.0;
    1185       17163 :             Node(WaterInletNode).HumRat = 0.0;
    1186       17163 :             state.dataWaterCoils->MyUAAndFlowCalcFlag(CoilNum) = false;
    1187             :             // fill values for variable UA
    1188       17163 :             CpAirStd = PsyCpAirFnW(0.0);
    1189       17163 :             state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate =
    1190       17163 :                 state.dataEnvrn->StdRhoAir * state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate;
    1191       17163 :             state.dataWaterCoils->WaterCoil(CoilNum).LiquidSideNominalConvect =
    1192       34326 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoil * (state.dataWaterCoils->WaterCoil(CoilNum).RatioAirSideToWaterSideConvect + 1) /
    1193       17163 :                 state.dataWaterCoils->WaterCoil(CoilNum).RatioAirSideToWaterSideConvect;
    1194       34326 :             state.dataWaterCoils->WaterCoil(CoilNum).AirSideNominalConvect = state.dataWaterCoils->WaterCoil(CoilNum).RatioAirSideToWaterSideConvect *
    1195       17163 :                                                                              state.dataWaterCoils->WaterCoil(CoilNum).LiquidSideNominalConvect;
    1196             :         } else {
    1197        3569 :             state.dataWaterCoils->MyUAAndFlowCalcFlag(CoilNum) = false;
    1198             :         }
    1199             : 
    1200       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate = rho * state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    1201             : 
    1202       62196 :         InitComponentNodes(state,
    1203             :                            0.0,
    1204       20732 :                            state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate,
    1205       20732 :                            state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum,
    1206       20732 :                            state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum);
    1207             : 
    1208             :         // effective fin diameter for detailed flat fin coil
    1209       20732 :         if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    1210         872 :             state.dataWaterCoils->WaterCoil(CoilNum).EffectiveFinDiam =
    1211        1744 :                 std::sqrt(4.0 * state.dataWaterCoils->WaterCoil(CoilNum).FinDiam * state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth /
    1212        1744 :                           (DataGlobalConstants::Pi * state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubeRows *
    1213         872 :                            state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow));
    1214             : 
    1215             :             //   calculate fixed geometric parameters of the coil:
    1216             :             //   Total Area
    1217         872 :             state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea =
    1218         872 :                 state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideSurfArea + state.dataWaterCoils->WaterCoil(CoilNum).FinSurfArea;
    1219             :             //   Effective Tube Inside Diameter - the model assumes that the coil
    1220             :             //   can be simulated as a tube with an equivalent hydraulic diameter.
    1221        2616 :             state.dataWaterCoils->WaterCoil(CoilNum).CoilEffectiveInsideDiam = 4.0 * state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea *
    1222        1744 :                                                                                state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth /
    1223         872 :                                                                                state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1224             :             //   Ratio of tube outside diameter to effective fin diameter should always
    1225             :             //   be less than 1
    1226         872 :             TubeToFinDiamRatio = state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideDiam / state.dataWaterCoils->WaterCoil(CoilNum).EffectiveFinDiam;
    1227         872 :             if (TubeToFinDiamRatio > 1.0) {
    1228           0 :                 ShowWarningError(state, format("InitWaterCoil: Detailed Flat Fin Coil, TubetoFinDiamRatio > 1.0, [{:.4R}]", TubeToFinDiamRatio));
    1229             :                 // reset tube depth spacing and recalc dependent parameters
    1230           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).TubeDepthSpacing *= (pow_2(TubeToFinDiamRatio) + 0.1);
    1231           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth =
    1232           0 :                     state.dataWaterCoils->WaterCoil(CoilNum).TubeDepthSpacing * state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubeRows;
    1233           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).EffectiveFinDiam =
    1234           0 :                     std::sqrt(4.0 * state.dataWaterCoils->WaterCoil(CoilNum).FinDiam * state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth /
    1235           0 :                               (DataGlobalConstants::Pi * state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubeRows *
    1236           0 :                                state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow));
    1237           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).CoilEffectiveInsideDiam = 4.0 * state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea *
    1238           0 :                                                                                    state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth /
    1239           0 :                                                                                    state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1240           0 :                 TubeToFinDiamRatio =
    1241           0 :                     state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideDiam / state.dataWaterCoils->WaterCoil(CoilNum).EffectiveFinDiam;
    1242           0 :                 ShowContinueError(
    1243           0 :                     state, format("  Resetting tube depth spacing to {:.4R} meters", state.dataWaterCoils->WaterCoil(CoilNum).TubeDepthSpacing));
    1244           0 :                 ShowContinueError(state, format("  Resetting coil depth to {:.4R} meters", state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth));
    1245             :             }
    1246             : 
    1247         872 :             CalcDryFinEffCoef(state, TubeToFinDiamRatio, state.dataWaterCoils->CoefSeries);
    1248             : 
    1249         872 :             state.dataWaterCoils->WaterCoil(CoilNum).DryFinEfficncyCoef = state.dataWaterCoils->CoefSeries;
    1250             : 
    1251         872 :             FinDiamVar = 0.5 * (state.dataWaterCoils->WaterCoil(CoilNum).EffectiveFinDiam - state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideDiam);
    1252             : 
    1253         872 :             state.dataWaterCoils->WaterCoil(CoilNum).GeometryCoef1 =
    1254         872 :                 0.159 *
    1255         872 :                 std::pow(state.dataWaterCoils->WaterCoil(CoilNum).FinThickness / state.dataWaterCoils->WaterCoil(CoilNum).CoilEffectiveInsideDiam,
    1256         872 :                          -0.065) *
    1257         872 :                 std::pow(state.dataWaterCoils->WaterCoil(CoilNum).FinThickness / FinDiamVar, 0.141);
    1258         872 :             state.dataWaterCoils->WaterCoil(CoilNum).GeometryCoef2 =
    1259        1744 :                 -0.323 * std::pow(state.dataWaterCoils->WaterCoil(CoilNum).FinSpacing / FinDiamVar, 0.049) *
    1260         872 :                 std::pow(state.dataWaterCoils->WaterCoil(CoilNum).EffectiveFinDiam / state.dataWaterCoils->WaterCoil(CoilNum).TubeDepthSpacing,
    1261         872 :                          0.549) *
    1262         872 :                 std::pow(state.dataWaterCoils->WaterCoil(CoilNum).FinThickness / state.dataWaterCoils->WaterCoil(CoilNum).FinSpacing, -0.028);
    1263             : 
    1264             :             // Set some initial values for simulation
    1265         872 :             state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveConstCoef = -10.57;
    1266         872 :             state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope = 3.3867;
    1267         872 :             state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope = 3.3867;
    1268         872 :             state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveConst = -10.57;
    1269             :             // Set Saved Values to Zero
    1270         872 :             state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetSaved = 0.0;
    1271         872 :             state.dataWaterCoils->WaterCoil(CoilNum).MeanWaterTempSaved = 0.0;
    1272         872 :             state.dataWaterCoils->WaterCoil(CoilNum).InWaterTempSaved = 0.0;
    1273         872 :             state.dataWaterCoils->WaterCoil(CoilNum).OutWaterTempSaved = 0.0;
    1274             : 
    1275             :         } // End the Detailed Flat Fin Coil Initialization
    1276             : 
    1277             :         // Calculation for Cooling Coil, The part between the '@@@' are design condition
    1278             :         // and are calculated only once to calculate standard values for UAs and other physical parameters of
    1279             :         // the cooling coil.
    1280             :         // Basic Idea for UA:  Heat Transfer= UAenthalpybased*(Delta enthalpy), this is a necessity since the
    1281             :         // coil may be Wet or Dry or Partially Wet-Dry, so latent effects are accounted for in this model while
    1282             :         // calculating the UA. A fictitious specific heat is also defined to caculate the conventional UA.
    1283             :         // On the air side, enthalpy capacity rate is the air mass flow rate,while on water side it is
    1284             :         // enthalpy of saturated air at water temperature.
    1285             :         //@@@ DESIGN CONDITION BEGIN HERE @@@
    1286             : 
    1287             :         // Check for zero design cooling capacity as specified by coil design inputs
    1288       59910 :         if (state.dataWaterCoils->MyCoilDesignFlag(CoilNum) &&
    1289       18857 :             (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingSimple) &&
    1290       21554 :             (state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate > 0.0) &&
    1291         411 :             (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate > 0.0)) {
    1292             : 
    1293         401 :             DesInletAirEnth =
    1294         401 :                 PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp, state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat);
    1295         401 :             DesOutletAirEnth =
    1296         401 :                 PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp, state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat);
    1297         401 :             DesSatEnthAtWaterInTemp =
    1298        1203 :                 PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp,
    1299         802 :                            PsyWFnTdpPb(state, state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp, state.dataEnvrn->StdBaroPress));
    1300             :             // check for dry coil
    1301         401 :             DesHumRatAtWaterInTemp =
    1302         401 :                 PsyWFnTdbH(state, state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp, DesSatEnthAtWaterInTemp, RoutineName);
    1303         436 :             if (DesHumRatAtWaterInTemp > state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat &&
    1304          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp > state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp) {
    1305             :                 // if the design outlet air humrat is lower than the saturated air humrat at the design inlet water temp
    1306             :                 // and the design outlet air temperature is higher than the design inlet water temp (i.e, cooling possible),
    1307             :                 // move the design outlet air saturated enthalpy down (i.e., to Twaterin, Wair,out) to allow the coil to size.
    1308          35 :                 DesSatEnthAtWaterInTemp = PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp,
    1309          35 :                                                      state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat) -
    1310             :                                           0.0001;
    1311             :             }
    1312         802 :             if (DesOutletAirEnth >= DesInletAirEnth ||
    1313         401 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp >= state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp) {
    1314           0 :                 ShowWarningError(state,
    1315           0 :                                  "The design cooling capacity is zero for Coil:Cooling:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    1316           0 :                 ShowContinueError(state, "  The maximum water flow rate for this coil will be set to zero and the coil will do no cooling.");
    1317           0 :                 ShowContinueError(state,
    1318           0 :                                   format("  Check the following coil design inputs for problems: Tair,in = {:.4R}",
    1319           0 :                                          state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp));
    1320           0 :                 ShowContinueError(state,
    1321           0 :                                   format("                                                       Wair,in = {:.6R}",
    1322           0 :                                          state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat));
    1323           0 :                 ShowContinueError(state,
    1324           0 :                                   format("                                                       Twater,in = {:.4R}",
    1325           0 :                                          state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp));
    1326           0 :                 ShowContinueError(state,
    1327           0 :                                   format("                                                       Tair,out = {:.4R}",
    1328           0 :                                          state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp));
    1329           0 :                 ShowContinueError(state,
    1330           0 :                                   format("                                                       Wair,out = {:.6R}",
    1331           0 :                                          state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat));
    1332           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = 0.0;
    1333           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate = 0.0;
    1334             :             }
    1335             :         }
    1336             : 
    1337       59910 :         if (state.dataWaterCoils->MyCoilDesignFlag(CoilNum) &&
    1338       18857 :             (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingSimple) &&
    1339       21554 :             (state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate > 0.0) &&
    1340         411 :             (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate > 0.0)) { // 'Cooling'
    1341             : 
    1342         401 :             state.dataWaterCoils->MyCoilDesignFlag(CoilNum) = false;
    1343         401 :             state.dataWaterCoils->NoSatCurveIntersect = false;
    1344         401 :             state.dataWaterCoils->BelowInletWaterTemp = false;
    1345         401 :             state.dataWaterCoils->CBFTooLarge = false;
    1346         401 :             state.dataWaterCoils->NoExitCondReset = false;
    1347         835 :             for (Ipass = 1; Ipass <= 2; ++Ipass) {
    1348         759 :                 if (Ipass == 2) {
    1349         697 :                     if (!state.dataWaterCoils->NoSatCurveIntersect && !state.dataWaterCoils->BelowInletWaterTemp &&
    1350         339 :                         !state.dataWaterCoils->CBFTooLarge) {
    1351         282 :                         goto Inlet_Conditions_Loop_exit; // coil UA calcs OK
    1352             :                     } else {
    1353         228 :                         ShowWarningError(state,
    1354         152 :                                          "In calculating the design coil UA for Coil:Cooling:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    1355          76 :                         if (state.dataWaterCoils->NoSatCurveIntersect) {
    1356          14 :                             ShowContinueError(state, "no apparatus dew-point can be found for the initial entering and leaving conditions;");
    1357             :                         }
    1358          76 :                         if (state.dataWaterCoils->BelowInletWaterTemp) {
    1359           6 :                             ShowContinueError(state, "the apparatus dew-point is below the coil design inlet water temperature;");
    1360             :                         }
    1361          76 :                         if (state.dataWaterCoils->CBFTooLarge) {
    1362          58 :                             ShowContinueError(state, "the coil bypass factor is unrealistically large;");
    1363             :                         }
    1364          76 :                         if (!state.dataWaterCoils->NoExitCondReset) {
    1365           8 :                             ShowContinueError(state, "the coil outlet design conditions will be changed to correct the problem.");
    1366             :                         }
    1367         228 :                         ShowContinueError(
    1368             :                             state,
    1369         152 :                             format("The initial design conditions are: Tair,in = {:.4R}", state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp));
    1370         228 :                         ShowContinueError(state,
    1371         228 :                                           format("                                   Wair,in = {:.6R}",
    1372         152 :                                                  state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat));
    1373         228 :                         ShowContinueError(state,
    1374         228 :                                           format("                                   Twater,in = {:.4R}",
    1375         152 :                                                  state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp));
    1376         228 :                         ShowContinueError(state,
    1377         228 :                                           format("                                   Tair,out = {:.4R}",
    1378         152 :                                                  state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp));
    1379         228 :                         ShowContinueError(state,
    1380         228 :                                           format("                                   Wair,out = {:.6R}",
    1381         152 :                                                  state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat));
    1382          76 :                         if (!state.dataWaterCoils->NoExitCondReset) {
    1383           8 :                             ShowContinueError(state, format("The revised design conditions are: Tair,out = {:.4R}", state.dataWaterCoils->TOutNew));
    1384           8 :                             ShowContinueError(state, format("                                   Wair,out = {:.6R}", state.dataWaterCoils->WOutNew));
    1385           8 :                             state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat = state.dataWaterCoils->WOutNew;
    1386           8 :                             state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp = state.dataWaterCoils->TOutNew;
    1387             :                             // update outlet air conditions used for sizing
    1388          16 :                             std::string CompType;
    1389           8 :                             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) {
    1390           0 :                                 CompType = cAllCoilTypes(Coil_CoolingWaterDetailed);
    1391             :                             } else {
    1392           8 :                                 CompType = cAllCoilTypes(Coil_CoolingWater);
    1393             :                             }
    1394          24 :                             state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(
    1395          16 :                                 state, state.dataWaterCoils->WaterCoil(CoilNum).Name, CompType, state.dataWaterCoils->TOutNew);
    1396          24 :                             state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(
    1397          16 :                                 state, state.dataWaterCoils->WaterCoil(CoilNum).Name, CompType, state.dataWaterCoils->WOutNew);
    1398             :                             // end update outlet air conditions used for sizing
    1399             :                         }
    1400             :                     }
    1401             :                 }
    1402             : 
    1403             :                 // Volume flow rate being converted to mass flow rate for water
    1404         477 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate =
    1405         477 :                     state.dataEnvrn->StdRhoAir * state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate;
    1406             : 
    1407             :                 // Enthalpy of Air at Inlet design conditions
    1408         477 :                 DesInletAirEnth =
    1409         477 :                     PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp, state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat);
    1410             : 
    1411             :                 // Enthalpy of Air at outlet at design conditions
    1412         477 :                 DesOutletAirEnth = PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp,
    1413         477 :                                               state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat);
    1414             : 
    1415             :                 // already calculated above and possibly reset if dry coil
    1416             :                 //        ! Enthalpy of Water at Inlet design conditions
    1417             :                 //        DesSatEnthAtWaterInTemp =PsyHFnTdbW(WaterCoil(CoilNum)%DesInletWaterTemp, &
    1418             :                 //                                             PsyWFnTdpPb(state, WaterCoil(CoilNum)%DesInletWaterTemp,StdBaroPress))
    1419             : 
    1420             :                 // Total Coil Load from Inlet and Outlet Air States (which include fan heat as appropriate).
    1421         477 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad =
    1422         477 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate * (DesInletAirEnth - DesOutletAirEnth);
    1423             : 
    1424             :                 // Enthalpy of Water at Intlet design conditions
    1425        1431 :                 Cp = GetSpecificHeatGlycol(state,
    1426         477 :                                            state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    1427         477 :                                            state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp,
    1428         477 :                                            state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    1429             :                                            RoutineName);
    1430             : 
    1431         954 :                 DesOutletWaterTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp +
    1432         954 :                                      state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad /
    1433         477 :                                          (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate * Cp);
    1434             : 
    1435         477 :                 DesSatEnthAtWaterOutTemp = PsyHFnTdbW(DesOutletWaterTemp, PsyWFnTdpPb(state, DesOutletWaterTemp, state.dataEnvrn->StdBaroPress));
    1436         477 :                 DesEnthAtWaterOutTempAirInHumRat = PsyHFnTdbW(DesOutletWaterTemp, state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat);
    1437         477 :                 DesEnthWaterOut = min(DesSatEnthAtWaterOutTemp, DesEnthAtWaterOutTempAirInHumRat);
    1438             : 
    1439             :                 // dry coil test
    1440         911 :                 if (state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat < state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat &&
    1441         434 :                     DesHumRatAtWaterInTemp < state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat) { // wet coil
    1442             : 
    1443             :                     // Calculations for BYPASS FACTOR at design conditions
    1444             :                     // Calculate "slope" of temperature vs. humidity ratio between entering and leaving states
    1445         434 :                     SlopeTempVsHumRatio =
    1446         434 :                         (state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp) /
    1447         868 :                         max((state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat -
    1448         434 :                              state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat),
    1449             :                             SmallNo);
    1450             : 
    1451             :                     // Initialize iteration parameters
    1452         434 :                     DesAirTempApparatusDewPt =
    1453         868 :                         PsyTdpFnWPb(state, state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat, state.dataEnvrn->OutBaroPress);
    1454             : 
    1455             :                     // Iterating to calculate Apparatus Dew Point Temperature at Design Conditions
    1456        2237 :                     for (iter = 1; iter <= itmax; ++iter) {
    1457             : 
    1458             :                         // Calculate apparatus dewpoint and compare with predicted value
    1459             :                         // using entering conditions and SlopeTempVsHumRatio
    1460        2237 :                         DesAirHumRatApparatusDewPt = PsyWFnTdpPb(state, DesAirTempApparatusDewPt, state.dataEnvrn->OutBaroPress);
    1461             : 
    1462             :                         // Initial Estimate for apparatus Dew Point Temperature
    1463        2237 :                         TempApparatusDewPtEstimate =
    1464        2237 :                             state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp -
    1465        2237 :                             SlopeTempVsHumRatio * (state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat - DesAirHumRatApparatusDewPt);
    1466             : 
    1467             :                         // Iterating to calculate Apparatus Dew Point Temperature at Design Condition
    1468        2237 :                         error = DesAirTempApparatusDewPt - TempApparatusDewPtEstimate;
    1469        2237 :                         Iterate(ResultX, 0.01, DesAirTempApparatusDewPt, error, X1, Y1, iter, icvg);
    1470        2237 :                         DesAirTempApparatusDewPt = ResultX;
    1471             : 
    1472             :                         // If converged, exit loop
    1473        2237 :                         if (icvg == 1) {
    1474         408 :                             goto App_DewPoint_Loop1_exit;
    1475             :                         }
    1476             : 
    1477             :                         // If not converged due to low Humidity Ratio approximate value at outlet conditions
    1478        1829 :                         if (iter == itmax) {
    1479          26 :                             state.dataWaterCoils->NoSatCurveIntersect = true;
    1480          26 :                             DesAirTempApparatusDewPt =
    1481          52 :                                 PsyTdpFnWPb(state, state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat, state.dataEnvrn->OutBaroPress);
    1482          26 :                             DesAirHumRatApparatusDewPt = PsyWFnTdpPb(state, DesAirTempApparatusDewPt, state.dataEnvrn->OutBaroPress);
    1483          26 :                             goto App_DewPoint_Loop1_exit;
    1484             :                         }
    1485             : 
    1486             :                         // End of Loop for Iteration
    1487             :                     }
    1488           0 :                 App_DewPoint_Loop1_exit:;
    1489             : 
    1490             :                     // Air enthalpy at apparatus dew point at design conditions
    1491         434 :                     DesAirApparatusDewPtEnth = PsyHFnTdbW(DesAirTempApparatusDewPt, DesAirHumRatApparatusDewPt);
    1492             : 
    1493             :                     // Calculate bypass factor from enthalpies calculated above.
    1494         434 :                     DesBypassFactor = (DesOutletAirEnth - DesAirApparatusDewPtEnth) / (DesInletAirEnth - DesAirApparatusDewPtEnth);
    1495             : 
    1496             :                     // Check for bypass factor for unsuitable value. Note that bypass factor is never used in the coil calculation
    1497         434 :                     if ((DesBypassFactor > 0.5) || (DesBypassFactor < 0.0)) {
    1498         116 :                         state.dataWaterCoils->CBFTooLarge = true;
    1499         116 :                         DesBypassFactor = 0.37;
    1500             :                     }
    1501             : 
    1502         434 :                     if (DesEnthWaterOut > DesInletAirEnth) {
    1503           0 :                         ShowWarningError(state,
    1504           0 :                                          "In calculating the design coil UA for Coil:Cooling:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    1505           0 :                         ShowContinueError(state, "the outlet chilled water design enthalpy is greater than the inlet air design enthalpy.");
    1506           0 :                         ShowContinueError(state,
    1507           0 :                                           format("To correct this condition the design chilled water flow rate will be increased from {:.5R}",
    1508           0 :                                                  state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate));
    1509           0 :                         EnthCorrFrac = (DesEnthWaterOut - DesInletAirEnth) / (DesEnthWaterOut - DesSatEnthAtWaterInTemp);
    1510           0 :                         state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate *= (1.0 + 2.0 * EnthCorrFrac);
    1511           0 :                         ShowContinueError(state, format("to {:.5R} m3/s", state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate));
    1512           0 :                         state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate =
    1513           0 :                             rho * state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    1514           0 :                         DesOutletWaterTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp +
    1515           0 :                                              state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad /
    1516           0 :                                                  (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate * Cp);
    1517           0 :                         DesSatEnthAtWaterOutTemp =
    1518           0 :                             PsyHFnTdbW(DesOutletWaterTemp, PsyWFnTdpPb(state, DesOutletWaterTemp, state.dataEnvrn->StdBaroPress));
    1519           0 :                         DesEnthAtWaterOutTempAirInHumRat = PsyHFnTdbW(DesOutletWaterTemp, state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat);
    1520           0 :                         DesEnthWaterOut = min(DesSatEnthAtWaterOutTemp, DesEnthAtWaterOutTempAirInHumRat);
    1521             :                     }
    1522             : 
    1523             :                     // Determine air-side coefficient, UACoilExternal, assuming that the
    1524             :                     // surface temperature is at the apparatus dewpoint temperature
    1525         434 :                     if (DesAirApparatusDewPtEnth <= DesSatEnthAtWaterInTemp) state.dataWaterCoils->BelowInletWaterTemp = true;
    1526         434 :                     if ((DesInletAirEnth - DesEnthWaterOut) > SmallNo && (DesOutletAirEnth - DesSatEnthAtWaterInTemp) > SmallNo) {
    1527         868 :                         LogMeanEnthDiff = ((DesInletAirEnth - DesEnthWaterOut) - (DesOutletAirEnth - DesSatEnthAtWaterInTemp)) /
    1528         434 :                                           std::log((DesInletAirEnth - DesEnthWaterOut) / (DesOutletAirEnth - DesSatEnthAtWaterInTemp));
    1529             :                     } else {
    1530           0 :                         LogMeanEnthDiff = 2000.0; // UA will be 1/2 the design coil load
    1531             :                     }
    1532         434 :                     DesUACoilExternalEnth = state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad / LogMeanEnthDiff;
    1533         434 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal =
    1534         434 :                         DesUACoilExternalEnth * PsyCpAirFnW(state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat);
    1535             : 
    1536         720 :                     if (Ipass == 1 && (state.dataWaterCoils->NoSatCurveIntersect || state.dataWaterCoils->CBFTooLarge ||
    1537         286 :                                        state.dataWaterCoils->BelowInletWaterTemp)) {
    1538             :                         // reset outlet conditions to 90% relative humidity at the same outlet enthalpy
    1539          76 :                         state.dataWaterCoils->TOutNew = TdbFnHRhPb(state, DesOutletAirEnth, 0.9, state.dataEnvrn->StdBaroPress);
    1540          76 :                         state.dataWaterCoils->WOutNew = PsyWFnTdbH(state, state.dataWaterCoils->TOutNew, DesOutletAirEnth);
    1541         151 :                         if (state.dataWaterCoils->WOutNew >= state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat ||
    1542          75 :                             state.dataWaterCoils->TOutNew > state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp) {
    1543          68 :                             state.dataWaterCoils->NoExitCondReset = true;
    1544             :                         }
    1545          76 :                         goto Inlet_Conditions_Loop_loop;
    1546             :                     }
    1547             : 
    1548         358 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal * 3.30;
    1549             :                     // Overall heat transfer coefficient
    1550         716 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal = 1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal +
    1551         358 :                                                                                   1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal);
    1552             : 
    1553             :                 } else { // dry coil
    1554             : 
    1555          43 :                     if (DesOutletWaterTemp > state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp) {
    1556           0 :                         ShowWarningError(state,
    1557           0 :                                          "In calculating the design coil UA for Coil:Cooling:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    1558           0 :                         ShowContinueError(state, "the outlet chilled water design temperature is greater than the inlet air design temperature.");
    1559           0 :                         ShowContinueError(state,
    1560           0 :                                           format("To correct this condition the design chilled water flow rate will be increased from {:.5R}",
    1561           0 :                                                  state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate));
    1562           0 :                         TempCorrFrac = (DesOutletWaterTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp) /
    1563           0 :                                        (DesOutletWaterTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp);
    1564           0 :                         state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate *= (1.0 + 2.0 * TempCorrFrac);
    1565           0 :                         ShowContinueError(state, format("to {:.5R} m3/s", state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate));
    1566           0 :                         state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate =
    1567           0 :                             rho * state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    1568           0 :                         DesOutletWaterTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp +
    1569           0 :                                              state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad /
    1570           0 :                                                  (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate * Cp);
    1571             :                     }
    1572             : 
    1573          86 :                     if ((state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp - DesOutletWaterTemp) > SmallNo &&
    1574          43 :                         (state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp) >
    1575             :                             SmallNo) {
    1576         129 :                         LogMeanTempDiff = ((state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp - DesOutletWaterTemp) -
    1577          86 :                                            (state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp -
    1578          43 :                                             state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp)) /
    1579          86 :                                           std::log((state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp - DesOutletWaterTemp) /
    1580          86 :                                                    (state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp -
    1581          43 :                                                     state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp));
    1582          43 :                         state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal =
    1583          43 :                             state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad / LogMeanTempDiff;
    1584             :                     } else {
    1585           0 :                         state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal =
    1586           0 :                             state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad / 2.0; // make the UA large
    1587             :                     }
    1588          43 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal * 3.30;
    1589             :                     // Overall heat transfer coefficient
    1590          86 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal = 1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal +
    1591          43 :                                                                                   1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal);
    1592          43 :                     goto Inlet_Conditions_Loop_exit;
    1593             :                 }
    1594             : 
    1595         434 :             Inlet_Conditions_Loop_loop:;
    1596             :             }
    1597          76 :         Inlet_Conditions_Loop_exit:;
    1598             : 
    1599             :             // estimate the heat external transfer surface area using typical design over all U value
    1600         401 :             state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea = EstimateHEXSurfaceArea(state, CoilNum);
    1601             :             // calculate internal and external "UA per external surface area"
    1602         401 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalPerUnitArea =
    1603         401 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1604         401 :             state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea =
    1605         401 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1606             :             // approximate the dry UA as 1.0 times wet UA
    1607         401 :             state.dataWaterCoils->WaterCoil(CoilNum).UADryExtPerUnitArea = state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea;
    1608             : 
    1609             :             // Now use SolveRoot to "invert" the cooling coil model to obtain the UA given the specified design inlet and outlet conditions
    1610             :             // Note that the UAs we have obtained so far are rough estimates that are the starting points for the the following iterative
    1611             :             //   calulation of the actual UAs.
    1612         401 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp;
    1613         401 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat;
    1614         401 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp;
    1615         401 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate = rho * state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    1616         401 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate;
    1617             :             // set the lower and upper limits on the UA
    1618         401 :             UA0 = 0.1 * state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal;
    1619         401 :             UA1 = 10.0 * state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal;
    1620             :             // Invert the simple cooling coil model: given the design inlet conditions and the design load, find the design UA
    1621      315320 :             auto f = [&state, CoilNum](Real64 const UA) {
    1622             :                 int FanOpMode;
    1623             :                 Real64 PartLoadRatio;
    1624             : 
    1625        7883 :                 FanOpMode = ContFanCycCoil;
    1626        7883 :                 PartLoadRatio = 1.0;
    1627       23649 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal = UA;
    1628       31532 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal * 3.3;
    1629       39415 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal = 1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal +
    1630       15766 :                                                                               1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal);
    1631       23649 :                 state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea = EstimateHEXSurfaceArea(state, CoilNum);
    1632       15766 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalPerUnitArea =
    1633       31532 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1634       15766 :                 state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea =
    1635       31532 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1636       31532 :                 state.dataWaterCoils->WaterCoil(CoilNum).UADryExtPerUnitArea = state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea;
    1637             : 
    1638       15766 :                 CoolingCoil(state, CoilNum, true, state.dataWaterCoils->DesignCalc, FanOpMode, PartLoadRatio);
    1639             : 
    1640       23649 :                 return (state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad -
    1641       15766 :                         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate) /
    1642       15766 :                        state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad;
    1643         401 :             };
    1644         401 :             General::SolveRoot(state, 0.001, MaxIte, SolFla, UA, f, UA0, UA1);
    1645             :             // if the numerical inversion failed, issue error messages.
    1646         401 :             if (SolFla == -1) {
    1647           0 :                 ShowSevereError(state, "Calculation of cooling coil design UA failed for coil " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    1648           0 :                 ShowContinueError(state, "  Iteration limit exceeded in calculating coil UA");
    1649           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal = UA0 * 10.0;
    1650           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal * 3.3;
    1651           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal = 1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal +
    1652           0 :                                                                               1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal);
    1653           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea = EstimateHEXSurfaceArea(state, CoilNum);
    1654           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalPerUnitArea =
    1655           0 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1656           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea =
    1657           0 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1658           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UADryExtPerUnitArea = state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea;
    1659           0 :                 ShowContinueError(state, format(" Coil design UA set to {:.6R} [W/C]", state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal));
    1660         401 :             } else if (SolFla == -2) {
    1661          11 :                 ShowSevereError(state, "Calculation of cooling coil design UA failed for coil " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    1662          11 :                 ShowContinueError(state, "  Bad starting values for UA");
    1663          11 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal = UA0 * 10.0;
    1664          11 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal * 3.3;
    1665          22 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal = 1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal +
    1666          11 :                                                                               1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal);
    1667          11 :                 state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea = EstimateHEXSurfaceArea(state, CoilNum);
    1668          11 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalPerUnitArea =
    1669          11 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1670          11 :                 state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea =
    1671          11 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1672          11 :                 state.dataWaterCoils->WaterCoil(CoilNum).UADryExtPerUnitArea = state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea;
    1673          11 :                 ShowContinueError(state, format(" Coil design UA set to {:.6R} [W/C]", state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal));
    1674             :             }
    1675             : 
    1676             :             // cooling coil surface area
    1677         401 :             state.dataWaterCoils->SurfaceArea = state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    1678             : 
    1679             :             // cooling coil overall UA value
    1680         401 :             state.dataWaterCoils->UATotal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal;
    1681             : 
    1682             :             // save the design internal and external UAs
    1683         401 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternalDes = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal;
    1684         401 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalDes = state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal;
    1685             :         }
    1686             : 
    1687             :         //@@@@ DESIGN CONDITION END HERE @@@@
    1688             : 
    1689             :         // Calculate rated Total, latent, sensible capacity, SHR, effectiveness
    1690       20732 :         if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
    1691       17163 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp = 16.6;
    1692       17163 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat = PsyWFnTdbRhPb(state, 16.6, 0.5, state.dataEnvrn->StdBaroPress, RoutineName);
    1693       17163 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp = 82.2;
    1694             :         } else {
    1695        3569 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp = 26.67;
    1696        3569 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat = PsyWFnTdbTwbPb(state, 26.67, 19.44, state.dataEnvrn->StdBaroPress, RoutineName);
    1697        3569 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp = 6.67;
    1698             :         }
    1699       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).InletAirEnthalpy =
    1700       20732 :             PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp, state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat);
    1701       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate;
    1702       20732 :         state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate =
    1703       20732 :             state.dataEnvrn->StdRhoAir * state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate;
    1704       20732 :         CapacitanceAir =
    1705       20732 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate * PsyCpAirFnW(state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat);
    1706             : 
    1707       62196 :         Cp = GetSpecificHeatGlycol(state,
    1708       20732 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    1709       20732 :                                    state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp,
    1710       20732 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    1711             :                                    RoutineName);
    1712             : 
    1713       20732 :         state.dataWaterCoils->CapacitanceWater = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate * Cp;
    1714       20732 :         state.dataWaterCoils->CMin = min(CapacitanceAir, state.dataWaterCoils->CapacitanceWater);
    1715       20732 :         if (state.dataWaterCoils->CMin > 0.0) {
    1716       20461 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) {
    1717        2687 :                 CoolingCoil(state, CoilNum, FirstHVACIteration, state.dataWaterCoils->DesignCalc, ContFanCycCoil, 1.0);
    1718        2687 :                 state.dataWaterCoils->CoilEffectiveness =
    1719        5374 :                     (state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp) /
    1720        5374 :                     (state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp) *
    1721        2687 :                     (CapacitanceAir / state.dataWaterCoils->CMin);
    1722        5374 :                 state.dataWaterCoils->RatedLatentCapacity = state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate -
    1723        2687 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate;
    1724        5374 :                 state.dataWaterCoils->RatedSHR = state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate /
    1725        2687 :                                                  state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate;
    1726       17774 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling) {
    1727         872 :                 CalcDetailFlatFinCoolingCoil(state, CoilNum, state.dataWaterCoils->DesignCalc, ContFanCycCoil, 1.0);
    1728         872 :                 state.dataWaterCoils->CoilEffectiveness =
    1729        1744 :                     (state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp) /
    1730        1744 :                     (state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp) *
    1731         872 :                     (CapacitanceAir / state.dataWaterCoils->CMin);
    1732        1744 :                 state.dataWaterCoils->RatedLatentCapacity = state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate -
    1733         872 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate;
    1734        1744 :                 state.dataWaterCoils->RatedSHR = state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate /
    1735         872 :                                                  state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate;
    1736       16902 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
    1737       16902 :                 CalcSimpleHeatingCoil(state, CoilNum, ContFanCycCoil, 1.0, state.dataWaterCoils->DesignCalc);
    1738       16902 :                 state.dataWaterCoils->CoilEffectiveness =
    1739       33804 :                     (state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp) /
    1740       33804 :                     (state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp - state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp) *
    1741       16902 :                     (CapacitanceAir / state.dataWaterCoils->CMin);
    1742             :             }
    1743             :         } else {
    1744         271 :             state.dataWaterCoils->CoilEffectiveness = 0.0;
    1745         271 :             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate = 0.0;
    1746         271 :             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate = 0.0;
    1747         271 :             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate = 0.0;
    1748         271 :             state.dataWaterCoils->RatedLatentCapacity = 0.0;
    1749         271 :             state.dataWaterCoils->RatedSHR = 0.0;
    1750             :         }
    1751       20732 :         state.dataWaterCoils->MyEnvrnFlag(CoilNum) = false;
    1752             : 
    1753             :     } // End If for the Begin Environment initializations
    1754             : 
    1755   137535475 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    1756   137191014 :         state.dataWaterCoils->MyEnvrnFlag(CoilNum) = true;
    1757             :     }
    1758             : 
    1759   137535475 :     if (!state.dataGlobal->DoingSizing) {
    1760   137533328 :         if (state.dataWaterCoils->MyCoilReportFlag(CoilNum)) {
    1761             :             // create predefined report entries
    1762        3100 :             state.dataWaterCoils->MyCoilReportFlag(CoilNum) = false;
    1763        3100 :             switch (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType) {
    1764        2554 :             case DataPlant::PlantEquipmentType::CoilWaterSimpleHeating: {
    1765        2554 :                 if (state.dataWaterCoils->RptCoilHeaderFlag(1)) {
    1766         303 :                     print(state.files.eio, "{}", "! <Water Heating Coil Capacity Information>,Component Type,Name,Nominal Total Capacity {W}\n");
    1767         303 :                     state.dataWaterCoils->RptCoilHeaderFlag(1) = false;
    1768             :                 }
    1769        5108 :                 PreDefTableEntry(
    1770        5108 :                     state, state.dataOutRptPredefined->pdchHeatCoilType, state.dataWaterCoils->WaterCoil(CoilNum).Name, "Coil:Heating:Water");
    1771       10216 :                 PreDefTableEntry(state,
    1772        2554 :                                  state.dataOutRptPredefined->pdchHeatCoilDesCap,
    1773        2554 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1774        2554 :                                  state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate);
    1775       10216 :                 PreDefTableEntry(state,
    1776        2554 :                                  state.dataOutRptPredefined->pdchHeatCoilNomCap,
    1777        2554 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1778        2554 :                                  state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate);
    1779        2554 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, state.dataWaterCoils->WaterCoil(CoilNum).Name, "-");
    1780        2554 :                 addFootNoteSubTable(
    1781             :                     state,
    1782        2554 :                     state.dataOutRptPredefined->pdstHeatCoil,
    1783        2554 :                     "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
    1784        7662 :                 print(state.files.eio,
    1785             :                       "{},{},{:.2R}\n",
    1786             :                       "Water Heating Coil Capacity Information,Coil:Heating:Water",
    1787        2554 :                       state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1788        5108 :                       state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate);
    1789       10216 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilAirFlow(state,
    1790        2554 :                                                                                    state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1791             :                                                                                    "Coil:Heating:Water",
    1792        2554 :                                                                                    state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate,
    1793        2554 :                                                                                    state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize);
    1794       17878 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterHeaterCapacityNodeNums(
    1795             :                     state,
    1796        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1797             :                     "Coil:Heating:Water",
    1798        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate,
    1799        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize,
    1800        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum,
    1801        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum,
    1802        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum); // coil report
    1803        2554 :                 break;
    1804             :             }
    1805         143 :             case DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling: {
    1806         143 :                 if (state.dataWaterCoils->RptCoilHeaderFlag(2)) {
    1807         114 :                     print(state.files.eio,
    1808             :                           "{}\n",
    1809             :                           "! <Water Cooling Coil Capacity Information>,Component Type,Name,Nominal Total "
    1810             :                           "Capacity {W},Nominal Sensible Capacity {W},Nominal Latent Capacity {W},Nominal "
    1811         114 :                           "Sensible Heat Ratio");
    1812         114 :                     state.dataWaterCoils->RptCoilHeaderFlag(2) = false;
    1813             :                 }
    1814         286 :                 state.dataWaterCoils->RatedLatentCapacity = state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate -
    1815         143 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate;
    1816         143 :                 state.dataWaterCoils->RatedSHR = SafeDivide(state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate,
    1817         143 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate);
    1818         286 :                 PreDefTableEntry(state,
    1819         143 :                                  state.dataOutRptPredefined->pdchCoolCoilType,
    1820         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1821         143 :                                  "Coil:Cooling:Water:DetailedGeometry");
    1822         572 :                 PreDefTableEntry(state,
    1823         143 :                                  state.dataOutRptPredefined->pdchCoolCoilDesCap,
    1824         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1825         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate);
    1826         572 :                 PreDefTableEntry(state,
    1827         143 :                                  state.dataOutRptPredefined->pdchCoolCoilTotCap,
    1828         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1829         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate);
    1830         572 :                 PreDefTableEntry(state,
    1831         143 :                                  state.dataOutRptPredefined->pdchCoolCoilSensCap,
    1832         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1833         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate);
    1834         572 :                 PreDefTableEntry(state,
    1835         143 :                                  state.dataOutRptPredefined->pdchCoolCoilLatCap,
    1836         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1837         143 :                                  state.dataWaterCoils->RatedLatentCapacity);
    1838         572 :                 PreDefTableEntry(state,
    1839         143 :                                  state.dataOutRptPredefined->pdchCoolCoilSHR,
    1840         143 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1841         143 :                                  state.dataWaterCoils->RatedSHR);
    1842         143 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, state.dataWaterCoils->WaterCoil(CoilNum).Name, "-");
    1843         143 :                 addFootNoteSubTable(
    1844             :                     state,
    1845         143 :                     state.dataOutRptPredefined->pdstCoolCoil,
    1846         143 :                     "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
    1847         858 :                 print(state.files.eio,
    1848             :                       "{},{},{:.2R},{:.2R},{:.2R},{:.2R}\n",
    1849             :                       "Water Cooling Coil Capacity Information,Coil:Cooling:Water:DetailedGeometry",
    1850         143 :                       state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1851         143 :                       state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate,
    1852         143 :                       state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate,
    1853         143 :                       state.dataWaterCoils->RatedLatentCapacity,
    1854         286 :                       state.dataWaterCoils->RatedSHR);
    1855         572 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilAirFlow(
    1856             :                     state,
    1857         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1858             :                     "Coil:Cooling:Water:DetailedGeometry",
    1859         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate,
    1860         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize); // Coil Report
    1861        1001 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterCoolingCapacity(
    1862             :                     state,
    1863         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1864             :                     "Coil:Cooling:Water:DetailedGeometry",
    1865         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate,
    1866         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize,
    1867         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum,
    1868         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum,
    1869         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum); // Coil Report
    1870         143 :                 break;
    1871             :             }
    1872         403 :             case DataPlant::PlantEquipmentType::CoilWaterCooling: {
    1873         403 :                 if (state.dataWaterCoils->RptCoilHeaderFlag(2)) {
    1874         184 :                     print(state.files.eio,
    1875             :                           "{}\n",
    1876             :                           "! <Water Cooling Coil Capacity Information>,Component Type,Name,Nominal Total "
    1877             :                           "Capacity {W},Nominal Sensible Capacity {W},Nominal Latent Capacity {W},Nominal "
    1878         184 :                           "Sensible Heat Ratio, Nominal Coil UA Value {W/C}, Nominal Coil Surface Area {m2}");
    1879         184 :                     state.dataWaterCoils->RptCoilHeaderFlag(2) = false;
    1880             :                 }
    1881         806 :                 state.dataWaterCoils->RatedLatentCapacity = state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate -
    1882         403 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate;
    1883         403 :                 state.dataWaterCoils->RatedSHR = SafeDivide(state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate,
    1884         403 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate);
    1885         806 :                 PreDefTableEntry(
    1886         806 :                     state, state.dataOutRptPredefined->pdchCoolCoilType, state.dataWaterCoils->WaterCoil(CoilNum).Name, "Coil:Cooling:Water");
    1887        1612 :                 PreDefTableEntry(state,
    1888         403 :                                  state.dataOutRptPredefined->pdchCoolCoilDesCap,
    1889         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1890         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate);
    1891        1612 :                 PreDefTableEntry(state,
    1892         403 :                                  state.dataOutRptPredefined->pdchCoolCoilTotCap,
    1893         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1894         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate);
    1895        1612 :                 PreDefTableEntry(state,
    1896         403 :                                  state.dataOutRptPredefined->pdchCoolCoilSensCap,
    1897         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1898         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate);
    1899        1612 :                 PreDefTableEntry(state,
    1900         403 :                                  state.dataOutRptPredefined->pdchCoolCoilLatCap,
    1901         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1902         403 :                                  state.dataWaterCoils->RatedLatentCapacity);
    1903        1612 :                 PreDefTableEntry(state,
    1904         403 :                                  state.dataOutRptPredefined->pdchCoolCoilSHR,
    1905         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1906         403 :                                  state.dataWaterCoils->RatedSHR);
    1907         403 :                 PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, state.dataWaterCoils->WaterCoil(CoilNum).Name, "-");
    1908        1612 :                 PreDefTableEntry(state,
    1909         403 :                                  state.dataOutRptPredefined->pdchCoolCoilUATotal,
    1910         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1911         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal);
    1912        1612 :                 PreDefTableEntry(state,
    1913         403 :                                  state.dataOutRptPredefined->pdchCoolCoilArea,
    1914         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1915         403 :                                  state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea);
    1916         403 :                 addFootNoteSubTable(
    1917             :                     state,
    1918         403 :                     state.dataOutRptPredefined->pdstCoolCoil,
    1919         403 :                     "Nominal values are gross at rated conditions, i.e., the supply air fan heat and electric power NOT accounted for.");
    1920        3224 :                 print(state.files.eio,
    1921             :                       "{},{},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R},{:.2R}\n",
    1922             :                       "Water Cooling Coil Capacity Information,Coil:Cooling:Water",
    1923         403 :                       state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1924         403 :                       state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate,
    1925         403 :                       state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate,
    1926         403 :                       state.dataWaterCoils->RatedLatentCapacity,
    1927         403 :                       state.dataWaterCoils->RatedSHR,
    1928         403 :                       state.dataWaterCoils->UATotal,
    1929         806 :                       state.dataWaterCoils->SurfaceArea);
    1930        1612 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilAirFlow(
    1931             :                     state,
    1932         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1933             :                     "Coil:Cooling:Water",
    1934         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate,
    1935         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize); // Coil Report
    1936        2821 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterCoolingCapacity(
    1937             :                     state,
    1938         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    1939             :                     "Coil:Cooling:Water",
    1940         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate,
    1941         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize,
    1942         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum,
    1943         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum,
    1944         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum); // Coil Report
    1945         403 :                 break;
    1946             :             }
    1947           0 :             default:
    1948           0 :                 break;
    1949             :             }
    1950        3100 :             if (state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate <= 0.0)
    1951        2659 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate = state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate;
    1952        3100 :             if (state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate <= 0.0)
    1953         883 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate = state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate;
    1954             : 
    1955             :             // call coil model with everthing set at rating point
    1956        3100 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate;
    1957        3100 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp;
    1958        3100 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat =
    1959        3100 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat; // fixed in sizing routine
    1960        6200 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirEnthalpy = Psychrometrics::PsyHFnTdbW(
    1961        6200 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp, state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat);
    1962        9300 :             Real64 DesInletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state,
    1963        3100 :                                                                     state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp,
    1964        3100 :                                                                     state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat,
    1965             :                                                                     DataEnvironment::StdPressureSeaLevel,
    1966        6200 :                                                                     "InitWaterCoils");
    1967        3100 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate;
    1968        3100 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp;
    1969       12400 :             Real64 cp = GetSpecificHeatGlycol(state,
    1970        3100 :                                               state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    1971        3100 :                                               state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp,
    1972        3100 :                                               state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    1973        6200 :                                               "InitWaterCoil");
    1974        3100 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterEnthalpy = cp * state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp;
    1975             : 
    1976        3100 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable = state.dataWaterCoils->WaterCoil(CoilNum).UACoil;
    1977        3100 :             state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingFactor = 0.0;
    1978        3100 :             Real64 holdOutBaroPress = state.dataEnvrn->OutBaroPress;
    1979        3100 :             state.dataEnvrn->OutBaroPress = DataEnvironment::StdPressureSeaLevel; // assume rating is for sea level.
    1980        3100 :             CalcAdjustedCoilUA(state, CoilNum);
    1981             : 
    1982        6200 :             std::string coilTypeName(" ");
    1983             :             // calculate coil sim model at rating point, full load, continuous fan
    1984        3100 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling) {
    1985         143 :                 CalcDetailFlatFinCoolingCoil(state, CoilNum, state.dataWaterCoils->SimCalc, ContFanCycCoil, 1.0);
    1986         143 :                 coilTypeName = "Coil:Cooling:Water:DetailedGeometry";
    1987        2957 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) {
    1988         403 :                 CoolingCoil(state, CoilNum, FirstHVACIteration, state.dataWaterCoils->SimCalc, ContFanCycCoil, 1.0);
    1989         403 :                 coilTypeName = "Coil:Cooling:Water";
    1990        2554 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
    1991        2554 :                 CalcSimpleHeatingCoil(state, CoilNum, ContFanCycCoil, 1.0, state.dataWaterCoils->SimCalc);
    1992        2554 :                 coilTypeName = "Coil:Heating:Water";
    1993             :             }
    1994             : 
    1995             :             // coil outlets
    1996        3100 :             Real64 RatedOutletWetBulb(0.0);
    1997        6200 :             RatedOutletWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state,
    1998        3100 :                                                                 state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp,
    1999        3100 :                                                                 state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat,
    2000             :                                                                 DataEnvironment::StdPressureSeaLevel,
    2001        3100 :                                                                 "InitWaterCoil");
    2002             : 
    2003             :             // call set routine in coil report
    2004        6057 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling ||
    2005        2957 :                 state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) {
    2006        4914 :                 state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
    2007             :                     state,
    2008         546 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    2009             :                     coilTypeName,
    2010         546 :                     state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate, // this is the report variable
    2011         546 :                     state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate, // this is the report variable
    2012         546 :                     state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate,
    2013         546 :                     state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp,
    2014         546 :                     state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat,
    2015             :                     DesInletWetBulb,
    2016         546 :                     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp,
    2017         546 :                     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat,
    2018             :                     RatedOutletWetBulb,
    2019             :                     -999.0,
    2020             :                     -999.0,
    2021             :                     -999.0,
    2022             :                     -999.0); // coil effectiveness
    2023        2554 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
    2024       22986 :                 state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(
    2025             :                     state,
    2026        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    2027             :                     coilTypeName,
    2028        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate, // this is the report variable
    2029        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate, // this is the report variable
    2030        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate,
    2031        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp,
    2032        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat,
    2033             :                     DesInletWetBulb,
    2034        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp,
    2035        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat,
    2036             :                     RatedOutletWetBulb,
    2037             :                     -999.0,
    2038             :                     -999.0,
    2039             :                     -999.0,
    2040             :                     -999.0); // coil effectiveness
    2041             :             }
    2042             :             // now replace the outdoor air conditions set above for one time rating point calc
    2043        3100 :             state.dataEnvrn->OutBaroPress = holdOutBaroPress;
    2044             :         }
    2045             :     }
    2046             : 
    2047             :     // Do the Begin Day initializations
    2048             :     // NONE
    2049             : 
    2050             :     // Do the begin HVAC time step initializations
    2051             :     // NONE
    2052             : 
    2053             :     // Do the following initializations (every time step): This should be the info from
    2054             :     // the previous components outlets or the node data in this section.
    2055             :     // First set the conditions for the air into the coil model
    2056   137535475 :     AirInletNode = state.dataWaterCoils->WaterCoil(CoilNum).AirInletNodeNum;
    2057   137535475 :     WaterInletNode = state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum;
    2058   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate = Node(AirInletNode).MassFlowRate;
    2059   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp = Node(AirInletNode).Temp;
    2060   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat = Node(AirInletNode).HumRat;
    2061   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).InletAirEnthalpy = Node(AirInletNode).Enthalpy;
    2062             : 
    2063   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate = Node(WaterInletNode).MassFlowRate;
    2064   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp = Node(WaterInletNode).Temp;
    2065   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).InletWaterEnthalpy = Node(WaterInletNode).Enthalpy;
    2066             : 
    2067   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable = state.dataWaterCoils->WaterCoil(CoilNum).UACoil;
    2068             : 
    2069   137535475 :     CalcAdjustedCoilUA(state, CoilNum);
    2070             : 
    2071   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate = 0.0;
    2072   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate = 0.0;
    2073   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate = 0.0;
    2074   137535475 : }
    2075             : 
    2076             : // refactor coilUA adjustment into separate routine, for use with rating calc
    2077   137538575 : void CalcAdjustedCoilUA(EnergyPlusData &state, int const CoilNum)
    2078             : {
    2079             :     // Pull these precalc routines out of big init routine
    2080             :     // modify the coil UA based on model in Wetter 1999
    2081             :     Real64 x_a;                  // result of Eq.70 in Wetter 1999
    2082             :     Real64 x_w;                  // result of Eq.72 in Wetter 1999
    2083             :     Real64 AirConvectTerm;       // result of Eq.71 in Wetter 1999
    2084             :     Real64 WaterConvectTerm;     // result of Eq.73 in Wetter 1999
    2085             :     Real64 WaterConvSensitivity; // "s" in Wetter 1999, temperature sensitivity in water side convection
    2086             : 
    2087             :     // Coil:Heating:Water
    2088   249695694 :     if ((state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) &&
    2089   112157119 :         (!(state.dataWaterCoils->MyUAAndFlowCalcFlag(CoilNum)))) { // update Coil UA based on inlet mass flows and temps
    2090   112155112 :         x_a = 1.0 + 4.769E-3 * (state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp);
    2091   112155112 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate > 0.0) {
    2092   111491444 :             AirConvectTerm =
    2093   111491444 :                 x_a *
    2094   111491444 :                 std::pow(state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate,
    2095             :                          0.8) *
    2096   111491444 :                 state.dataWaterCoils->WaterCoil(CoilNum).AirSideNominalConvect;
    2097             :         } else {
    2098      663668 :             AirConvectTerm = 0.0;
    2099             :         }
    2100   112155112 :         WaterConvSensitivity = 0.014 / (1.0 + 0.014 * state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp);
    2101   112155112 :         x_w = 1.0 + WaterConvSensitivity *
    2102   112155112 :                         (state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp);
    2103   112155112 :         if (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate > 0.0) {
    2104   222062574 :             WaterConvectTerm = x_w *
    2105   222062574 :                                std::pow(state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate /
    2106   111031287 :                                             state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate,
    2107             :                                         0.85) *
    2108   111031287 :                                state.dataWaterCoils->WaterCoil(CoilNum).LiquidSideNominalConvect;
    2109             :         } else {
    2110     1123825 :             WaterConvectTerm = 0.0;
    2111             :         }
    2112   112155112 :         if ((AirConvectTerm > 0.0) && (WaterConvectTerm > 0.0)) {
    2113    71051070 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable = 1.0 / ((1.0 / WaterConvectTerm) + (1.0 / AirConvectTerm));
    2114             :         } else {
    2115             :             // use nominal UA since variable UA cannot be calculated
    2116    41104042 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable = state.dataWaterCoils->WaterCoil(CoilNum).UACoil;
    2117             :         }
    2118             : 
    2119             :         // calculate the Faulty Coil Fouling (thermal insulance) Factor using fault information
    2120   224326315 :         if (state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingFlag &&
    2121             :             // The fault shouldn't apply during sizing.
    2122   112157730 :             (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation) &&
    2123             :             // This was preexisting
    2124        1309 :             !(state.dataWaterCoils->MyUAAndFlowCalcFlag(CoilNum))) {
    2125             :             // Store original value
    2126        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilVariable = state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable;
    2127             : 
    2128        1309 :             int FaultIndex = state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingIndex;
    2129        1309 :             FaultsManager::FaultPropertiesFoulingCoil &fouling = state.dataFaultsMgr->FouledCoils(FaultIndex);
    2130        1309 :             Real64 FaultFrac = fouling.FaultFraction(state);
    2131             : 
    2132        1309 :             if (fouling.FoulingInputMethod == FaultsManager::FouledCoil::UARated) {
    2133             :                 // 1/UA' = Frac * (1/UAFouled) + (1-Frac) / UA
    2134        1309 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable =
    2135        1309 :                     1 / (FaultFrac / (fouling.UAFouled) + (1 - FaultFrac) / state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable);
    2136             :             } else {
    2137             :                 // R' = R + Rfoul
    2138             :                 // Rfoul = r_air/A_air + r_water/A_water (FoulingFactor = thermal insulance [K/W, A] = Area [m2], r=fouling factor [m2.K/W]
    2139           0 :                 Real64 FoulingFactor = FaultFrac * (fouling.Rfw / (fouling.Aratio * fouling.Aout) + fouling.Rfa / fouling.Aout);
    2140           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable =
    2141           0 :                     1.0 / ((1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable) + FoulingFactor);
    2142             :             }
    2143             : 
    2144             :             // Do not allow improving coil performance
    2145        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable =
    2146        1309 :                 min(state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable, state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilVariable);
    2147             : 
    2148             :             // Only for reporting purposes
    2149        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingFactor =
    2150        2618 :                 (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable) -
    2151        1309 :                 (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilVariable);
    2152             :         } else {
    2153   112153803 :             state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingFactor = 0;
    2154             :         }
    2155             :     }
    2156             : 
    2157             :     // Coil:Cooling:Water
    2158             :     // update Coil UA based on inlet mass flows and temps
    2159   159582947 :     if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling &&
    2160    22044372 :         (!state.dataWaterCoils->MyCoilDesignFlag(CoilNum))) {
    2161    22034986 :         if (state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate > 0.0) {
    2162    22034986 :             x_a = 1.0 + 4.769E-3 * (state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp);
    2163    22034986 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal =
    2164    22034986 :                 x_a *
    2165    22034986 :                 std::pow(state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate,
    2166    22034986 :                          0.8) *
    2167    22034986 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternalDes;
    2168             :         } else {
    2169           0 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternalDes;
    2170             :         }
    2171             : 
    2172    22034986 :         if (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate > 0.0) {
    2173    22034986 :             WaterConvSensitivity = 0.014 / (1.0 + 0.014 * state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp);
    2174    22034986 :             x_w = 1.0 + WaterConvSensitivity *
    2175    22034986 :                             (state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp);
    2176    44069972 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = x_w *
    2177    44069972 :                                                                       std::pow(state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate /
    2178    22034986 :                                                                                    state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate,
    2179    22034986 :                                                                                0.85) *
    2180    22034986 :                                                                       state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalDes;
    2181             :         } else {
    2182           0 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalDes;
    2183             :         }
    2184             : 
    2185    22034986 :         if (!(state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal > 0.0 && state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal > 0.0)) {
    2186     9621553 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalDes;
    2187     9621553 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternalDes;
    2188             :         }
    2189             : 
    2190             :         // If Fouling
    2191    44086063 :         if (state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingFlag &&
    2192             :             // The fault shouldn't apply during sizing.
    2193    22037604 :             (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation) &&
    2194             :             // This was preexisting
    2195        1309 :             !(state.dataWaterCoils->MyUAAndFlowCalcFlag(CoilNum))) {
    2196             :             // Store original value
    2197             :             // This is really UACoilTotal technically, but I don't see the point of declaring another Real on the struct just for that
    2198        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilVariable =
    2199        1309 :                 1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal + 1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal);
    2200             : 
    2201        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilExternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal;
    2202        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal;
    2203             : 
    2204        1309 :             int FaultIndex = state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingIndex;
    2205             : 
    2206        1309 :             FaultsManager::FaultPropertiesFoulingCoil &fouling = state.dataFaultsMgr->FouledCoils(FaultIndex);
    2207        1309 :             Real64 FaultFrac = fouling.FaultFraction(state);
    2208             : 
    2209        1309 :             if (fouling.FoulingInputMethod == FaultsManager::FouledCoil::FoulingFactor) {
    2210             :                 // Adjust the External (air) UA and Internal (water) UA accordingly
    2211           0 :                 Real64 Rfoul_air = FaultFrac * (fouling.Rfa / fouling.Aout);
    2212           0 :                 Real64 Rfoul_water = FaultFrac * (fouling.Rfw / (fouling.Aratio * fouling.Aout));
    2213             : 
    2214           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal =
    2215           0 :                     1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal + Rfoul_water);
    2216           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal =
    2217           0 :                     1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal + Rfoul_air);
    2218             :                 //
    2219             :             } else { // iFouledCoil_UARated
    2220             :                 // FouledUARated is supposed to be the overall UA. So we need to split between Internal and External UAs
    2221             : 
    2222             :                 // How should I split fouling between internal/external?
    2223             :                 // We can actually use the current ratio before fouling...
    2224             :                 // splitRatio = UACoilInternal/UACoilExternal
    2225             :                 // UACoilInternal = UACoilExternal * splitRatio
    2226             : 
    2227             :                 // UACoilTotal = 1 / (1 / UACoilExternal + 1 / UACoilInternal)
    2228             :                 // UACoilTotal = 1 / (1 / UACoilExternal + 1 / (UACoilExernal * splitRatio))
    2229             :                 // UACoilTotal = UACoilExternal / (1 + 1 / splitRatio) = UACoilExternal  * splitRatio / (1 + splitRatio)
    2230             :                 // UACoilExternal = UACoilTotal * (1 + splitRatio) / splitRatio
    2231             :                 // UACoilInternal = UACoilTotal * (1 + splitRatio)
    2232             : 
    2233             :                 // Adding in FaultFrac:
    2234             :                 // UACoilExternal = FaultFrac * [UAFouled * (1+splitRatio) / splitRatio] + (1-FaultFrac) * UACoilExternal
    2235             :                 // UACoilInternal = FaultFrac * [UAFouled * splitRatio] + (1-FaultFrac) * UACoilInternal
    2236             : 
    2237        1309 :                 Real64 splitRatio = state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal;
    2238             : 
    2239        1309 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal =
    2240        2618 :                     1.0 / ((FaultFrac * splitRatio) / ((1 + splitRatio) * fouling.UAFouled) +
    2241        1309 :                            (1 - FaultFrac) / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal);
    2242             : 
    2243             :                 // WaterCoil(CoilNum).UACoilInternal =   1.0 /
    2244             :                 //( FaultFrac / ((1 + splitRatio) * fouling.UAFouled) +
    2245             :                 //(1-FaultFrac) / WaterCoil(CoilNum).UACoilInternal);
    2246             : 
    2247        1309 :                 state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal = splitRatio * state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal;
    2248             :             }
    2249             : 
    2250             :             // Do not allow improving coil performance
    2251        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal =
    2252        1309 :                 min(state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal, state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilExternal);
    2253        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal =
    2254        1309 :                 min(state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal, state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilInternal);
    2255             : 
    2256             :             // Only for reporting purposes
    2257        1309 :             state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingFactor =
    2258        2618 :                 (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal) -
    2259        2618 :                 (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilExternal) +
    2260        2618 :                 (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal) -
    2261        1309 :                 (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).OriginalUACoilInternal);
    2262             :         } else {
    2263    22033677 :             state.dataWaterCoils->WaterCoil(CoilNum).FaultyCoilFoulingFactor = 0;
    2264             :         }
    2265             : 
    2266    22034986 :         state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal =
    2267    22034986 :             1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal + 1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal);
    2268             : 
    2269    22034986 :         state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalPerUnitArea =
    2270    22034986 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    2271    22034986 :         state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea =
    2272    22034986 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    2273    22034986 :         state.dataWaterCoils->WaterCoil(CoilNum).UADryExtPerUnitArea = state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea;
    2274             :     }
    2275   137538575 : }
    2276             : 
    2277        3100 : void SizeWaterCoil(EnergyPlusData &state, int const CoilNum)
    2278             : {
    2279             : 
    2280             :     // SUBROUTINE INFORMATION:
    2281             :     //       AUTHOR         Fred Buhl
    2282             :     //       DATE WRITTEN   November 2001
    2283             :     //       MODIFIED       August 2013 Daeho Kang, add component sizing table entries
    2284             :     //       RE-ENGINEERED  na
    2285             : 
    2286             :     // PURPOSE OF THIS SUBROUTINE:
    2287             :     // This subroutine is for sizing Water Coil Components for which flow rates and UAs have not been
    2288             :     // specified in the input.
    2289             : 
    2290             :     // METHODOLOGY EMPLOYED:
    2291             :     // Obtains flow rates from the zone or system sizing arrays and plant sizing data. UAs are
    2292             :     // calculated by numerically inverting the individual coil calculation routines.
    2293             : 
    2294             :     // Using/Aliasing
    2295             :     using namespace DataSizing;
    2296             :     using PlantUtilities::RegisterPlantCompDesignFlow;
    2297             : 
    2298             :     // SUBROUTINE PARAMETER DEFINITIONS:
    2299             :     static constexpr std::string_view RoutineName("SizeWaterCoil");
    2300             : 
    2301             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2302             :     Real64 rho;
    2303        3100 :     int FieldNum = 2;                      // IDD numeric field number where input field description is found
    2304        6200 :     std::string CompType;                  // component type
    2305             :     int SizingType;                        // type of sizing to perform
    2306        6200 :     std::string SizingString;              // input field sizing description (e.g., Nominal Capacity)
    2307        3100 :     bool bPRINT = true;                    // TRUE if sizing is reported to output (eio)
    2308             :     Real64 TempSize;                       // autosized value
    2309             :     Real64 DesCoilWaterInTempSaved;        // coil water inlet temp used for error checking UA sizing
    2310        3100 :     Real64 DesCoilInletWaterTempUsed(0.0); // coil design inlet water temp for UA sizing only
    2311             :     Real64 Cp;
    2312        3100 :     bool NomCapUserInp = false; // flag for whether user has onput a nominal heating capacity
    2313             : 
    2314        3100 :     bool ErrorsFound = false;
    2315        3100 :     bool LoopErrorsFound = false;
    2316        3100 :     int PltSizCoolNum = 0;
    2317        3100 :     int PltSizHeatNum = 0;
    2318        3100 :     Real64 DesCoilAirFlow = 0.0;
    2319        3100 :     Real64 DesCoilExitTemp = 0.0;
    2320        3100 :     Real64 CpAirStd = PsyCpAirFnW(0.0);
    2321        6200 :     std::string CompName = state.dataWaterCoils->WaterCoil(CoilNum).Name;
    2322             : 
    2323        3100 :     auto &ZoneEqSizing(state.dataSize->ZoneEqSizing);
    2324        3100 :     auto &OASysEqSizing(state.dataSize->OASysEqSizing);
    2325             : 
    2326             :     // cooling coils
    2327        8897 :     if (((state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) ||
    2328        3646 :          (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling)) &&
    2329         546 :         state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize) {
    2330             :         // find the appropriate Plant Sizing object
    2331        1772 :         PltSizCoolNum = PlantUtilities::MyPlantSizingIndex(state,
    2332             :                                                            "chilled water coil",
    2333         443 :                                                            state.dataWaterCoils->WaterCoil(CoilNum).Name,
    2334         443 :                                                            state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum,
    2335         443 :                                                            state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum,
    2336             :                                                            LoopErrorsFound);
    2337             :     }
    2338             : 
    2339        5797 :     if (((state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) ||
    2340        2697 :          (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling))) { // 'Cooling'
    2341             : 
    2342         546 :         if (state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp) {
    2343          28 :             state.dataSize->DataWaterCoilSizCoolDeltaT = state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp;
    2344             :         } else {
    2345         518 :             if (PltSizCoolNum > 0) {
    2346         415 :                 state.dataSize->DataWaterCoilSizCoolDeltaT = state.dataSize->PlantSizData(PltSizCoolNum).DeltaT;
    2347             :             }
    2348             :         }
    2349             : 
    2350         546 :         if (PltSizCoolNum > 0) {
    2351             : 
    2352         443 :             state.dataSize->DataPltSizCoolNum = PltSizCoolNum;
    2353         443 :             state.dataSize->DataWaterLoopNum = state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum;
    2354             : 
    2355         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2356          62 :                 CompType = cAllCoilTypes(Coil_CoolingWaterDetailed);                                     // Coil:Cooling:Water:DetailedGeometry
    2357             :             } else {
    2358         381 :                 CompType = cAllCoilTypes(Coil_CoolingWater); // Coil:Cooling:Water
    2359             :             }
    2360             : 
    2361         443 :             bPRINT = false; // do not print this sizing request since the autosized value is needed and this input may not be autosized (we should
    2362             :                             // print this!)
    2363         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate == state.dataSize->DataFlowUsedForSizing) {
    2364          84 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate; // represents parent object has hard-sized airflow
    2365             :             } else {
    2366         359 :                 TempSize = AutoSize; // get the autosized air volume flow rate for use in other calculations
    2367             :             }
    2368             : 
    2369         443 :             bool errorsFound = false;
    2370         886 :             CoolingAirFlowSizer sizingCoolingAirFlow;
    2371         443 :             CompName = state.dataWaterCoils->WaterCoil(CoilNum).Name;
    2372         443 :             sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2373         443 :             Real64 autoSizedValue = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    2374         443 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate =
    2375         443 :                 state.dataEnvrn->StdRhoAir * autoSizedValue; // inlet air mass flow rate is the autosized value
    2376             : 
    2377             :             // Check if the air volume flow rate is defined in parent HVAC equipment and set water coil design air volume flow rate accordingly
    2378         443 :             if (state.dataSize->CurZoneEqNum > 0) {
    2379         173 :                 if (ZoneEqSizing(state.dataSize->CurZoneEqNum).DesignSizeFromParent &&
    2380          81 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate == autoSizedValue) {
    2381          80 :                     state.dataSize->DataAirFlowUsedForSizing = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
    2382          80 :                     state.dataSize->DataFlowUsedForSizing = ZoneEqSizing(state.dataSize->CurZoneEqNum).AirVolFlow;
    2383          80 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate = AutoSize; // represents water coil being autosized
    2384             :                 } else {
    2385          12 :                     state.dataSize->DataAirFlowUsedForSizing =
    2386             :                         autoSizedValue; // many autosized inputs use the design (autosized) air volume flow rate, save this value
    2387          12 :                     state.dataSize->DataFlowUsedForSizing = autoSizedValue;
    2388             :                 }
    2389             :             } else {
    2390         351 :                 state.dataSize->DataAirFlowUsedForSizing =
    2391             :                     autoSizedValue; // many autosized inputs use the design (autosized) air volume flow rate, save this value
    2392         351 :                 state.dataSize->DataFlowUsedForSizing = autoSizedValue;
    2393             :             }
    2394             : 
    2395         443 :             if (state.dataSize->CurSysNum > 0 && state.dataSize->CurOASysNum == 0) {
    2396         323 :                 Real64 DesCoilExitHumRat(0.0); // fix coil sizing inconsistency
    2397         323 :                 DataSizing::GetCoilDesFlowT(state, state.dataSize->CurSysNum, CpAirStd, DesCoilAirFlow, DesCoilExitTemp, DesCoilExitHumRat);
    2398         323 :                 state.dataSize->DataAirFlowUsedForSizing = DesCoilAirFlow;
    2399         323 :                 state.dataSize->DataFlowUsedForSizing = DesCoilAirFlow;
    2400         323 :                 state.dataSize->DataDesOutletAirTemp = DesCoilExitTemp;
    2401         323 :                 state.dataSize->DataDesOutletAirHumRat = DesCoilExitHumRat; // need to test for dry coil but inlet conditions not yet known
    2402             :             }
    2403             : 
    2404             :             // calculate pre-sizing data needed for specific functions (e.g., CoolingWaterDesAirInletTempSizing needs HRin and air flow)
    2405             :             // these will be calculated again after other parameters are known
    2406         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2407          62 :                 TempSize = AutoSize;                                                                     // coil report
    2408             :             } else {
    2409         381 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat; // preserve input if entered
    2410             :             }
    2411         886 :             CoolingWaterDesAirInletHumRatSizer sizerCWDesInHumRat;
    2412         443 :             sizerCWDesInHumRat.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2413         443 :             state.dataSize->DataDesInletAirHumRat = sizerCWDesInHumRat.size(state, TempSize, ErrorsFound);
    2414             : 
    2415         443 :             TempSize = AutoSize;
    2416         886 :             CoolingCapacitySizer sizerCoolingCapacity;
    2417         443 :             sizerCoolingCapacity.overrideSizingString(SizingString);
    2418         443 :             sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2419         443 :             state.dataSize->DataCapacityUsedForSizing = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
    2420         443 :             TempSize = state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    2421         886 :             CoolingWaterflowSizer sizerCWWaterflow;
    2422         443 :             sizerCWWaterflow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2423         443 :             Real64 autoSizedCWFlow = sizerCWWaterflow.size(state, TempSize, ErrorsFound);
    2424             :             // Check if the water flow rate is defined in parent HVAC equipment and set water coil design water flow rate accordingly
    2425         443 :             if (state.dataSize->CurZoneEqNum > 0) {
    2426          92 :                 if (ZoneEqSizing(state.dataSize->CurZoneEqNum).DesignSizeFromParent) {
    2427          81 :                     state.dataSize->DataWaterFlowUsedForSizing = ZoneEqSizing(state.dataSize->CurZoneEqNum).MaxCWVolFlow;
    2428             :                 } else {
    2429          11 :                     state.dataSize->DataWaterFlowUsedForSizing = autoSizedCWFlow;
    2430             :                 }
    2431             :             } else {
    2432         351 :                 state.dataSize->DataWaterFlowUsedForSizing = autoSizedCWFlow;
    2433             :             }
    2434             :             // end pre-sizing data calculations
    2435             : 
    2436         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2437          62 :                 bPRINT = false;       // do not print this sizing request since this coil does not have a design inlet air temp input field (we
    2438             :                                       // should print this!)
    2439          62 :                 TempSize = AutoSize;  // not an input for this model
    2440          62 :                 SizingString.clear(); // doesn't matter
    2441             :             } else {
    2442         381 :                 FieldNum = 4; //  N4 , \field Design Inlet Air Temperature
    2443         381 :                 bPRINT = true;
    2444         381 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp; // preserve input if entered
    2445         381 :                 SizingString = state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames(FieldNum) + " [C]";
    2446             :             }
    2447             : 
    2448         886 :             CoolingWaterDesAirInletTempSizer sizerCWDesInletAirTemp;
    2449         443 :             sizerCWDesInletAirTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2450         443 :             state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp = sizerCWDesInletAirTemp.size(state, TempSize, ErrorsFound);
    2451         443 :             state.dataSize->DataDesInletAirTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp;
    2452             : 
    2453         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2454          62 :                 bPRINT = false;       // no field for detailed water coil, should print to eio anyway
    2455          62 :                 TempSize = AutoSize;  // coil report
    2456          62 :                 SizingString.clear(); // doesn't matter
    2457             :             } else {
    2458         381 :                 FieldNum = 3; //  N3 , \field Design Inlet Water Temperature
    2459         381 :                 bPRINT = true;
    2460         381 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp; // preserve input if entered
    2461         381 :                 SizingString = state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames(FieldNum) + " [C]";
    2462             :             }
    2463         886 :             CoolingWaterDesWaterInletTempSizer sizerCWDesWaterInTemp;
    2464         443 :             sizerCWDesWaterInTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2465         443 :             state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp = sizerCWDesWaterInTemp.size(state, TempSize, ErrorsFound);
    2466             : 
    2467         563 :             if ((state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp > state.dataSize->DataDesOutletAirTemp) &&
    2468         120 :                 state.dataSize->DataDesOutletAirTemp > 0.0) {
    2469           0 :                 ShowWarningError(state, "Invalid design inlet water temperature for " + std::string{CompType} + " = " + std::string{CompName});
    2470           0 :                 ShowContinueError(state,
    2471           0 :                                   format("...design inlet water temperature = {:.3R} C", state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp));
    2472           0 :                 ShowContinueError(state, format("...design outlet air temperature = {:.3R} C", state.dataSize->DataDesOutletAirTemp));
    2473           0 :                 ShowContinueError(state, "...design inlet water temperature should be less than the design outlet air temperature");
    2474           0 :                 ShowContinueError(state, "...design inlet water temperature is set to the design outlet air temperature minus 5.0C");
    2475           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp = state.dataSize->DataDesOutletAirTemp - 5.0;
    2476             :             }
    2477             : 
    2478         443 :             if (state.dataSize->CurZoneEqNum > 0) { // zone equipment use air inlet humrat to calculate design outlet air temperature
    2479          92 :                 if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2480           0 :                     bPRINT = false;      // no field for detailed water coil, should print to eio anyway
    2481           0 :                     TempSize = AutoSize; // coil report
    2482             :                 } else {
    2483          92 :                     bPRINT = true;
    2484          92 :                     TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat; // preserve input if entered
    2485             :                 }
    2486          92 :                 sizerCWDesInHumRat.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2487          92 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat = sizerCWDesInHumRat.size(state, TempSize, ErrorsFound);
    2488             :             }
    2489             : 
    2490         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2491          62 :                 bPRINT = false;       // no field for detailed water coil, should print to eio anyway
    2492          62 :                 TempSize = AutoSize;  // coil report
    2493          62 :                 SizingString.clear(); // doesn't matter
    2494             :             } else {
    2495         381 :                 FieldNum = 5; //  N5 , \field Design Outlet Air Temperature
    2496         381 :                 bPRINT = true;
    2497         381 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp; // preserve input if entered
    2498         381 :                 SizingString = state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames(FieldNum) + " [C]";
    2499             :             }
    2500             : 
    2501         443 :             state.dataSize->DataDesInletWaterTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp; // used for warning messages
    2502         886 :             CoolingWaterDesAirOutletTempSizer sizerCWDesAirOutTemp;
    2503         443 :             sizerCWDesAirOutTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2504         443 :             state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp = sizerCWDesAirOutTemp.size(state, TempSize, ErrorsFound);
    2505         443 :             state.dataSize->DataDesOutletAirTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp;
    2506             : 
    2507         443 :             if (state.dataSize->CurSysNum > 0) { // This call can be deleted at a future time and remove the if ( CurZoneEqNum > 0 ) check above. This
    2508             :                                                  // will change the order of the eio file.
    2509         351 :                 if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2510          62 :                     bPRINT = false;      // no field for detailed water coil, should print this to eio anyway
    2511          62 :                     TempSize = AutoSize; // coil report
    2512             :                 } else {
    2513         289 :                     bPRINT = true;
    2514         289 :                     TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat;
    2515             :                 }
    2516         351 :                 sizerCWDesInHumRat.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2517         351 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat = sizerCWDesInHumRat.size(state, TempSize, ErrorsFound);
    2518             :             }
    2519             : 
    2520         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2521          62 :                 bPRINT = false;      // no field for detailed water coil, should print this to eio anyway
    2522          62 :                 TempSize = AutoSize; // coil report
    2523             :             } else {
    2524         381 :                 bPRINT = true;
    2525         381 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat; // preserve input if entered
    2526             :             }
    2527         886 :             CoolingWaterDesAirOutletHumRatSizer sizerCWDesOutHumRat;
    2528         443 :             sizerCWDesOutHumRat.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2529         443 :             state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat = sizerCWDesOutHumRat.size(state, TempSize, ErrorsFound);
    2530         443 :             state.dataSize->DataDesOutletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirHumRat;
    2531             : 
    2532         443 :             TempSize = AutoSize;
    2533         443 :             bPRINT = true;
    2534         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate != AutoSize) bPRINT = false;
    2535         443 :             if (state.dataSize->CurSysNum == 0) bPRINT = false;
    2536         443 :             SizingString = "Design Coil Load [W]"; // there is no input field for this value and this is not the rated capacity (we should
    2537             :                                                    // always print this!)
    2538             :             // air inlet/outlet conditions should be known. Don't include fan heat in capacity calculation.
    2539         443 :             state.dataSize->DataDesAccountForFanHeat = false;
    2540         886 :             CoolingCapacitySizer sizerCoolingCapacity2;
    2541         443 :             sizerCoolingCapacity2.overrideSizingString(SizingString);
    2542         443 :             sizerCoolingCapacity2.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2543         443 :             state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate = sizerCoolingCapacity2.size(state, TempSize, ErrorsFound);
    2544         443 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate =
    2545         443 :                 state.dataEnvrn->StdRhoAir * state.dataSize->DataFlowUsedForSizing; // inlet air mass flow rate is the autosized value
    2546         443 :             state.dataSize->DataCapacityUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate;
    2547             : 
    2548             :             // Why isn't the water volume flow rate based on the user inputs for inlet/outlet air/water temps? Water volume flow rate is
    2549             :             // always based on autosized inputs.
    2550         443 :             bPRINT = true;
    2551         443 :             TempSize = state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    2552         443 :             sizerCWWaterflow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2553         443 :             state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = sizerCWWaterflow.size(state, TempSize, ErrorsFound);
    2554         443 :             state.dataSize->DataWaterFlowUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    2555             : 
    2556         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) { // 'DETAILED FLAT FIN'
    2557          62 :                 bPRINT = false; // do not print this sizing request since this coil does not have a design air flow rate input field (we
    2558             :                                 // should print this!)
    2559             :             } else {
    2560         381 :                 bPRINT = true;
    2561             :             }
    2562         443 :             TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate;
    2563         886 :             CoolingAirFlowSizer sizingCoolingAirFlow2;
    2564         886 :             std::string stringOverride = "Design Air Flow Rate [m3/s]";
    2565         443 :             if (state.dataGlobal->isEpJSON) stringOverride = "design_air_flow_rate [m3/s]";
    2566         443 :             sizingCoolingAirFlow2.overrideSizingString(stringOverride);
    2567             :             // sizingCoolingAirFlow2.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    2568         443 :             sizingCoolingAirFlow2.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2569         443 :             state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate = sizingCoolingAirFlow2.size(state, TempSize, errorsFound);
    2570         443 :             state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate =
    2571         443 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate * state.dataEnvrn->StdRhoAir;
    2572             : 
    2573         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate <= 0.0) {
    2574           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate = 0.0;
    2575           0 :                 ShowWarningError(state, "The design air flow rate is zero for " + std::string{CompType} + " = " + std::string{CompName});
    2576           0 :                 ShowContinueError(state, "The autosize value for max air volume flow rate is zero");
    2577             :             }
    2578             : 
    2579         443 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilModel == CoilModel::CoolingDetailed) {
    2580             : 
    2581          62 :                 FieldNum = 16; //  N16, \field Number of Tubes per Row
    2582          62 :                 bPRINT = true;
    2583          62 :                 SizingString = state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames(FieldNum);
    2584             :                 // Auto size detailed cooling coil number of tubes per row = int( 13750.0 * WaterCoil( CoilNum ).MaxWaterVolFlowRate ) + 1
    2585          62 :                 state.dataSize->DataFlowUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    2586          62 :                 TempSize = float(state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow);
    2587         124 :                 CoolingWaterNumofTubesPerRowSizer sizerCWNumofTubesPerRow;
    2588          62 :                 sizerCWNumofTubesPerRow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2589          62 :                 state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow = sizerCWNumofTubesPerRow.size(state, TempSize, ErrorsFound);
    2590             : 
    2591             :                 // Auto size water coil fin diameter = 0.335 * WaterCoil( CoilNum ).InletAirMassFlowRate
    2592          62 :                 state.dataSize->DataConstantUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    2593          62 :                 state.dataSize->DataFractionUsedForSizing = 0.335;
    2594          62 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).FinDiam;
    2595             : 
    2596         124 :                 AutoCalculateSizer sizerFinDiameter;
    2597         124 :                 std::string stringOverride = "Fin Diameter [m]";
    2598          62 :                 if (state.dataGlobal->isEpJSON) stringOverride = "fin_diameter [m]";
    2599          62 :                 sizerFinDiameter.overrideSizingString(stringOverride);
    2600          62 :                 sizerFinDiameter.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2601          62 :                 state.dataWaterCoils->WaterCoil(CoilNum).FinDiam = sizerFinDiameter.size(state, TempSize, ErrorsFound);
    2602             : 
    2603             :                 // Auto size water coil minimum airflow area = 0.44 * WaterCoil( CoilNum ).InletAirMassFlowRate
    2604          62 :                 state.dataSize->DataConstantUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    2605          62 :                 state.dataSize->DataFractionUsedForSizing = 0.44;
    2606          62 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea;
    2607             : 
    2608         124 :                 AutoCalculateSizer sizerMinAirFlowArea;
    2609          62 :                 stringOverride = "Minimum Airflow Area [m2]";
    2610          62 :                 if (state.dataGlobal->isEpJSON) stringOverride = "minimum_airflow_area [m2]";
    2611          62 :                 sizerMinAirFlowArea.overrideSizingString(stringOverride);
    2612          62 :                 sizerMinAirFlowArea.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2613          62 :                 state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea = sizerMinAirFlowArea.size(state, TempSize, ErrorsFound);
    2614             : 
    2615          62 :                 if (state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea <= 0.0) {
    2616           0 :                     ShowSevereError(state, "Coil:Cooling:Water:DetailedGeometry: \"" + state.dataWaterCoils->WaterCoil(CoilNum).Name + "\"");
    2617           0 :                     ShowContinueError(state,
    2618           0 :                                       format("Coil Minimum Airflow Area must be greater than 0. Coil area = {:.6T}",
    2619           0 :                                              state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea));
    2620           0 :                     ErrorsFound = true;
    2621             :                 }
    2622             : 
    2623             :                 // Auto size water coil finned surface area = 78.5 * WaterCoil( CoilNum ).InletAirMassFlowRate
    2624          62 :                 state.dataSize->DataConstantUsedForSizing =
    2625          62 :                     state.dataWaterCoils->WaterCoil(CoilNum)
    2626          62 :                         .InletAirMassFlowRate; // actual autosized air mass flow rate, not calculated from user input
    2627          62 :                 state.dataSize->DataFractionUsedForSizing = 78.5;
    2628          62 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).FinSurfArea;
    2629             : 
    2630         124 :                 AutoCalculateSizer sizerFinSurfaceArea;
    2631          62 :                 stringOverride = "Fin Surface Area [m2]";
    2632          62 :                 if (state.dataGlobal->isEpJSON) stringOverride = "fin_surface_area [m2]";
    2633          62 :                 sizerFinSurfaceArea.overrideSizingString(stringOverride);
    2634          62 :                 sizerFinSurfaceArea.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2635          62 :                 state.dataWaterCoils->WaterCoil(CoilNum).FinSurfArea = sizerFinSurfaceArea.size(state, TempSize, ErrorsFound);
    2636             : 
    2637             :                 // Auto size water coil total tube inside surface area = 4.4 * WaterCoil( CoilNum ).TubeInsideDiam * WaterCoil( CoilNum
    2638             :                 // ).NumOfTubeRows * WaterCoil( CoilNum ).NumOfTubesPerRow
    2639         186 :                 state.dataSize->DataConstantUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).TubeInsideDiam *
    2640         124 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubeRows *
    2641          62 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow;
    2642          62 :                 state.dataSize->DataFractionUsedForSizing = 4.4;
    2643          62 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).TotTubeInsideArea;
    2644             : 
    2645         124 :                 AutoCalculateSizer sizerTubeInsideArea;
    2646          62 :                 stringOverride = "Total Tube Inside Area [m2]";
    2647          62 :                 if (state.dataGlobal->isEpJSON) stringOverride = "total_tube_inside_area [m2]";
    2648          62 :                 sizerTubeInsideArea.overrideSizingString(stringOverride);
    2649          62 :                 sizerTubeInsideArea.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2650          62 :                 state.dataWaterCoils->WaterCoil(CoilNum).TotTubeInsideArea = sizerTubeInsideArea.size(state, TempSize, ErrorsFound);
    2651             : 
    2652             :                 // Auto size water coil total tube outside surface area = 4.1 * WaterCoil( CoilNum ).TubeOutsideDiam * WaterCoil( CoilNum
    2653             :                 // ).NumOfTubeRows * WaterCoil( CoilNum ).NumOfTubesPerRow
    2654         186 :                 state.dataSize->DataConstantUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideDiam *
    2655         124 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubeRows *
    2656          62 :                                                             state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow;
    2657          62 :                 state.dataSize->DataFractionUsedForSizing = 4.1;
    2658          62 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideSurfArea;
    2659             : 
    2660         124 :                 AutoCalculateSizer sizerTubeOutsideArea;
    2661          62 :                 stringOverride = "Tube Outside Surface Area [m2]";
    2662          62 :                 if (state.dataGlobal->isEpJSON) stringOverride = "tube_outside_surface_area [m2]";
    2663          62 :                 sizerTubeOutsideArea.overrideSizingString(stringOverride);
    2664          62 :                 sizerTubeOutsideArea.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2665          62 :                 state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideSurfArea = sizerTubeOutsideArea.size(state, TempSize, ErrorsFound);
    2666             : 
    2667          62 :                 if ((state.dataWaterCoils->WaterCoil(CoilNum).FinSurfArea + state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideSurfArea) <= 0.0) {
    2668           0 :                     ShowSevereError(state, "Coil:Cooling:Water:DetailedGeometry: \"" + state.dataWaterCoils->WaterCoil(CoilNum).Name + "\"");
    2669           0 :                     ShowContinueError(
    2670             :                         state,
    2671           0 :                         format(
    2672             :                             "Coil Fin Surface Area plus Coil Tube Outside Surface Area must be greater than 0. Total surface area = {:.6T}",
    2673           0 :                             (state.dataWaterCoils->WaterCoil(CoilNum).FinSurfArea + state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideSurfArea)));
    2674           0 :                     ErrorsFound = true;
    2675             :                 }
    2676             : 
    2677             :                 // Auto size water coil coil depth = WaterCoil( CoilNum ).TubeDepthSpacing * WaterCoil( CoilNum ).NumOfTubeRows
    2678          62 :                 state.dataSize->DataConstantUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).TubeDepthSpacing;
    2679          62 :                 state.dataSize->DataFractionUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubeRows;
    2680          62 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth;
    2681             : 
    2682         124 :                 AutoCalculateSizer sizerCoilDepth;
    2683          62 :                 stringOverride = "Coil Depth [m]";
    2684          62 :                 if (state.dataGlobal->isEpJSON) stringOverride = "coil_depth [m]";
    2685          62 :                 sizerCoilDepth.overrideSizingString(stringOverride);
    2686          62 :                 sizerCoilDepth.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2687          62 :                 state.dataWaterCoils->WaterCoil(CoilNum).CoilDepth = sizerCoilDepth.size(state, TempSize, ErrorsFound);
    2688             :             }
    2689         443 :             state.dataSize->DataPltSizCoolNum = 0; // reset all globals to 0 to ensure correct sizing for other child components
    2690         443 :             state.dataSize->DataWaterLoopNum = 0;
    2691         443 :             state.dataSize->DataConstantUsedForSizing = 0.0;
    2692         443 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    2693         443 :             state.dataSize->DataAirFlowUsedForSizing = 0.0;
    2694         443 :             state.dataSize->DataFlowUsedForSizing = 0.0;
    2695         443 :             state.dataSize->DataWaterFlowUsedForSizing = 0.0;
    2696         443 :             state.dataSize->DataCapacityUsedForSizing = 0.0;
    2697         443 :             state.dataSize->DataDesInletAirTemp = 0.0;
    2698         443 :             state.dataSize->DataDesOutletAirTemp = 0.0;
    2699         443 :             state.dataSize->DataDesOutletAirHumRat = 0.0;
    2700         443 :             state.dataSize->DataDesInletAirHumRat = 0.0;
    2701         443 :             state.dataSize->DataDesInletWaterTemp = 0.0;
    2702         443 :             state.dataSize->DataWaterCoilSizCoolDeltaT = 0.0;
    2703         443 :             state.dataSize->DataDesAccountForFanHeat = true;
    2704             :         } else {
    2705             :             // If there is no cooling Plant Sizing object and autosizing was requested, issue fatal error message
    2706         103 :             if (state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize) {
    2707           0 :                 ShowSevereError(state, "Autosizing of water coil requires a cooling loop Sizing:Plant object");
    2708           0 :                 ShowContinueError(state, "Occurs in water coil object= " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    2709           0 :                 ErrorsFound = true;
    2710             :             }
    2711             :         }
    2712             :         //} // end of cooling Plant Sizing existence IF - ELSE
    2713             :     } // end cooling coil IF
    2714             : 
    2715             :     // if this is a heating coil
    2716        5654 :     if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating &&
    2717        2554 :         state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize) {
    2718             :         // find the appropriate heating Plant Sizing object
    2719        8992 :         PltSizHeatNum = PlantUtilities::MyPlantSizingIndex(state,
    2720             :                                                            "hot water coil",
    2721        2248 :                                                            state.dataWaterCoils->WaterCoil(CoilNum).Name,
    2722        2248 :                                                            state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum,
    2723        2248 :                                                            state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum,
    2724             :                                                            LoopErrorsFound);
    2725             :     }
    2726             : 
    2727        3100 :     if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
    2728             : 
    2729        2554 :         if (state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp) {
    2730             :             // use water design deltaT specified in the heating water coils
    2731          93 :             state.dataSize->DataWaterCoilSizHeatDeltaT = state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp;
    2732             :         } else {
    2733        2461 :             if (PltSizHeatNum > 0) {
    2734        2155 :                 state.dataSize->DataWaterCoilSizHeatDeltaT = state.dataSize->PlantSizData(PltSizHeatNum).DeltaT;
    2735             :             }
    2736             :         }
    2737             : 
    2738        2554 :         if (PltSizHeatNum > 0) {
    2739             : 
    2740        2248 :             state.dataSize->DataPltSizHeatNum = PltSizHeatNum;
    2741        2248 :             state.dataSize->DataWaterLoopNum = state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum;
    2742        4496 :             rho = GetDensityGlycol(state,
    2743        2248 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    2744             :                                    DataGlobalConstants::HWInitConvTemp,
    2745        2248 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    2746             :                                    RoutineName);
    2747        4496 :             Cp = GetSpecificHeatGlycol(state,
    2748        2248 :                                        state.dataPlnt->PlantLoop(state.dataSize->DataWaterLoopNum).FluidName,
    2749             :                                        DataGlobalConstants::HWInitConvTemp,
    2750        2248 :                                        state.dataPlnt->PlantLoop(state.dataSize->DataWaterLoopNum).FluidIndex,
    2751             :                                        RoutineName);
    2752        2248 :             if (state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad > 0.0) {
    2753          35 :                 NomCapUserInp = true;
    2754        2213 :             } else if (state.dataSize->CurSysNum > 0 && state.dataSize->CurSysNum <= state.dataHVACGlobal->NumPrimaryAirSys) {
    2755         370 :                 if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatingCapMethod == CapacityPerFloorArea) {
    2756           0 :                     NomCapUserInp = true;
    2757         739 :                 } else if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatingCapMethod == HeatingDesignCapacity &&
    2758         369 :                            state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).HeatingTotalCapacity > 0.0) {
    2759           0 :                     NomCapUserInp = true;
    2760             :                 }
    2761             :             } else {
    2762        1843 :                 NomCapUserInp = false;
    2763             :             }
    2764        2248 :             bPRINT = false;                              // do not print this sizing request
    2765        2248 :             TempSize = AutoSize;                         // get the autosized air volume flow rate for use in other calculations
    2766        2248 :             SizingString.clear();                        // doesn't matter
    2767        2248 :             CompType = cAllCoilTypes(Coil_HeatingWater); // "Coil:Heating:Water"
    2768        2248 :             CompName = state.dataWaterCoils->WaterCoil(CoilNum).Name;
    2769        2248 :             if (state.dataWaterCoils->WaterCoil(CoilNum).DesiccantRegenerationCoil) {
    2770           0 :                 state.dataSize->DataDesicRegCoil = true;
    2771           0 :                 state.dataSize->DataDesicDehumNum = state.dataWaterCoils->WaterCoil(CoilNum).DesiccantDehumNum;
    2772           0 :                 HeatingCoilDesAirInletTempSizer sizerHeatingDesInletTemp;
    2773           0 :                 bool ErrorsFound = false;
    2774           0 :                 sizerHeatingDesInletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2775           0 :                 state.dataSize->DataDesInletAirTemp = sizerHeatingDesInletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
    2776             : 
    2777           0 :                 HeatingCoilDesAirOutletTempSizer sizerHeatingDesOutletTemp;
    2778           0 :                 ErrorsFound = false;
    2779           0 :                 sizerHeatingDesOutletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2780           0 :                 state.dataSize->DataDesOutletAirTemp = sizerHeatingDesOutletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
    2781             : 
    2782           0 :                 if (state.dataSize->CurOASysNum > 0) {
    2783           0 :                     OASysEqSizing(state.dataSize->CurOASysNum).AirFlow = true;
    2784           0 :                     OASysEqSizing(state.dataSize->CurOASysNum).AirVolFlow =
    2785           0 :                         state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesOutAirVolFlow;
    2786             :                 }
    2787           0 :                 TempSize = AutoSize; // reset back
    2788             :             }
    2789        2248 :             bool errorsFound = false;
    2790        4496 :             HeatingAirFlowSizer sizingHeatingAirFlow;
    2791        2248 :             sizingHeatingAirFlow.overrideSizingString(SizingString);
    2792             :             // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
    2793        2248 :             sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2794        2248 :             TempSize = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
    2795             :             // reset the design air volume flow rate for air loop coils only
    2796        2248 :             if (state.dataSize->CurSysNum > 0) state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate = TempSize;
    2797        2248 :             state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate =
    2798        2248 :                 state.dataEnvrn->StdRhoAir * TempSize; // inlet air mass flow rate is not the autosized value
    2799        2248 :             state.dataSize->DataAirFlowUsedForSizing = TempSize;
    2800        2248 :             state.dataSize->DataFlowUsedForSizing = TempSize; // many autosized inputs use the design (autosized) air flow rate, save this value
    2801             : 
    2802        2248 :             bPRINT = true;
    2803        2248 :             if (state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth == state.dataWaterCoils->NomCap && NomCapUserInp) {
    2804          35 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad;
    2805          35 :                 state.dataSize->DataNomCapInpMeth = true;
    2806             :             } else {
    2807        2213 :                 TempSize = AutoSize;
    2808             :             }
    2809        2248 :             if (state.dataSize->CurSysNum > 0) {
    2810         371 :                 SizingType = HeatingCapacitySizing;
    2811         371 :                 FieldNum = 3; //  N3 , \field Rated Capacity
    2812         371 :                 SizingString = state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames(FieldNum) + " [W]";
    2813         371 :                 bool errorsFound = false;
    2814         742 :                 HeatingCapacitySizer sizerHeatingCapacity;
    2815         371 :                 sizerHeatingCapacity.overrideSizingString(SizingString);
    2816         371 :                 sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2817         371 :                 TempSize = sizerHeatingCapacity.size(state, TempSize, errorsFound);
    2818         371 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate = TempSize;
    2819         371 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad = TempSize;
    2820         371 :                 state.dataSize->DataCapacityUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate;
    2821             :             } else {
    2822        3754 :                 WaterHeatingCapacitySizer sizerWaterHeatingCapacity;
    2823        1877 :                 bool ErrorsFound = false;
    2824        1877 :                 sizerWaterHeatingCapacity.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2825        1877 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate = sizerWaterHeatingCapacity.size(state, TempSize, ErrorsFound);
    2826        1877 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad = state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate;
    2827        1877 :                 state.dataSize->DataCapacityUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate;
    2828             :             }
    2829             : 
    2830             :             // We now have the design load if it was autosized. For the case of CoilPerfInpMeth == NomCap, calculate the air flow rate
    2831             :             // specified by the NomCap inputs. This overrides all previous values
    2832        2248 :             if (state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth == state.dataWaterCoils->NomCap && NomCapUserInp) {
    2833          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate =
    2834          70 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad /
    2835          35 :                     (CpAirStd *
    2836          35 :                      (state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp));
    2837          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate =
    2838          35 :                     state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / state.dataEnvrn->StdRhoAir;
    2839          35 :                 state.dataSize->DataAirFlowUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate;
    2840          35 :                 state.dataSize->DataFlowUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate;
    2841             :             }
    2842             : 
    2843        2248 :             TempSize = state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    2844             : 
    2845        2248 :             if (state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth == state.dataWaterCoils->NomCap && NomCapUserInp) {
    2846          35 :                 if (state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad > SmallLoad) {
    2847          35 :                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate =
    2848          70 :                         state.dataSize->DataCapacityUsedForSizing /
    2849          70 :                         (Cp * rho *
    2850          35 :                          (state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp - state.dataWaterCoils->WaterCoil(CoilNum).DesOutletWaterTemp));
    2851             :                 } else {
    2852           0 :                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = 0.0;
    2853             :                 }
    2854          35 :                 state.dataSize->DataConstantUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate;
    2855          35 :                 state.dataSize->DataFractionUsedForSizing = 1.0;
    2856             :             }
    2857        4496 :             HeatingWaterflowSizer sizerHWWaterflow;
    2858        2248 :             sizerHWWaterflow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2859        2248 :             Real64 sizedMaxWaterVolFlowRate = sizerHWWaterflow.size(state, TempSize, ErrorsFound);
    2860             :             // Check if the water flow rate is defined in parent HVAC equipment and set water coil design water flow rate accordingly
    2861        2248 :             if (state.dataSize->CurZoneEqNum > 0) {
    2862        1877 :                 if (ZoneEqSizing(state.dataSize->CurZoneEqNum).DesignSizeFromParent) {
    2863          80 :                     state.dataSize->DataWaterFlowUsedForSizing = ZoneEqSizing(state.dataSize->CurZoneEqNum).MaxHWVolFlow;
    2864          80 :                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = ZoneEqSizing(state.dataSize->CurZoneEqNum).MaxHWVolFlow;
    2865             :                 } else {
    2866        1797 :                     state.dataSize->DataWaterFlowUsedForSizing = sizedMaxWaterVolFlowRate;
    2867        1797 :                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = sizedMaxWaterVolFlowRate;
    2868             :                 }
    2869             :             } else {
    2870         371 :                 state.dataSize->DataWaterFlowUsedForSizing = sizedMaxWaterVolFlowRate;
    2871         371 :                 state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = sizedMaxWaterVolFlowRate;
    2872             :             }
    2873        2248 :             state.dataSize->DataConstantUsedForSizing = 0.0; // reset these in case NomCapUserInp was true
    2874        2248 :             state.dataSize->DataFractionUsedForSizing = 0.0;
    2875        2248 :             if (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate <= 0.0) {
    2876             :                 //                    MaxWaterVolFlowRateDes = 0.0;
    2877          31 :                 ShowWarningError(state, "The design coil load is zero for Coil:Heating:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    2878          31 :                 ShowContinueError(state, "The autosize value for maximum water flow rate is zero");
    2879          31 :                 ShowContinueError(state, "To change this, input a value for UA, change the heating design day, or raise the");
    2880          31 :                 ShowContinueError(state, "  system heating design supply air temperature. Also check to make sure the Preheat");
    2881          31 :                 ShowContinueError(state, "  Design Temperature is not the same as the Central Heating Design Supply Air Temperature. ");
    2882             :             }
    2883             : 
    2884             :             // initialize the water coil inlet conditions
    2885        2248 :             bPRINT = false; // no need to print to eio since we only need the values
    2886        2248 :             state.dataSize->DataFlowUsedForSizing = state.dataSize->DataAirFlowUsedForSizing;
    2887        2248 :             if (state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth == state.dataWaterCoils->NomCap && NomCapUserInp) {
    2888          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp;
    2889          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat =
    2890          35 :                     PsyWFnTdbRhPb(state, state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirTemp, 0.5, state.dataEnvrn->StdBaroPress, RoutineName);
    2891          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate =
    2892          35 :                     state.dataSize->DataAirFlowUsedForSizing * state.dataEnvrn->StdRhoAir;                        // don't need this
    2893          35 :                 state.dataSize->DataDesOutletAirTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesOutletAirTemp; // for error messages
    2894          35 :                 state.dataSize->DataDesOutletAirHumRat =
    2895          35 :                     PsyWFnTdbRhPb(state, state.dataSize->DataDesOutletAirTemp, 0.5, state.dataEnvrn->StdBaroPress, RoutineName); // for error messages
    2896          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate = rho * state.dataSize->DataWaterFlowUsedForSizing;
    2897          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate = rho * state.dataSize->DataWaterFlowUsedForSizing;
    2898          35 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp = state.dataWaterCoils->WaterCoil(CoilNum).DesInletWaterTemp;
    2899        2213 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).DesiccantRegenerationCoil) {
    2900           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp = state.dataSize->DataDesInletAirTemp;
    2901           0 :                 HeatingCoilDesAirInletHumRatSizer sizerHeatingDesInletHumRat;
    2902           0 :                 bool ErrorsFound = false;
    2903           0 :                 sizerHeatingDesInletHumRat.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2904           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat =
    2905           0 :                     sizerHeatingDesInletHumRat.size(state, DataSizing::AutoSize, ErrorsFound);
    2906           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat;
    2907             : 
    2908           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate = state.dataSize->DataAirFlowUsedForSizing; // coil report
    2909           0 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate =
    2910           0 :                     state.dataSize->DataAirFlowUsedForSizing * state.dataEnvrn->StdRhoAir; // this is stiil volume flow!
    2911             :             } else {
    2912        4426 :                 HeatingWaterDesAirInletTempSizer sizerHWDesInletTemp;
    2913        2213 :                 sizerHWDesInletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2914        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp = sizerHWDesInletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
    2915             : 
    2916        2213 :                 TempSize = AutoSize; // these data are initially 0, set to autosize to receive a result from Sizers
    2917        4426 :                 HeatingWaterDesAirInletHumRatSizer sizerHWAirInletHumRat;
    2918        2213 :                 sizerHWAirInletHumRat.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2919        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat = sizerHWAirInletHumRat.size(state, DataSizing::AutoSize, ErrorsFound);
    2920        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).DesInletAirHumRat;
    2921             : 
    2922        4426 :                 HeatingAirflowUASizer sizerHWAirFlowUA;
    2923        2213 :                 sizerHWAirFlowUA.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2924        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate = sizerHWAirFlowUA.size(state, DataSizing::AutoSize, ErrorsFound);
    2925        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).DesAirMassFlowRate;
    2926             :             }
    2927             : 
    2928             :             // zone and air loop coils use different design coil load calculations, air loop coils use air side capacity,
    2929             :             // zone coils use water side capacity
    2930        2248 :             state.dataSize->DataDesInletAirTemp = state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp;                   // used in error mesages
    2931        2248 :             state.dataSize->DataDesInletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;               // used in error mesages
    2932        2248 :             state.dataSize->DataFlowUsedForSizing = state.dataSize->DataAirFlowUsedForSizing * state.dataEnvrn->StdRhoAir; // used in error mesages
    2933        2248 :             state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate = state.dataSize->DataWaterFlowUsedForSizing;     // why is this here?
    2934        2248 :             if (!(state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth == state.dataWaterCoils->NomCap && NomCapUserInp)) {
    2935             :                 // get the design coil load used to size UA
    2936        4426 :                 HeatingWaterDesCoilLoadUsedForUASizer sizerHWDesCoilLoadForUA;
    2937        2213 :                 sizerHWDesCoilLoadForUA.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2938        2213 :                 state.dataSize->DataCapacityUsedForSizing = sizerHWDesCoilLoadForUA.size(state, DataSizing::AutoSize, ErrorsFound);
    2939             :                 // get the water volume flow rate used to size UA
    2940        4426 :                 HeatingWaterDesCoilWaterVolFlowUsedForUASizer sizerHWWaterVolFlowUA;
    2941        2213 :                 sizerHWWaterVolFlowUA.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2942        2213 :                 state.dataSize->DataWaterFlowUsedForSizing = sizerHWWaterVolFlowUA.size(state, DataSizing::AutoSize, ErrorsFound);
    2943        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp = state.dataSize->PlantSizData(PltSizHeatNum).ExitTemp;
    2944        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate = rho * state.dataSize->DataWaterFlowUsedForSizing;
    2945        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate = rho * state.dataSize->DataWaterFlowUsedForSizing;
    2946        2213 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate = state.dataSize->DataCapacityUsedForSizing;
    2947             :             }
    2948             :             // calculate UA
    2949        2248 :             if (state.dataSize->CurSysNum > 0)
    2950         371 :                 state.dataWaterCoils->WaterCoil(CoilNum).DesTotWaterCoilLoad = state.dataSize->DataCapacityUsedForSizing;
    2951        2248 :             FieldNum = 1;  // N1 , \field U-Factor Times Area Value
    2952        2248 :             bPRINT = true; // report to eio the UA value
    2953        2248 :             SizingString = state.dataWaterCoils->WaterCoilNumericFields(CoilNum).FieldNames(FieldNum) + " [W/K]";
    2954        2248 :             state.dataSize->DataCoilNum = CoilNum;
    2955        2248 :             state.dataSize->DataFanOpMode = ContFanCycCoil;
    2956        2248 :             if (state.dataWaterCoils->WaterCoil(CoilNum).CoilPerfInpMeth == state.dataWaterCoils->NomCap && NomCapUserInp) {
    2957          35 :                 TempSize = AutoSize;
    2958             :             } else {
    2959        2213 :                 TempSize = state.dataWaterCoils->WaterCoil(CoilNum).UACoil;
    2960             :             }
    2961             : 
    2962        2248 :             state.dataSize->DataFlowUsedForSizing = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    2963        2248 :             DesCoilWaterInTempSaved = state.dataWaterCoils->WaterCoil(state.dataSize->DataCoilNum).InletWaterTemp;
    2964        2248 :             if (DesCoilWaterInTempSaved < DesCoilHWInletTempMin) {
    2965             :                 // at low coil design water inlet temp, sizing has convergence issue hence slightly higher water inlet temperature
    2966             :                 // is estimated in "EstimateCoilInletWaterTemp" and used for UA autosizing only
    2967           0 :                 EstimateCoilInletWaterTemp(state,
    2968           0 :                                            state.dataSize->DataCoilNum,
    2969           0 :                                            state.dataSize->DataFanOpMode,
    2970             :                                            1.0,
    2971           0 :                                            state.dataSize->DataCapacityUsedForSizing,
    2972             :                                            DesCoilInletWaterTempUsed);
    2973           0 :                 state.dataWaterCoils->WaterCoil(state.dataSize->DataCoilNum).InletWaterTemp = DesCoilInletWaterTempUsed;
    2974             :             }
    2975             :             // must set DataCapacityUsedForSizing, DataWaterFlowUsedForSizing and DataFlowUsedForSizing to size UA. Any value of 0 will result
    2976             :             // in UA = 1.
    2977        4496 :             WaterHeatingCoilUASizer sizerHWCoilUA;
    2978        2248 :             sizerHWCoilUA.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
    2979        2248 :             state.dataWaterCoils->WaterCoil(CoilNum).UACoil = sizerHWCoilUA.size(state, TempSize, ErrorsFound);
    2980        2248 :             if (DesCoilWaterInTempSaved < DesCoilHWInletTempMin) {
    2981           0 :                 ShowWarningError(state, "Autosizing of heating coil UA for Coil:Heating:Water \"" + std::string{CompName} + "\"");
    2982           0 :                 ShowContinueError(state,
    2983           0 :                                   format(" Plant design loop exit temperature = {:.2T} C",
    2984           0 :                                          state.dataSize->PlantSizData(state.dataSize->DataPltSizHeatNum).ExitTemp));
    2985           0 :                 ShowContinueError(state, " Plant design loop exit temperature is low for design load and leaving air temperature anticipated.");
    2986           0 :                 ShowContinueError(state,
    2987           0 :                                   format(" Heating coil UA-value is sized using coil water inlet temperature = {:.2T} C", DesCoilInletWaterTempUsed));
    2988           0 :                 state.dataWaterCoils->WaterCoil(state.dataSize->DataCoilNum).InletWaterTemp =
    2989             :                     DesCoilWaterInTempSaved; // reset the Design Coil Inlet Water Temperature
    2990             :             }
    2991             :             // if coil UA did not size due to one of these variables being 0, must set UACoilVariable to avoid crash later on
    2992        4465 :             if (state.dataSize->DataCapacityUsedForSizing == 0.0 || state.dataSize->DataWaterFlowUsedForSizing == 0.0 ||
    2993        2217 :                 state.dataSize->DataFlowUsedForSizing == 0.0) {
    2994          31 :                 if (state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable == AutoSize) {
    2995          31 :                     state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable = state.dataWaterCoils->WaterCoil(CoilNum).UACoil;
    2996             :                 }
    2997             :             }
    2998             :             // WaterCoil(CoilNum).UACoilVariable = WaterCoil(CoilNum).UACoil;
    2999        2248 :             state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate = state.dataSize->DataCapacityUsedForSizing;
    3000        2248 :             state.dataWaterCoils->WaterCoil(state.dataSize->DataCoilNum).InletWaterTemp =
    3001             :                 DesCoilWaterInTempSaved; // reset the Design Coil Inlet Water Temperature
    3002             : 
    3003        2248 :             state.dataSize->DataWaterLoopNum = 0; // reset all globals to 0 to ensure correct sizing for other child components
    3004        2248 :             state.dataSize->DataPltSizHeatNum = 0;
    3005        2248 :             state.dataSize->DataCoilNum = 0;
    3006        2248 :             state.dataSize->DataFanOpMode = 0;
    3007        2248 :             state.dataSize->DataCapacityUsedForSizing = 0.0;
    3008        2248 :             state.dataSize->DataWaterFlowUsedForSizing = 0.0;
    3009        2248 :             state.dataSize->DataDesInletAirTemp = 0.0;
    3010        2248 :             state.dataSize->DataDesInletAirHumRat = 0.0;
    3011        2248 :             state.dataSize->DataDesOutletAirTemp = 0.0;
    3012        2248 :             state.dataSize->DataDesOutletAirHumRat = 0.0;
    3013        2248 :             state.dataSize->DataAirFlowUsedForSizing = 0.0;
    3014        2248 :             state.dataSize->DataFlowUsedForSizing = 0.0;
    3015        2248 :             state.dataSize->DataDesicDehumNum = 0;
    3016        2248 :             state.dataSize->DataDesicRegCoil = false;
    3017        2248 :             state.dataSize->DataWaterCoilSizHeatDeltaT = 0.0;
    3018        2248 :             state.dataSize->DataNomCapInpMeth = false;
    3019             : 
    3020             :         } else {
    3021             :             // if there is no heating Plant Sizing object and autosizng was requested, issue an error message
    3022         306 :             if (state.dataWaterCoils->WaterCoil(CoilNum).RequestingAutoSize) {
    3023           0 :                 ShowSevereError(state, "Autosizing of water coil requires a heating loop Sizing:Plant object");
    3024           0 :                 ShowContinueError(state, "Occurs in water coil object= " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    3025           0 :                 ErrorsFound = true;
    3026             :             }
    3027             :         }
    3028             :         //} // end of heating Plant Sizing existence IF - ELSE
    3029             :     } // end heating coil IF
    3030             : 
    3031             :     // save the design water volumetric flow rate for use by the water loop sizing algorithms
    3032        3100 :     if (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate > 0.0) {
    3033        6134 :         RegisterPlantCompDesignFlow(
    3034        6134 :             state, state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum, state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate);
    3035             :     }
    3036             : 
    3037        3100 :     if (ErrorsFound || state.dataSize->DataErrorsFound) {
    3038           0 :         ShowFatalError(state, "Preceding water coil sizing errors cause program termination");
    3039             :     }
    3040        3100 : }
    3041             : 
    3042             : // End Initialization Section of the Module
    3043             : //******************************************************************************
    3044             : 
    3045             : // Begin Algorithm Section of the Module
    3046             : //******************************************************************************
    3047             : 
    3048   112202558 : void CalcSimpleHeatingCoil(EnergyPlusData &state,
    3049             :                            int const CoilNum,          // index to heating coil
    3050             :                            int const FanOpMode,        // fan operating mode
    3051             :                            Real64 const PartLoadRatio, // part-load ratio of heating coil
    3052             :                            int const CalcMode          // 1 = design calc; 2 = simulation calculation
    3053             : )
    3054             : {
    3055             :     // SUBROUTINE INFORMATION:
    3056             :     //       AUTHOR         Rich Liesen
    3057             :     //       DATE WRITTEN
    3058             :     //       MODIFIED       Aug. 2007 - R. Raustad, added fan operating mode and part-load ratio to
    3059             :     //                                  calculate the outlet conditions when fan and coil cycle.
    3060             :     //                                  Air and water outlet temperature are full output with average
    3061             :     //                                  air and water mass flow rate when fan and coil cycle.
    3062             :     //       RE-ENGINEERED  na
    3063             : 
    3064             :     // PURPOSE OF THIS SUBROUTINE:
    3065             :     // Simulates a simple NTU effectiveness model heating coil
    3066             : 
    3067             :     // METHODOLOGY EMPLOYED:
    3068             :     // (1) outlet conditions are calculated from the effectiveness and the inlet conditions.
    3069             :     // (2) Effectiveness is calculated from the NTU formula for a cross flow heat exchanger
    3070             :     //     with both streams unmixed.
    3071             :     // Note: UA is input by user and is fixed.
    3072             : 
    3073             :     // REFERENCES:
    3074             :     // See for instance ASHRAE HVAC 2 Toolkit, page 4-4, formula (4-7)
    3075             : 
    3076             :     // Using/Aliasing
    3077             : 
    3078             :     // Locals
    3079             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    3080             : 
    3081             :     // SUBROUTINE PARAMETER DEFINITIONS:
    3082             :     static constexpr std::string_view RoutineName("CalcSimpleHeatingCoil");
    3083             : 
    3084             :     // INTERFACE BLOCK SPECIFICATIONS
    3085             :     // na
    3086             : 
    3087             :     // DERIVED TYPE DEFINITIONS
    3088             :     // na
    3089             : 
    3090             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3091             :     Real64 WaterMassFlowRate;
    3092             :     Real64 AirMassFlow; // [kg/sec]
    3093             :     Real64 TempAirIn;   // [C]
    3094             :     Real64 TempAirOut;  // [C]
    3095             :     Real64 Win;
    3096             :     Real64 TempWaterIn;
    3097             :     Real64 TempWaterOut;
    3098             :     Real64 UA;
    3099             :     Real64 CapacitanceAir;
    3100             :     Real64 CapacitanceWater;
    3101             :     Real64 CapacitanceMin;
    3102             :     Real64 CapacitanceMax;
    3103             :     Real64 HeatingCoilLoad;
    3104             :     Real64 NTU;
    3105             :     Real64 ETA;
    3106             :     Real64 A;
    3107             :     Real64 CapRatio;
    3108             :     Real64 E1;
    3109             :     Real64 E2;
    3110             :     Real64 Effec;
    3111             :     Real64 Cp;
    3112             :     int Control;
    3113             : 
    3114   112202558 :     UA = state.dataWaterCoils->WaterCoil(CoilNum).UACoilVariable;
    3115   112202558 :     TempAirIn = state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp;
    3116   112202558 :     Win = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    3117   112202558 :     Control = state.dataWaterCoils->WaterCoil(CoilNum).Control;
    3118   112202558 :     TempWaterIn = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp;
    3119             : 
    3120             :     // adjust mass flow rates for cycling fan cycling coil operation
    3121   112202558 :     if (FanOpMode == CycFanCycCoil) {
    3122     2155645 :         if (PartLoadRatio > 0.0) {
    3123     1581726 :             AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / PartLoadRatio;
    3124     1581726 :             WaterMassFlowRate = min(state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate / PartLoadRatio,
    3125     1581726 :                                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate);
    3126             :         } else {
    3127      573919 :             AirMassFlow = 0.0;
    3128      573919 :             WaterMassFlowRate = 0.0;
    3129             :         }
    3130             :     } else {
    3131   110046913 :         AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    3132   110046913 :         WaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    3133             :     }
    3134             : 
    3135   112202558 :     if (WaterMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) { // If the coil is operating
    3136    71618883 :         CapacitanceAir = PsyCpAirFnW(Win) * AirMassFlow;
    3137   143237766 :         Cp = GetSpecificHeatGlycol(state,
    3138    71618883 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    3139             :                                    TempWaterIn,
    3140    71618883 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    3141             :                                    RoutineName);
    3142    71618883 :         CapacitanceWater = Cp * WaterMassFlowRate;
    3143    71618883 :         CapacitanceMin = min(CapacitanceAir, CapacitanceWater);
    3144    71618883 :         CapacitanceMax = max(CapacitanceAir, CapacitanceWater);
    3145             :     } else {
    3146    40583675 :         CapacitanceAir = 0.0;
    3147    40583675 :         CapacitanceWater = 0.0;
    3148             :     }
    3149             : 
    3150             :     // If the coil is operating there should be some heating capacitance
    3151             :     //  across the coil, so do the simulation. If not set outlet to inlet and no load.
    3152             :     //  Also the coil has to be scheduled to be available
    3153   255355948 :     if (((CapacitanceAir > 0.0) && (CapacitanceWater > 0.0)) &&
    3154   214770488 :         (CalcMode == state.dataWaterCoils->DesignCalc || state.dataWaterCoils->MySizeFlag(CoilNum) ||
    3155   143131008 :          state.dataWaterCoils->MyUAAndFlowCalcFlag(CoilNum) ||
    3156    71565504 :          GetCurrentScheduleValue(state, state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr) > 0.0)) {
    3157             : 
    3158    71542447 :         if (UA <= 0.0) {
    3159           0 :             ShowFatalError(state, "UA is zero for COIL:Heating:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    3160             :         }
    3161    71542447 :         NTU = UA / CapacitanceMin;
    3162    71542447 :         ETA = std::pow(NTU, 0.22);
    3163    71542447 :         CapRatio = CapacitanceMin / CapacitanceMax;
    3164    71542447 :         A = CapRatio * NTU / ETA;
    3165             : 
    3166    71542447 :         if (A > 20.0) {
    3167           0 :             A = ETA * 1.0 / CapRatio;
    3168             :         } else {
    3169    71542447 :             E1 = std::exp(-A);
    3170    71542447 :             A = ETA * (1.0 - E1) / CapRatio;
    3171             :         }
    3172             : 
    3173    71542447 :         if (A > 20.0) {
    3174      226535 :             Effec = 1.0;
    3175             :         } else {
    3176    71315912 :             E2 = std::exp(-A);
    3177    71315912 :             Effec = 1.0 - E2;
    3178             :         }
    3179             : 
    3180    71542447 :         TempAirOut = TempAirIn + Effec * CapacitanceMin * (TempWaterIn - TempAirIn) / CapacitanceAir;
    3181    71542447 :         TempWaterOut = TempWaterIn - CapacitanceAir * (TempAirOut - TempAirIn) / CapacitanceWater;
    3182    71542447 :         HeatingCoilLoad = CapacitanceWater * (TempWaterIn - TempWaterOut);
    3183             :         // The HeatingCoilLoad is the change in the enthalpy of the water
    3184    71542447 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterEnthalpy =
    3185   143084894 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterEnthalpy -
    3186    71542447 :             HeatingCoilLoad / state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    3187    71542447 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    3188             : 
    3189             :     } else { // If not running Conditions do not change across coil from inlet to outlet
    3190             : 
    3191    40660111 :         TempAirOut = TempAirIn;
    3192    40660111 :         TempWaterOut = TempWaterIn;
    3193    40660111 :         HeatingCoilLoad = 0.0;
    3194    40660111 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterEnthalpy = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterEnthalpy;
    3195    40660111 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterMassFlowRate = 0.0;
    3196             :     }
    3197             : 
    3198   112202558 :     if (FanOpMode == CycFanCycCoil) {
    3199     2155645 :         HeatingCoilLoad *= PartLoadRatio;
    3200             :     }
    3201             : 
    3202             :     // Set the outlet conditions
    3203   112202558 :     state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate = HeatingCoilLoad;
    3204   112202558 :     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp = TempAirOut;
    3205   112202558 :     state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterTemp = TempWaterOut;
    3206             : 
    3207             :     // This WaterCoil does not change the moisture or Mass Flow across the component
    3208   112202558 :     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    3209   112202558 :     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    3210             :     // Set the outlet enthalpys for air and water
    3211   112202558 :     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirEnthalpy =
    3212   112202558 :         PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp, state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat);
    3213   112202558 : }
    3214             : 
    3215     3337956 : void CalcDetailFlatFinCoolingCoil(EnergyPlusData &state,
    3216             :                                   int const CoilNum,
    3217             :                                   int const CalcMode,
    3218             :                                   int const FanOpMode,       // fan operating mode
    3219             :                                   Real64 const PartLoadRatio // part-load ratio of heating coil
    3220             : )
    3221             : {
    3222             : 
    3223             :     // SUBROUTINE INFORMATION:
    3224             :     //       AUTHOR(S)      Russell Taylor / Richard Liesen
    3225             :     //       DATE WRITTEN   Mar 1997
    3226             :     //       MODIFIED       Feb 2010, B. Nigusse, FSEC, corrected units inconsistency for tube and fins
    3227             :     //                      materials thermal conductivties. Now input values in the idf are in {W/(m.K)}
    3228             :     //       RE-ENGINEERED  Sept 1998
    3229             : 
    3230             :     // PURPOSE OF THIS SUBROUTINE:
    3231             :     // This subroutine simulates a chilled water cooling coil.  Provided with
    3232             :     // the coil geometry and the flow (i.e. air and water) inlet conditions,
    3233             :     // it will calculate the flow outlet conditions and the total and latent
    3234             :     // heat extraction rates from the air.  The coil model has some limitations
    3235             :     // as noted in the code.
    3236             : 
    3237             :     // METHODOLOGY EMPLOYED:
    3238             :     // successive substitution, solve coil as if all wet, then
    3239             :     // again if partly or entirely dry
    3240             : 
    3241             :     // REFERENCES:
    3242             :     // First found in Type 12 from MODSIM, but now
    3243             :     // programmed directly from Elmahdy, A.H. and Mitalas, G.P.  "A
    3244             :     // Simple Model for Cooling and Dehumidifying Coils for Use in
    3245             :     // Calculating Energy Requirements for Buildings"  _ASHRAE
    3246             :     // Transactions_ Vol. 83, Part 2, pp. 103-117 (1977).
    3247             : 
    3248             :     // OTHER NOTES:
    3249             :     // Routine was originally adapted for use in IBLAST by R.D. Taylor in l993.
    3250             :     // Subsequently rewritten and improved by J.C. Vanderzee in 1994
    3251             :     // Revised and further enhanced by R.D. Taylor in Jan 1996
    3252             :     // Re-engineered for EnergyPlus by Richard Liesen PhD in 1998
    3253             : 
    3254             :     // Using/Aliasing
    3255             : 
    3256             :     // Locals
    3257             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    3258             : 
    3259             :     // SUBROUTINE PARAMETER DEFINITIONS:
    3260             :     static Real64 const exp_47(std::exp(-0.41718));
    3261             :     static Real64 const exp_35(std::exp(-0.3574));
    3262             :     static constexpr std::string_view RoutineName("CalcDetailFlatFinCoolingCoil");
    3263             : 
    3264     3337956 :     constexpr Real64 AirViscosity(1.846e-5); // Dynamic Viscosity of Air in kg/(m.s)
    3265     3337956 :     constexpr Real64 ConvK(1.0e-3);          // Unit conversion factor
    3266     3337956 :     constexpr Real64 unity(1.0);
    3267     3337956 :     constexpr Real64 zero(0.0);
    3268     3337956 :     constexpr Real64 TubeFoulFactor(5.0e-2); // Inside tube fouling factor for water, in m2K/kW
    3269             :     // Changed from m2K/W to m2K/kW for consistency with the
    3270             :     // other parameters in "TubeFoulThermResis" calculation
    3271             : 
    3272             :     // INTERFACE BLOCK SPECIFICATIONS
    3273             :     // na
    3274             : 
    3275             :     // DERIVED TYPE DEFINITIONS
    3276             :     // na
    3277             : 
    3278             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3279             :     int CoefPointer;
    3280             :     //    INTEGER :: CoolCoilErrs = 0
    3281             :     int PartWetIterations;
    3282             :     int WaterTempConvgLoop;
    3283             : 
    3284             :     bool CoilPartWetConvg;
    3285             :     bool WaterTempConvg;
    3286             : 
    3287             :     Real64 AirEnthAtRsdInletWaterTemp;
    3288             :     Real64 AirExitEnthlAtCoilSurfTemp;
    3289             :     Real64 AirExitCoilSurfTemp;
    3290             :     Real64 AirReynoldsNo;
    3291             :     Real64 AirEnthAtWetDryIntrfcSurfTemp;
    3292             :     Real64 AirSideDrySurfFilmCoef;
    3293             :     Real64 AirSideWetSurfFilmCoef;
    3294             :     Real64 AirWetDryInterfcTemp;
    3295             :     Real64 CoilToAirThermResistDrySurf;
    3296             :     Real64 CoilToAirThermResistWetSurf;
    3297             :     Real64 DryAirSpecHeat;
    3298             :     Real64 DryCoilCoeff1;
    3299             :     Real64 DryCoilCoeff;
    3300             :     Real64 DryCoilEfficiency;
    3301             :     Real64 DryFinEfficncy;
    3302             :     Real64 DryCoilInThermResist;
    3303             :     Real64 DrySideEffectiveWaterTemp;
    3304             :     Real64 EnterAirDewPoint;
    3305             :     Real64 EnterAirHumRatDiff;
    3306             :     Real64 WetDryInterSurfTempErrorLast;
    3307             :     Real64 WetDryInterSurfTempError;
    3308             :     Real64 expon;
    3309             :     Real64 FilmCoefEqnFactor;
    3310             :     Real64 FilmCoefReynldsCorrelatnFact;
    3311             :     Real64 FinToTotSurfAreaRatio;
    3312             :     Real64 InCoilSurfTemp;
    3313             :     Real64 InsdToOutsdThermResistRatio;
    3314             :     Real64 InSurfTempSatAirEnthl;
    3315             :     Real64 K1;
    3316             :     Real64 MeanWaterTemp;
    3317             :     Real64 MoistAirSpecificHeat;
    3318             :     Real64 OutCoilSurfTemp;
    3319             :     Real64 OutSurfTempSatAirEnthl;
    3320             :     Real64 RaisedInletWaterTemp;
    3321             :     Real64 RsdInletWaterTempSatAirHumRat;
    3322             :     Real64 ScaledAirMassFlowRate;
    3323             :     Real64 ScaledCoilAirThermResistWetSurf;
    3324             :     Real64 ScaledWaterSpecHeat;
    3325             :     Real64 ScaledWaterToTubeThermResist;
    3326             :     Real64 SensToTotEnthDiffRatio;
    3327             :     Real64 SurfAreaWet;
    3328             :     Real64 TubeFoulThermResist;
    3329             :     Real64 TubeWaterVel;
    3330             :     Real64 UACoilAllWet;
    3331             :     Real64 UACoilPartWet;
    3332             :     Real64 UADryCoil;
    3333             :     Real64 WaterToTubeThermResist;
    3334             :     Real64 WetAreaChange;
    3335             :     Real64 WetAreaLast;
    3336             :     Real64 WetCoilCoeff;
    3337             :     Real64 WetCoilFinEfficncy;
    3338             :     Real64 WetDryInterfcAirEnthl;
    3339             :     Real64 WetDryInterfcSurfTemp;
    3340             :     Real64 WetDryInterfcWaterTemp;
    3341             :     Real64 WetFinEfficncy;
    3342             :     Real64 WetSideEffctvWaterTemp;
    3343             :     Real64 y;
    3344             :     Real64 TempAirIn;
    3345             :     Real64 TempAirOut;
    3346             :     Real64 InletAirHumRat;
    3347             :     Real64 OutletAirHumRat;
    3348             :     Real64 InletAirEnthalpy;
    3349             :     Real64 OutletAirEnthalpy;
    3350             :     Real64 WaterMassFlowRate;
    3351             :     Real64 AirMassFlow;
    3352             :     Real64 TempWaterIn;
    3353             :     Real64 TempWaterOut;
    3354             :     Real64 TotWaterCoilLoad;
    3355             :     Real64 SenWaterCoilLoad;
    3356             :     Real64 AirDensity;
    3357             :     Real64 AirVelocity;
    3358             :     Real64 denom;
    3359             :     Real64 rho;
    3360             :     Real64 Cp;
    3361             : 
    3362             :     // Set derived type variables to shorter local variables
    3363     3337956 :     TempAirIn = state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp;
    3364     3337956 :     InletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    3365     3337956 :     TempWaterIn = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp;
    3366             : 
    3367             :     //  adjust mass flow rates for cycling fan cycling coil operation
    3368     3337956 :     if (FanOpMode == CycFanCycCoil) {
    3369           0 :         if (PartLoadRatio > 0.0) {
    3370           0 :             AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / PartLoadRatio;
    3371           0 :             WaterMassFlowRate = min(state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate / PartLoadRatio,
    3372           0 :                                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate);
    3373             :         } else {
    3374           0 :             AirMassFlow = 0.0;
    3375           0 :             WaterMassFlowRate = 0.0;
    3376             :         }
    3377             :     } else {
    3378     3337956 :         AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    3379     3337956 :         WaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    3380             :     }
    3381             : 
    3382     3337956 :     if (WaterMassFlowRate < state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate * WaterCoils::MinWaterMassFlowFrac) {
    3383     1633368 :         WaterMassFlowRate = 0.0;
    3384             :     }
    3385     3337956 :     if (TempAirIn <= TempWaterIn) {
    3386      269278 :         WaterMassFlowRate = 0.0;
    3387             :     }
    3388     3337956 :     WetDryInterfcAirEnthl = 0.0;
    3389     3337956 :     OutletAirEnthalpy = 0.0;
    3390     3337956 :     InletAirEnthalpy = 0.0;
    3391             : 
    3392             :     // Warning and error messages for large flow rates for the given user input geometry
    3393     3337956 :     AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempAirIn, InletAirHumRat, RoutineName);
    3394     3340614 :     if (AirMassFlow > (5.0 * state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea / AirDensity) &&
    3395        2658 :         state.dataWaterCoils->CoilWarningOnceFlag(CoilNum)) {
    3396           2 :         ShowWarningError(state, "Coil:Cooling:Water:DetailedGeometry in Coil =" + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    3397           2 :         ShowContinueError(state, "Air Flow Rate Velocity has greatly exceeded upper design guidelines of ~2.5 m/s");
    3398           2 :         ShowContinueError(state, format("Air Mass Flow Rate[kg/s]={:.6T}", AirMassFlow));
    3399             :         // [m/s] = [kg/s] / ([m2] * [kg/m3])
    3400           2 :         AirVelocity = AirMassFlow / (state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea * AirDensity);
    3401           2 :         ShowContinueError(state, format("Air Face Velocity[m/s]={:.6T}", AirVelocity));
    3402           6 :         ShowContinueError(state,
    3403           4 :                           format("Approximate Mass Flow Rate limit for Face Area[kg/s]={:.6T}",
    3404           4 :                                  2.5 * state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea * AirDensity));
    3405           2 :         ShowContinueError(state, "Coil:Cooling:Water:DetailedGeometry could be resized/autosized to handle capacity");
    3406           2 :         state.dataWaterCoils->CoilWarningOnceFlag(CoilNum) = false;
    3407     3337954 :     } else if (AirMassFlow > (44.7 * state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea * AirDensity)) {
    3408           0 :         ShowSevereError(state, "Coil:Cooling:Water:DetailedGeometry in Coil =" + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    3409           0 :         ShowContinueError(state, "Air Flow Rate Velocity is > 100MPH (44.7m/s) and simulation cannot continue");
    3410           0 :         ShowContinueError(state, format("Air Mass Flow Rate[kg/s]={:.6T}", AirMassFlow));
    3411           0 :         AirVelocity = AirMassFlow / (state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea * AirDensity);
    3412           0 :         ShowContinueError(state, format("Air Face Velocity[m/s]={:.6T}", AirVelocity));
    3413           0 :         ShowContinueError(state,
    3414           0 :                           format("Approximate Mass Flow Rate limit for Face Area[kg/s]={:.6T}",
    3415           0 :                                  44.7 * state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea * AirDensity));
    3416           0 :         ShowFatalError(state, "Coil:Cooling:Water:DetailedGeometry needs to be resized/autosized to handle capacity");
    3417             :     }
    3418             : 
    3419             :     // If Coil is Scheduled ON then do the simulation
    3420    10907974 :     if (((GetCurrentScheduleValue(state, state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr) > 0.0) && (WaterMassFlowRate > 0.0) &&
    3421     6676941 :          (AirMassFlow >= WaterCoils::MinAirMassFlow)) ||
    3422     1720997 :         (CalcMode == state.dataWaterCoils->DesignCalc)) {
    3423             :         //        transfer inputs to simulation variables and calculate
    3424             :         //        known thermodynamic functions
    3425             :         // All coil calcs are done in KJoules.  Convert to KJ here and then convert
    3426             :         //  back to Joules at the end of the Subroutine.
    3427     1617457 :         DryAirSpecHeat = PsyCpAirFnW(zero) * ConvK;
    3428     1617457 :         MoistAirSpecificHeat = PsyCpAirFnW(InletAirHumRat) * ConvK;
    3429     1617457 :         InletAirEnthalpy = state.dataWaterCoils->WaterCoil(CoilNum).InletAirEnthalpy * ConvK;
    3430             : 
    3431     1617457 :         EnterAirDewPoint = PsyTdpFnWPb(state, InletAirHumRat, state.dataEnvrn->OutBaroPress, RoutineName);
    3432             :         //       Ratio of secondary (fin) to total (secondary plus primary) surface areas
    3433     1617457 :         FinToTotSurfAreaRatio =
    3434     1617457 :             state.dataWaterCoils->WaterCoil(CoilNum).FinSurfArea / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    3435             :         //      known water and air flow parameters:
    3436     3234914 :         rho = GetDensityGlycol(state,
    3437     1617457 :                                state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    3438             :                                TempWaterIn,
    3439     1617457 :                                state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    3440             :                                RoutineName);
    3441             :         //      water flow velocity - assuming number of water circuits = NumOfTubesPerRow
    3442     3234914 :         TubeWaterVel = WaterMassFlowRate * 4.0 /
    3443     3234914 :                        (state.dataWaterCoils->WaterCoil(CoilNum).NumOfTubesPerRow * rho * DataGlobalConstants::Pi *
    3444     3234914 :                         state.dataWaterCoils->WaterCoil(CoilNum).TubeInsideDiam * state.dataWaterCoils->WaterCoil(CoilNum).TubeInsideDiam);
    3445             :         //      air mass flow rate per unit area
    3446     1617457 :         ScaledAirMassFlowRate = (1.0 + InletAirHumRat) * AirMassFlow / state.dataWaterCoils->WaterCoil(CoilNum).MinAirFlowArea;
    3447             :         //      air flow Reynold's Number
    3448     1617457 :         AirReynoldsNo = state.dataWaterCoils->WaterCoil(CoilNum).CoilEffectiveInsideDiam * ScaledAirMassFlowRate / AirViscosity;
    3449             :         //       heat transfer coefficients and resistance components:
    3450             :         //              inside (water)
    3451     3234914 :         WaterToTubeThermResist = std::pow(state.dataWaterCoils->WaterCoil(CoilNum).TubeInsideDiam, 0.2) /
    3452     1617457 :                                  (state.dataWaterCoils->WaterCoil(CoilNum).TotTubeInsideArea * 1.429 * std::pow(TubeWaterVel, 0.8));
    3453             :         //              metal and fouling
    3454     1617457 :         TubeFoulThermResist =
    3455     3234914 :             (0.5 * (state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideDiam - state.dataWaterCoils->WaterCoil(CoilNum).TubeInsideDiam) /
    3456     3234914 :                  (ConvK * state.dataWaterCoils->WaterCoil(CoilNum).TubeThermConductivity) +
    3457             :              TubeFoulFactor) /
    3458     1617457 :             state.dataWaterCoils->WaterCoil(CoilNum).TotTubeInsideArea;
    3459             :         //              outside (wet and dry coil)
    3460     1617457 :         FilmCoefEqnFactor =
    3461     1617457 :             state.dataWaterCoils->WaterCoil(CoilNum).GeometryCoef1 * std::pow(AirReynoldsNo, state.dataWaterCoils->WaterCoil(CoilNum).GeometryCoef2);
    3462             :         //       (1.23 is 1/Prandt(air)**(2/3))
    3463     1617457 :         AirSideDrySurfFilmCoef = 1.23 * FilmCoefEqnFactor * MoistAirSpecificHeat * ScaledAirMassFlowRate;
    3464     1617457 :         FilmCoefReynldsCorrelatnFact = 1.425 + AirReynoldsNo * (-0.51e-3 + AirReynoldsNo * 0.263e-6);
    3465             :         //       NOTE: the equation for FilmCoefReynldsCorrelatnFact generates valid results over
    3466             :         //             a limited range of Air Reynolds Numbers as indicated by
    3467             :         //             deleted code below.  Reynolds Numbers outside this range
    3468             :         //             may result in inaccurate results or failure of the coil
    3469             :         //             simulation to obtain a solution
    3470             :         //             Deleted code by J.C. Vanderzee
    3471             : 
    3472     1617457 :         AirSideWetSurfFilmCoef = FilmCoefReynldsCorrelatnFact * AirSideDrySurfFilmCoef;
    3473             :         //--                     need wet fin efficiency for outside
    3474     1617457 :         RaisedInletWaterTemp = TempWaterIn + 0.5;
    3475             : 
    3476             :         // By this statement the Inlet Air enthalpy will never be equal to AirEnthAtRsdInletWaterTemp
    3477     1617457 :         if ((RaisedInletWaterTemp - TempAirIn) < 0.000001) {
    3478     1617287 :             RaisedInletWaterTemp = TempWaterIn + 0.3;
    3479             :         }
    3480     1617457 :         if (TempAirIn < RaisedInletWaterTemp) {
    3481         170 :             RaisedInletWaterTemp = TempAirIn - 0.3;
    3482             :         }
    3483             : 
    3484     1617457 :         RsdInletWaterTempSatAirHumRat = PsyWFnTdbRhPb(state, RaisedInletWaterTemp, unity, state.dataEnvrn->OutBaroPress, RoutineName);
    3485     1617457 :         AirEnthAtRsdInletWaterTemp = PsyHFnTdbW(RaisedInletWaterTemp, RsdInletWaterTempSatAirHumRat) * ConvK;
    3486             : 
    3487     1617457 :         SensToTotEnthDiffRatio = DryAirSpecHeat * (TempAirIn - RaisedInletWaterTemp) / (InletAirEnthalpy - AirEnthAtRsdInletWaterTemp);
    3488             : 
    3489     1617457 :         EnterAirHumRatDiff = InletAirHumRat - RsdInletWaterTempSatAirHumRat;
    3490     1617457 :         DryFinEfficncy =
    3491     1617457 :             0.5 * (state.dataWaterCoils->WaterCoil(CoilNum).EffectiveFinDiam - state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideDiam) *
    3492     1617457 :             std::sqrt(
    3493     1617457 :                 2.0 * AirSideWetSurfFilmCoef /
    3494     1617457 :                 (ConvK * state.dataWaterCoils->WaterCoil(CoilNum).FinThermConductivity * state.dataWaterCoils->WaterCoil(CoilNum).FinThickness));
    3495     1617457 :         if (EnterAirHumRatDiff < 0) {
    3496             :             //       note that this condition indicates dry coil
    3497       63730 :             EnterAirHumRatDiff = -EnterAirHumRatDiff;
    3498       63730 :             SensToTotEnthDiffRatio = std::abs(SensToTotEnthDiffRatio);
    3499             :         }
    3500             : 
    3501     1617457 :         if (EnterAirHumRatDiff > 1.0) {
    3502           0 :             EnterAirHumRatDiff = 1.0;
    3503     1617457 :         } else if (EnterAirHumRatDiff < 0.00001) {
    3504         828 :             EnterAirHumRatDiff = 0.00001;
    3505             :         }
    3506             : 
    3507     1617457 :         if (DryFinEfficncy > 1.0) {
    3508           0 :             DryFinEfficncy = 1.0;
    3509     1617457 :         } else if (DryFinEfficncy < 0.00001) {
    3510           0 :             DryFinEfficncy = 0.00001;
    3511             :         }
    3512             : 
    3513     1617457 :         if (TempAirIn > 48.0 / 1.8) {
    3514      161103 :             WetFinEfficncy =
    3515      161103 :                 exp_47 * std::pow(SensToTotEnthDiffRatio, 0.09471) * std::pow(EnterAirHumRatDiff, 0.0108) * std::pow(DryFinEfficncy, -0.50303);
    3516             :         } else {
    3517     1456354 :             WetFinEfficncy =
    3518     1456354 :                 exp_35 * std::pow(SensToTotEnthDiffRatio, 0.16081) * std::pow(EnterAirHumRatDiff, 0.01995) * std::pow(DryFinEfficncy, -0.52951);
    3519             :         }
    3520             : 
    3521     1617457 :         if (WetFinEfficncy > 1.0) WetFinEfficncy = 0.99;
    3522     1617457 :         if (WetFinEfficncy < 0.0) WetFinEfficncy = 0.001;
    3523             :         //       wet coil fin efficiency
    3524             : 
    3525     1617457 :         WetCoilFinEfficncy = 1.0 + FinToTotSurfAreaRatio * (WetFinEfficncy - 1.0);
    3526             :         //       wet coil outside thermal resistance = [1/UA] (wet coil)
    3527     1617457 :         CoilToAirThermResistWetSurf =
    3528     1617457 :             MoistAirSpecificHeat / (state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea * AirSideWetSurfFilmCoef * WetCoilFinEfficncy);
    3529             :         //--                     and dry fin efficiency
    3530     1617457 :         DryFinEfficncy =
    3531     1617457 :             0.5 * (state.dataWaterCoils->WaterCoil(CoilNum).EffectiveFinDiam - state.dataWaterCoils->WaterCoil(CoilNum).TubeOutsideDiam) *
    3532     1617457 :             std::sqrt(
    3533     1617457 :                 2.0 * AirSideDrySurfFilmCoef /
    3534     1617457 :                 (ConvK * state.dataWaterCoils->WaterCoil(CoilNum).FinThermConductivity * state.dataWaterCoils->WaterCoil(CoilNum).FinThickness));
    3535             :         //      NOTE: The same caveats on the validity of the FilmCoefReynldsCorrelatnFact equation
    3536             :         //            hold for the DryFinEfficncy equation.  Values of DryFinEfficncy outside the
    3537             :         //            specified range of validity are not guaranteed to
    3538             :         //            produce results
    3539             :         //             Deleted code by J.C. Vanderzee
    3540             :         //       dry coil fin efficiency
    3541     1617457 :         DryCoilEfficiency = 0.0;
    3542             :         // Tuned Replaced by below to eliminate pow calls
    3543             :         //            for ( CoefPointer = 1; CoefPointer <= 5; ++CoefPointer ) {
    3544             :         //                DryCoilEfficiency += WaterCoil( CoilNum ).DryFinEfficncyCoef( CoefPointer ) * std::pow(
    3545             :         // DryFinEfficncy,
    3546             :         // CoefPointer
    3547             :         //-
    3548             :         // 1
    3549             :         //);             } // CoefPointer
    3550     1617457 :         auto const &dry_fin_eff_coef(state.dataWaterCoils->WaterCoil(CoilNum).DryFinEfficncyCoef);
    3551     1617457 :         auto DryFinEfficncy_pow(1.0);
    3552     9704742 :         for (CoefPointer = 1; CoefPointer <= 5; ++CoefPointer) {
    3553     8087285 :             DryCoilEfficiency += dry_fin_eff_coef(CoefPointer) * DryFinEfficncy_pow;
    3554     8087285 :             DryFinEfficncy_pow *= DryFinEfficncy;
    3555             :         } // CoefPointer
    3556     1617457 :         DryCoilEfficiency = 1.0 + FinToTotSurfAreaRatio * (DryCoilEfficiency - 1.0);
    3557             :         //       dry coil outside thermal resistance = [1/UA] (dry coil)
    3558     1617457 :         CoilToAirThermResistDrySurf =
    3559     1617457 :             1.0 / (state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea * AirSideDrySurfFilmCoef * DryCoilEfficiency);
    3560             :         //       definitions made to simplify some of the expressions used below
    3561     3234914 :         Cp = GetSpecificHeatGlycol(state,
    3562     1617457 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    3563             :                                    TempWaterIn,
    3564     1617457 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    3565             :                                    RoutineName);
    3566     1617457 :         ScaledWaterSpecHeat = WaterMassFlowRate * Cp * ConvK / AirMassFlow;
    3567     1617457 :         DryCoilCoeff1 = 1.0 / (AirMassFlow * MoistAirSpecificHeat) - 1.0 / (WaterMassFlowRate * Cp * ConvK);
    3568             :         //       perform initialisations for all wet solution
    3569     1617457 :         WetSideEffctvWaterTemp =
    3570     1617457 :             state.dataWaterCoils->WaterCoil(CoilNum).MeanWaterTempSaved + (TempWaterIn - state.dataWaterCoils->WaterCoil(CoilNum).InWaterTempSaved);
    3571     1617457 :         WaterTempConvgLoop = 0;
    3572     1617457 :         WaterTempConvg = false;
    3573             :         //       Loop to solve coil as if all wet, converges on MeanWaterTemp eq WetSideEffctvWaterTemp
    3574             :         //       if conv=.TRUE. at any time program exits loop and proceeds
    3575             :         //       to part wet / part dry solution
    3576     6630525 :         while (WaterTempConvgLoop < 8 && !WaterTempConvg) {
    3577     2506534 :             ++WaterTempConvgLoop;
    3578     2506534 :             ScaledWaterToTubeThermResist = WaterToTubeThermResist / (1.0 + 0.0146 * WetSideEffctvWaterTemp);
    3579     2506534 :             ScaledCoilAirThermResistWetSurf = CoilToAirThermResistWetSurf / state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope;
    3580     5013068 :             UACoilAllWet = 1.0 / (state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope *
    3581     2506534 :                                   (TubeFoulThermResist + ScaledWaterToTubeThermResist + ScaledCoilAirThermResistWetSurf));
    3582             :             //       prevents floating point error when taking exponential
    3583             :             //       of a very large number
    3584     2506534 :             expon =
    3585     2506534 :                 UACoilAllWet * (1.0 / AirMassFlow - state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope / (WaterMassFlowRate * Cp * ConvK));
    3586     2506534 :             if (expon < 20.0) { // CR7189 changed from ABS(expon) < 20
    3587             :                 //       negative expon can happen, but lead to tiny WetCoilCoef that aren't a problem
    3588     2506430 :                 WetCoilCoeff = std::exp(expon);
    3589             :                 // following appears similar to eq. 320 in Eng Ref but neglects K1 term
    3590     7519290 :                 TempWaterOut = ((1.0 - WetCoilCoeff) * (InletAirEnthalpy - state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveConstCoef) +
    3591     2506430 :                                 WetCoilCoeff * TempWaterIn * (state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope - ScaledWaterSpecHeat)) /
    3592     2506430 :                                (state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope - WetCoilCoeff * ScaledWaterSpecHeat);
    3593             :             } else {
    3594             :                 // following appears to be same as above with equation simplified to use only significant terms when WetCoilCoeff very large
    3595         208 :                 TempWaterOut = ((InletAirEnthalpy - state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveConstCoef) -
    3596         104 :                                 TempWaterIn * (state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope - ScaledWaterSpecHeat)) /
    3597             :                                ScaledWaterSpecHeat;
    3598             :             }
    3599             :             //      above is inverted form of WaterMassFlowRate*cpw*(TempWaterOut-TempWaterIn) = UA(LMHD)
    3600             :             //      note simplification that hsat = WaterCoil(CoilNum)%SatEnthlCurveConstCoef +  &
    3601             :             //                                      WaterCoil(CoilNum)%SatEnthlCurveSlope*WetSideEffctvWaterTemp
    3602     2506534 :             MeanWaterTemp = 0.5 * (TempWaterIn + TempWaterOut);
    3603     2506534 :             OutletAirEnthalpy = InletAirEnthalpy - (TempWaterOut - TempWaterIn) * ScaledWaterSpecHeat;
    3604             : 
    3605     2506534 :             InsdToOutsdThermResistRatio = (TubeFoulThermResist + ScaledWaterToTubeThermResist) / ScaledCoilAirThermResistWetSurf;
    3606     5013068 :             InCoilSurfTemp = UACoilAllWet * ScaledCoilAirThermResistWetSurf *
    3607     5013068 :                              (state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope * TempWaterIn +
    3608     2506534 :                               (OutletAirEnthalpy - state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveConstCoef) * InsdToOutsdThermResistRatio);
    3609     5013068 :             OutCoilSurfTemp = UACoilAllWet * ScaledCoilAirThermResistWetSurf *
    3610     5013068 :                               (state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope * TempWaterOut +
    3611     2506534 :                                (InletAirEnthalpy - state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveConstCoef) * InsdToOutsdThermResistRatio);
    3612             : 
    3613     2506534 :             if (std::abs(MeanWaterTemp - WetSideEffctvWaterTemp) > 0.01) {
    3614      889077 :                 WetSideEffctvWaterTemp = MeanWaterTemp;
    3615      889077 :                 InSurfTempSatAirEnthl = PsyHFnTdbRhPb(state, InCoilSurfTemp, unity, state.dataEnvrn->OutBaroPress, RoutineName) * ConvK;
    3616      889077 :                 OutSurfTempSatAirEnthl = PsyHFnTdbRhPb(state, OutCoilSurfTemp, unity, state.dataEnvrn->OutBaroPress, RoutineName) * ConvK;
    3617             : 
    3618      889077 :                 state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope =
    3619      889077 :                     (OutSurfTempSatAirEnthl - InSurfTempSatAirEnthl) / (OutCoilSurfTemp - InCoilSurfTemp);
    3620      889077 :                 state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveConstCoef =
    3621      889077 :                     InSurfTempSatAirEnthl - state.dataWaterCoils->WaterCoil(CoilNum).SatEnthlCurveSlope * InCoilSurfTemp;
    3622             :             } else {
    3623     1617457 :                 WaterTempConvg = true;
    3624             :             }
    3625             :         } // End of iteration loop to get MeanWaterTemp=WetSideEffctvWaterTemp
    3626             :         //      if 8 CoolCoilErrs are reached without convergence and the
    3627             :         //      predicted coil surface temperature at the outlet is less than
    3628             :         //      the dew point coil is apparently all wet but a solution
    3629             :         //      cannot be obtained
    3630     1617457 :         if (!WaterTempConvg && !state.dataGlobal->WarmupFlag && (OutCoilSurfTemp < EnterAirDewPoint)) {
    3631           0 :             ShowRecurringWarningErrorAtEnd(state,
    3632           0 :                                            state.dataWaterCoils->WaterCoil(CoilNum).Name +
    3633             :                                                " not converged (8 iterations) due to \"Wet Convergence\" conditions.",
    3634           0 :                                            state.dataWaterCoils->WaterTempCoolCoilErrs(CoilNum),
    3635           0 :                                            std::abs(MeanWaterTemp - WetSideEffctvWaterTemp),
    3636           0 :                                            std::abs(MeanWaterTemp - WetSideEffctvWaterTemp));
    3637             :             //       CoolCoilErrs = CoolCoilErrs + 1
    3638             :             //       IF (CoolCoilErrs .LE. MaxCoolCoilErrs) THEN
    3639             :             //          CALL ShowWarningError(state, 'tp12c0:  not converged in 8 CoolCoilErrs')
    3640             :             //       END IF
    3641             :         }
    3642     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).MeanWaterTempSaved = MeanWaterTemp;
    3643             :         //      now simulate wet dry coil - test outlet condition from all
    3644             :         //      wet case to give an idea of the expected solution
    3645     1617457 :         PartWetIterations = 0;
    3646     1617457 :         WetDryInterSurfTempError = 0.0;
    3647     1617457 :         CoilPartWetConvg = false;
    3648             :         //      Surface temp at coil water outlet (air inlet) is less than
    3649             :         //      the dew point - Coil must be completely wet so no need to
    3650             :         //      simulate wet/dry case
    3651     1617457 :         if (OutCoilSurfTemp < EnterAirDewPoint) {
    3652      234586 :             CoilPartWetConvg = true;
    3653      234586 :             state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction = 1.0;
    3654      234586 :             TotWaterCoilLoad = AirMassFlow * (InletAirEnthalpy - OutletAirEnthalpy);
    3655      234586 :             AirWetDryInterfcTemp = TempAirIn;
    3656      234586 :             WetDryInterfcAirEnthl = InletAirEnthalpy;
    3657             :             //      Surface temperature at coil water inlet is greater than the
    3658             :             //      dewpoint - coil cannot be all wet but may be all dry -
    3659             :             //      initialise with all dry solution
    3660     1382871 :         } else if (InCoilSurfTemp > EnterAirDewPoint) {
    3661      219512 :             SurfAreaWet = 0.0;
    3662      219512 :             state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction = 0.0;
    3663      219512 :             WetDryInterfcWaterTemp = TempWaterIn;
    3664      439024 :             TempWaterOut = state.dataWaterCoils->WaterCoil(CoilNum).OutWaterTempSaved +
    3665      219512 :                            (TempWaterIn - state.dataWaterCoils->WaterCoil(CoilNum).InWaterTempSaved);
    3666      219512 :             WetAreaLast = 0.05 * state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    3667             :             //      General case - must be part-wet/part-dry - initialise
    3668             :             //      accordingly with some non-zero wet area
    3669             :         } else {
    3670     1163359 :             if (state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetSaved != 0.0) {
    3671     1162506 :                 SurfAreaWet = state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetSaved;
    3672             :             } else {
    3673        1706 :                 SurfAreaWet = 0.8 * state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea * (EnterAirDewPoint - InCoilSurfTemp) /
    3674         853 :                               (OutCoilSurfTemp - InCoilSurfTemp);
    3675             :             }
    3676     1163359 :             WetDryInterfcWaterTemp = TempWaterIn + EnterAirDewPoint - InCoilSurfTemp;
    3677     1163359 :             WetAreaLast = 0.0;
    3678             :         }
    3679             :         //       Loop to solve partly wet coil, converges on wet area and
    3680             :         //       boundary temperature at dew point
    3681             :         //       Dry coil is special case with zero wet area, converges on
    3682             :         //       mean water temperature
    3683    21371069 :         while (PartWetIterations < 40 && !CoilPartWetConvg) {
    3684     9876806 :             ++PartWetIterations;
    3685             :             //      effective water temp on dry side of coil
    3686     9876806 :             DrySideEffectiveWaterTemp = 0.5 * (TempWaterOut + WetDryInterfcWaterTemp);
    3687             :             //      tube inside thermal resistance
    3688     9876806 :             DryCoilInThermResist = WaterToTubeThermResist / (1.0 + 0.0146 * DrySideEffectiveWaterTemp);
    3689             :             //      overall UA, from water to air, of dry portion of coil
    3690             : 
    3691    19753612 :             UADryCoil = (state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea - SurfAreaWet) /
    3692    19753612 :                         (state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea *
    3693     9876806 :                          (TubeFoulThermResist + DryCoilInThermResist + CoilToAirThermResistDrySurf));
    3694             : 
    3695             :             // This is a numerical trap for a very small number in the EXP function that is approaching zero
    3696     9876806 :             if (UADryCoil * DryCoilCoeff1 < -60.0) {
    3697           0 :                 DryCoilCoeff = 0.0;
    3698             :             } else {
    3699     9876806 :                 DryCoilCoeff = std::exp(UADryCoil * DryCoilCoeff1);
    3700             :             }
    3701             : 
    3702    19753612 :             K1 = WaterMassFlowRate * Cp * ConvK * (DryCoilCoeff - 1.0) /
    3703     9876806 :                  (WaterMassFlowRate * Cp * ConvK * DryCoilCoeff - AirMassFlow * MoistAirSpecificHeat);
    3704     9876806 :             if (SurfAreaWet != 0) {
    3705     9391660 :                 state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction =
    3706     9391660 :                     SurfAreaWet / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    3707             :                 //      effective water temp on wet side of coil
    3708     9391660 :                 WetSideEffctvWaterTemp = 0.5 * (TempWaterIn + WetDryInterfcWaterTemp);
    3709             :                 //      tube inside thermal resistance
    3710     9391660 :                 ScaledWaterToTubeThermResist = WaterToTubeThermResist / (1.0 + 0.0146 * WetSideEffctvWaterTemp);
    3711     9391660 :                 ScaledCoilAirThermResistWetSurf = CoilToAirThermResistWetSurf / state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope;
    3712             :                 //      overall UA, from water to air, of wet portion of coil
    3713    18783320 :                 UACoilAllWet = 1.0 / (state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope *
    3714     9391660 :                                       (TubeFoulThermResist + ScaledWaterToTubeThermResist + ScaledCoilAirThermResistWetSurf));
    3715     9391660 :                 UACoilPartWet = state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction * UACoilAllWet;
    3716     9391660 :                 expon = UACoilPartWet *
    3717     9391660 :                         (1.0 / AirMassFlow - state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope / (WaterMassFlowRate * Cp * ConvK));
    3718             :                 //        prevents floating point error when taking exponential
    3719             :                 //        of a very large number
    3720     9391660 :                 if (expon < 20.0) {
    3721     9391660 :                     WetCoilCoeff = std::exp(expon);
    3722             :                     //          write(outputfiledebug,*) ' wcc=',wetcoilcoeff
    3723    18783320 :                     denom = (state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope - WetCoilCoeff * ScaledWaterSpecHeat -
    3724     9391660 :                              (1.0 - WetCoilCoeff) * K1 * MoistAirSpecificHeat);
    3725             :                     //          write(outputfiledebug,*) ' denom=',denom
    3726             :                     //          WetDryInterfcWaterTemp = ((1.0 - WetCoilCoeff) * (InletAirEnthalpy - WaterCoil(CoilNum)%EnthVsTempCurveConst -
    3727             :                     //          K1
    3728             :                     //          *  &
    3729             :                     //                                     MoistAirSpecificHeat * TempAirIn) + WetCoilCoeff * &
    3730             :                     //                                     TempWaterIn * (WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope -  &
    3731             :                     //                                     ScaledWaterSpecHeat)) / (WaterCoil(CoilNum)%EnthVsTempCurveAppxSlope -  &
    3732             :                     //                                      WetCoilCoeff * ScaledWaterSpecHeat - (1.0 - WetCoilCoeff) * K1 * &
    3733             :                     //                                     MoistAirSpecificHeat)
    3734     9391660 :                     WetDryInterfcWaterTemp =
    3735    18783320 :                         ((1.0 - WetCoilCoeff) * (InletAirEnthalpy - state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveConst -
    3736    18783320 :                                                  K1 * MoistAirSpecificHeat * TempAirIn) +
    3737     9391660 :                          WetCoilCoeff * TempWaterIn * (state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope - ScaledWaterSpecHeat)) /
    3738             :                         denom;
    3739             :                 } else {
    3740             :                     //         approximation to equation for WetDryInterfcWaterTemp when WetCoilCoeff-->inf.
    3741           0 :                     WetDryInterfcWaterTemp =
    3742           0 :                         (TempWaterIn * (state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope - ScaledWaterSpecHeat) -
    3743           0 :                          (InletAirEnthalpy - state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveConst - K1 * MoistAirSpecificHeat * TempAirIn)) /
    3744           0 :                         (K1 * MoistAirSpecificHeat - ScaledWaterSpecHeat);
    3745             :                 }
    3746             :             }
    3747             :             //        air temperature at wet-dry interface
    3748     9876806 :             AirWetDryInterfcTemp = TempAirIn - (TempAirIn - WetDryInterfcWaterTemp) * K1;
    3749             :             //        coil surface temperature at wet-dry interface
    3750    29630418 :             WetDryInterfcSurfTemp = WetDryInterfcWaterTemp + (AirWetDryInterfcTemp - WetDryInterfcWaterTemp) *
    3751    19753612 :                                                                  (TubeFoulThermResist + DryCoilInThermResist) /
    3752     9876806 :                                                                  (TubeFoulThermResist + DryCoilInThermResist + CoilToAirThermResistDrySurf);
    3753     9876806 :             if (SurfAreaWet != 0) {
    3754     9391660 :                 WetDryInterfcAirEnthl = InletAirEnthalpy - MoistAirSpecificHeat * (TempAirIn - AirWetDryInterfcTemp);
    3755             :                 //        conservation of energy - wet portion of coil
    3756     9391660 :                 OutletAirEnthalpy = WetDryInterfcAirEnthl - WaterMassFlowRate * Cp * ConvK * (WetDryInterfcWaterTemp - TempWaterIn) / AirMassFlow;
    3757             :                 //        ratio of inside to outside thermal resistance
    3758     9391660 :                 InsdToOutsdThermResistRatio = (TubeFoulThermResist + ScaledWaterToTubeThermResist) / ScaledCoilAirThermResistWetSurf;
    3759             :                 //        coil surface temperature at water inlet (air outlet)
    3760    18783320 :                 InCoilSurfTemp = UACoilAllWet * ScaledCoilAirThermResistWetSurf *
    3761    18783320 :                                  (state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope * TempWaterIn +
    3762     9391660 :                                   (OutletAirEnthalpy - state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveConst) * InsdToOutsdThermResistRatio);
    3763     9391660 :                 WetDryInterSurfTempErrorLast = WetDryInterSurfTempError;
    3764             :                 //        in part-wet/part-dry solution EnterAirDewPoint=WetDryInterfcSurfTemp drives WetDryInterSurfTempError->0
    3765     9391660 :                 WetDryInterSurfTempError = EnterAirDewPoint - WetDryInterfcSurfTemp;
    3766             :             } else {
    3767             :                 //        dry coil solution
    3768      485146 :                 WetDryInterfcAirEnthl = 0.0;
    3769      485146 :                 OutletAirEnthalpy = InletAirEnthalpy - MoistAirSpecificHeat * (TempAirIn - AirWetDryInterfcTemp);
    3770             :             }
    3771             :             //        total cooling = change in air enthalpy across coil
    3772     9876806 :             TotWaterCoilLoad = AirMassFlow * (InletAirEnthalpy - OutletAirEnthalpy);
    3773             :             //        conservation of energy on water stream gives water outlet
    3774             :             //        temperature
    3775     9876806 :             TempWaterOut = WaterMassFlowRate * Cp * ConvK; // Temp for next calc
    3776     9876806 :             TempWaterOut = min(TempWaterIn + TotWaterCoilLoad / TempWaterOut, TempAirIn);
    3777             :             //        update estimate of coil wet area
    3778             : 
    3779     9876806 :             if (SurfAreaWet == 0) {
    3780      485146 :                 MeanWaterTemp = 0.5 * (TempWaterOut + WetDryInterfcWaterTemp);
    3781      485146 :                 if (EnterAirDewPoint > WetDryInterfcSurfTemp) {
    3782       92090 :                     SurfAreaWet = 0.5 * WetAreaLast;
    3783      393056 :                 } else if (std::abs(MeanWaterTemp - DrySideEffectiveWaterTemp) <= 0.00002) {
    3784      128742 :                     CoilPartWetConvg = true;
    3785             :                 }
    3786    10699197 :             } else if (std::abs(WetDryInterSurfTempError) > 0.00002 ||
    3787     1307537 :                        std::abs(SurfAreaWet - WetAreaLast) / state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea > 0.00001) {
    3788     8154040 :                 if (WetAreaLast == 0) {
    3789     1163359 :                     WetAreaLast = SurfAreaWet;
    3790     2326718 :                     SurfAreaWet += 0.4 * state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea * WetDryInterSurfTempError /
    3791     1163359 :                                    (OutCoilSurfTemp - InCoilSurfTemp);
    3792     6990681 :                 } else if (WetDryInterSurfTempError != WetDryInterSurfTempErrorLast) {
    3793     6990681 :                     WetAreaChange = SurfAreaWet - WetAreaLast;
    3794     6990681 :                     WetAreaLast = SurfAreaWet;
    3795     6990681 :                     SurfAreaWet -= 0.8 * WetDryInterSurfTempError * WetAreaChange / (WetDryInterSurfTempError - WetDryInterSurfTempErrorLast);
    3796             :                 }
    3797     8154040 :                 if (SurfAreaWet >= state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea) {
    3798       80734 :                     SurfAreaWet = state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    3799       80734 :                     MeanWaterTemp = 0.5 * (TempWaterIn + WetDryInterfcWaterTemp);
    3800      140412 :                     if (WetAreaLast == state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea &&
    3801       59678 :                         std::abs(MeanWaterTemp - WetSideEffctvWaterTemp) <= 0.00002) {
    3802       16509 :                         CoilPartWetConvg = true;
    3803             :                     }
    3804             :                 }
    3805     8154040 :                 if (SurfAreaWet <= 0) {
    3806        1320 :                     SurfAreaWet = 0.0;
    3807        1320 :                     state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction = 0.0;
    3808        1320 :                     WetDryInterfcWaterTemp = TempWaterIn;
    3809             :                 }
    3810     8154040 :                 InSurfTempSatAirEnthl = PsyHFnTdbRhPb(state, InCoilSurfTemp, unity, state.dataEnvrn->OutBaroPress, RoutineName) * ConvK;
    3811     8154040 :                 if ((EnterAirDewPoint - InCoilSurfTemp) >= 0.0001) {
    3812     8054607 :                     AirEnthAtWetDryIntrfcSurfTemp = PsyHFnTdbRhPb(state, EnterAirDewPoint, unity, state.dataEnvrn->OutBaroPress, RoutineName) * ConvK;
    3813     8054607 :                     state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope =
    3814     8054607 :                         (AirEnthAtWetDryIntrfcSurfTemp - InSurfTempSatAirEnthl) / (EnterAirDewPoint - InCoilSurfTemp);
    3815             :                 } else {
    3816       99433 :                     AirEnthAtWetDryIntrfcSurfTemp =
    3817       99433 :                         PsyHFnTdbRhPb(state, InCoilSurfTemp + 0.0001, unity, state.dataEnvrn->OutBaroPress, RoutineName) * ConvK;
    3818       99433 :                     state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope =
    3819       99433 :                         (AirEnthAtWetDryIntrfcSurfTemp - InSurfTempSatAirEnthl) / 0.0001;
    3820             :                 }
    3821     8154040 :                 state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveConst =
    3822     8154040 :                     InSurfTempSatAirEnthl - state.dataWaterCoils->WaterCoil(CoilNum).EnthVsTempCurveAppxSlope * InCoilSurfTemp;
    3823             :             } else {
    3824     1237620 :                 CoilPartWetConvg = true;
    3825             :             }
    3826             :         }
    3827             :         //      error checking to see if convergence has been achieved
    3828     1617457 :         if (!CoilPartWetConvg && !state.dataGlobal->WarmupFlag) {
    3829           0 :             ShowRecurringWarningErrorAtEnd(state,
    3830           0 :                                            state.dataWaterCoils->WaterCoil(CoilNum).Name +
    3831             :                                                " not converged (40 iterations) due to \"Partial Wet Convergence\" conditions.",
    3832           0 :                                            state.dataWaterCoils->PartWetCoolCoilErrs(CoilNum));
    3833             :             //      CoolCoilErrs = CoolCoilErrs + 1
    3834             :             //      IF (CoolCoilErrs .LE. MaxCoolCoilErrs) THEN
    3835             :             //        CALL ShowWarningError(state, 'tp12c0:  not converged in 20 CoolCoilErrs')
    3836             :             //      END IF
    3837             :         }
    3838     1617457 :         if (state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction > 0 && state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction < 1) {
    3839     1237620 :             state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetSaved = SurfAreaWet;
    3840             :         }
    3841             :         //       calculate TempAirOut, OutletAirHumRat, and SensCoolRate based on equations from
    3842             :         //       TYPE12 and the ASHRAE toolkit
    3843     1617457 :         if (state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction == 0) {
    3844             :             //       dry coil
    3845      128742 :             TempAirOut = TempAirIn - TotWaterCoilLoad / (AirMassFlow * MoistAirSpecificHeat);
    3846      128742 :             OutletAirHumRat = InletAirHumRat;
    3847      128742 :             SenWaterCoilLoad = TotWaterCoilLoad;
    3848             :         } else {
    3849             :             //       coil effectiveness
    3850     1488715 :             expon = state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction / (CoilToAirThermResistWetSurf * AirMassFlow);
    3851     1488715 :             y = 0.0;
    3852     1488715 :             if (expon < 20.0) y = std::exp(-expon);
    3853     1488715 :             AirExitEnthlAtCoilSurfTemp = WetDryInterfcAirEnthl - (WetDryInterfcAirEnthl - OutletAirEnthalpy) / (1.0 - y);
    3854     1488715 :             AirExitCoilSurfTemp = AirExitEnthlAtCoilSurfTemp / ConvK; // TEmporary calc
    3855     1488715 :             AirExitCoilSurfTemp = PsyTsatFnHPb(state, AirExitCoilSurfTemp, state.dataEnvrn->OutBaroPress);
    3856             :             //       Implementation of epsilon*NTU method
    3857     1488715 :             TempAirOut = AirExitCoilSurfTemp + (AirWetDryInterfcTemp - AirExitCoilSurfTemp) * y;
    3858     1488715 :             OutletAirHumRat = PsyWFnTdbH(state, TempAirOut, 1000.0 * OutletAirEnthalpy, RoutineName);
    3859     1488715 :             SenWaterCoilLoad = AirMassFlow * (PsyCpAirFnW(InletAirHumRat) * TempAirIn - PsyCpAirFnW(OutletAirHumRat) * TempAirOut) * ConvK;
    3860             :         }
    3861             : 
    3862     1617457 :         if (FanOpMode == CycFanCycCoil) {
    3863           0 :             TotWaterCoilLoad *= PartLoadRatio;
    3864           0 :             SenWaterCoilLoad *= PartLoadRatio;
    3865             :         }
    3866             : 
    3867             :         // Set the outlet conditions
    3868     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate = TotWaterCoilLoad * 1000.0;
    3869     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate = SenWaterCoilLoad * 1000.0;
    3870     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp = TempAirOut;
    3871     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterTemp = TempWaterOut;
    3872     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirEnthalpy = OutletAirEnthalpy * 1000.0;
    3873     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat = OutletAirHumRat;
    3874             :         // The CoolingCoilLoad is the change in the enthalpy of the water
    3875     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterEnthalpy =
    3876     3234914 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterEnthalpy +
    3877     1617457 :             state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate / state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    3878             : 
    3879             :         // This WaterCoil does not change the Mass Flow across the component
    3880     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    3881     1617457 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    3882             :     } else {
    3883             :         // If Coil is scheduled OFF then Outlet conditions are set to Inlet Conditions
    3884     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate = 0.0;
    3885     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate = 0.0;
    3886     1720499 :         TempAirOut = TempAirIn;
    3887     1720499 :         TempWaterOut = TempWaterIn;
    3888             :         // set the outlet conditions to the coil derived type
    3889     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp = TempAirOut;
    3890     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterTemp = TempWaterOut;
    3891     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirEnthalpy = state.dataWaterCoils->WaterCoil(CoilNum).InletAirEnthalpy;
    3892     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    3893             :         // The CoolingCoilLoad is the change in the enthalpy of the water
    3894     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterEnthalpy = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterEnthalpy;
    3895             : 
    3896             :         // This WaterCoil does not change the Mass Flow across the component
    3897     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    3898     1720499 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterMassFlowRate = 0.0;
    3899             :     }
    3900             : 
    3901             :     // Save some of the Values for next Time step
    3902     3337956 :     state.dataWaterCoils->WaterCoil(CoilNum).InWaterTempSaved = TempWaterIn;
    3903     3337956 :     state.dataWaterCoils->WaterCoil(CoilNum).OutWaterTempSaved = TempWaterOut;
    3904     3337956 : }
    3905             : 
    3906    22054942 : void CoolingCoil(EnergyPlusData &state,
    3907             :                  int const CoilNum,
    3908             :                  bool const FirstHVACIteration,
    3909             :                  int const CalcMode,
    3910             :                  int const FanOpMode,       // fan operating mode
    3911             :                  Real64 const PartLoadRatio // part-load ratio of heating coil
    3912             : )
    3913             : {
    3914             : 
    3915             :     // FUNCTION INFORMATION:
    3916             :     // AUTHOR         Rahul Chillar
    3917             :     // DATE WRITTEN   Mar 2004
    3918             :     // MODIFIED       na
    3919             :     // RE-ENGINEERED  na
    3920             : 
    3921             :     // PURPOSE OF THIS FUNCTION:
    3922             :     // The subroutine has the coil logic. Three types of Cooling Coils exist:
    3923             :     // They are 1.CoilDry , 2.CoilWet, 3. CoilPartDryPartWet. The logic for
    3924             :     // the three individual cases is in this subroutine.
    3925             : 
    3926             :     // METHODOLOGY EMPLOYED:
    3927             :     // Simulates a Coil Model from Design conditions and subsequently uses
    3928             :     // configuration values (example: UA)calculated from those design conditions
    3929             :     // to calculate new performance of coil from operating inputs.The values are
    3930             :     // calculated in the Subroutine InitWaterCoil
    3931             : 
    3932             :     // REFERENCES:
    3933             :     // ASHRAE Secondary HVAC Toolkit TRNSYS.  1990.  A Transient System
    3934             :     // Simulation Program: Reference Manual. Solar Energy Laboratory, Univ. Wisconsin-
    3935             :     // Madison, pp. 4.6.8-1 - 4.6.8-12.
    3936             :     // Threlkeld, J.L.  1970.  Thermal Environmental Engineering, 2nd Edition,
    3937             :     // Englewood Cliffs: Prentice-Hall,Inc. pp. 254-270.
    3938             : 
    3939             :     // Using/Aliasing
    3940             :     using General::SafeDivide;
    3941             : 
    3942             :     // Enforce explicit typing of all variables in this routine
    3943             : 
    3944             :     // Locals
    3945             :     // FUNCTION ARGUMENT DEFINITIONS:
    3946             : 
    3947             :     // FUNCTION PARAMETER DEFINITIONS:
    3948             :     // na
    3949             : 
    3950             :     // INTERFACE BLOCK SPECIFICATIONS
    3951             :     // na
    3952             : 
    3953             :     // DERIVED TYPE DEFINITIONS
    3954             :     // na
    3955             : 
    3956             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    3957             :     Real64 AirInletCoilSurfTemp; // Coil surface temperature at air entrance(C)
    3958             :     Real64 AirDewPointTemp;      // Temperature dew point at operating condition
    3959             :     Real64 OutletAirTemp;        // Outlet air temperature at operating condition
    3960             :     Real64 OutletAirHumRat;      // Outlet air humidity ratio at operating condition
    3961             :     Real64 OutletWaterTemp;      // Outlet water temperature at operating condtitons
    3962             :     Real64 TotWaterCoilLoad;     // Total heat transfer rate(W)
    3963             :     Real64 SenWaterCoilLoad;     // Sensible heat transfer rate
    3964             :     Real64 SurfAreaWetFraction;  // Fraction of surface area wet
    3965             :     Real64 AirMassFlowRate;      // Air mass flow rate for the calculation
    3966             : 
    3967    22054942 :     AirInletCoilSurfTemp = 0.0; // Coil surface temperature at air entrance(C)
    3968    22054942 :     AirDewPointTemp = 0.0;      // Temperature dew point at operating condition
    3969    22054942 :     OutletAirTemp = 0.0;        // Outlet air temperature at operating condition
    3970    22054942 :     OutletAirHumRat = 0.0;      // Outlet air humidity ratio at operating condition
    3971    22054942 :     OutletWaterTemp = 0.0;      // Outlet water temperature at operating condtitons
    3972    22054942 :     TotWaterCoilLoad = 0.0;     // Total heat transfer rate(W)
    3973    22054942 :     SenWaterCoilLoad = 0.0;     // Sensible heat transfer rate
    3974    22054942 :     SurfAreaWetFraction = 0.0;  // Fraction of surface area wet
    3975             : 
    3976    22054942 :     if (FanOpMode == CycFanCycCoil && PartLoadRatio > 0.0) { // FB Start
    3977     1349120 :         AirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / PartLoadRatio;
    3978             :     } else {
    3979    20705822 :         AirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    3980             :     }
    3981             : 
    3982             :     // If Coil is Scheduled ON then do the simulation
    3983    65079296 :     if (((GetCurrentScheduleValue(state, state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr) > 0.0) &&
    3984    45347556 :          (state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate > 0.0) && (AirMassFlowRate >= WaterCoils::MinAirMassFlow) &&
    3985    24370060 :          (state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate > 0.0) &&
    3986    44109884 :          (state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate > 0.0)) ||
    3987     9869912 :         (CalcMode == state.dataWaterCoils->DesignCalc)) {
    3988             : 
    3989             :         // Calculate Temperature Dew Point at operating conditions.
    3990    12186409 :         AirDewPointTemp = PsyTdpFnWPb(state, state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat, state.dataEnvrn->OutBaroPress);
    3991             : 
    3992    12186409 :         if (state.dataWaterCoils->WaterCoil(CoilNum).CoolingCoilAnalysisMode == state.dataWaterCoils->DetailedAnalysis) {
    3993             :             // Coil is completely dry if AirDewPointTemp is less than InletWaterTemp,hence Call CoilCompletelyDry
    3994      890386 :             if (AirDewPointTemp <= state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp) {
    3995             : 
    3996             :                 // Calculate the leaving conditions and performance of dry coil
    3997        4452 :                 CoilCompletelyDry(state,
    3998             :                                   CoilNum,
    3999        1484 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp,
    4000        1484 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp,
    4001        1484 :                                   state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal,
    4002             :                                   OutletWaterTemp,
    4003             :                                   OutletAirTemp,
    4004             :                                   OutletAirHumRat,
    4005             :                                   TotWaterCoilLoad,
    4006             :                                   FanOpMode,
    4007             :                                   PartLoadRatio);
    4008             : 
    4009        1484 :                 SenWaterCoilLoad = TotWaterCoilLoad;
    4010        1484 :                 SurfAreaWetFraction = 0.0;
    4011             : 
    4012             :             } else {
    4013             :                 // Else If AirDewPointTemp is greater than InletWaterTemp then assume the
    4014             :                 // external surface of coil is completely wet,hence Call CoilCompletelyWet
    4015             :                 // Calculate the leaving conditions and performance of wet coil
    4016     4444510 :                 CoilCompletelyWet(state,
    4017             :                                   CoilNum,
    4018      888902 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp,
    4019      888902 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp,
    4020      888902 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat,
    4021      888902 :                                   state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal,
    4022      888902 :                                   state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal,
    4023             :                                   OutletWaterTemp,
    4024             :                                   OutletAirTemp,
    4025             :                                   OutletAirHumRat,
    4026             :                                   TotWaterCoilLoad,
    4027             :                                   SenWaterCoilLoad,
    4028             :                                   SurfAreaWetFraction,
    4029             :                                   AirInletCoilSurfTemp,
    4030             :                                   FanOpMode,
    4031             :                                   PartLoadRatio);
    4032             : 
    4033             :                 // If AirDewPointTemp is less than temp of coil surface at entry of air
    4034      888902 :                 if (AirDewPointTemp < AirInletCoilSurfTemp) {
    4035             : 
    4036             :                     // Then coil is partially wet and dry hence call CoilPartWetPartDry
    4037             :                     // Calculate the leaving conditions and performance of dry coil
    4038     1412438 :                     CoilPartWetPartDry(state,
    4039             :                                        CoilNum,
    4040             :                                        FirstHVACIteration,
    4041      706219 :                                        state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp,
    4042      706219 :                                        state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp,
    4043             :                                        AirDewPointTemp,
    4044             :                                        OutletWaterTemp,
    4045             :                                        OutletAirTemp,
    4046             :                                        OutletAirHumRat,
    4047             :                                        TotWaterCoilLoad,
    4048             :                                        SenWaterCoilLoad,
    4049             :                                        SurfAreaWetFraction,
    4050             :                                        FanOpMode,
    4051             :                                        PartLoadRatio);
    4052             : 
    4053             :                 } // End if for part wet part dry coil
    4054             :             }     // End if for dry coil
    4055             : 
    4056    11296023 :         } else if (state.dataWaterCoils->WaterCoil(CoilNum).CoolingCoilAnalysisMode == state.dataWaterCoils->SimpleAnalysis) {
    4057             :             // Coil is completely dry if AirDewPointTemp is less than InletWaterTemp,hence Call CoilCompletelyDry
    4058    11296023 :             if (AirDewPointTemp <= state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp) {
    4059             : 
    4060             :                 // Calculate the leaving conditions and performance of dry coil
    4061     5001183 :                 CoilCompletelyDry(state,
    4062             :                                   CoilNum,
    4063     1667061 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp,
    4064     1667061 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp,
    4065     1667061 :                                   state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal,
    4066             :                                   OutletWaterTemp,
    4067             :                                   OutletAirTemp,
    4068             :                                   OutletAirHumRat,
    4069             :                                   TotWaterCoilLoad,
    4070             :                                   FanOpMode,
    4071             :                                   PartLoadRatio);
    4072             : 
    4073     1667061 :                 SenWaterCoilLoad = TotWaterCoilLoad;
    4074     1667061 :                 SurfAreaWetFraction = 0.0;
    4075             : 
    4076             :             } else {
    4077             :                 // Else If AirDewPointTemp is greater than InletWaterTemp then assume the
    4078             :                 // external surface of coil is completely wet,hence Call CoilCompletelyWet
    4079             :                 // Calculate the leaving conditions and performance of wet coil
    4080    48144810 :                 CoilCompletelyWet(state,
    4081             :                                   CoilNum,
    4082     9628962 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp,
    4083     9628962 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp,
    4084     9628962 :                                   state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat,
    4085     9628962 :                                   state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal,
    4086     9628962 :                                   state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal,
    4087             :                                   OutletWaterTemp,
    4088             :                                   OutletAirTemp,
    4089             :                                   OutletAirHumRat,
    4090             :                                   TotWaterCoilLoad,
    4091             :                                   SenWaterCoilLoad,
    4092             :                                   SurfAreaWetFraction,
    4093             :                                   AirInletCoilSurfTemp,
    4094             :                                   FanOpMode,
    4095             :                                   PartLoadRatio);
    4096             : 
    4097             :             } // End if for dry coil
    4098             :         }
    4099             : 
    4100             :         // Report outlet variables at nodes
    4101    12186409 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp = OutletAirTemp;
    4102    12186409 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat = OutletAirHumRat;
    4103    12186409 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterTemp = OutletWaterTemp;
    4104             :         // Report output results if the coil was operating
    4105             : 
    4106    12186409 :         if (FanOpMode == CycFanCycCoil) {
    4107      714002 :             TotWaterCoilLoad *= PartLoadRatio;
    4108      714002 :             SenWaterCoilLoad *= PartLoadRatio;
    4109             :         }
    4110             : 
    4111    12186409 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate = TotWaterCoilLoad;
    4112    12186409 :         state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate = SenWaterCoilLoad;
    4113    12186409 :         state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction = SurfAreaWetFraction;
    4114             :         //       WaterCoil(CoilNum)%OutletWaterEnthalpy = WaterCoil(CoilNum)%InletWaterEnthalpy+ &
    4115             :         //                                WaterCoil(CoilNum)%TotWaterCoolingCoilRate/WaterCoil(CoilNum)%InletWaterMassFlowRate
    4116    12186409 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterEnthalpy =
    4117    24372818 :             state.dataWaterCoils->WaterCoil(CoilNum).InletWaterEnthalpy + SafeDivide(state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate,
    4118    12186409 :                                                                                      state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate);
    4119             : 
    4120             :     } else {
    4121             :         // If both mass flow rates are zero, set outputs to inputs and return
    4122     9868533 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterTemp = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp;
    4123     9868533 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp = state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp;
    4124     9868533 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    4125     9868533 :         state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterEnthalpy = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterEnthalpy;
    4126     9868533 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilEnergy = 0.0;
    4127     9868533 :         state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilEnergy = 0.0;
    4128     9868533 :         state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFraction = 0.0;
    4129             : 
    4130             :     } // End of the Flow or No flow If block
    4131    22054942 :     state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    4132    22054942 :     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    4133    22054942 :     state.dataWaterCoils->WaterCoil(CoilNum).OutletAirEnthalpy =
    4134    22054942 :         PsyHFnTdbW(state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp, state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat);
    4135    22054942 : }
    4136             : 
    4137             : // End Algorithm Section of the Module
    4138             : 
    4139             : // Coil Completely Dry Subroutine for Cooling Coil
    4140             : 
    4141    17783792 : void CoilCompletelyDry(EnergyPlusData &state,
    4142             :                        int const CoilNum,
    4143             :                        Real64 const WaterTempIn,  // Entering water temperature
    4144             :                        Real64 const AirTempIn,    // Entering air dry bulb temperature
    4145             :                        Real64 const CoilUA,       // Overall heat transfer coefficient
    4146             :                        Real64 &OutletWaterTemp,   // Leaving water temperature
    4147             :                        Real64 &OutletAirTemp,     // Leaving air dry bulb temperature
    4148             :                        Real64 &OutletAirHumRat,   // Leaving air humidity ratio
    4149             :                        Real64 &Q,                 // Heat transfer rate
    4150             :                        int const FanOpMode,       // fan operating mode
    4151             :                        Real64 const PartLoadRatio // part-load ratio of heating coil
    4152             : )
    4153             : {
    4154             : 
    4155             :     // FUNCTION INFORMATION:
    4156             :     // AUTHOR         Rahul Chillar
    4157             :     // DATE WRITTEN   March 2004
    4158             :     // MODIFIED       na
    4159             :     // RE-ENGINEERED  na
    4160             : 
    4161             :     // PURPOSE OF THIS FUNCTION:
    4162             :     // Calculate the performance of a sensible air-liquid heat exchanger.  Calculated
    4163             :     // results include outlet air temperature and humidity, outlet water temperature,
    4164             :     // and heat transfer rate.
    4165             : 
    4166             :     // METHODOLOGY EMPLOYED:
    4167             :     // Models coil using effectiveness-NTU model.
    4168             : 
    4169             :     // REFERENCES:
    4170             :     // Kays, W.M. and A.L. London.  1964,Compact Heat Exchangers, 2nd Edition,
    4171             :     // New York: McGraw-Hill.
    4172             : 
    4173             :     // USE STATEMENTS:
    4174             :     // na
    4175             : 
    4176             :     // Enforce explicit typing of all variables in this routine
    4177             : 
    4178             :     // Locals
    4179             :     // FUNCTION ARGUMENT DEFINITIONS:
    4180             : 
    4181             :     // FUNCTION PARAMETER DEFINITIONS:
    4182             :     static constexpr std::string_view RoutineName("CoilCompletelyDry");
    4183             : 
    4184             :     // INTERFACE BLOCK SPECIFICATIONS
    4185             :     // na
    4186             : 
    4187             :     // DERIVED TYPE DEFINITIONS
    4188             :     // na
    4189             : 
    4190             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4191             :     Real64 CapacitanceAir;   // Air-side capacity rate(W/C)
    4192             :     Real64 CapacitanceWater; // Water-side capacity rate(W/C)
    4193             :     Real64 AirMassFlow;
    4194             :     Real64 WaterMassFlowRate;
    4195             :     Real64 Cp;
    4196             : 
    4197             :     //  adjust mass flow rates for cycling fan cycling coil operation
    4198    17783792 :     if (FanOpMode == CycFanCycCoil) {
    4199     2124185 :         if (PartLoadRatio > 0.0) {
    4200     2124185 :             AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / PartLoadRatio;
    4201     2124185 :             WaterMassFlowRate = min(state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate / PartLoadRatio,
    4202     2124185 :                                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate);
    4203             :         } else {
    4204           0 :             AirMassFlow = 0.0;
    4205           0 :             WaterMassFlowRate = 0.0;
    4206             :         }
    4207             :     } else {
    4208    15659607 :         AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    4209    15659607 :         WaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    4210             :     }
    4211             : 
    4212             :     // Calculate air and water capacity rates
    4213    17783792 :     CapacitanceAir = AirMassFlow * PsyCpAirFnW(state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat);
    4214             :     // Water Capacity Rate
    4215    35567584 :     Cp = GetSpecificHeatGlycol(state,
    4216    17783792 :                                state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    4217             :                                WaterTempIn,
    4218    17783792 :                                state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    4219             :                                RoutineName);
    4220             : 
    4221    17783792 :     CapacitanceWater = WaterMassFlowRate * Cp;
    4222             : 
    4223             :     // Determine the air and water outlet conditions
    4224    17783792 :     CoilOutletStreamCondition(state, CoilNum, CapacitanceWater, WaterTempIn, CapacitanceAir, AirTempIn, CoilUA, OutletWaterTemp, OutletAirTemp);
    4225             : 
    4226             :     // Calculate the total and sensible heat transfer rate both are equal in case of Dry Coil
    4227    17783792 :     Q = CapacitanceAir * (AirTempIn - OutletAirTemp);
    4228             : 
    4229             :     // Outlet humidity is equal to Inlet Humidity because its a dry coil
    4230    17783792 :     OutletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    4231    17783792 : }
    4232             : 
    4233             : // Coil Completely Wet Subroutine for Cooling Coil
    4234             : 
    4235    26633111 : void CoilCompletelyWet(EnergyPlusData &state,
    4236             :                        int const CoilNum,            // Number of Coil
    4237             :                        Real64 const WaterTempIn,     // Water temperature IN to this function (C)
    4238             :                        Real64 const AirTempIn,       // Air dry bulb temperature IN to this function(C)
    4239             :                        Real64 const AirHumRat,       // Air Humidity Ratio IN to this funcation (C)
    4240             :                        Real64 const UAInternalTotal, // Internal overall heat transfer coefficient(W/m2 C)
    4241             :                        Real64 const UAExternalTotal, // External overall heat transfer coefficient(W/m2 C)
    4242             :                        Real64 &OutletWaterTemp,      // Leaving water temperature (C)
    4243             :                        Real64 &OutletAirTemp,        // Leaving air dry bulb temperature(C)
    4244             :                        Real64 &OutletAirHumRat,      // Leaving air humidity ratio
    4245             :                        Real64 &TotWaterCoilLoad,     // Total heat transfer rate(W)
    4246             :                        Real64 &SenWaterCoilLoad,     // Sensible heat transfer rate(W)
    4247             :                        Real64 &SurfAreaWetFraction,  // Fraction of surface area wet
    4248             :                        Real64 &AirInletCoilSurfTemp, // Surface temperature at air entrance(C)
    4249             :                        int const FanOpMode,          // fan operating mode
    4250             :                        Real64 const PartLoadRatio    // part-load ratio of heating coil
    4251             : )
    4252             : {
    4253             : 
    4254             :     // FUNCTION INFORMATION:
    4255             :     // AUTHOR         Rahul Chillar
    4256             :     // DATE WRITTEN   Mar 2004
    4257             :     // MODIFIED       na
    4258             :     // RE-ENGINEERED  na
    4259             : 
    4260             :     // PURPOSE OF THIS FUNCTION:
    4261             :     // Calculate the performance of a cooling coil when the external fin surface is
    4262             :     // complete wet.  Results include outlet air temperature and humidity,
    4263             :     // outlet water temperature, sensible and total cooling capacities, and the wet
    4264             :     // fraction of the air-side surface area.
    4265             : 
    4266             :     // METHODOLOGY EMPLOYED:
    4267             :     // Models coil as counterflow heat exchanger. Approximates saturated air enthalpy as
    4268             :     // a linear function of temperature
    4269             :     // TRNSYS.  1990.  A Transient System Simulation Program: Reference Manual.
    4270             :     // Solar Energy Laboratory, Univ. Wisconsin Madison, pp. 4.6.8-1 - 4.6.8-12.
    4271             :     // Threlkeld, J.L.  1970.  Thermal Environmental Engineering, 2nd Edition,
    4272             :     // Englewood Cliffs: Prentice-Hall,Inc. pp. 254-270.
    4273             :     // Coil Uses Enthalpy Based Heat Transfer Coefficents and converts them to
    4274             :     // convential UA values. Intermediate value of fictitious Cp is defined. This follow
    4275             :     // the same procedure followed in the Design Calculation of the Coil. See the node in
    4276             :     // the one time calculation for design condition.
    4277             : 
    4278             :     // REFERENCES:
    4279             :     // Elmahdy, A.H. and Mitalas, G.P.  1977."A Simple Model for Cooling and
    4280             :     // Dehumidifying Coils for Use In Calculating Energy Requirements for Buildings,"
    4281             :     // ASHRAE Transactions,Vol.83 Part 2, pp. 103-117.
    4282             : 
    4283             :     // USE STATEMENTS:
    4284             : 
    4285             :     // Enforce explicit typing of all variables in this routine
    4286             : 
    4287             :     // Locals
    4288             :     // FUNCTION ARGUMENT DEFINITIONS:
    4289             : 
    4290             :     // FUNCTION PARAMETER DEFINITIONS:
    4291             :     static constexpr std::string_view RoutineName("CoilCompletelyWet");
    4292             : 
    4293             :     // INTERFACE BLOCK SPECIFICATIONS
    4294             :     // na
    4295             : 
    4296             :     // DERIVED TYPE DEFINITIONS
    4297             :     // na
    4298             : 
    4299             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4300             :     Real64 AirSideResist;                  // Air-side resistance to heat transfer(m2 C/W)
    4301             :     Real64 WaterSideResist;                // Liquid-side resistance to heat transfer(m2 C/W)
    4302             :     Real64 EnteringAirDewPt;               // Entering air dew point(C)
    4303             :     Real64 UACoilTotalEnth;                // Overall enthalpy heat transfer coefficient(kg/s)
    4304             :     Real64 CapacityRateAirWet;             // Air-side capacity rate(kg/s)
    4305             :     Real64 CapacityRateWaterWet;           // Liquid-side capacity rate(kg/s)
    4306             :     Real64 ResistRatio;                    // Ratio of resistances
    4307             :     Real64 EnthAirOutlet;                  // Outlet air enthalpy
    4308             :     Real64 EnthSatAirInletWaterTemp;       // Saturated enthalpy of air at entering water temperature(J/kg)
    4309             :     Real64 EnthSatAirOutletWaterTemp;      // Saturated enthalpy of air at exit water temperature(J/kg)
    4310             :     Real64 EnthSatAirCoilSurfaceEntryTemp; // Saturated enthalpy of air at entering surface temperature(J/kg)
    4311             :     Real64 EnthSatAirCoilSurfaceExitTemp;  // Saturated enthalpy of air at exit surface temperature(J/kg)
    4312             :     Real64 EnthAirInlet;                   // Enthalpy of air at inlet
    4313             :     Real64 IntermediateCpSat;              // Coefficient for equation below(J/kg C)
    4314             :     // EnthSat1-EnthSat2 = IntermediateCpSat*(TSat1-TSat2)
    4315             :     // (all water and surface temperatures are
    4316             :     // related to saturated air enthalpies for
    4317             :     // wet surface heat transfer calculations)
    4318    26633111 :     Real64 constexpr SmallNo(1.e-9); // smallNo used in place of 0
    4319             :     Real64 AirMassFlow;
    4320             :     Real64 WaterMassFlowRate;
    4321             :     Real64 Cp;
    4322             : 
    4323    26633111 :     SurfAreaWetFraction = 1.0;
    4324    26633111 :     AirSideResist = 1.0 / max(UAExternalTotal, SmallNo);
    4325    26633111 :     WaterSideResist = 1.0 / max(UAInternalTotal, SmallNo);
    4326             : 
    4327             :     //  adjust mass flow rates for cycling fan cycling coil operation
    4328    26633111 :     if (FanOpMode == CycFanCycCoil) {
    4329     2481243 :         if (PartLoadRatio > 0.0) {
    4330     2481243 :             AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / PartLoadRatio;
    4331     2481243 :             WaterMassFlowRate = min(state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate / PartLoadRatio,
    4332     2481243 :                                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate);
    4333             :         } else {
    4334           0 :             AirMassFlow = 0.0;
    4335           0 :             WaterMassFlowRate = 0.0;
    4336             :         }
    4337             :     } else {
    4338    24151868 :         AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    4339    24151868 :         WaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    4340             :     }
    4341             : 
    4342             :     // Calculate enthalpies of entering air and water
    4343             : 
    4344             :     // Enthalpy of air at inlet to the coil
    4345    26633111 :     EnthAirInlet = PsyHFnTdbW(AirTempIn, AirHumRat);
    4346             : 
    4347             :     // Saturation Enthalpy of Air at inlet water temperature
    4348    26633111 :     EnthSatAirInletWaterTemp = PsyHFnTdbW(WaterTempIn, PsyWFnTdpPb(state, WaterTempIn, state.dataEnvrn->OutBaroPress));
    4349             : 
    4350             :     // Estimate IntermediateCpSat using entering air dewpoint and water temperature
    4351    26633111 :     EnteringAirDewPt = PsyTdpFnWPb(state, AirHumRat, state.dataEnvrn->OutBaroPress);
    4352             : 
    4353             :     // An intermediate value of Specific heat . EnthSat1-EnthSat2 = IntermediateCpSat*(TSat1-TSat2)
    4354    26633111 :     IntermediateCpSat =
    4355    53266222 :         (PsyHFnTdbW(EnteringAirDewPt, PsyWFnTdpPb(state, EnteringAirDewPt, state.dataEnvrn->OutBaroPress)) - EnthSatAirInletWaterTemp) /
    4356    26633111 :         (EnteringAirDewPt - WaterTempIn);
    4357             : 
    4358             :     // Determine air and water enthalpy outlet conditions by modeling
    4359             :     // coil as counterflow enthalpy heat exchanger
    4360    26633111 :     UACoilTotalEnth = 1.0 / (IntermediateCpSat * WaterSideResist + AirSideResist * PsyCpAirFnW(0.0));
    4361    26633111 :     CapacityRateAirWet = AirMassFlow;
    4362    53266222 :     Cp = GetSpecificHeatGlycol(state,
    4363    26633111 :                                state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    4364             :                                WaterTempIn,
    4365    26633111 :                                state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    4366             :                                RoutineName);
    4367    26633111 :     CapacityRateWaterWet = WaterMassFlowRate * (Cp / IntermediateCpSat);
    4368    26633111 :     CoilOutletStreamCondition(state,
    4369             :                               CoilNum,
    4370             :                               CapacityRateAirWet,
    4371             :                               EnthAirInlet,
    4372             :                               CapacityRateWaterWet,
    4373             :                               EnthSatAirInletWaterTemp,
    4374             :                               UACoilTotalEnth,
    4375             :                               EnthAirOutlet,
    4376             :                               EnthSatAirOutletWaterTemp);
    4377             : 
    4378             :     // Calculate entering and leaving external surface conditions from
    4379             :     // air and water conditions and the ratio of resistances
    4380    26633111 :     ResistRatio = (WaterSideResist) / (WaterSideResist + PsyCpAirFnW(0.0) / IntermediateCpSat * AirSideResist);
    4381    26633111 :     EnthSatAirCoilSurfaceEntryTemp = EnthSatAirOutletWaterTemp + ResistRatio * (EnthAirInlet - EnthSatAirOutletWaterTemp);
    4382    26633111 :     EnthSatAirCoilSurfaceExitTemp = EnthSatAirInletWaterTemp + ResistRatio * (EnthAirOutlet - EnthSatAirInletWaterTemp);
    4383             : 
    4384             :     // Calculate Coil Surface Temperature at air entry to the coil
    4385    26633111 :     AirInletCoilSurfTemp = PsyTsatFnHPb(state, EnthSatAirCoilSurfaceEntryTemp, state.dataEnvrn->OutBaroPress);
    4386             : 
    4387             :     // Calculate outlet air temperature and humidity from enthalpies and surface conditions.
    4388    26633111 :     TotWaterCoilLoad = AirMassFlow * (EnthAirInlet - EnthAirOutlet);
    4389    26633111 :     OutletWaterTemp = WaterTempIn + TotWaterCoilLoad / max(WaterMassFlowRate, SmallNo) / Cp;
    4390             : 
    4391             :     // Calculates out put variable for  the completely wet coil
    4392    26633111 :     WetCoilOutletCondition(state, CoilNum, AirTempIn, EnthAirInlet, EnthAirOutlet, UAExternalTotal, OutletAirTemp, OutletAirHumRat, SenWaterCoilLoad);
    4393    26633111 : }
    4394             : 
    4395             : // Coil Part Wet Part Dry Subroutine for Cooling Coil
    4396             : 
    4397      706219 : void CoilPartWetPartDry(EnergyPlusData &state,
    4398             :                         int const CoilNum,             // Number of Coil
    4399             :                         bool const FirstHVACIteration, // Saving Old values
    4400             :                         Real64 const InletWaterTemp,   // Entering liquid temperature(C)
    4401             :                         Real64 const InletAirTemp,     // Entering air dry bulb temperature(C)
    4402             :                         Real64 const AirDewPointTemp,  // Entering air dew point(C)
    4403             :                         Real64 &OutletWaterTemp,       // Leaving liquid temperature(C)
    4404             :                         Real64 &OutletAirTemp,         // Leaving air dry bulb temperature(C)
    4405             :                         Real64 &OutletAirHumRat,       // Leaving air humidity ratio
    4406             :                         Real64 &TotWaterCoilLoad,      // Total heat transfer rate (W)
    4407             :                         Real64 &SenWaterCoilLoad,      // Sensible heat transfer rate (W)
    4408             :                         Real64 &SurfAreaWetFraction,   // Fraction of surface area wet
    4409             :                         int const FanOpMode,           // fan operating mode
    4410             :                         Real64 const PartLoadRatio     // part-load ratio of heating coil
    4411             : )
    4412             : {
    4413             : 
    4414             :     // FUNCTION INFORMATION:
    4415             :     // AUTHOR         Rahul Chillar
    4416             :     // DATE WRITTEN   March 2004
    4417             :     // MODIFIED       na
    4418             :     // RE-ENGINEERED  na
    4419             : 
    4420             :     // PURPOSE OF THIS FUNCTION:
    4421             :     // Calculate the performance of a cooling  coil when the external fin surface is
    4422             :     // part wet and part dry.  Results include outlet air temperature and humidity,
    4423             :     // outlet liquid temperature, sensible and total cooling capacities, and the wet
    4424             :     // fraction of the air-side surface area.
    4425             : 
    4426             :     // METHODOLOGY EMPLOYED:
    4427             :     // Models coil using effectiveness NTU model
    4428             : 
    4429             :     // REFERENCES:
    4430             :     // Elmahdy, A.H. and Mitalas, G.P.  1977. "A Simple Model for Cooling and
    4431             :     // Dehumidifying Coils for Use In Calculating Energy Requirements for Buildings,"
    4432             :     // ASHRAE Transactions,Vol.83 Part 2, pp. 103-117.
    4433             :     // TRNSYS.  1990.  A Transient System Simulation Program: Reference Manual.
    4434             :     // Solar Energy Laboratory, Univ. Wisconsin- Madison, pp. 4.6.8-1 - 4.6.8-12.
    4435             :     // Threlkeld, J.L.  1970.  Thermal Environmental Engineering, 2nd Edition,
    4436             :     // Englewood Cliffs: Prentice-Hall,Inc. pp. 254-270.
    4437             : 
    4438             :     // Using/Aliasing
    4439             :     using General::Iterate;
    4440             : 
    4441             :     // Enforce explicit typing of all variables in this routine
    4442             : 
    4443             :     // Locals
    4444             :     // FUNCTION ARGUMENT DEFINITIONS:
    4445             : 
    4446             :     // FUNCTION PARAMETER DEFINITIONS:
    4447      706219 :     int constexpr itmax(60);
    4448      706219 :     Real64 constexpr smalltempdiff(1.0e-9);
    4449             : 
    4450             :     // INTERFACE BLOCK SPECIFICATIONS
    4451             :     // na
    4452             : 
    4453             :     // DERIVED TYPE DEFINITIONS
    4454             :     // na
    4455             : 
    4456             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4457             :     Real64 DryCoilHeatTranfer;             // Heat transfer rate for dry coil(W)
    4458             :     Real64 WetCoilTotalHeatTransfer;       // Total heat transfer rate for wet coil(W)
    4459             :     Real64 WetCoilSensibleHeatTransfer;    // Sensible heat transfer rate for wet coil(W)
    4460             :     Real64 SurfAreaWet;                    // Air-side area of wet coil(m2)
    4461             :     Real64 SurfAreaDry;                    // Air-side area of dry coil(m2)
    4462             :     Real64 DryCoilUA;                      // Overall heat transfer coefficient for dry coil(W/C)
    4463             :     Real64 WetDryInterfcWaterTemp;         // Liquid temperature at wet/dry boundary(C)
    4464             :     Real64 WetDryInterfcAirTemp;           // Air temperature at wet/dry boundary(C)
    4465             :     Real64 WetDryInterfcSurfTemp;          // Surface temperature at wet/dry boundary(C)
    4466             :     Real64 EstimateWetDryInterfcWaterTemp; // Estimated liquid temperature at wet/dry boundary(C)
    4467             :     Real64 EstimateSurfAreaWetFraction;    // Initial Estimate for Fraction of Surface Wet with condensation
    4468             :     Real64 WetPartUAInternal;              // UA of Wet Coil Internal
    4469             :     Real64 WetPartUAExternal;              // UA of Dry Coil External
    4470             :     Real64 WetDryInterfcHumRat;            // Humidity Ratio at interface of the wet dry transition
    4471             :     Real64 X1T;                            // Variables used in the two iteration in this subroutine.
    4472             :     Real64 NewSurfAreaWetFrac;             // Variables used in the two iteration in this subroutine.
    4473             :     Real64 ResultXT;                       // Variables used in the two iteration in this subroutine.
    4474             :     Real64 Y1T;                            // Variables used in the two iterations in this subroutine.
    4475             :     Real64 errorT;                         // Error in interation for First If loop
    4476             :     Real64 error;                          // Deviation of dependent variable in iteration
    4477             :     Real64 SurfAreaFracPrevious;
    4478             :     Real64 ErrorPrevious;
    4479             :     Real64 SurfAreaFracLast;
    4480             :     Real64 ErrorLast;
    4481             :     int iter;  // Iteration counter
    4482             :     int icvg;  // Iteration convergence flag
    4483             :     int icvgT; // Iteration Convergence Flag for First If loop
    4484             :     int itT;   // Iteration Counter for First If Loop
    4485             : 
    4486             :     // Iterates on SurfAreaWetFraction to converge on surface temperature equal to
    4487             :     // entering air dewpoint at wet/dry boundary.
    4488             : 
    4489             :     // Preliminary estimates of coil performance to begin iteration
    4490      706219 :     OutletWaterTemp = InletAirTemp;
    4491      706219 :     DryCoilHeatTranfer = 0.0;
    4492      706219 :     WetCoilTotalHeatTransfer = 0.0;
    4493      706219 :     WetCoilSensibleHeatTransfer = 0.0;
    4494             : 
    4495      706219 :     if (FirstHVACIteration) {
    4496             :         // Estimate liquid temperature at boundary as entering air dew point
    4497      313054 :         WetDryInterfcWaterTemp = AirDewPointTemp;
    4498             : 
    4499             :         // Estimate fraction wet surface area based on liquid temperatures
    4500      313054 :         if (std::abs(OutletWaterTemp - InletWaterTemp) > smalltempdiff) {
    4501      313054 :             SurfAreaWetFraction = (WetDryInterfcWaterTemp - InletWaterTemp) / (OutletWaterTemp - InletWaterTemp);
    4502             :         } else {
    4503           0 :             SurfAreaWetFraction = 0.0;
    4504             :         }
    4505             : 
    4506             :     } else {
    4507      393165 :         SurfAreaWetFraction = state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFractionSaved;
    4508             :     }
    4509             :     // BEGIN LOOP to converge on SurfAreaWetFraction
    4510             :     // The method employed in this loop is as follows: The coil is partially wet and partially dry,
    4511             :     // we calculate the temperature of the coil at the interface, (the point at which the moisture begins
    4512             :     // to condense) temperature of the  water  at interface and air temp is dew point at that location.
    4513             :     // This is done by Iterating between the Completely Dry and Completely Wet Coil until the outlet
    4514             :     // water temperature of one coil equals the inlet water temperature of another.
    4515             :     // Using this value of interface temperature we now iterate to calculate Surface Fraction Wet, Iterate
    4516             :     // function perturbs the value of Surface Fraction Wet and based on this new value the entire loop is
    4517             :     // repeated to get a new interface water temperature and then surface fraction wet is again calculated.
    4518             :     // This process continues till the error between the Wet Dry Interface Temp and Air Dew Point becomes
    4519             :     // very negligible and in 95% of the cases its is a complete convergence to give the exact surface Wet
    4520             :     // fraction.
    4521      706219 :     NewSurfAreaWetFrac = SurfAreaWetFraction;
    4522      706219 :     error = 0.0;
    4523      706219 :     SurfAreaFracPrevious = SurfAreaWetFraction;
    4524      706219 :     ErrorPrevious = 0.0;
    4525      706219 :     SurfAreaFracLast = SurfAreaWetFraction;
    4526      706219 :     ErrorLast = 0.0;
    4527             : 
    4528     4038163 :     for (iter = 1; iter <= itmax; ++iter) {
    4529             : 
    4530             :         // Calculating Surface Area Wet and Surface Area Dry
    4531     4038163 :         SurfAreaWet = SurfAreaWetFraction * state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea;
    4532     4038163 :         SurfAreaDry = state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea - SurfAreaWet;
    4533             : 
    4534             :         // Calculating UA values for the Dry Part of the Coil
    4535     8076326 :         DryCoilUA = SurfAreaDry / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalPerUnitArea +
    4536     4038163 :                                    1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UADryExtPerUnitArea);
    4537             : 
    4538             :         // Calculating UA Value for the Wet part of the Coil
    4539     4038163 :         WetPartUAExternal = state.dataWaterCoils->WaterCoil(CoilNum).UAWetExtPerUnitArea * SurfAreaWet;
    4540     4038163 :         WetPartUAInternal = state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalPerUnitArea * SurfAreaWet;
    4541             : 
    4542             :         // Calculating Water Temperature at Wet Dry Interface of the coil
    4543     4038163 :         WetDryInterfcWaterTemp = InletWaterTemp + SurfAreaWetFraction * (OutletWaterTemp - InletWaterTemp);
    4544             : 
    4545             :         // BEGIN LOOP to converge on liquid temperature at wet/dry boundary
    4546    16115247 :         for (itT = 1; itT <= itmax; ++itT) {
    4547             : 
    4548             :             // Calculate dry coil performance with estimated liquid temperature at the boundary.
    4549    16115247 :             CoilCompletelyDry(state,
    4550             :                               CoilNum,
    4551             :                               WetDryInterfcWaterTemp,
    4552             :                               InletAirTemp,
    4553             :                               DryCoilUA,
    4554             :                               OutletWaterTemp,
    4555             :                               WetDryInterfcAirTemp,
    4556             :                               WetDryInterfcHumRat,
    4557             :                               DryCoilHeatTranfer,
    4558             :                               FanOpMode,
    4559             :                               PartLoadRatio);
    4560             : 
    4561             :             // Calculate wet coil performance with calculated air temperature at the boundary.
    4562    16115247 :             CoilCompletelyWet(state,
    4563             :                               CoilNum,
    4564             :                               InletWaterTemp,
    4565             :                               WetDryInterfcAirTemp,
    4566             :                               WetDryInterfcHumRat,
    4567             :                               WetPartUAInternal,
    4568             :                               WetPartUAExternal,
    4569             :                               EstimateWetDryInterfcWaterTemp,
    4570             :                               OutletAirTemp,
    4571             :                               OutletAirHumRat,
    4572             :                               WetCoilTotalHeatTransfer,
    4573             :                               WetCoilSensibleHeatTransfer,
    4574             :                               EstimateSurfAreaWetFraction,
    4575             :                               WetDryInterfcSurfTemp,
    4576             :                               FanOpMode,
    4577             :                               PartLoadRatio);
    4578             : 
    4579             :             // Iterating to calculate the actual wet dry interface water temperature.
    4580    16115247 :             errorT = EstimateWetDryInterfcWaterTemp - WetDryInterfcWaterTemp;
    4581    16115247 :             Iterate(ResultXT, 0.001, WetDryInterfcWaterTemp, errorT, X1T, Y1T, itT, icvgT);
    4582    16115247 :             WetDryInterfcWaterTemp = ResultXT;
    4583             : 
    4584             :             // IF convergence is achieved then exit the itT to itmax Do loop.
    4585    16115247 :             if (icvgT == 1) break;
    4586             : 
    4587             :         } // End Do for Liq Boundary temp Convergence
    4588             : 
    4589             :         // Wet Dry Interface temperature not converged after maximum specified iterations.
    4590             :         // Print error message, set return error flag
    4591     4038163 :         if ((itT > itmax) && (!state.dataGlobal->WarmupFlag)) {
    4592           0 :             ShowWarningError(state, "For Coil:Cooling:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    4593           0 :             ShowContinueError(state, "CoilPartWetPartDry: Maximum iterations exceeded for Liq Temp, at Interface");
    4594             :         }
    4595             : 
    4596             :         // If Following condition prevails then surface is dry, calculate dry coil performance and return
    4597     4038163 :         if (SurfAreaWetFraction <= 0.0 && WetDryInterfcSurfTemp >= AirDewPointTemp) {
    4598             : 
    4599             :             // Calculating Value of Dry UA for the coil
    4600           0 :             DryCoilUA = state.dataWaterCoils->WaterCoil(CoilNum).TotCoilOutsideSurfArea /
    4601           0 :                         (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternalPerUnitArea +
    4602           0 :                          1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UADryExtPerUnitArea);
    4603             : 
    4604             :             // Calling the Completely Dry Coil for outputs
    4605           0 :             CoilCompletelyDry(state,
    4606             :                               CoilNum,
    4607             :                               InletWaterTemp,
    4608             :                               InletAirTemp,
    4609             :                               DryCoilUA,
    4610             :                               OutletWaterTemp,
    4611             :                               OutletAirTemp,
    4612             :                               OutletAirHumRat,
    4613             :                               TotWaterCoilLoad,
    4614             :                               FanOpMode,
    4615             :                               PartLoadRatio);
    4616             : 
    4617             :             // Sensible load = Total load in a Completely Dry Coil
    4618           0 :             SenWaterCoilLoad = TotWaterCoilLoad;
    4619             : 
    4620             :             // All coil is Dry so fraction wet is ofcourse =0
    4621           0 :             SurfAreaWetFraction = 0.0;
    4622           0 :             return;
    4623             :         }
    4624             : 
    4625             :         // IF the coil is not Dry then iterate to calculate Fraction of surface area that is wet.
    4626     4038163 :         error = WetDryInterfcSurfTemp - AirDewPointTemp;
    4627     4038163 :         CoilAreaFracIter(
    4628             :             NewSurfAreaWetFrac, SurfAreaWetFraction, error, SurfAreaFracPrevious, ErrorPrevious, SurfAreaFracLast, ErrorLast, iter, icvg);
    4629     4038163 :         SurfAreaWetFraction = NewSurfAreaWetFrac;
    4630             : 
    4631             :         // If converged, leave iteration loop
    4632     4038163 :         if (icvg == 1) break;
    4633             : 
    4634             :         // Surface temperature not converged.  Repeat calculations with new
    4635             :         // estimate of fraction wet surface area.
    4636     3331944 :         if (SurfAreaWetFraction > 1.0) SurfAreaWetFraction = 1.0;
    4637     3331944 :         if (SurfAreaWetFraction <= 0.0) SurfAreaWetFraction = 0.0098;
    4638             : 
    4639             :     } // End do for the overall iteration
    4640             : 
    4641             :     // Calculate sum of total and sensible heat transfer from dry and wet parts.
    4642      706219 :     TotWaterCoilLoad = DryCoilHeatTranfer + WetCoilTotalHeatTransfer;
    4643      706219 :     SenWaterCoilLoad = DryCoilHeatTranfer + WetCoilSensibleHeatTransfer;
    4644             : 
    4645             :     // Save last iterations values for this current time step
    4646      706219 :     state.dataWaterCoils->WaterCoil(CoilNum).SurfAreaWetFractionSaved = SurfAreaWetFraction;
    4647             : }
    4648             : 
    4649             : // Calculating coil UA for Cooling Coil
    4650             : 
    4651           0 : Real64 CalcCoilUAbyEffectNTU(EnergyPlusData &state,
    4652             :                              int const CoilNum,
    4653             :                              Real64 const CapacityStream1,     // Capacity rate of stream1.(W/C)
    4654             :                              Real64 const EnergyInStreamOne,   // Inlet state of stream1.(C)
    4655             :                              Real64 const CapacityStream2,     // Capacity rate of stream2.(W/C)
    4656             :                              Real64 const EnergyInStreamTwo,   // Inlet state of stream2.(C)
    4657             :                              Real64 const DesTotalHeatTransfer // Heat transfer rate(W)
    4658             : )
    4659             : {
    4660             : 
    4661             :     // FUNCTION INFORMATION:
    4662             :     // AUTHOR         Rahul Chillar
    4663             :     // DATE WRITTEN   March 2004
    4664             :     // MODIFIED       na
    4665             :     // RE-ENGINEERED  na
    4666             : 
    4667             :     // PURPOSE OF THIS FUNCTION:
    4668             :     // Calculate the UA of a heat exchanger using the effectiveness-NTU relationships
    4669             :     // given the entering capacity rate and temperature of each flow stream, the
    4670             :     // heat transfer rate under these conditions and the heat exchanger configuration.
    4671             : 
    4672             :     // METHODOLOGY EMPLOYED:
    4673             :     // Models coil using effectiveness NTU model
    4674             : 
    4675             :     // REFERENCES:
    4676             :     // na
    4677             : 
    4678             :     // Using/Aliasing
    4679             :     using General::Iterate;
    4680             : 
    4681             :     // Enforce explicit typing of all variables in this routine
    4682             : 
    4683             :     // Return value
    4684             :     Real64 CalcCoilUAbyEffectNTU; // Overall heat transfer coefficient(W/C)
    4685             : 
    4686             :     // Locals
    4687             :     // FUNCTION ARGUMENT DEFINITIONS:
    4688             : 
    4689             :     // FUNCTION PARAMETER DEFINITIONS:
    4690           0 :     Real64 constexpr SmallNo(1.e-9);
    4691           0 :     int constexpr itmax(12);
    4692             : 
    4693             :     // INTERFACE BLOCK SPECIFICATIONS
    4694             :     // na
    4695             : 
    4696             :     // DERIVED TYPE DEFINITIONS
    4697             :     // na
    4698             : 
    4699             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4700             :     Real64 MaxHeatTransfer;       // Maximum heat transfer from inlet conditions (W)
    4701             :     Real64 EstimatedHeatTransfer; // Estimated heat transfer in iteration(W)
    4702             :     Real64 CoilUA;                // Estimated heat transfer coefficient(W/C)
    4703             :     Real64 error;                 // Deviation of dependent variable in iteration
    4704             :     Real64 X1;                    // Previous values of independent variable in iteration
    4705             :     Real64 Y1;
    4706             :     Real64 ResultX;
    4707             :     Real64 EnergyOutStreamOne;        // Intermediate Variable used
    4708             :     Real64 EnergyOutStreamTwo;        // Intermediate variable used
    4709             :     Real64 DesTotalHeatTransferCheck; // Check value to keep design total heat transfer in range
    4710             :     int iter;                         // Iteration index
    4711             :     int icvg;                         // Iteration convergence flag
    4712             : 
    4713             :     // Check for Q out of range (effectiveness > 1)
    4714           0 :     MaxHeatTransfer = std::abs(min(CapacityStream1, CapacityStream2) * (EnergyInStreamOne - EnergyInStreamTwo));
    4715             : 
    4716             :     // Error Message
    4717           0 :     if ((std::abs(DesTotalHeatTransfer) - MaxHeatTransfer) / max(MaxHeatTransfer, SmallNo) > SmallNo) {
    4718           0 :         ShowWarningError(state, "For Coil:Cooling:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    4719           0 :         ShowContinueError(state, "CalcCoilUAbyEffectNTU:Given Q impossible for given inlet states, proceeding with MaxHeat Transfer");
    4720           0 :         ShowContinueError(state, "Check the Sizing:System and Sizing:Zone cooling design supply air temperature and ");
    4721           0 :         ShowContinueError(state,
    4722             :                           "the Sizing:Plant design Loop exit temperature.  There must be sufficient difference between these two temperatures.");
    4723             :     }
    4724             : 
    4725             :     // Design Heat Transfer cannot exceed Max heat Transfer , setting it value such that effectiveness<1.0
    4726           0 :     if ((DesTotalHeatTransfer) > (MaxHeatTransfer)) {
    4727             :         // Pegging value so that effectiveness is less than 1.
    4728           0 :         DesTotalHeatTransferCheck = 0.9 * MaxHeatTransfer;
    4729             : 
    4730             :         // Estimate CalcCoilUAbyEffectNTU
    4731           0 :         CoilUA = std::abs(DesTotalHeatTransferCheck / (EnergyInStreamOne - EnergyInStreamTwo));
    4732             : 
    4733             :     } else {
    4734             : 
    4735             :         // Estimate CalcCoilUAbyEffectNTU
    4736           0 :         CoilUA = std::abs(DesTotalHeatTransfer / (EnergyInStreamOne - EnergyInStreamTwo));
    4737             :     }
    4738             : 
    4739             :     // BEGIN LOOP to iteratively calculate CalcCoilUAbyEffectNTU
    4740           0 :     for (iter = 1; iter <= itmax; ++iter) {
    4741             : 
    4742             :         // Calculate heat transfer rate for estimated CalcCoilUAbyEffectNTU
    4743           0 :         CoilOutletStreamCondition(
    4744             :             state, CoilNum, CapacityStream1, EnergyInStreamOne, CapacityStream2, EnergyInStreamTwo, CoilUA, EnergyOutStreamOne, EnergyOutStreamTwo);
    4745             : 
    4746             :         // Initial Guess for a value of heat transfer
    4747           0 :         EstimatedHeatTransfer = CapacityStream1 * (EnergyInStreamOne - EnergyOutStreamOne);
    4748             : 
    4749             :         // Calculate new estimate for CalcCoilUAbyEffectNTU by iteration
    4750           0 :         if (DesTotalHeatTransfer > MaxHeatTransfer) {
    4751           0 :             error = std::abs(EstimatedHeatTransfer) - std::abs(DesTotalHeatTransferCheck);
    4752             :         } else {
    4753           0 :             error = std::abs(EstimatedHeatTransfer) - std::abs(DesTotalHeatTransfer);
    4754             :         }
    4755           0 :         Iterate(ResultX, 0.01, CoilUA, error, X1, Y1, iter, icvg);
    4756           0 :         CoilUA = ResultX;
    4757             :         // If converged, leave loop
    4758           0 :         if (icvg == 1) break;
    4759             :     }
    4760             : 
    4761             :     // If not converged after itmax iterations, return error code
    4762           0 :     if ((iter > itmax) && (!state.dataGlobal->WarmupFlag)) {
    4763           0 :         ShowWarningError(state, "For Coil:Cooling:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    4764           0 :         ShowContinueError(state, "CalcCoilUAbyEffectNTU: Maximum iterations exceeded:Coil UA calculation");
    4765           0 :         CalcCoilUAbyEffectNTU = 0.0; // Autodesk:Return Line added to set return value: Using non-converged CoilUA value may be preferred but
    4766             :                                      // that was not happening
    4767             :     } else {
    4768             : 
    4769             :         // Assign value to CalcCoilUAbyEffectNTU
    4770           0 :         CalcCoilUAbyEffectNTU = CoilUA;
    4771             :     }
    4772             : 
    4773           0 :     return CalcCoilUAbyEffectNTU;
    4774             : }
    4775             : 
    4776             : // Calculating coil outlet stream conditions and coil UA for Cooling Coil
    4777             : 
    4778    44416903 : void CoilOutletStreamCondition(EnergyPlusData &state,
    4779             :                                int const CoilNum,
    4780             :                                Real64 const CapacityStream1,   // Capacity rate of stream1(W/C)
    4781             :                                Real64 const EnergyInStreamOne, // Inlet state of stream1 (C)
    4782             :                                Real64 const CapacityStream2,   // Capacity rate of stream2 (W/C)
    4783             :                                Real64 const EnergyInStreamTwo, // Inlet state of stream2 (C)
    4784             :                                Real64 const CoilUA,            // Heat transfer rateW)
    4785             :                                Real64 &EnergyOutStreamOne,     // Outlet state of stream1 (C)
    4786             :                                Real64 &EnergyOutStreamTwo      // Outlet state of stream2 (C)
    4787             : )
    4788             : {
    4789             : 
    4790             :     // FUNCTION INFORMATION:
    4791             :     // AUTHOR         Rahul Chillar
    4792             :     // DATE WRITTEN   March 2004
    4793             :     // MODIFIED       na
    4794             :     // RE-ENGINEERED  na
    4795             : 
    4796             :     // PURPOSE OF THIS FUNCTION:
    4797             :     // Calculate the outlet states of a simple heat exchanger using the effectiveness-Ntu
    4798             :     // method of analysis.
    4799             : 
    4800             :     // METHODOLOGY EMPLOYED:
    4801             :     // na
    4802             : 
    4803             :     // REFERENCES:
    4804             :     // Kays, W.M. and A.L. London.  1964.Compact Heat Exchangers, 2nd Ed.McGraw-Hill:New York.
    4805             : 
    4806             :     // USE STATEMENTS:
    4807             :     // na
    4808             : 
    4809             :     // Enforce explicit typing of all variables in this routine
    4810             : 
    4811             :     // Locals
    4812             :     // FUNCTION ARGUMENT DEFINITIONS:
    4813             : 
    4814             :     // FUNCTION PARAMETER DEFINITIONS:
    4815    44416903 :     Real64 constexpr LargeNo(1.e10);  // value used in place of infinity
    4816    44416903 :     Real64 constexpr SmallNo(1.e-15); // value used in place of zero
    4817             : 
    4818             :     // INTERFACE BLOCK SPECIFICATIONS
    4819             :     // na
    4820             : 
    4821             :     // DERIVED TYPE DEFINITIONS
    4822             :     // na
    4823             : 
    4824             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4825             :     Real64 MinimumCapacityStream; // Minimum capacity rate of the streams(W/C)
    4826             :     Real64 MaximumCapacityStream; // Maximum capacity rate of the streams(W/C)
    4827             :     Real64 RatioStreamCapacity;   // Ratio of minimum to maximum capacity rate
    4828             :     Real64 NTU;                   // Number of transfer units
    4829    44416903 :     Real64 effectiveness(0.0);    // Heat exchanger effectiveness
    4830             :     Real64 MaxHeatTransfer;       // Maximum heat transfer possible(W)
    4831             :     Real64 e;                     // Intermediate variables in effectiveness equation
    4832             :     Real64 eta;
    4833             :     Real64 b;
    4834             :     Real64 d;
    4835             : 
    4836             :     // NTU and MinimumCapacityStream/MaximumCapacityStream (RatioStreamCapacity) calculations
    4837    44416903 :     MinimumCapacityStream = min(CapacityStream1, CapacityStream2);
    4838    44416903 :     MaximumCapacityStream = max(CapacityStream1, CapacityStream2);
    4839             : 
    4840    44416903 :     if (std::abs(MaximumCapacityStream) <= 1.e-6) { // .EQ. 0.0d0) THEN
    4841           0 :         RatioStreamCapacity = 1.0;
    4842             :     } else {
    4843    44416903 :         RatioStreamCapacity = MinimumCapacityStream / MaximumCapacityStream;
    4844             :     }
    4845             : 
    4846    44416903 :     if (std::abs(MinimumCapacityStream) <= 1.e-6) { // .EQ. 0.0d0) THEN
    4847           0 :         NTU = LargeNo;
    4848             :     } else {
    4849    44416903 :         NTU = CoilUA / MinimumCapacityStream;
    4850             :     }
    4851             : 
    4852             :     // Calculate effectiveness for special limiting cases
    4853    44416903 :     if (NTU <= 0.0) {
    4854      171699 :         effectiveness = 0.0;
    4855             : 
    4856    44245204 :     } else if (RatioStreamCapacity < SmallNo) {
    4857             :         // MinimumCapacityStream/MaximumCapacityStream = 0 and effectiveness is independent of configuration
    4858             :         // 20 is the Limit Chosen for Exponential Function, beyond which there is float point error.
    4859           0 :         if (NTU > 20.0) {
    4860           0 :             effectiveness = 1.0;
    4861             :         } else {
    4862           0 :             effectiveness = 1.0 - std::exp(-NTU);
    4863             :         }
    4864             :         // Calculate effectiveness depending on heat exchanger configuration
    4865    44245204 :     } else if (state.dataWaterCoils->WaterCoil(CoilNum).HeatExchType == state.dataWaterCoils->CounterFlow) {
    4866             : 
    4867             :         // Counterflow Heat Exchanger Configuration
    4868       12283 :         if (std::abs(RatioStreamCapacity - 1.0) < SmallNo) {
    4869           0 :             effectiveness = NTU / (NTU + 1.0);
    4870             :         } else {
    4871       12283 :             if (NTU * (1.0 - RatioStreamCapacity) > 20.0) {
    4872           0 :                 e = 0.0;
    4873             :             } else {
    4874       12283 :                 e = std::exp(-NTU * (1.0 - RatioStreamCapacity));
    4875             :             }
    4876       12283 :             effectiveness = (1.0 - e) / (1.0 - RatioStreamCapacity * e);
    4877             :         }
    4878             : 
    4879    44232921 :     } else if (state.dataWaterCoils->WaterCoil(CoilNum).HeatExchType == state.dataWaterCoils->CrossFlow) {
    4880             :         // Cross flow, both streams unmixed
    4881    44232921 :         eta = std::pow(NTU, -0.22);
    4882    44232921 :         if ((NTU * RatioStreamCapacity * eta) > 20.0) {
    4883           0 :             b = 1.0 / (RatioStreamCapacity * eta);
    4884           0 :             if (b > 20.0) {
    4885           0 :                 effectiveness = 1.0;
    4886             :             } else {
    4887           0 :                 effectiveness = 1.0 - std::exp(-b);
    4888           0 :                 if (effectiveness < 0.0) effectiveness = 0.0;
    4889             :             }
    4890             :         } else {
    4891    44232921 :             d = ((std::exp(-NTU * RatioStreamCapacity * eta) - 1.0) / (RatioStreamCapacity * eta));
    4892    44232921 :             if (d < -20.0 || d > 0.0) {
    4893       15093 :                 effectiveness = 1.0;
    4894             :             } else {
    4895    44217828 :                 effectiveness = 1.0 - std::exp((std::exp(-NTU * RatioStreamCapacity * eta) - 1.0) / (RatioStreamCapacity * eta));
    4896    44217828 :                 if (effectiveness < 0.0) effectiveness = 0.0;
    4897             :             }
    4898             :         }
    4899             :     }
    4900             : 
    4901             :     // Determine leaving conditions for the two streams
    4902    44416903 :     MaxHeatTransfer = max(MinimumCapacityStream, SmallNo) * (EnergyInStreamOne - EnergyInStreamTwo);
    4903    44416903 :     EnergyOutStreamOne = EnergyInStreamOne - effectiveness * MaxHeatTransfer / max(CapacityStream1, SmallNo);
    4904    44416903 :     EnergyOutStreamTwo = EnergyInStreamTwo + effectiveness * MaxHeatTransfer / max(CapacityStream2, SmallNo);
    4905    44416903 : }
    4906             : 
    4907             : // Subroutine for caculating outlet condition if coil is wet , for Cooling Coil
    4908             : 
    4909    26633111 : void WetCoilOutletCondition(EnergyPlusData &state,
    4910             :                             int const CoilNum,
    4911             :                             Real64 const AirTempIn,      // Entering air dry bulb temperature(C)
    4912             :                             Real64 const EnthAirInlet,   // Entering air enthalpy(J/kg)
    4913             :                             Real64 const EnthAirOutlet,  // Leaving air enthalpy(J/kg)
    4914             :                             Real64 const UACoilExternal, // Heat transfer coefficient for external surface (W/C)
    4915             :                             Real64 &OutletAirTemp,       // Leaving air dry bulb temperature(C)
    4916             :                             Real64 &OutletAirHumRat,     // Leaving air humidity ratio
    4917             :                             Real64 &SenWaterCoilLoad     // Sensible heat transfer rate(W)
    4918             : )
    4919             : {
    4920             : 
    4921             :     // FUNCTION INFORMATION:
    4922             :     // AUTHOR         Rahul Chillar
    4923             :     // DATE WRITTEN   Mar 2004
    4924             :     // MODIFIED       na
    4925             :     // RE-ENGINEERED  na
    4926             : 
    4927             :     // PURPOSE OF THIS FUNCTION:
    4928             :     // Calculate the leaving air temperature,the leaving air humidity ratio and the
    4929             :     // sensible cooling capacity of wet cooling coil.
    4930             : 
    4931             :     // METHODOLOGY EMPLOYED:
    4932             :     // Assumes condensate at uniform temperature.
    4933             : 
    4934             :     // REFERENCES:
    4935             :     // Elmahdy, A.H. and Mitalas, G.P.  1977."A Simple Model for Cooling and
    4936             :     // Dehumidifying Coils for Use In Calculating Energy Requirements for Buildings,"
    4937             :     // ASHRAE Transactions,Vol.83 Part 2, pp. 103-117.
    4938             : 
    4939             :     // USE STATEMENTS:
    4940             : 
    4941             :     // Enforce explicit typing of all variables in this routine
    4942             : 
    4943             :     // Locals
    4944             :     // FUNCTION ARGUMENT DEFINITIONS:
    4945             : 
    4946             :     // FUNCTION PARAMETER DEFINITIONS:
    4947    26633111 :     Real64 constexpr SmallNo(1.e-9); // SmallNo value used in place of zero
    4948             : 
    4949             :     // INTERFACE BLOCK SPECIFICATIONS
    4950             :     // na
    4951             : 
    4952             :     // DERIVED TYPE DEFINITIONS
    4953             :     // na
    4954             : 
    4955             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4956             :     Real64 CapacitanceAir;        // Air capacity rate(W/C)
    4957             :     Real64 NTU;                   // Number of heat transfer units
    4958             :     Real64 effectiveness;         // Heat exchanger effectiveness
    4959             :     Real64 EnthAirCondensateTemp; // Saturated air enthalpy at temperature of condensate(J/kg)
    4960             :     Real64 TempCondensation;      // Temperature of condensate(C)
    4961             :     Real64 TempAirDewPoint;       // Temperature air dew point
    4962             : 
    4963             :     // Determine the temperature effectiveness, assuming the temperature
    4964             :     // of the condensate is constant (MinimumCapacityStream/MaximumCapacityStream = 0) and the specific heat
    4965             :     // of moist air is constant
    4966    26633111 :     CapacitanceAir =
    4967    26633111 :         state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate * PsyCpAirFnW(state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat);
    4968             : 
    4969             :     // Calculating NTU from UA and Capacitance.
    4970             :     // del      NTU = UACoilExternal/MAX(CapacitanceAir,SmallNo)
    4971             :     // del      effectiveness = 1 - EXP(-MAX(0.0d0,NTU))
    4972             :     // Calculating NTU from UA and Capacitance.
    4973    26633111 :     if (UACoilExternal > 0.0) {
    4974    26633111 :         if (CapacitanceAir > 0.0) {
    4975    26633111 :             NTU = UACoilExternal / CapacitanceAir;
    4976             :         } else {
    4977           0 :             NTU = 0.0;
    4978             :         }
    4979    26633111 :         effectiveness = 1.0 - std::exp(-NTU);
    4980             :     } else {
    4981           0 :         effectiveness = 0.0;
    4982             :     }
    4983             : 
    4984             :     // Calculate coil surface enthalpy and temperature at the exit
    4985             :     // of the wet part of the coil using the effectiveness relation
    4986    26633111 :     effectiveness = max(effectiveness, SmallNo);
    4987    26633111 :     EnthAirCondensateTemp = EnthAirInlet - (EnthAirInlet - EnthAirOutlet) / effectiveness;
    4988             : 
    4989             :     // Calculate condensate temperature as the saturation temperature
    4990             :     // at given saturation enthalpy
    4991    26633111 :     TempCondensation = PsyTsatFnHPb(state, EnthAirCondensateTemp, state.dataEnvrn->OutBaroPress);
    4992             : 
    4993    26633111 :     TempAirDewPoint = PsyTdpFnWPb(state, state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat, state.dataEnvrn->OutBaroPress);
    4994             : 
    4995    26633111 :     if ((TempAirDewPoint - TempCondensation) > 0.1) {
    4996             : 
    4997             :         // Calculate Outlet Air Temperature using effectivness
    4998    23255988 :         OutletAirTemp = AirTempIn - (AirTempIn - TempCondensation) * effectiveness;
    4999             :         // Calculate Outlet air humidity ratio from PsyWFnTdbH routine
    5000    23255988 :         OutletAirHumRat = PsyWFnTdbH(state, OutletAirTemp, EnthAirOutlet);
    5001             : 
    5002             :     } else {
    5003     3377123 :         OutletAirHumRat = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    5004     3377123 :         OutletAirTemp = PsyTdbFnHW(EnthAirOutlet, OutletAirHumRat);
    5005             :     }
    5006             : 
    5007             :     // Calculate Sensible Coil Load
    5008    26633111 :     SenWaterCoilLoad = CapacitanceAir * (AirTempIn - OutletAirTemp);
    5009    26633111 : }
    5010             : 
    5011             : // Beginning of Update subroutines for the WaterCoil Module
    5012             : // *****************************************************************************
    5013             : 
    5014   137535475 : void UpdateWaterCoil(EnergyPlusData &state, int const CoilNum)
    5015             : {
    5016             :     // SUBROUTINE INFORMATION:
    5017             :     //       AUTHOR         Richard Liesen
    5018             :     //       DATE WRITTEN   1998
    5019             :     //       MODIFIED       April 2004: Rahul Chillar
    5020             :     //                      Feb 2010 B. Griffith, plant upgrades
    5021             :     //       RE-ENGINEERED  na
    5022             : 
    5023             :     // PURPOSE OF THIS SUBROUTINE:
    5024             :     // This subroutine updates the coil outlet nodes.
    5025             : 
    5026             :     // METHODOLOGY EMPLOYED:
    5027             :     // Data is moved from the coil data structure to the coil outlet nodes.
    5028             : 
    5029             :     // REFERENCES:
    5030             :     // na
    5031             : 
    5032             :     // Using/Aliasing
    5033             :     using PlantUtilities::SetComponentFlowRate;
    5034             : 
    5035             :     // Locals
    5036             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5037             : 
    5038             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5039             :     // na
    5040             : 
    5041             :     // INTERFACE BLOCK SPECIFICATIONS
    5042             :     // na
    5043             : 
    5044             :     // DERIVED TYPE DEFINITIONS
    5045             :     // na
    5046             : 
    5047             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5048             :     int AirInletNode;
    5049             :     int WaterInletNode;
    5050             :     int AirOutletNode;
    5051             :     int WaterOutletNode;
    5052             : 
    5053   137535475 :     AirInletNode = state.dataWaterCoils->WaterCoil(CoilNum).AirInletNodeNum;
    5054   137535475 :     WaterInletNode = state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum;
    5055   137535475 :     AirOutletNode = state.dataWaterCoils->WaterCoil(CoilNum).AirOutletNodeNum;
    5056   137535475 :     WaterOutletNode = state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum;
    5057             : 
    5058             :     // Set the outlet air nodes of the WaterCoil
    5059   137535475 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).OutletAirMassFlowRate;
    5060   137535475 :     state.dataLoopNodes->Node(AirOutletNode).Temp = state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp;
    5061   137535475 :     state.dataLoopNodes->Node(AirOutletNode).HumRat = state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat;
    5062   137535475 :     state.dataLoopNodes->Node(AirOutletNode).Enthalpy = state.dataWaterCoils->WaterCoil(CoilNum).OutletAirEnthalpy;
    5063             : 
    5064   137535475 :     state.dataLoopNodes->Node(WaterOutletNode).Temp = state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterTemp;
    5065   137535475 :     state.dataLoopNodes->Node(WaterOutletNode).Enthalpy = state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterEnthalpy;
    5066             : 
    5067             :     // Set the outlet nodes for properties that just pass through & not used
    5068   137535475 :     state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
    5069   137535475 :     state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
    5070   137535475 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
    5071   137535475 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
    5072   137535475 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
    5073   137535475 :     state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
    5074   137535475 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    5075           0 :         state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
    5076             :     }
    5077   137535475 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    5078           0 :         state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
    5079             :     }
    5080   137535475 : }
    5081             : 
    5082             : //        End of Update subroutines for the WaterCoil Module
    5083             : // *****************************************************************************
    5084             : 
    5085             : // Beginning of Reporting subroutines for the WaterCoil Module
    5086             : // *****************************************************************************
    5087             : 
    5088   137535475 : void ReportWaterCoil(EnergyPlusData &state, int const CoilNum)
    5089             : {
    5090             : 
    5091             :     // SUBROUTINE INFORMATION:
    5092             :     //       AUTHOR         Richard Liesen
    5093             :     //       DATE WRITTEN   1998
    5094             :     //       MODIFIED       na
    5095             :     //       RE-ENGINEERED  na
    5096             : 
    5097             :     // PURPOSE OF THIS SUBROUTINE:
    5098             :     // This subroutine updates the report variable for the coils.
    5099             : 
    5100             :     // METHODOLOGY EMPLOYED:
    5101             :     // NA
    5102             : 
    5103             :     // REFERENCES:
    5104             :     // na
    5105             : 
    5106             :     // Using/Aliasing
    5107             : 
    5108             :     // Locals
    5109             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5110             : 
    5111             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5112             :     static constexpr std::string_view RoutineName("ReportWaterCoil");
    5113             : 
    5114             :     // INTERFACE BLOCK SPECIFICATIONS
    5115             :     // na
    5116             : 
    5117             :     // DERIVED TYPE DEFINITIONS
    5118             :     // na
    5119             : 
    5120             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5121             :     Real64 RhoWater;
    5122             :     Real64 Tavg;
    5123             :     Real64 SpecHumOut;
    5124             :     Real64 SpecHumIn;
    5125             :     Real64 ReportingConstant;
    5126             : 
    5127   137535475 :     if (state.dataWaterCoils->WaterCoil(CoilNum).reportCoilFinalSizes) {
    5128    18944507 :         if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
    5129        6200 :             std::string coilObjClassName;
    5130        3100 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
    5131        2554 :                 coilObjClassName = "Coil:Heating:Water";
    5132       15324 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
    5133             :                     state,
    5134        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    5135             :                     coilObjClassName,
    5136        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate,
    5137        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesWaterHeatingCoilRate,
    5138        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate,
    5139        2554 :                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate);
    5140        2554 :                 state.dataWaterCoils->WaterCoil(CoilNum).reportCoilFinalSizes = false;
    5141         546 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling) {
    5142         143 :                 coilObjClassName = "Coil:Cooling:Water:DetailedGeometry";
    5143         715 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
    5144             :                     state,
    5145         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    5146             :                     coilObjClassName,
    5147         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate,
    5148             :                     -999.0,
    5149         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate,
    5150         143 :                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate);
    5151         143 :                 state.dataWaterCoils->WaterCoil(CoilNum).reportCoilFinalSizes = false;
    5152         403 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) {
    5153         403 :                 coilObjClassName = "Coil:Cooling:Water";
    5154        2015 :                 state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
    5155             :                     state,
    5156         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).Name,
    5157             :                     coilObjClassName,
    5158         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesWaterCoolingCoilRate,
    5159             :                     -999.0,
    5160         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).DesAirVolFlowRate,
    5161         403 :                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterVolFlowRate);
    5162         403 :                 state.dataWaterCoils->WaterCoil(CoilNum).reportCoilFinalSizes = false;
    5163             :             }
    5164             :         }
    5165             :     }
    5166   137535475 :     ReportingConstant = state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
    5167             :     // report the WaterCoil energy from this component
    5168   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilEnergy =
    5169   137535475 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterHeatingCoilRate * ReportingConstant;
    5170   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilEnergy =
    5171   137535475 :         state.dataWaterCoils->WaterCoil(CoilNum).TotWaterCoolingCoilRate * ReportingConstant;
    5172   137535475 :     state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilEnergy =
    5173   137535475 :         state.dataWaterCoils->WaterCoil(CoilNum).SenWaterCoolingCoilRate * ReportingConstant;
    5174             : 
    5175             :     // report the WaterCoil water collection to water storage tank (if needed)
    5176             : 
    5177   137535475 :     if (state.dataWaterCoils->WaterCoil(CoilNum).CondensateCollectMode == state.dataWaterCoils->CondensateToTank) {
    5178             :         // calculate and report condensation rates  (how much water extracted from the air stream)
    5179             :         // water volumetric flow of water in m3/s for water system interactions
    5180             :         //  put here to catch all types of DX coils
    5181           0 :         Tavg = (state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp - state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp) / 2.0;
    5182             : 
    5183           0 :         RhoWater = GetDensityGlycol(state,
    5184           0 :                                     state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    5185             :                                     Tavg,
    5186           0 :                                     state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    5187             :                                     RoutineName);
    5188             :         //   CR9155 Remove specific humidity calculations
    5189           0 :         SpecHumIn = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    5190           0 :         SpecHumOut = state.dataWaterCoils->WaterCoil(CoilNum).OutletAirHumRat;
    5191             :         //  mdot * del HumRat / rho water
    5192           0 :         state.dataWaterCoils->WaterCoil(CoilNum).CondensateVdot =
    5193           0 :             max(0.0, (state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate * (SpecHumIn - SpecHumOut) / RhoWater));
    5194           0 :         state.dataWaterCoils->WaterCoil(CoilNum).CondensateVol = state.dataWaterCoils->WaterCoil(CoilNum).CondensateVdot * ReportingConstant;
    5195             : 
    5196           0 :         state.dataWaterData->WaterStorage(state.dataWaterCoils->WaterCoil(CoilNum).CondensateTankID)
    5197           0 :             .VdotAvailSupply(state.dataWaterCoils->WaterCoil(CoilNum).CondensateTankSupplyARRID) =
    5198           0 :             state.dataWaterCoils->WaterCoil(CoilNum).CondensateVdot;
    5199           0 :         state.dataWaterData->WaterStorage(state.dataWaterCoils->WaterCoil(CoilNum).CondensateTankID)
    5200           0 :             .TwaterSupply(state.dataWaterCoils->WaterCoil(CoilNum).CondensateTankSupplyARRID) =
    5201           0 :             state.dataWaterCoils->WaterCoil(CoilNum).OutletAirTemp;
    5202             :     }
    5203   137535475 : }
    5204             : 
    5205             : //        End of Reporting subroutines for the WaterCoil Module
    5206             : // *****************************************************************************
    5207             : 
    5208             : // Beginning of Coil Utility subroutines for the Detailed Model
    5209             : // *****************************************************************************
    5210             : 
    5211         872 : void CalcDryFinEffCoef(EnergyPlusData &state, Real64 const OutTubeEffFinDiamRatio, Array1D<Real64> &PolynomCoef)
    5212             : {
    5213             :     // SUBROUTINE INFORMATION:
    5214             :     //       AUTHOR   Unknown
    5215             :     //       DATE WRITTEN   Unknown
    5216             :     //       DATE REWRITTEN  April 1997 by Russell D. Taylor, Ph.D.
    5217             :     //       MODIFIED
    5218             :     //       RE-ENGINEERED
    5219             : 
    5220             :     // PURPOSE OF THIS SUBROUTINE:
    5221             :     // The following subroutines are used once per cooling coil
    5222             :     // simulation to obtain the coefficients of the dry fin
    5223             :     // efficiency equation.  CalcDryFinEffCoef is the main calling
    5224             :     // routine which manages calls to the Bessel funtion and polynomial
    5225             :     // fit routines.
    5226             : 
    5227             :     // REFERENCES:
    5228             :     // First found in MODSIM.
    5229             :     // USE STATEMENTS:
    5230             :     // na
    5231             : 
    5232             :     // Argument array dimensioning
    5233             : 
    5234             :     // Locals
    5235             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5236             : 
    5237             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5238             :     // na
    5239             : 
    5240             :     // INTERFACE BLOCK SPECIFICATIONS
    5241             :     // na
    5242             : 
    5243             :     // DERIVED TYPE DEFINITIONS
    5244             :     // na
    5245             : 
    5246             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5247             :     Real64 FAI;
    5248             :     Real64 FED;
    5249             :     Real64 FEDnumerator;
    5250             :     int I;
    5251             :     int IE1;
    5252             :     int IE2;
    5253             :     int IE3;
    5254             :     int IE4;
    5255             :     int IE5;
    5256             :     int IE6;
    5257             :     Real64 R1;
    5258             :     Real64 R1I1;
    5259             :     Real64 R1K1;
    5260             :     Real64 R2;
    5261             :     Real64 R2I0;
    5262             :     Real64 R2I1;
    5263             :     Real64 R2K0;
    5264             :     Real64 R2K1;
    5265             :     Real64 RO;
    5266             : 
    5267         872 :     FAI = 0.02;
    5268       53192 :     for (I = 1; I <= WaterCoils::MaxOrderedPairs; ++I) {
    5269       52320 :         FAI += 0.035;
    5270       52320 :         R1 = FAI / (1.0 - OutTubeEffFinDiamRatio);
    5271       52320 :         R2 = R1 * OutTubeEffFinDiamRatio;
    5272       52320 :         RO = 2.0 * OutTubeEffFinDiamRatio / (FAI * (1.0 + OutTubeEffFinDiamRatio));
    5273       52320 :         CalcIBesselFunc(R1, 1, R1I1, IE1);
    5274       52320 :         CalcKBesselFunc(R2, 1, R2K1, IE2);
    5275       52320 :         CalcIBesselFunc(R2, 1, R2I1, IE3);
    5276       52320 :         CalcKBesselFunc(R1, 1, R1K1, IE4);
    5277       52320 :         CalcIBesselFunc(R2, 0, R2I0, IE5);
    5278       52320 :         CalcKBesselFunc(R2, 0, R2K0, IE6);
    5279       52320 :         FEDnumerator = RO * (R1I1 * R2K1 - R2I1 * R1K1);
    5280       52320 :         if (FEDnumerator != 0.0) {
    5281       52320 :             FED = FEDnumerator / (R2I0 * R1K1 + R1I1 * R2K0);
    5282             :         } else {
    5283           0 :             FED = 0.0;
    5284             :         }
    5285             :         //      FED = RO * (R1I1 * R2K1 - R2I1 * R1K1) / (R2I0 * R1K1 + R1I1 * R2K0)
    5286       52320 :         state.dataWaterCoils->OrderedPair(I, 1) = FAI;
    5287       52320 :         state.dataWaterCoils->OrderedPair(I, 2) = FED;
    5288             :     }
    5289         872 :     CalcPolynomCoef(state, state.dataWaterCoils->OrderedPair, PolynomCoef);
    5290         872 : }
    5291             : 
    5292      156960 : void CalcIBesselFunc(Real64 const BessFuncArg, int const BessFuncOrd, Real64 &IBessFunc, int &ErrorCode)
    5293             : {
    5294             :     // SUBROUTINE INFORMATION:
    5295             :     //       AUTHOR   Unknown
    5296             :     //       DATE WRITTEN   Unknown
    5297             :     //       DATE REWRITTEN  April 1997 by Russell D. Taylor, Ph.D.
    5298             :     //       MODIFIED
    5299             :     //       RE-ENGINEERED
    5300             : 
    5301             :     // PURPOSE OF THIS SUBROUTINE:
    5302             :     // To calculate the modified Bessel Function from order 0 to BessFuncOrd
    5303             :     // BessFuncArg    ARGUMENT OF BESSEL FUNCTION
    5304             :     // BessFuncOrd    ORDER OF BESSEL FUNCTION, GREATER THAN OR EQUAL TO ZERO
    5305             :     // IBessFunc   RESULTANT VALUE OF I BESSEL FUNCTION
    5306             :     // ErrorCode  RESULTANT ERROR CODE:
    5307             :     //       ErrorCode = 0   NO ERROR
    5308             :     //       ErrorCode = 1   BessFuncOrd .LT. 0
    5309             :     //       ErrorCode = 2   BessFuncArg .LT. 0
    5310             :     //       ErrorCode = 3   IBessFunc .LT. 10**(-30),     IBessFunc IS SET TO 0
    5311             :     //       ErrorCode = 4   BessFuncArg .GT. BessFuncOrd & BessFuncArg .GT. 90,  IBessFunc IS SET TO 10**38
    5312             : 
    5313             :     // REFERENCES:
    5314             :     // First found in MODSIM.
    5315             : 
    5316             :     // USE STATEMENTS:
    5317             :     // na
    5318             : 
    5319             :     // Locals
    5320             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5321             : 
    5322             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5323      156960 :     Real64 constexpr ErrorTol(1.0e-06);
    5324             : 
    5325             :     // INTERFACE BLOCK SPECIFICATIONS
    5326             :     // na
    5327             : 
    5328             :     // DERIVED TYPE DEFINITIONS
    5329             :     // na
    5330             : 
    5331             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5332             :     int LoopCount;
    5333             : 
    5334             :     Real64 FI;
    5335             :     Real64 FK;
    5336             :     Real64 TERM;
    5337             : 
    5338      156960 :     ErrorCode = 0;
    5339      156960 :     IBessFunc = 1.0;
    5340      156960 :     if (BessFuncArg == 0.0 && BessFuncOrd == 0) return;
    5341             : 
    5342      156960 :     if (BessFuncOrd < 0) {
    5343           0 :         ErrorCode = 1;
    5344           0 :         return;
    5345      156960 :     } else if (BessFuncArg < 0.0) {
    5346           0 :         ErrorCode = 2;
    5347           0 :         return;
    5348      156960 :     } else if (BessFuncArg > 12.0 && BessFuncArg > BessFuncOrd) {
    5349           0 :         if (BessFuncArg > 90.0) {
    5350           0 :             ErrorCode = 4;
    5351           0 :             IBessFunc = 1.0e30;
    5352           0 :             return;
    5353             :         }
    5354           0 :         TERM = 1.0;
    5355           0 :         IBessFunc = 1.0;
    5356           0 :         for (LoopCount = 1; LoopCount <= 30; ++LoopCount) { // Start of 1st LoopCount Loop
    5357           0 :             if (std::abs(TERM) <= std::abs(ErrorTol * IBessFunc)) {
    5358           0 :                 IBessFunc *= std::exp(BessFuncArg) / std::sqrt(2.0 * DataGlobalConstants::Pi * BessFuncArg);
    5359           0 :                 return;
    5360             :             }
    5361           0 :             TERM *= 0.125 / BessFuncArg * (pow_2(2 * LoopCount - 1) - 4 * BessFuncOrd * BessFuncOrd) / double(LoopCount);
    5362           0 :             IBessFunc += TERM;
    5363             :         } // End of 1st LoopCount loop
    5364             :     }
    5365             : 
    5366      156960 :     TERM = 1.0;
    5367      156960 :     if (BessFuncOrd > 0) {
    5368      209280 :         for (LoopCount = 1; LoopCount <= BessFuncOrd; ++LoopCount) { // Start of 2nd LoopCount Loop
    5369      104640 :             FI = LoopCount;
    5370      104640 :             if (std::abs(TERM) < 1.0e-30 * FI / (BessFuncArg * 2.0)) {
    5371           0 :                 ErrorCode = 3;
    5372           0 :                 IBessFunc = 0.0;
    5373           0 :                 return;
    5374             :             }
    5375      104640 :             TERM *= BessFuncArg / (2.0 * FI);
    5376             :         } // End of 2nd LoopCount loop
    5377             :     }
    5378             : 
    5379      156960 :     IBessFunc = TERM;
    5380      970432 :     for (LoopCount = 1; LoopCount <= 1000; ++LoopCount) { // Start of 3rd LoopCount Loop
    5381      970432 :         if (std::abs(TERM) <= std::abs(IBessFunc * ErrorTol)) return;
    5382      813472 :         FK = LoopCount * (BessFuncOrd + LoopCount);
    5383      813472 :         TERM *= pow_2(BessFuncArg) / (4.0 * FK);
    5384      813472 :         IBessFunc += TERM;
    5385             :     } // End of  3rd LoopCount loop
    5386             : }
    5387             : 
    5388      156960 : void CalcKBesselFunc(Real64 const BessFuncArg, int const BessFuncOrd, Real64 &KBessFunc, int &ErrorCode)
    5389             : {
    5390             :     // SUBROUTINE INFORMATION:
    5391             :     //       AUTHOR   Unknown
    5392             :     //       DATE WRITTEN   Unknown
    5393             :     //       DATE REWRITTEN  April 1997 by Russell D. Taylor, Ph.D.
    5394             :     //       MODIFIED
    5395             :     //       RE-ENGINEERED
    5396             : 
    5397             :     // PURPOSE OF THIS SUBROUTINE:
    5398             :     // To calculate the K Bessel Function for a given argument and
    5399             :     // order
    5400             :     //  BessFuncArg    THE ARGUMENT OF THE K BESSEL FUNCTION DESIRED
    5401             :     //  BessFuncOrd    THE ORDER OF THE K BESSEL FUNCTION DESIRED
    5402             :     //  KBessFunc   THE RESULTANT K BESSEL FUNCTION
    5403             :     //  ErrorCode  RESULTANT ERROR CODE:
    5404             :     //        ErrorCode=0  NO ERROR
    5405             :     //        ErrorCode=1  BessFuncOrd IS NEGATIVE
    5406             :     //        ErrorCode=2  BessFuncArg IS ZERO OR NEGATIVE
    5407             :     //        ErrorCode=3  BessFuncArg .GT. 85, KBessFunc .LT. 10**-38; KBessFunc SET TO 0.
    5408             :     //        ErrorCode=4  KBessFunc .GT. 10**38; KBessFunc SET TO 10**38
    5409             :     // NOTE: BessFuncOrd MUST BE GREATER THAN OR EQUAL TO ZERO
    5410             :     // METHOD:
    5411             :     //  COMPUTES ZERO ORDER AND FIRST ORDER BESSEL FUNCTIONS USING
    5412             :     //  SERIES APPROXIMATIONS AND THEN COMPUTES BessFuncOrd TH ORDER FUNCTION
    5413             :     //  USING RECURRENCE RELATION.
    5414             :     //  RECURRENCE RELATION AND POLYNOMIAL APPROXIMATION TECHNIQUE
    5415             :     //  AS DESCRIBED BY A.J.M. HITCHCOCK, 'POLYNOMIAL APPROXIMATIONS
    5416             :     //  TO BESSEL FUNCTIONS OF ORDER ZERO AND ONE AND TO RELATED
    5417             :     //  FUNCTIONS,' M.T.A.C., V.11, 1957, PP. 86-88, AND G.BessFuncOrd. WATSON,
    5418             :     //  'A TREATISE ON THE THEORY OF BESSEL FUNCTIONS,' CAMBRIDGE
    5419             :     //  UNIVERSITY PRESS, 1958, P.62
    5420             : 
    5421             :     // USE STATEMENTS:
    5422             :     // na
    5423             : 
    5424             :     // Locals
    5425             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5426             : 
    5427             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5428      156960 :     Real64 constexpr GJMAX(1.0e+38);
    5429             : 
    5430             :     // INTERFACE BLOCK SPECIFICATIONS
    5431             :     // na
    5432             : 
    5433             :     // DERIVED TYPE DEFINITIONS
    5434             :     // na
    5435             : 
    5436             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5437             :     int LoopCount;
    5438             :     bool StopLoop;
    5439             : 
    5440             :     Real64 FACT;
    5441             :     Real64 G0;
    5442             :     Real64 G1;
    5443             :     Real64 GJ;
    5444             :     Real64 HJ;
    5445      156960 :     Array1D<Real64> T(12);
    5446             :     Real64 X2J;
    5447             : 
    5448      156960 :     KBessFunc = 0.0;
    5449      156960 :     G0 = 0.0;
    5450      156960 :     GJ = 0.0;
    5451             : 
    5452      156960 :     if (BessFuncOrd < 0.0) {
    5453           0 :         ErrorCode = 1;
    5454           0 :         return;
    5455      156960 :     } else if (BessFuncArg <= 0.0) {
    5456           0 :         ErrorCode = 2;
    5457           0 :         return;
    5458      156960 :     } else if (BessFuncArg > 85.0) {
    5459           0 :         ErrorCode = 3;
    5460           0 :         KBessFunc = 0.0;
    5461           0 :         return;
    5462             :     }
    5463             : 
    5464      156960 :     ErrorCode = 0;
    5465             : 
    5466             :     //     Use polynomial approximation if BessFuncArg > 1.
    5467             : 
    5468      156960 :     if (BessFuncArg > 1.0) {
    5469       95694 :         T(1) = 1.0 / BessFuncArg;
    5470     1148328 :         for (LoopCount = 2; LoopCount <= 12; ++LoopCount) {
    5471     1052634 :             T(LoopCount) = T(LoopCount - 1) / BessFuncArg;
    5472             :         } // End of LoopCount Loop
    5473       95694 :         if (BessFuncOrd != 1) {
    5474             : 
    5475             :             //     Compute K0 using polynomial approximation
    5476             : 
    5477       82587 :             G0 = std::exp(-BessFuncArg) *
    5478       55058 :                  (1.2533141 - 0.1566642 * T(1) + 0.08811128 * T(2) - 0.09139095 * T(3) + 0.1344596 * T(4) - 0.2299850 * T(5) + 0.3792410 * T(6) -
    5479       55058 :                   0.5247277 * T(7) + 0.5575368 * T(8) - 0.4262633 * T(9) + 0.2184518 * T(10) - 0.06680977 * T(11) + 0.009189383 * T(12)) *
    5480       27529 :                  std::sqrt(1.0 / BessFuncArg);
    5481       27529 :             if (BessFuncOrd == 0) {
    5482       27529 :                 KBessFunc = G0;
    5483       27529 :                 return;
    5484             :             }
    5485             :         }
    5486             : 
    5487             :         //     Compute K1 using polynomial approximation
    5488             : 
    5489      204495 :         G1 = std::exp(-BessFuncArg) *
    5490      136330 :              (1.2533141 + 0.4699927 * T(1) - 0.1468583 * T(2) + 0.1280427 * T(3) - 0.1736432 * T(4) + 0.2847618 * T(5) - 0.4594342 * T(6) +
    5491      136330 :               0.6283381 * T(7) - 0.6632295 * T(8) + 0.5050239 * T(9) - 0.2581304 * T(10) + 0.07880001 * T(11) - 0.01082418 * T(12)) *
    5492       68165 :              std::sqrt(1.0 / BessFuncArg);
    5493       68165 :         if (BessFuncOrd == 1) {
    5494       68165 :             KBessFunc = G1;
    5495       68165 :             return;
    5496             :         }
    5497             :     } else {
    5498             : 
    5499             :         //     Use series expansion if BessFuncArg <= 1.
    5500             : 
    5501       61266 :         if (BessFuncOrd != 1) {
    5502             : 
    5503             :             //     Compute K0 using series expansion
    5504             : 
    5505       24791 :             G0 = -(0.5772157 + std::log(BessFuncArg / 2.0));
    5506       24791 :             X2J = 1.0;
    5507       24791 :             FACT = 1.0;
    5508       24791 :             HJ = 0.0;
    5509      173537 :             for (LoopCount = 1; LoopCount <= 6; ++LoopCount) {
    5510      148746 :                 X2J *= pow_2(BessFuncArg) / 4.0;
    5511      148746 :                 FACT *= pow_2(1.0 / double(LoopCount));
    5512      148746 :                 HJ += 1.0 / double(LoopCount);
    5513      148746 :                 G0 += X2J * FACT * (HJ - (0.5772157 + std::log(BessFuncArg / 2.0)));
    5514             :             } // End of LoopCount Loop
    5515       24791 :             if (BessFuncOrd == 0.0) {
    5516       24791 :                 KBessFunc = G0;
    5517       24791 :                 return;
    5518             :             }
    5519             :         }
    5520             : 
    5521             :         //     Compute K1 using series expansion
    5522             : 
    5523       36475 :         X2J = BessFuncArg / 2.0;
    5524       36475 :         FACT = 1.0;
    5525       36475 :         HJ = 1.0;
    5526       36475 :         G1 = 1.0 / BessFuncArg + X2J * (0.5 + (0.5772157 + std::log(BessFuncArg / 2.0)) - HJ);
    5527      291800 :         for (LoopCount = 2; LoopCount <= 8; ++LoopCount) {
    5528      255325 :             X2J *= pow_2(BessFuncArg) / 4.0;
    5529      255325 :             FACT *= pow_2(1.0 / double(LoopCount));
    5530      255325 :             HJ += 1.0 / double(LoopCount);
    5531      255325 :             G1 += X2J * FACT * (0.5 + ((0.5772157 + std::log(BessFuncArg / 2.0)) - HJ) * double(LoopCount));
    5532             :         } // End of LoopCount Loop
    5533       36475 :         if (BessFuncOrd == 1) {
    5534       36475 :             KBessFunc = G1;
    5535       36475 :             return;
    5536             :         }
    5537             :     }
    5538             : 
    5539             :     //     From K0 and K1 compute KN using recurrence relation
    5540             : 
    5541           0 :     LoopCount = 2;
    5542           0 :     StopLoop = false;
    5543           0 :     while (LoopCount <= BessFuncOrd && !StopLoop) {
    5544           0 :         GJ = 2.0 * (double(LoopCount) - 1.0) * G1 / BessFuncArg + G0;
    5545           0 :         if (GJ - GJMAX > 0.0) {
    5546           0 :             ErrorCode = 4;
    5547           0 :             GJ = GJMAX;
    5548           0 :             StopLoop = true;
    5549             :         } else {
    5550           0 :             G0 = G1;
    5551           0 :             G1 = GJ;
    5552           0 :             ++LoopCount;
    5553             :         }
    5554             :     } // End of LoopCount Loop
    5555           0 :     KBessFunc = GJ;
    5556             : }
    5557             : 
    5558         872 : void CalcPolynomCoef(EnergyPlusData &state, Array2<Real64> const &OrderedPair, Array1D<Real64> &PolynomCoef)
    5559             : {
    5560             :     // SUBROUTINE INFORMATION:
    5561             :     //       AUTHOR   Unknown
    5562             :     //       DATE WRITTEN   Unknown
    5563             :     //       DATE REWRITTEN  April 1997 by Russell D. Taylor, Ph.D.
    5564             :     //       MODIFIED
    5565             :     //       RE-ENGINEERED
    5566             : 
    5567             :     // PURPOSE OF THIS SUBROUTINE:
    5568             :     // Fits polynomial of order from 1 to MaxPolynomOrder to the
    5569             :     // ordered pairs of data points X,Y
    5570             : 
    5571             :     // USE STATEMENTS:
    5572             :     // na
    5573             : 
    5574             :     // Locals
    5575             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5576             : 
    5577             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5578             :     // na
    5579             : 
    5580             :     // INTERFACE BLOCK SPECIFICATIONS
    5581             :     // na
    5582             : 
    5583             :     // DERIVED TYPE DEFINITIONS
    5584             :     // na
    5585             : 
    5586             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5587             :     bool Converged;
    5588             :     Real64 B;
    5589             :     int I;
    5590             :     int II;
    5591             :     int J;
    5592             :     int PolynomOrder;
    5593             :     int CurrentOrder;
    5594             :     int CurrentOrdPair;
    5595             :     Real64 S1;
    5596             :     Real64 S2;
    5597             : 
    5598         872 :     auto &OrdPairSum(state.dataWaterCoils->OrdPairSum);
    5599         872 :     auto &OrdPairSumMatrix(state.dataWaterCoils->OrdPairSumMatrix);
    5600             : 
    5601         872 :     OrdPairSum = 0.0;
    5602         872 :     OrdPairSum(1, 1) = WaterCoils::MaxOrderedPairs;
    5603         872 :     PolynomCoef = 0.0;
    5604       53192 :     for (CurrentOrdPair = 1; CurrentOrdPair <= WaterCoils::MaxOrderedPairs; ++CurrentOrdPair) {
    5605       52320 :         OrdPairSum(2, 1) += OrderedPair(CurrentOrdPair, 1);
    5606       52320 :         OrdPairSum(3, 1) += OrderedPair(CurrentOrdPair, 1) * OrderedPair(CurrentOrdPair, 1);
    5607       52320 :         OrdPairSum(1, 2) += OrderedPair(CurrentOrdPair, 2);
    5608       52320 :         OrdPairSum(2, 2) += OrderedPair(CurrentOrdPair, 1) * OrderedPair(CurrentOrdPair, 2);
    5609             :     }
    5610         872 :     PolynomOrder = 1;
    5611         872 :     Converged = false;
    5612        7848 :     while (!Converged) {
    5613       15696 :         for (CurrentOrder = 1; CurrentOrder <= PolynomOrder + 1; ++CurrentOrder) {
    5614       59296 :             for (J = 1; J <= PolynomOrder + 1; ++J) {
    5615       47088 :                 OrdPairSumMatrix(J, CurrentOrder) = OrdPairSum(J - 1 + CurrentOrder, 1);
    5616             :             } // End of J loop
    5617       12208 :             OrdPairSumMatrix(PolynomOrder + 2, CurrentOrder) = OrdPairSum(CurrentOrder, 2);
    5618             :         } // End of CurrentOrder loop
    5619             : 
    5620       15696 :         for (CurrentOrder = 1; CurrentOrder <= PolynomOrder + 1; ++CurrentOrder) {
    5621       12208 :             OrdPairSumMatrix(CurrentOrder, PolynomOrder + 2) = -1.0;
    5622       41856 :             for (J = CurrentOrder + 1; J <= PolynomOrder + 2; ++J) {
    5623       29648 :                 OrdPairSumMatrix(J, PolynomOrder + 2) = 0.0;
    5624             :             } // End of J loop
    5625             : 
    5626       59296 :             for (II = 2; II <= PolynomOrder + 2; ++II) {
    5627      168296 :                 for (J = CurrentOrder + 1; J <= PolynomOrder + 2; ++J) {
    5628      121208 :                     OrdPairSumMatrix(J, II) -= OrdPairSumMatrix(J, 1) * OrdPairSumMatrix(CurrentOrder, II) / OrdPairSumMatrix(CurrentOrder, 1);
    5629             :                 } // End of J loop
    5630             :             }     // End of II loop
    5631       59296 :             for (II = 1; II <= PolynomOrder + 1; ++II) {
    5632      168296 :                 for (J = CurrentOrder + 1; J <= PolynomOrder + 2; ++J) {
    5633      121208 :                     OrdPairSumMatrix(J, II) = OrdPairSumMatrix(J, II + 1);
    5634             :                 } // End of J loop
    5635             :             }     // End of II loop
    5636             :         }         // End of CurrentOrder loop
    5637             : 
    5638        3488 :         S2 = 0.0;
    5639      212768 :         for (CurrentOrdPair = 1; CurrentOrdPair <= WaterCoils::MaxOrderedPairs; ++CurrentOrdPair) {
    5640      209280 :             S1 = OrdPairSumMatrix(PolynomOrder + 2, 1);
    5641      209280 :             auto const OrderedPair1C(OrderedPair(CurrentOrdPair, 1));
    5642      209280 :             auto OrderedPair1C_pow(1.0);
    5643      732480 :             for (CurrentOrder = 1; CurrentOrder <= PolynomOrder; ++CurrentOrder) {
    5644      523200 :                 OrderedPair1C_pow *= OrderedPair1C;
    5645      523200 :                 S1 += OrdPairSumMatrix(PolynomOrder + 2, CurrentOrder + 1) * OrderedPair1C_pow;
    5646             :             } // End of CurrentOrder loop
    5647      209280 :             S2 += (S1 - OrderedPair(CurrentOrdPair, 2)) * (S1 - OrderedPair(CurrentOrdPair, 2));
    5648             :         } // End of CurrentOrdPair loop
    5649        3488 :         B = WaterCoils::MaxOrderedPairs - (PolynomOrder + 1);
    5650        3488 :         if (S2 > 0.0001) S2 = std::sqrt(S2 / B);
    5651       15696 :         for (CurrentOrder = 1; CurrentOrder <= PolynomOrder + 1; ++CurrentOrder) {
    5652       12208 :             PolynomCoef(CurrentOrder) = OrdPairSumMatrix(PolynomOrder + 2, CurrentOrder);
    5653             :         } // End of CurrentOrder loop
    5654             : 
    5655        3488 :         if ((PolynomOrder - WaterCoils::MaxPolynomOrder < 0) && (S2 - WaterCoils::PolyConvgTol > 0.0)) {
    5656        2616 :             ++PolynomOrder;
    5657        2616 :             J = 2 * PolynomOrder;
    5658        2616 :             OrdPairSum(J, 1) = OrdPairSum(J + 1, 1) = 0.0;
    5659        2616 :             auto OrdPairSum2P = OrdPairSum(PolynomOrder + 1, 2) = 0.0;
    5660      159576 :             for (I = 1; I <= WaterCoils::MaxOrderedPairs; ++I) {
    5661      156960 :                 auto const OrderedPair1I(OrderedPair(I, 1));
    5662      156960 :                 auto OrderedPair_pow(std::pow(OrderedPair1I, J - 1));
    5663      156960 :                 OrdPairSum(J, 1) += OrderedPair_pow;
    5664      156960 :                 OrderedPair_pow *= OrderedPair1I;
    5665      156960 :                 OrdPairSum(J + 1, 1) += OrderedPair_pow;
    5666      156960 :                 OrdPairSum2P += OrderedPair(I, 2) * std::pow(OrderedPair1I, PolynomOrder);
    5667             :             }
    5668        2616 :             OrdPairSum(PolynomOrder + 1, 2) = OrdPairSum2P;
    5669             :         } else {
    5670         872 :             Converged = true;
    5671             :         }
    5672             :     }
    5673         872 : }
    5674             : 
    5675             : // Iterate Routine for Cooling Coil
    5676             : 
    5677     4038163 : void CoilAreaFracIter(Real64 &NewSurfAreaWetFrac,       // Out Value of variable
    5678             :                       Real64 const SurfAreaFracCurrent, // Driver Value
    5679             :                       Real64 const ErrorCurrent,        // Objective Function
    5680             :                       Real64 &SurfAreaFracPrevious,     // First Previous value of Surf Area Fraction
    5681             :                       Real64 &ErrorPrevious,            // First Previous value of error
    5682             :                       Real64 &SurfAreaFracLast,         // Second Previous value of Surf Area Fraction
    5683             :                       Real64 &ErrorLast,                // Second Previous value of error
    5684             :                       int const IterNum,                // Number of Iterations
    5685             :                       int &icvg                         // Iteration convergence flag
    5686             : )
    5687             : {
    5688             :     // FUNCTION INFORMATION:
    5689             :     // AUTHOR         Rahul Chillar
    5690             :     // DATE WRITTEN   June 2004
    5691             :     // MODIFIED       na
    5692             :     // RE-ENGINEERED  na
    5693             : 
    5694             :     // PURPOSE OF THIS FUNCTION:
    5695             :     // Iterately solves for the value of SurfAreaWetFraction for the Cooling Coil.
    5696             : 
    5697             :     // METHODOLOGY EMPLOYED:
    5698             :     // First function generates 2 sets of guess points by perturbation and subsequently
    5699             :     // by Linear Fit and using the generated points calculates coeffecients for Quadratic
    5700             :     // fit to predict the next value of surface area wet fraction.
    5701             : 
    5702             :     // REFERENCES:
    5703             :     // ME 423 Design of Thermal Systems Class Notes.UIUC. W.F.Stoecker
    5704             : 
    5705             :     // USE STATEMENTS:
    5706             :     // na
    5707             : 
    5708             :     // Enforce explicit typing of all variables in this routine
    5709             : 
    5710             :     // Locals
    5711             :     // FUNCTION ARGUMENT DEFINITIONS:
    5712             : 
    5713             :     // FUNCTION PARAMETER DEFINITIONS:
    5714     4038163 :     Real64 constexpr Tolerance(1.e-5);         // Relative error tolerance
    5715     4038163 :     Real64 constexpr PerturbSurfAreaFrac(0.1); // Perturbation applied to Surf Fraction to initialize iteration
    5716     4038163 :     Real64 constexpr SmallNum(1.e-9);          // Small Number
    5717             : 
    5718             :     // INTERFACE BLOCK SPECIFICATIONS
    5719             :     // na
    5720             : 
    5721             :     // DERIVED TYPE DEFINITIONS
    5722             :     // na
    5723             : 
    5724             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    5725             :     Real64 check;             // Validity Check for moving to Quad Solution
    5726             :     Real64 QuadCoefThree;     // Term under radical in quadratic solution
    5727             :     Real64 QuadCoefOne;       // Term under radical in quadratic solution
    5728             :     Real64 QuadCoefTwo;       // Term under radical in quadratic solution
    5729             :     Real64 Slope;             // Slope for linear fit
    5730             :     Real64 SurfAreaFracOther; // Intermediate Value of Surf Area
    5731             :     int mode;                 // Linear/ perturbation option
    5732             : 
    5733             :     // Convergence Check  by comparing previous and current value of surf area fraction
    5734     4038163 :     if ((std::abs(SurfAreaFracCurrent - SurfAreaFracPrevious) < Tolerance * max(std::abs(SurfAreaFracCurrent), SmallNum) && IterNum != 1) ||
    5735             :         ErrorCurrent == 0.0) {
    5736             :         // Setting value for surface area fraction for coil
    5737      706219 :         NewSurfAreaWetFrac = SurfAreaFracCurrent;
    5738      706219 :         icvg = 1; // Convergance Flag
    5739      706219 :         return;
    5740             :     }
    5741             : 
    5742             :     // If Icvg = 0 , it has not converged.By perturbation for getting second set of
    5743             :     // data (mode=1), Getting Third set of data by performing a  linear fit(Mode=2).
    5744             :     // Now using the above 3 points generated by perturbation and Linear Fit to perform
    5745             :     // a quadratic fit.This will happen after second iteration only.
    5746     3331944 :     icvg = 0; // Convergance flag = false
    5747             :     // For First Iteration Start with perturbation, For second iteration start with linear fit
    5748             :     // from the previous two values
    5749     3331944 :     mode = IterNum;
    5750             : 
    5751     3374290 : Label10:;
    5752     3374290 :     if (mode == 1) {
    5753             : 
    5754             :         // FirstGuess Set of Points provided by perturbation
    5755      706220 :         if (std::abs(SurfAreaFracCurrent) > SmallNum) {
    5756      706220 :             NewSurfAreaWetFrac = SurfAreaFracCurrent * (1.0 + PerturbSurfAreaFrac);
    5757             :         } else {
    5758           0 :             NewSurfAreaWetFrac = PerturbSurfAreaFrac;
    5759             :         }
    5760             : 
    5761             :         // Second set of values being calculated from the first set of values (incoming & perturb)
    5762     2668070 :     } else if (mode == 2) {
    5763             : 
    5764             :         // Calculating Slope for interpolating to the New Point (Simple Linear Extrapolation)
    5765      748564 :         Slope = (ErrorPrevious - ErrorCurrent) / (SurfAreaFracPrevious - SurfAreaFracCurrent);
    5766             :         // Error Check for value or Slope
    5767      748564 :         if (Slope == 0.0) {
    5768           1 :             mode = 1; // Go back to Perturbation
    5769           1 :             goto Label10;
    5770             :         }
    5771             :         // Guessing New Value for Surface Area Fraction
    5772      748563 :         NewSurfAreaWetFrac = SurfAreaFracCurrent - ErrorCurrent / Slope;
    5773             :     } else {
    5774             : 
    5775             :         // Check for Quadratic Fit possible here ,Previous value of surf area fraction
    5776             :         // equals current value then Try linear fit for another point.
    5777     1919506 :         if (SurfAreaFracCurrent == SurfAreaFracPrevious) {
    5778             :             // Assign Value of previous point to Last Variable for storing
    5779             :             // Go back and calculate new value for Previous.
    5780           0 :             SurfAreaFracPrevious = SurfAreaFracLast;
    5781           0 :             ErrorPrevious = ErrorLast;
    5782           0 :             mode = 2;
    5783           0 :             goto Label10;
    5784     1919506 :         } else if (SurfAreaFracCurrent == SurfAreaFracLast) {
    5785             :             // Calculate another value using Linear Fit.
    5786       25980 :             mode = 2;
    5787       25980 :             goto Label10;
    5788             :         }
    5789             : 
    5790             :         // Now We have enough previous points to calculate coefficients and
    5791             :         // perform a quadratic fit for new guess value of surface area fraction
    5792             : 
    5793             :         // Calculating First Coefficients for Quadratic Curve Fit
    5794     5680578 :         QuadCoefThree = ((ErrorLast - ErrorCurrent) / (SurfAreaFracLast - SurfAreaFracCurrent) -
    5795     1893526 :                          (ErrorPrevious - ErrorCurrent) / (SurfAreaFracPrevious - SurfAreaFracCurrent)) /
    5796     1893526 :                         (SurfAreaFracLast - SurfAreaFracPrevious);
    5797             :         // Calculating Second Coefficients for Quadratic Curve Fit
    5798     3787052 :         QuadCoefTwo = (ErrorPrevious - ErrorCurrent) / (SurfAreaFracPrevious - SurfAreaFracCurrent) -
    5799     1893526 :                       (SurfAreaFracPrevious + SurfAreaFracCurrent) * QuadCoefThree;
    5800             : 
    5801             :         // Calculating Third Coefficients for Quadratic Curve Fit
    5802     1893526 :         QuadCoefOne = ErrorCurrent - (QuadCoefTwo + QuadCoefThree * SurfAreaFracCurrent) * SurfAreaFracCurrent;
    5803             : 
    5804             :         // Check for validity of coefficients , if not REAL(r64) ,Then fit is linear
    5805     1893526 :         if (std::abs(QuadCoefThree) < 1.E-10) {
    5806           0 :             mode = 2; // going to Linear mode, due to colinear points.
    5807           0 :             goto Label10;
    5808             :         }
    5809             : 
    5810             :         // If value of Quadratic coefficients not suitable enought due to round off errors
    5811             :         // to predict new point go to linear fit and acertain new values for the coefficients.
    5812     1893526 :         if (std::abs((QuadCoefOne + (QuadCoefTwo + QuadCoefThree * SurfAreaFracPrevious) * SurfAreaFracPrevious - ErrorPrevious) / ErrorPrevious) >
    5813             :             1.E-4) {
    5814           5 :             mode = 2; // go to linear mode
    5815           5 :             goto Label10;
    5816             :         }
    5817             : 
    5818             :         // Validity Check for Imaginary roots, In this case go back to linear fit.
    5819     1893521 :         check = pow_2(QuadCoefTwo) - 4.0 * QuadCoefOne * QuadCoefThree;
    5820             :         // Imaginary Root Exist
    5821     1893521 :         if (check < 0) {
    5822       16360 :             mode = 2;
    5823       16360 :             goto Label10;
    5824     1877161 :         } else if (check > 0) {
    5825             :             // real unequal roots exist, Determine the roots nearest to most recent guess
    5826     1877134 :             NewSurfAreaWetFrac = (-QuadCoefTwo + std::sqrt(check)) / QuadCoefThree / 2.0;
    5827     1877134 :             SurfAreaFracOther = -NewSurfAreaWetFrac - QuadCoefTwo / QuadCoefThree;
    5828             :             // Assigning value to Surface Area Fraction with recent
    5829     1877134 :             if (std::abs(NewSurfAreaWetFrac - SurfAreaFracCurrent) > std::abs(SurfAreaFracOther - SurfAreaFracCurrent))
    5830        3271 :                 NewSurfAreaWetFrac = SurfAreaFracOther;
    5831             :         } else {
    5832             :             // The roots are real, one solution exists.
    5833          27 :             NewSurfAreaWetFrac = -QuadCoefTwo / QuadCoefThree / 2;
    5834             :         }
    5835             :     }
    5836             : 
    5837     3331944 :     if (mode < 3) {
    5838             :         // No valid previous points to eliminate, since it just has 2 points.
    5839             :         // Loading previous values into last
    5840     1454783 :         SurfAreaFracLast = SurfAreaFracPrevious;
    5841     1454783 :         ErrorLast = ErrorPrevious;
    5842             :         // Loading Current Values into previous
    5843     1454783 :         SurfAreaFracPrevious = SurfAreaFracCurrent;
    5844     1454783 :         ErrorPrevious = ErrorCurrent;
    5845             :     } else {
    5846             : 
    5847             :         // Elimination the most distance previous point from the answer based on sign and
    5848             :         // magnitute of the error. Keeping Current Point
    5849     1877161 :         if (ErrorPrevious * ErrorCurrent > 0 && ErrorLast * ErrorCurrent > 0) {
    5850             :             // If sign are same , simply eliminate the one with biggest error value.
    5851      471122 :             if (std::abs(ErrorLast) > std::abs(ErrorPrevious)) {
    5852             :                 // Eliminating Last Value
    5853       96672 :                 SurfAreaFracLast = SurfAreaFracPrevious;
    5854       96672 :                 ErrorLast = ErrorPrevious;
    5855             :             }
    5856             :         } else {
    5857             :             // If signs are different eliminate previous error with same sign as current error
    5858     1641600 :             if (ErrorLast * ErrorCurrent > 0) {
    5859             :                 // Previous Loaded to Last
    5860      511195 :                 SurfAreaFracLast = SurfAreaFracPrevious;
    5861      511195 :                 ErrorLast = ErrorPrevious;
    5862             :             }
    5863             :         }
    5864             :         // Current Loaded into previous.
    5865     1877161 :         SurfAreaFracPrevious = SurfAreaFracCurrent;
    5866     1877161 :         ErrorPrevious = ErrorCurrent;
    5867             :     }
    5868             : }
    5869             : 
    5870      279206 : void CheckWaterCoilSchedule(EnergyPlusData &state, std::string_view CompName, Real64 &Value, int &CompIndex)
    5871             : {
    5872             : 
    5873             :     // SUBROUTINE INFORMATION:
    5874             :     //       AUTHOR         Linda Lawrie
    5875             :     //       DATE WRITTEN   October 2005
    5876             :     //       MODIFIED       na
    5877             :     //       RE-ENGINEERED  na
    5878             : 
    5879             :     // PURPOSE OF THIS SUBROUTINE:
    5880             :     // <description>
    5881             : 
    5882             :     // Using/Aliasing
    5883             : 
    5884             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5885             :     int CoilNum;
    5886             : 
    5887             :     // Obtains and Allocates WaterCoil related parameters from input file
    5888      279206 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) { // First time subroutine has been entered
    5889           0 :         GetWaterCoilInput(state);
    5890           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    5891             :     }
    5892             : 
    5893             :     // Find the correct Coil number
    5894      279206 :     if (CompIndex == 0) {
    5895           8 :         CoilNum = UtilityRoutines::FindItemInList(CompName, state.dataWaterCoils->WaterCoil);
    5896           8 :         if (CoilNum == 0) {
    5897           0 :             ShowFatalError(state, "CheckWaterCoilSchedule: Coil not found=" + std::string{CompName});
    5898             :         }
    5899           8 :         CompIndex = CoilNum;
    5900           8 :         Value = GetCurrentScheduleValue(state, state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr); // not scheduled?
    5901             :     } else {
    5902      279198 :         CoilNum = CompIndex;
    5903      279198 :         if (CoilNum > state.dataWaterCoils->NumWaterCoils || CoilNum < 1) {
    5904           0 :             ShowFatalError(state,
    5905           0 :                            format("CheckWaterCoilSchedule: Invalid CompIndex passed={}, Number of Heating Coils={}, Coil name={}",
    5906             :                                   CoilNum,
    5907           0 :                                   state.dataWaterCoils->NumWaterCoils,
    5908           0 :                                   CompName));
    5909             :         }
    5910      279198 :         if (CompName != state.dataWaterCoils->WaterCoil(CoilNum).Name) {
    5911           0 :             ShowFatalError(state,
    5912           0 :                            format("CheckWaterCoilSchedule: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
    5913             :                                   CoilNum,
    5914             :                                   CompName,
    5915           0 :                                   state.dataWaterCoils->WaterCoil(CoilNum).Name));
    5916             :         }
    5917      279198 :         Value = GetCurrentScheduleValue(state, state.dataWaterCoils->WaterCoil(CoilNum).SchedPtr); // not scheduled?
    5918             :     }
    5919      279206 : }
    5920             : 
    5921         137 : Real64 GetCoilMaxWaterFlowRate(EnergyPlusData &state,
    5922             :                                std::string_view CoilType,   // must match coil types in this module
    5923             :                                std::string const &CoilName, // must match coil names for the coil type
    5924             :                                bool &ErrorsFound            // set to true if problem
    5925             : )
    5926             : {
    5927             : 
    5928             :     // FUNCTION INFORMATION:
    5929             :     //       AUTHOR         Linda Lawrie
    5930             :     //       DATE WRITTEN   November 2006
    5931             :     //       MODIFIED       na
    5932             :     //       RE-ENGINEERED  na
    5933             : 
    5934             :     // PURPOSE OF THIS FUNCTION:
    5935             :     // This function looks up the max water flow rate for the given coil and returns it.  If
    5936             :     // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
    5937             :     // as negative.
    5938             : 
    5939             :     // Return value
    5940             :     Real64 MaxWaterFlowRate; // returned max water flow rate of matched coil
    5941             : 
    5942             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    5943             :     int WhichCoil;
    5944             : 
    5945             :     // Obtains and Allocates WaterCoil related parameters from input file
    5946         137 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) { // First time subroutine has been entered
    5947           2 :         GetWaterCoilInput(state);
    5948           2 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    5949             :     }
    5950             : 
    5951         137 :     WhichCoil = 0;
    5952         330 :     if (UtilityRoutines::SameString(CoilType, "Coil:Heating:Water") || UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water:DetailedGeometry") ||
    5953         193 :         UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water")) {
    5954         137 :         WhichCoil = UtilityRoutines::FindItem(CoilName, state.dataWaterCoils->WaterCoil);
    5955         137 :         if (WhichCoil != 0) {
    5956             :             // coil does not specify MaxWaterFlowRate
    5957         137 :             MaxWaterFlowRate = state.dataWaterCoils->WaterCoil(WhichCoil).MaxWaterVolFlowRate;
    5958             :         }
    5959             :     } else {
    5960           0 :         WhichCoil = 0;
    5961             :     }
    5962             : 
    5963         137 :     if (WhichCoil == 0) {
    5964           0 :         ShowSevereError(state, format("GetCoilMaxWaterFlowRate: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    5965           0 :         ShowContinueError(state, "... Max Water Flow rate returned as -1000.");
    5966           0 :         ErrorsFound = true;
    5967           0 :         MaxWaterFlowRate = -1000.0;
    5968             :     }
    5969             : 
    5970         137 :     return MaxWaterFlowRate;
    5971             : }
    5972             : 
    5973         185 : int GetCoilInletNode(EnergyPlusData &state,
    5974             :                      std::string_view CoilType,   // must match coil types in this module
    5975             :                      std::string const &CoilName, // must match coil names for the coil type
    5976             :                      bool &ErrorsFound            // set to true if problem
    5977             : )
    5978             : {
    5979             : 
    5980             :     // FUNCTION INFORMATION:
    5981             :     //       AUTHOR         R. Raustad
    5982             :     //       DATE WRITTEN   March 2007
    5983             :     //       MODIFIED       na
    5984             :     //       RE-ENGINEERED  na
    5985             : 
    5986             :     // PURPOSE OF THIS FUNCTION:
    5987             :     // This function looks up the given coil and returns the inlet node number.  If
    5988             :     // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    5989             :     // as zero.
    5990             : 
    5991             :     // Return value
    5992             :     int NodeNumber; // returned node number of matched coil
    5993             : 
    5994             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    5995             :     int WhichCoil;
    5996             : 
    5997             :     // Obtains and Allocates DXCoils
    5998         185 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    5999           0 :         GetWaterCoilInput(state);
    6000           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6001             :     }
    6002             : 
    6003         185 :     NodeNumber = 0;
    6004         185 :     WhichCoil = 0;
    6005         460 :     if (UtilityRoutines::SameString(CoilType, "Coil:Heating:Water") || UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water:DetailedGeometry") ||
    6006         275 :         UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water")) {
    6007         185 :         WhichCoil = UtilityRoutines::FindItem(CoilName, state.dataWaterCoils->WaterCoil);
    6008         185 :         if (WhichCoil != 0) {
    6009         185 :             NodeNumber = state.dataWaterCoils->WaterCoil(WhichCoil).AirInletNodeNum;
    6010             :         }
    6011             :     } else {
    6012           0 :         WhichCoil = 0;
    6013             :     }
    6014             : 
    6015         185 :     if (WhichCoil == 0) {
    6016           0 :         ShowSevereError(state, format("GetCoilInletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    6017           0 :         ErrorsFound = true;
    6018           0 :         NodeNumber = 0;
    6019             :     }
    6020             : 
    6021         185 :     return NodeNumber;
    6022             : }
    6023             : 
    6024         191 : int GetCoilOutletNode(EnergyPlusData &state,
    6025             :                       std::string_view CoilType,   // must match coil types in this module
    6026             :                       std::string const &CoilName, // must match coil names for the coil type
    6027             :                       bool &ErrorsFound            // set to true if problem
    6028             : )
    6029             : {
    6030             : 
    6031             :     // FUNCTION INFORMATION:
    6032             :     //       AUTHOR         R. Raustad
    6033             :     //       DATE WRITTEN   March 2007
    6034             :     //       MODIFIED       na
    6035             :     //       RE-ENGINEERED  na
    6036             : 
    6037             :     // PURPOSE OF THIS FUNCTION:
    6038             :     // This function looks up the given coil and returns the inlet node number.  If
    6039             :     // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    6040             :     // as zero.
    6041             : 
    6042             :     // Return value
    6043             :     int NodeNumber; // returned node number of matched coil
    6044             : 
    6045             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6046             :     int WhichCoil;
    6047             : 
    6048             :     // Obtains and Allocates DXCoils
    6049         191 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6050           0 :         GetWaterCoilInput(state);
    6051           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6052             :     }
    6053             : 
    6054         191 :     WhichCoil = 0;
    6055         191 :     NodeNumber = 0;
    6056         470 :     if (UtilityRoutines::SameString(CoilType, "Coil:Heating:Water") || UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water:DetailedGeometry") ||
    6057         279 :         UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water")) {
    6058         191 :         WhichCoil = UtilityRoutines::FindItem(CoilName, state.dataWaterCoils->WaterCoil);
    6059         191 :         if (WhichCoil != 0) {
    6060         191 :             NodeNumber = state.dataWaterCoils->WaterCoil(WhichCoil).AirOutletNodeNum;
    6061             :         }
    6062             :     } else {
    6063           0 :         WhichCoil = 0;
    6064             :     }
    6065             : 
    6066         191 :     if (WhichCoil == 0) {
    6067           0 :         ShowSevereError(
    6068             :             state,
    6069           0 :             format("GetCoilOutletNode: Could not find Coil, Type=\"{}\" Name=\"{}\" when accessing coil outlet node number.", CoilType, CoilName));
    6070           0 :         ErrorsFound = true;
    6071           0 :         NodeNumber = 0;
    6072             :     }
    6073             : 
    6074         191 :     return NodeNumber;
    6075             : }
    6076             : 
    6077        5157 : int GetCoilWaterInletNode(EnergyPlusData &state,
    6078             :                           std::string_view CoilType,   // must match coil types in this module
    6079             :                           std::string const &CoilName, // must match coil names for the coil type
    6080             :                           bool &ErrorsFound            // set to true if problem
    6081             : )
    6082             : {
    6083             : 
    6084             :     // FUNCTION INFORMATION:
    6085             :     //       AUTHOR         R. Raustad
    6086             :     //       DATE WRITTEN   July 2007
    6087             :     //       MODIFIED       na
    6088             :     //       RE-ENGINEERED  na
    6089             : 
    6090             :     // PURPOSE OF THIS FUNCTION:
    6091             :     // This function looks up the given coil and returns the inlet water control node number.  If
    6092             :     // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    6093             :     // as zero.
    6094             : 
    6095             :     // Return value
    6096             :     int NodeNumber; // returned node number of matched coil
    6097             : 
    6098             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6099             :     int WhichCoil;
    6100             : 
    6101             :     // Obtains and Allocates DXCoils
    6102        5157 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6103         297 :         GetWaterCoilInput(state);
    6104         297 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6105             :     }
    6106             : 
    6107        5157 :     NodeNumber = 0;
    6108        5157 :     WhichCoil = 0;
    6109       10812 :     if (UtilityRoutines::SameString(CoilType, "Coil:Heating:Water") || UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water:DetailedGeometry") ||
    6110        5655 :         UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water")) {
    6111        5157 :         WhichCoil = UtilityRoutines::FindItem(CoilName, state.dataWaterCoils->WaterCoil);
    6112        5157 :         if (WhichCoil != 0) {
    6113        5157 :             NodeNumber = state.dataWaterCoils->WaterCoil(WhichCoil).WaterInletNodeNum;
    6114             :         }
    6115             :     } else {
    6116           0 :         WhichCoil = 0;
    6117             :     }
    6118             : 
    6119        5157 :     if (WhichCoil == 0) {
    6120           0 :         ShowSevereError(state, format("GetCoilWaterInletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    6121           0 :         ErrorsFound = true;
    6122           0 :         NodeNumber = 0;
    6123             :     }
    6124             : 
    6125        5157 :     return NodeNumber;
    6126             : }
    6127             : 
    6128        2024 : int GetCoilWaterOutletNode(EnergyPlusData &state,
    6129             :                            std::string_view CoilType,   // must match coil types in this module
    6130             :                            std::string const &CoilName, // must match coil names for the coil type
    6131             :                            bool &ErrorsFound            // set to true if problem
    6132             : )
    6133             : {
    6134             : 
    6135             :     // FUNCTION INFORMATION:
    6136             :     //       AUTHOR         R. Raustad
    6137             :     //       DATE WRITTEN   July 2007
    6138             :     //       MODIFIED       na
    6139             :     //       RE-ENGINEERED  na
    6140             : 
    6141             :     // PURPOSE OF THIS FUNCTION:
    6142             :     // This function looks up the given coil and returns the outlet water node number.  If
    6143             :     // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
    6144             :     // as zero.
    6145             : 
    6146             :     // Return value
    6147             :     int NodeNumber; // returned node number of matched coil
    6148             : 
    6149             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6150             :     int WhichCoil;
    6151             : 
    6152             :     // Obtains and Allocates DXCoils
    6153        2024 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6154           0 :         GetWaterCoilInput(state);
    6155           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6156             :     }
    6157             : 
    6158        2024 :     NodeNumber = 0;
    6159        2024 :     WhichCoil = 0;
    6160        4145 :     if (UtilityRoutines::SameString(CoilType, "Coil:Heating:Water") || UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water:DetailedGeometry") ||
    6161        2121 :         UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water")) {
    6162        2024 :         WhichCoil = UtilityRoutines::FindItem(CoilName, state.dataWaterCoils->WaterCoil);
    6163        2024 :         if (WhichCoil != 0) {
    6164        2024 :             NodeNumber = state.dataWaterCoils->WaterCoil(WhichCoil).WaterOutletNodeNum;
    6165             :         }
    6166             :     } else {
    6167           0 :         WhichCoil = 0;
    6168             :     }
    6169             : 
    6170        2024 :     if (WhichCoil == 0) {
    6171           0 :         ShowSevereError(state, format("GetCoilWaterOutletNode: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    6172           0 :         ErrorsFound = true;
    6173           0 :         NodeNumber = 0;
    6174             :     }
    6175             : 
    6176        2024 :     return NodeNumber;
    6177             : }
    6178             : 
    6179        2882 : void SetCoilDesFlow(EnergyPlusData &state,
    6180             :                     std::string_view CoilType,   // must match coil types in this module
    6181             :                     std::string const &CoilName, // must match coil names for the coil type
    6182             :                     Real64 const CoilDesFlow,    // coil volumetric air flow rate [m3/s]
    6183             :                     bool &ErrorsFound            // set to true if problem
    6184             : )
    6185             : {
    6186             : 
    6187             :     // SUBROUTINE INFORMATION:
    6188             :     //       AUTHOR         Fred Buhl
    6189             :     //       DATE WRITTEN   May 2009
    6190             :     //       MODIFIED       na
    6191             :     //       RE-ENGINEERED  na
    6192             : 
    6193             :     // PURPOSE OF THIS SUBROUTINE:
    6194             :     // This routine is designed to set the design air volume flow rate in the
    6195             :     // water coil data structure. Some of the coil types do not have this datum as
    6196             :     // an input parameter and it is needed for calculating capacity for output reporting.
    6197             : 
    6198             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6199             :     int WhichCoil; // index to coil
    6200             : 
    6201        2882 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) { // First time subroutine has been entered
    6202          11 :         GetWaterCoilInput(state);
    6203          11 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6204             :     }
    6205             : 
    6206        5948 :     if (UtilityRoutines::SameString(CoilType, "Coil:Heating:Water") || UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water:DetailedGeometry") ||
    6207        3066 :         UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water")) {
    6208        2792 :         WhichCoil = UtilityRoutines::FindItem(CoilName, state.dataWaterCoils->WaterCoil);
    6209        2792 :         if (WhichCoil != 0) {
    6210        2792 :             if (state.dataWaterCoils->WaterCoil(WhichCoil).DesAirVolFlowRate <= 0.0) {
    6211        2783 :                 state.dataWaterCoils->WaterCoil(WhichCoil).DesAirVolFlowRate = CoilDesFlow;
    6212             :             } else {
    6213             :                 // WaterCoil(WhichCoil).DesAirVolFlowRate = CoilDesFlow;
    6214             :             }
    6215             :         } else {
    6216           0 :             ShowSevereError(state, format("GetCoilMaxWaterFlowRate: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
    6217           0 :             ErrorsFound = true;
    6218             :         }
    6219             :     }
    6220        2882 : }
    6221             : 
    6222           0 : Real64 GetWaterCoilDesAirFlow(EnergyPlusData &state,
    6223             :                               std::string const &CoilType, // must match coil types in this module
    6224             :                               std::string const &CoilName, // must match coil names for the coil type
    6225             :                               bool &ErrorsFound            // set to true if problem
    6226             : )
    6227             : {
    6228             : 
    6229             :     // SUBROUTINE INFORMATION:
    6230             :     //       AUTHOR         Fred Buhl
    6231             :     //       DATE WRITTEN   May 2009
    6232             :     //       MODIFIED       na
    6233             :     //       RE-ENGINEERED  na
    6234             : 
    6235             :     // PURPOSE OF THIS SUBROUTINE:
    6236             :     // This routine is designed to set the design air volume flow rate in the
    6237             :     // water coil data structure. Some of the coil types do not have this datum as
    6238             :     // an input parameter and it is needed for calculating capacity for output reporting.
    6239             : 
    6240             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6241             :     int WhichCoil; // index to coil
    6242             :     Real64 CoilDesAirFlow;
    6243             : 
    6244           0 :     CoilDesAirFlow = 0.0;
    6245             : 
    6246           0 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) { // First time subroutine has been entered
    6247           0 :         GetWaterCoilInput(state);
    6248           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6249             :     }
    6250             : 
    6251           0 :     if (UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water")) {
    6252           0 :         WhichCoil = UtilityRoutines::FindItem(CoilName, state.dataWaterCoils->WaterCoil);
    6253           0 :         if (WhichCoil != 0) {
    6254           0 :             CoilDesAirFlow = state.dataWaterCoils->WaterCoil(WhichCoil).DesAirVolFlowRate;
    6255             :         } else {
    6256           0 :             ShowSevereError(state, "GetWaterCoilDesAirFlowRate: Could not find Coil, Type=\"" + CoilType + "\" Name=\"" + CoilName + "\"");
    6257           0 :             ErrorsFound = true;
    6258             :         }
    6259             :     } else {
    6260           0 :         ShowSevereError(state, "GetWaterCoilDesAirFlowRate: Funciton not valid for Coil, Type=\"" + CoilType + "\" Name=\"" + CoilName + "\"");
    6261           0 :         ErrorsFound = true;
    6262             :     }
    6263             : 
    6264           0 :     return CoilDesAirFlow;
    6265             : }
    6266             : 
    6267         822 : void CheckActuatorNode(EnergyPlusData &state,
    6268             :                        int const ActuatorNodeNum,                    // input actuator node number
    6269             :                        DataPlant::PlantEquipmentType &WaterCoilType, // Cooling or Heating or 0
    6270             :                        bool &NodeNotFound                            // true if matching water inlet node not found
    6271             : )
    6272             : {
    6273             : 
    6274             :     // SUBROUTINE INFORMATION:
    6275             :     //       AUTHOR         Fred Buhl
    6276             :     //       DATE WRITTEN   January 2009
    6277             :     //       MODIFIED       na
    6278             :     //       RE-ENGINEERED  na
    6279             : 
    6280             :     // PURPOSE OF THIS FUNCTION:
    6281             :     // This subroutine checks that the input actuator node number is matched by
    6282             :     // the water inlet node number of some water coil
    6283             : 
    6284             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6285             :     int WhichCoil;
    6286             :     int CoilNum;
    6287             : 
    6288             :     // Obtains and Allocates DXCoils
    6289         822 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6290           0 :         GetWaterCoilInput(state);
    6291           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6292             :     }
    6293             : 
    6294         822 :     WhichCoil = 0;
    6295         822 :     WaterCoilType = DataPlant::PlantEquipmentType::Invalid;
    6296         822 :     NodeNotFound = true;
    6297       25324 :     for (CoilNum = 1; CoilNum <= state.dataWaterCoils->NumWaterCoils; ++CoilNum) {
    6298       24502 :         if (state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum == ActuatorNodeNum) {
    6299         822 :             WhichCoil = CoilNum;
    6300         822 :             WaterCoilType = state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType;
    6301         822 :             NodeNotFound = false;
    6302             :         }
    6303             :     }
    6304         822 : }
    6305             : 
    6306         822 : void CheckForSensorAndSetPointNode(EnergyPlusData &state,
    6307             :                                    int const SensorNodeNum,                          // controller sensor node number
    6308             :                                    HVACControllers::CtrlVarType const ControlledVar, // controlled variable type
    6309             :                                    bool &NodeNotFound                                // true if matching air outlet node not found
    6310             : )
    6311             : {
    6312             : 
    6313             :     // SUBROUTINE INFORMATION:
    6314             :     //       AUTHOR         Bereket Nigusse
    6315             :     //       DATE WRITTEN   March 2013
    6316             :     //       MODIFIED       na
    6317             :     //       RE-ENGINEERED  na
    6318             : 
    6319             :     // PURPOSE OF THIS SUBROUTINE:
    6320             :     // This subroutine checks that the sensor node number matches the air outlet node number
    6321             :     // of some water coils
    6322             : 
    6323             :     // Using/Aliasing
    6324             :     using EMSManager::CheckIfNodeSetPointManagedByEMS;
    6325             :     using SetPointManager::CtrlVarType;
    6326             :     using SetPointManager::NodeHasSPMCtrlVarType;
    6327             : 
    6328             :     // SUBROUTINE PARAMETER DEFINITIONS:
    6329             :     static constexpr std::string_view RoutineName("CheckForSensorAndSetpointNode: ");
    6330             : 
    6331             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6332             :     int WhichCoil;             // water coil index
    6333             :     int CoilNum;               // counter
    6334        1644 :     std::string WaterCoilType; // water coil type
    6335             :     bool EMSSetPointErrorFlag; // flag true is EMS is used to set node setpoints
    6336             : 
    6337             :     // Obtains and Allocates DXCoils
    6338         822 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6339           2 :         GetWaterCoilInput(state);
    6340           2 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6341             :     }
    6342             : 
    6343         822 :     WhichCoil = 0;
    6344         822 :     NodeNotFound = true;
    6345             : 
    6346       21064 :     for (CoilNum = 1; CoilNum <= state.dataWaterCoils->NumWaterCoils; ++CoilNum) {
    6347       21064 :         if (SensorNodeNum != state.dataWaterCoils->WaterCoil(CoilNum).AirOutletNodeNum) continue;
    6348         822 :         NodeNotFound = false;
    6349         822 :         WhichCoil = CoilNum;
    6350         822 :         break;
    6351             :     }
    6352             :     // now if the sensor node is on the water coil air outlet node then check that
    6353             :     // a setpoint is also specified on the water coil outlet node
    6354         822 :     if (!NodeNotFound) {
    6355         822 :         if (WhichCoil > 0) {
    6356         822 :             if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling) {
    6357         143 :                 WaterCoilType = "Coil:Cooling:Water:DetailedGeometry";
    6358         679 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) {
    6359         293 :                 WaterCoilType = "Coil:Cooling:Water";
    6360         386 :             } else if (state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
    6361         386 :                 WaterCoilType = "Coil:Heating:Water";
    6362             :             }
    6363         822 :             EMSSetPointErrorFlag = false;
    6364         822 :             switch (ControlledVar) {
    6365         779 :             case HVACControllers::CtrlVarType::Temperature: {
    6366         779 :                 CheckIfNodeSetPointManagedByEMS(state, SensorNodeNum, EMSManager::SPControlType::TemperatureSetPoint, EMSSetPointErrorFlag);
    6367         779 :                 state.dataLoopNodes->NodeSetpointCheck(SensorNodeNum).needsSetpointChecking = false;
    6368         779 :                 if (EMSSetPointErrorFlag) {
    6369         600 :                     if (!NodeHasSPMCtrlVarType(state, SensorNodeNum, CtrlVarType::Temp)) {
    6370           0 :                         ShowWarningError(state,
    6371           0 :                                          std::string{RoutineName} + WaterCoilType + "=\"" + state.dataWaterCoils->WaterCoil(WhichCoil).Name + "\". ");
    6372           0 :                         ShowContinueError(state, " ..Temperature setpoint not found on coil air outlet node.");
    6373           0 :                         ShowContinueError(state,
    6374             :                                           " ..The setpoint may have been placed on a node downstream of the coil or on an airloop outlet node.");
    6375           0 :                         ShowContinueError(state, " ..Specify the setpoint and the sensor on the coil air outlet node when possible.");
    6376             :                     }
    6377             :                 }
    6378         779 :                 break;
    6379             :             }
    6380           0 :             case HVACControllers::CtrlVarType::HumidityRatio: {
    6381           0 :                 CheckIfNodeSetPointManagedByEMS(state, SensorNodeNum, EMSManager::SPControlType::HumidityRatioMaxSetPoint, EMSSetPointErrorFlag);
    6382           0 :                 state.dataLoopNodes->NodeSetpointCheck(SensorNodeNum).needsSetpointChecking = false;
    6383           0 :                 if (EMSSetPointErrorFlag) {
    6384           0 :                     if (!NodeHasSPMCtrlVarType(state, SensorNodeNum, CtrlVarType::MaxHumRat)) {
    6385           0 :                         ShowWarningError(state,
    6386           0 :                                          std::string{RoutineName} + WaterCoilType + "=\"" + state.dataWaterCoils->WaterCoil(WhichCoil).Name + "\". ");
    6387           0 :                         ShowContinueError(state, " ..Humidity ratio setpoint not found on coil air outlet node.");
    6388           0 :                         ShowContinueError(state,
    6389             :                                           " ..The setpoint may have been placed on a node downstream of the coil or on an airloop outlet node.");
    6390           0 :                         ShowContinueError(state, " ..Specify the setpoint and the sensor on the coil air outlet node when possible.");
    6391             :                     }
    6392             :                 }
    6393           0 :                 break;
    6394             :             }
    6395          43 :             case HVACControllers::CtrlVarType::TemperatureAndHumidityRatio: {
    6396          43 :                 CheckIfNodeSetPointManagedByEMS(state, SensorNodeNum, EMSManager::SPControlType::TemperatureSetPoint, EMSSetPointErrorFlag);
    6397          43 :                 state.dataLoopNodes->NodeSetpointCheck(SensorNodeNum).needsSetpointChecking = false;
    6398          43 :                 if (EMSSetPointErrorFlag) {
    6399          28 :                     if (!NodeHasSPMCtrlVarType(state, SensorNodeNum, CtrlVarType::Temp)) {
    6400           0 :                         ShowWarningError(state,
    6401           0 :                                          std::string{RoutineName} + WaterCoilType + "=\"" + state.dataWaterCoils->WaterCoil(WhichCoil).Name + "\". ");
    6402           0 :                         ShowContinueError(state, " ..Temperature setpoint not found on coil air outlet node.");
    6403           0 :                         ShowContinueError(state,
    6404             :                                           " ..The setpoint may have been placed on a node downstream of the coil or on an airloop outlet node.");
    6405           0 :                         ShowContinueError(state, " ..Specify the setpoint and the sensor on the coil air outlet node when possible.");
    6406             :                     }
    6407             :                 }
    6408          43 :                 EMSSetPointErrorFlag = false;
    6409          43 :                 CheckIfNodeSetPointManagedByEMS(state, SensorNodeNum, EMSManager::SPControlType::HumidityRatioMaxSetPoint, EMSSetPointErrorFlag);
    6410          43 :                 state.dataLoopNodes->NodeSetpointCheck(SensorNodeNum).needsSetpointChecking = false;
    6411          43 :                 if (EMSSetPointErrorFlag) {
    6412          28 :                     if (!NodeHasSPMCtrlVarType(state, SensorNodeNum, CtrlVarType::MaxHumRat)) {
    6413           0 :                         ShowWarningError(state,
    6414           0 :                                          std::string{RoutineName} + WaterCoilType + "=\"" + state.dataWaterCoils->WaterCoil(WhichCoil).Name + "\". ");
    6415           0 :                         ShowContinueError(state, " ..Humidity ratio setpoint not found on coil air outlet node.");
    6416           0 :                         ShowContinueError(state,
    6417             :                                           " ..The setpoint may have been placed on a node downstream of the coil or on an airloop outlet node.");
    6418           0 :                         ShowContinueError(state, " ..Specify the setpoint and the sensor on the coil air outlet node when possible.");
    6419             :                     }
    6420             :                 }
    6421          43 :                 break;
    6422             :             }
    6423           0 :             default:
    6424           0 :                 break;
    6425             :             }
    6426             :         }
    6427             :     }
    6428         822 : }
    6429             : 
    6430          76 : Real64 TdbFnHRhPb(EnergyPlusData &state,
    6431             :                   Real64 const H,  // specific enthalpy {J/kg}
    6432             :                   Real64 const RH, // relative humidity value (0.0-1.0)
    6433             :                   Real64 const PB  // barometric pressure {Pascals}
    6434             : )
    6435             : {
    6436             : 
    6437             :     // FUNCTION INFORMATION:
    6438             :     //       AUTHOR         Fred Buhl
    6439             :     //       DATE WRITTEN   April 1, 2009
    6440             :     //       MODIFIED       na
    6441             :     //       RE-ENGINEERED  na
    6442             : 
    6443             :     // PURPOSE OF THIS FUNCTION:
    6444             :     // Given the specific enthalpy, relative humidity, and the
    6445             :     // barometric pressure, the function returns the dry bulb temperature.
    6446             : 
    6447             :     // METHODOLOGY EMPLOYED:
    6448             :     // Inverts PsyHFnTdbRhPb
    6449             : 
    6450             :     // REFERENCES:
    6451             :     // none
    6452             : 
    6453             :     // Using/Aliasing
    6454             : 
    6455             :     using General::SolveRoot;
    6456             : 
    6457             :     // Return value
    6458             :     Real64 T; // result=> humidity ratio
    6459             : 
    6460             :     // Locals
    6461             :     // FUNCTION ARGUMENT DEFINITIONS:
    6462             : 
    6463             :     // FUNCTION PARAMETER DEFINITIONS:
    6464          76 :     int constexpr MaxIte(500); // Maximum number of iterations
    6465          76 :     Real64 constexpr Acc(1.0); // Accuracy of result
    6466             : 
    6467             :     // INTERFACE BLOCK SPECIFICATIONS
    6468             :     // na
    6469             : 
    6470             :     // DERIVED TYPE DEFINITIONS
    6471             :     // na
    6472             : 
    6473             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6474             :     int SolFla;        // Flag of solver
    6475             :     Real64 T0;         // lower bound for Tprov [C]
    6476             :     Real64 T1;         // upper bound for Tprov [C]
    6477          76 :     Real64 Tprov(0.0); // provisional value of drybulb temperature [C]
    6478             : 
    6479          76 :     T0 = 1.0;
    6480          76 :     T1 = 50.0;
    6481             : 
    6482        1752 :     auto f = [&state, H, RH, PB](Real64 const Tprov) { return H - Psychrometrics::PsyHFnTdbRhPb(state, Tprov, RH, PB); };
    6483             : 
    6484          76 :     General::SolveRoot(state, Acc, MaxIte, SolFla, Tprov, f, T0, T1);
    6485             :     // if the numerical inversion failed, issue error messages.
    6486          76 :     if (SolFla == -1) {
    6487           0 :         ShowSevereError(state, "Calculation of drybulb temperature failed in TdbFnHRhPb(H,RH,PB)");
    6488           0 :         ShowContinueError(state, "   Iteration limit exceeded");
    6489           0 :         ShowContinueError(state, format("   H=[{:.6R}], RH=[{:.4R}], PB=[{:.5R}].", H, RH, PB));
    6490          76 :     } else if (SolFla == -2) {
    6491           0 :         ShowSevereError(state, "Calculation of drybulb temperature failed in TdbFnHRhPb(H,RH,PB)");
    6492           0 :         ShowContinueError(state, "  Bad starting values for Tdb");
    6493           0 :         ShowContinueError(state, format("   H=[{:.6R}], RH=[{:.4R}], PB=[{:.5R}].", H, RH, PB));
    6494             :     }
    6495          76 :     if (SolFla < 0) {
    6496           0 :         T = 0.0;
    6497             :     } else {
    6498          76 :         T = Tprov;
    6499             :     }
    6500             : 
    6501          76 :     return T;
    6502             : }
    6503             : 
    6504        8295 : Real64 EstimateHEXSurfaceArea(EnergyPlusData &state, int const CoilNum) // coil number, [-]
    6505             : {
    6506             : 
    6507             :     // FUNCTION INFORMATION:
    6508             :     //       AUTHOR         Bereket A Nigusse, FSEC
    6509             :     //       DATE WRITTEN   July 2010
    6510             :     //       MODIFIED
    6511             :     //       RE-ENGINEERED
    6512             : 
    6513             :     // PURPOSE OF THIS FUNCTION:
    6514             :     // Splits the UA value of a simple coil:cooling:water heat exchanger model into
    6515             :     // "A" and U" values.
    6516             : 
    6517             :     // METHODOLOGY EMPLOYED:
    6518             :     // A typical design U overall heat transfer coefficient is used to split the "UA" into "A"
    6519             :     // and "U" values. Currently a constant U value calculated for a typical cooling coil is
    6520             :     // used. The assumptions used to calculate a typical U value are:
    6521             :     //     (1) tube side water velocity of 2.0 [m/s]
    6522             :     //     (2) inside to outside total surface area ratio (Ai/Ao) =  0.07 [-]
    6523             :     //     (3) fins overall efficiency = 0.92 based on aluminum fin, 12 fins per inch, and
    6524             :     //         fins area to total outside surafce area ratio of about 90%.
    6525             :     //     (4) air side convection coefficient of 140.0 [W/m2C].  Assumes sensible convection
    6526             :     //         of 58.0 [W/m2C] and 82.0 [W/m2C] sensible convection equivalent of the mass
    6527             :     //         transfer coefficient converted using the approximate relation:
    6528             :     //         hequivalent = hmasstransfer/CpAir.
    6529             : 
    6530             :     // REFERENCES:
    6531             : 
    6532             :     // USE STATEMENTS:
    6533             : 
    6534             :     // Return value
    6535             : 
    6536             :     // Locals
    6537             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    6538             : 
    6539             :     // FUNCTION PARAMETER DEFINITIONS:
    6540        8295 :     constexpr Real64 OverallFinEfficiency(0.92); // Assumes aluminum fins, 12 fins per inch, fins
    6541             :     // area of about 90% of external surface area Ao.
    6542             : 
    6543        8295 :     constexpr Real64 AreaRatio(0.07); // Heat exchanger Inside to Outside surface area ratio
    6544             :     // design values range from (Ai/Ao) = 0.06 to 0.08
    6545             : 
    6546             :     // Constant value air side heat transfer coefficient is assumed. This coefficient has sensible
    6547             :     // (58.d0 [W/m2C]) and latent (82.d0 [W/m2C]) heat transfer coefficient components.
    6548        8295 :     constexpr Real64 hAirTubeOutside(58.0 + 82.0); // Air side heat transfer coefficient [W/m2C]
    6549             : 
    6550             :     // Tube side water convection heat transfer coefficient of the cooling coil is calculated for
    6551             :     // inside tube diameter of 0.0122m (~0.5 inch nominal diameter) and water velocity 2.0 m/s:
    6552             :     static Real64 const hWaterTubeInside(1429.0 * std::pow(2.0, 0.8) * std::pow(0.0122, -0.2)); // water (tube) side heat transfer coefficient [W/m2C]
    6553             : 
    6554             :     // Estimate the overall heat transfer coefficient, UOverallHeatTransferCoef in [W/(m2C)].
    6555             :     // Neglecting tube wall and fouling resistance, the overall U value can be estimated as:
    6556             :     // 1/UOverallHeatTransferCoef = 1/(hi*AreaRatio) + 1/(ho*OverallFinEfficiency)
    6557             :     static Real64 const UOverallHeatTransferCoef_inv(
    6558             :         1.0 / (hWaterTubeInside * AreaRatio) +
    6559             :         1.0 / (hAirTubeOutside * OverallFinEfficiency)); // Inverse of overall heat transfer coefficient for coil [W/m2C]
    6560             : 
    6561             :     // INTERFACE BLOCK SPECIFICATIONS
    6562             :     // na
    6563             : 
    6564             :     // DERIVED TYPE DEFINITIONS
    6565             :     // na
    6566             : 
    6567             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6568             : 
    6569        8295 :     state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal =
    6570        8295 :         1.0 / (1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilExternal + 1.0 / state.dataWaterCoils->WaterCoil(CoilNum).UACoilInternal);
    6571             : 
    6572             :     // the heat exchanger surface area is calculated as follows:
    6573        8295 :     return state.dataWaterCoils->WaterCoil(CoilNum).UACoilTotal * UOverallHeatTransferCoef_inv; // Heat exchanger surface area [m2]
    6574             : }
    6575             : 
    6576         192 : int GetWaterCoilIndex(EnergyPlusData &state,
    6577             :                       std::string_view CoilType,   // must match coil types in this module
    6578             :                       std::string const &CoilName, // must match coil names for the coil type
    6579             :                       bool &ErrorsFound            // set to true if problem
    6580             : )
    6581             : {
    6582             : 
    6583             :     // FUNCTION INFORMATION:
    6584             :     //       AUTHOR         B. Nigusse, FSEC
    6585             :     //       DATE WRITTEN   Feb 2012
    6586             :     //       MODIFIED       na
    6587             :     //       RE-ENGINEERED  na
    6588             : 
    6589             :     // PURPOSE OF THIS FUNCTION:
    6590             :     // This function looks up the index for the given coil and returns it.  If incorrect coil
    6591             :     // type or name is given, ErrorsFound is returned as true and node number is returned
    6592             :     // as zero.
    6593             : 
    6594             :     // Return value
    6595             :     int IndexNum; // returned coil index if matched coil
    6596             : 
    6597             :     // Obtains and allocates WaterCoil related parameters from input file
    6598         192 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6599           8 :         GetWaterCoilInput(state);
    6600           8 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6601             :     }
    6602             : 
    6603         192 :     IndexNum = 0;
    6604         192 :     if (CoilType == "COIL:HEATING:WATER") {
    6605          98 :         IndexNum = UtilityRoutines::FindItemInList(CoilName, state.dataWaterCoils->WaterCoil);
    6606          94 :     } else if (CoilType == "COIL:COOLING:WATER") {
    6607          94 :         IndexNum = UtilityRoutines::FindItemInList(CoilName, state.dataWaterCoils->WaterCoil);
    6608           0 :     } else if (CoilType == "COIL:COOLING:WATER:DETAILEDGEOMETRY") {
    6609           0 :         IndexNum = UtilityRoutines::FindItemInList(CoilName, state.dataWaterCoils->WaterCoil);
    6610             :     } else {
    6611           0 :         IndexNum = 0;
    6612             :     }
    6613             : 
    6614         192 :     if (IndexNum == 0) {
    6615           0 :         ShowSevereError(state, format("GetWaterCoilIndex: Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
    6616           0 :         ErrorsFound = true;
    6617             :     }
    6618             : 
    6619         192 :     return IndexNum;
    6620             : }
    6621          24 : int GetCompIndex(EnergyPlusData &state, CoilModel compType, std::string_view const coilName)
    6622             : {
    6623             :     static constexpr std::array<std::string_view, (int)WaterCoils::CoilModel::Num> CoilModelNamesUC = {
    6624             :         "COIL:HEATING:WATER", "COIL:COOLING:WATER", "COIL:COOLING:WATER:DETAILED"};
    6625             : 
    6626          24 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6627           5 :         GetWaterCoilInput(state);
    6628           5 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6629             :     }
    6630             : 
    6631          24 :     int index = UtilityRoutines::FindItemInList(coilName, state.dataWaterCoils->WaterCoil);
    6632             : 
    6633          24 :     if (index == 0) { // may not find coil name
    6634           0 :         ShowSevereError(state,
    6635           0 :                         format("GetWaterCoilIndex: Could not find CoilType = \"{}\" with Name = \"{}\"", CoilModelNamesUC[(int)compType], coilName));
    6636             :     }
    6637          24 :     return index;
    6638             : }
    6639             : 
    6640          14 : Real64 GetWaterCoilCapacity(EnergyPlusData &state,
    6641             :                             std::string const &CoilType, // must match coil types in this module
    6642             :                             std::string const &CoilName, // must match coil names for the coil type
    6643             :                             bool &ErrorsFound            // set to true if problem
    6644             : )
    6645             : {
    6646             : 
    6647             :     // FUNCTION INFORMATION:
    6648             :     //       AUTHOR         R. Raustad, FSEC
    6649             :     //       DATE WRITTEN   Sep 2013
    6650             :     //       MODIFIED       na
    6651             :     //       RE-ENGINEERED  na
    6652             : 
    6653             :     // PURPOSE OF THIS FUNCTION:
    6654             :     // This function looks up the capacity for the given coil and returns it.  If incorrect coil
    6655             :     // type or name is given, ErrorsFound is returned as true and capacity is returned
    6656             :     // as zero.
    6657             : 
    6658             :     // Return value
    6659             :     Real64 Capacity; // returned coil capacity if matched coil
    6660             : 
    6661             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6662             :     int IndexNum; // index to water coil
    6663             : 
    6664             :     // Obtains and allocates WaterCoil related parameters from input file
    6665          14 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6666           0 :         GetWaterCoilInput(state);
    6667           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6668             :     }
    6669             : 
    6670          14 :     Capacity = -1.0;
    6671             : 
    6672          14 :     if (CoilType == "COIL:HEATING:WATER") {
    6673           9 :         IndexNum = UtilityRoutines::FindItemInList(CoilName, state.dataWaterCoils->WaterCoil);
    6674           9 :         Capacity = state.dataWaterCoils->WaterCoil(IndexNum).DesWaterHeatingCoilRate;
    6675           5 :     } else if (CoilType == "COIL:COOLING:WATER") {
    6676           5 :         IndexNum = UtilityRoutines::FindItemInList(CoilName, state.dataWaterCoils->WaterCoil);
    6677           5 :         Capacity = state.dataWaterCoils->WaterCoil(IndexNum).DesWaterCoolingCoilRate;
    6678           0 :     } else if (CoilType == "COIL:COOLING:WATER:DETAILEDGEOMETRY") {
    6679           0 :         IndexNum = UtilityRoutines::FindItemInList(CoilName, state.dataWaterCoils->WaterCoil);
    6680           0 :         Capacity = state.dataWaterCoils->WaterCoil(IndexNum).DesWaterCoolingCoilRate;
    6681             :     } else {
    6682           0 :         IndexNum = 0;
    6683             :     }
    6684             : 
    6685          14 :     if (IndexNum == 0) {
    6686           0 :         ShowSevereError(state, "GetWaterCoilCapacity: Could not find CoilType=\"" + CoilType + "\" with Name=\"" + CoilName + "\"");
    6687           0 :         ErrorsFound = true;
    6688             :     }
    6689             : 
    6690          14 :     return Capacity;
    6691             : }
    6692             : 
    6693           0 : void UpdateWaterToAirCoilPlantConnection(EnergyPlusData &state,
    6694             :                                          DataPlant::PlantEquipmentType const CoilType,
    6695             :                                          std::string const &CoilName,
    6696             :                                          [[maybe_unused]] int const EquipFlowCtrl,   // Flow control mode for the equipment
    6697             :                                          int const LoopNum,                          // Plant loop index for where called from
    6698             :                                          const DataPlant::LoopSideLocation LoopSide, // Plant loop side index for where called from
    6699             :                                          int &CompIndex,                             // Chiller number pointer
    6700             :                                          [[maybe_unused]] bool const FirstHVACIteration,
    6701             :                                          bool &InitLoopEquip // If not zero, calculate the max load for operating conditions
    6702             : )
    6703             : {
    6704             : 
    6705             :     // SUBROUTINE INFORMATION:
    6706             :     //       AUTHOR         B. Griffith
    6707             :     //       DATE WRITTEN   February 2010
    6708             :     //       MODIFIED       na
    6709             :     //       RE-ENGINEERED  na
    6710             : 
    6711             :     // PURPOSE OF THIS SUBROUTINE:
    6712             :     // update sim routine called from plant
    6713             : 
    6714             :     // Using/Aliasing
    6715             :     using DataPlant::PlantEquipTypeNames;
    6716             : 
    6717             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6718             : 
    6719             :     int CoilNum;
    6720           0 :     bool DidAnythingChange(false); // set to true if conditions changed
    6721             :     int InletNodeNum;
    6722             :     int OutletNodeNum;
    6723             : 
    6724             :     // Find the correct water coil
    6725           0 :     if (CompIndex == 0) {
    6726           0 :         CoilNum = UtilityRoutines::FindItemInList(CoilName, state.dataWaterCoils->WaterCoil);
    6727           0 :         if (CoilNum == 0) {
    6728           0 :             ShowFatalError(state, "UpdateWaterToAirCoilPlantConnection: Specified Coil not one of Valid water coils=" + CoilName);
    6729             :         }
    6730           0 :         CompIndex = CoilNum;
    6731             :     } else {
    6732           0 :         CoilNum = CompIndex;
    6733           0 :         if (CoilNum > state.dataWaterCoils->NumWaterCoils || CoilNum < 1) {
    6734           0 :             ShowFatalError(state,
    6735           0 :                            format("UpdateWaterToAirCoilPlantConnection:  Invalid CompIndex passed={}, Number of Coils={}, Entered Coil name={}",
    6736             :                                   CoilNum,
    6737           0 :                                   state.dataWaterCoils->NumWaterCoils,
    6738           0 :                                   CoilName));
    6739             :         }
    6740           0 :         if (state.dataGlobal->KickOffSimulation) {
    6741           0 :             if (CoilName != state.dataWaterCoils->WaterCoil(CoilNum).Name) {
    6742           0 :                 ShowFatalError(
    6743             :                     state,
    6744           0 :                     format("UpdateWaterToAirCoilPlantConnection: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
    6745             :                            CoilNum,
    6746             :                            CoilName,
    6747           0 :                            state.dataWaterCoils->WaterCoil(CoilNum).Name));
    6748             :             }
    6749           0 :             if (CoilType != state.dataWaterCoils->WaterCoil(CoilNum).WaterCoilType) {
    6750           0 :                 ShowFatalError(
    6751             :                     state,
    6752           0 :                     format("UpdateWaterToAirCoilPlantConnection: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
    6753             :                            CoilNum,
    6754             :                            CoilName,
    6755           0 :                            PlantEquipTypeNames[static_cast<int>(CoilType)]));
    6756             :             }
    6757             :         }
    6758             :     }
    6759             : 
    6760           0 :     if (InitLoopEquip) {
    6761           0 :         return;
    6762             :     }
    6763             : 
    6764           0 :     DidAnythingChange = false;
    6765             : 
    6766           0 :     InletNodeNum = state.dataWaterCoils->WaterCoil(CoilNum).WaterInletNodeNum;
    6767           0 :     OutletNodeNum = state.dataWaterCoils->WaterCoil(CoilNum).WaterOutletNodeNum;
    6768             : 
    6769           0 :     if (state.dataLoopNodes->Node(InletNodeNum).Temp != state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp) DidAnythingChange = true;
    6770             : 
    6771           0 :     if (state.dataLoopNodes->Node(OutletNodeNum).Temp != state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterTemp) DidAnythingChange = true;
    6772             : 
    6773           0 :     if (state.dataLoopNodes->Node(InletNodeNum).MassFlowRate != state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterMassFlowRate) {
    6774           0 :         DidAnythingChange = true;
    6775           0 :         state.dataLoopNodes->Node(OutletNodeNum).MassFlowRate =
    6776           0 :             state.dataLoopNodes->Node(InletNodeNum).MassFlowRate; // make sure flows are consistent
    6777             :     }
    6778             : 
    6779           0 :     if (state.dataLoopNodes->Node(OutletNodeNum).MassFlowRate != state.dataWaterCoils->WaterCoil(CoilNum).OutletWaterMassFlowRate)
    6780           0 :         DidAnythingChange = true;
    6781             : 
    6782           0 :     if (DidAnythingChange) {
    6783             :         // set sim flag for this loop
    6784           0 :         state.dataPlnt->PlantLoop(LoopNum).LoopSide(LoopSide).SimLoopSideNeeded = true;
    6785             :         // set sim flags for air side users of coils
    6786             : 
    6787           0 :         state.dataHVACGlobal->SimAirLoopsFlag = true;
    6788           0 :         state.dataHVACGlobal->SimZoneEquipmentFlag = true;
    6789             :     } else { // nothing changed so turn off sim flag
    6790           0 :         state.dataPlnt->PlantLoop(LoopNum).LoopSide(LoopSide).SimLoopSideNeeded = false;
    6791             :     }
    6792             : }
    6793             : 
    6794           0 : int GetWaterCoilAvailScheduleIndex(EnergyPlusData &state,
    6795             :                                    std::string const &CoilType, // must match coil types in this module
    6796             :                                    std::string const &CoilName, // must match coil names for the coil type
    6797             :                                    bool &ErrorsFound            // set to true if problem
    6798             : )
    6799             : {
    6800             : 
    6801             :     // FUNCTION INFORMATION:
    6802             :     //       AUTHOR         Chandan Sharma, FSEC
    6803             :     //       DATE WRITTEN   February 2013
    6804             :     //       MODIFIED       na
    6805             :     //       RE-ENGINEERED  na
    6806             : 
    6807             :     // PURPOSE OF THIS FUNCTION:
    6808             :     // This function looks up the given coil and returns the availability schedule index.  If
    6809             :     // incorrect coil type or name is given, ErrorsFound is returned as true and index is returned
    6810             :     // as zero.
    6811             : 
    6812             :     // Return value
    6813             :     int AvailSchIndex; // returned availability schedule of matched coil
    6814             : 
    6815             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    6816             :     int WhichCoil;
    6817             : 
    6818             :     // Obtains and Allocates HeatingCoil related parameters from input file
    6819             :     // Obtains and Allocates DXCoils
    6820           0 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6821           0 :         GetWaterCoilInput(state);
    6822           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6823             :     }
    6824             : 
    6825           0 :     WhichCoil = 0;
    6826           0 :     AvailSchIndex = 0;
    6827             : 
    6828           0 :     if (UtilityRoutines::SameString(CoilType, "Coil:Heating:Water") || UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water") ||
    6829           0 :         UtilityRoutines::SameString(CoilType, "Coil:Cooling:Water:DetailedGeometry")) {
    6830           0 :         WhichCoil = UtilityRoutines::FindItem(CoilName, state.dataWaterCoils->WaterCoil);
    6831           0 :         if (WhichCoil != 0) {
    6832           0 :             AvailSchIndex = state.dataWaterCoils->WaterCoil(WhichCoil).SchedPtr;
    6833             :         }
    6834             :     } else {
    6835           0 :         WhichCoil = 0;
    6836             :     }
    6837             : 
    6838           0 :     if (WhichCoil == 0) {
    6839           0 :         ShowSevereError(state, "GetCoilAvailScheduleIndex: Could not find Coil, Type=\"" + CoilType + "\" Name=\"" + CoilName + "\"");
    6840           0 :         ErrorsFound = true;
    6841           0 :         AvailSchIndex = 0;
    6842             :     }
    6843             : 
    6844           0 :     return AvailSchIndex;
    6845             : }
    6846             : 
    6847           2 : void SetWaterCoilData(EnergyPlusData &state,
    6848             :                       int const CoilNum,                       // Number of hot water heating Coil
    6849             :                       bool &ErrorsFound,                       // Set to true if certain errors found
    6850             :                       Optional_bool DesiccantRegenerationCoil, // Flag that this coil is used as regeneration air heating coil
    6851             :                       Optional_int DesiccantDehumIndex,        // Index for the desiccant dehum system where this caoil is used
    6852             :                       Optional_bool heatRecoveryCoil)          // true if water coil is connected to heat recovery loop
    6853             : {
    6854             : 
    6855             :     // FUNCTION INFORMATION:
    6856             :     //       AUTHOR         Bereket Nigusse
    6857             :     //       DATE WRITTEN   February 2016
    6858             :     //       MODIFIED       na
    6859             :     //       RE-ENGINEERED  na
    6860             : 
    6861             :     // PURPOSE OF THIS FUNCTION:
    6862             :     // This function sets data to water Heating Coil using the coil index and arguments passed
    6863             : 
    6864             :     // Using/Aliasing
    6865             : 
    6866           2 :     if (state.dataWaterCoils->GetWaterCoilsInputFlag) {
    6867           0 :         GetWaterCoilInput(state);
    6868           0 :         state.dataWaterCoils->GetWaterCoilsInputFlag = false;
    6869             :     }
    6870             : 
    6871           2 :     if (CoilNum <= 0 || CoilNum > state.dataWaterCoils->NumWaterCoils) {
    6872           0 :         ShowSevereError(state,
    6873           0 :                         format("SetHeatingCoilData: called with heating coil Number out of range={} should be >0 and <{}",
    6874             :                                CoilNum,
    6875           0 :                                state.dataWaterCoils->NumWaterCoils));
    6876           0 :         ErrorsFound = true;
    6877           0 :         return;
    6878             :     }
    6879             : 
    6880           2 :     if (present(DesiccantRegenerationCoil)) {
    6881           0 :         state.dataWaterCoils->WaterCoil(CoilNum).DesiccantRegenerationCoil = DesiccantRegenerationCoil;
    6882             :     }
    6883             : 
    6884           2 :     if (present(DesiccantDehumIndex)) {
    6885           0 :         state.dataWaterCoils->WaterCoil(CoilNum).DesiccantDehumNum = DesiccantDehumIndex;
    6886             :     }
    6887             : 
    6888           2 :     if (present(heatRecoveryCoil)) {
    6889           2 :         state.dataWaterCoils->WaterCoil(CoilNum).heatRecoveryCoil = heatRecoveryCoil;
    6890             :     }
    6891             : }
    6892             : 
    6893           0 : void EstimateCoilInletWaterTemp(EnergyPlusData &state,
    6894             :                                 int const CoilNum,                // index to heating coil
    6895             :                                 int const FanOpMode,              // fan operating mode
    6896             :                                 Real64 const PartLoadRatio,       // part-load ratio of heating coil
    6897             :                                 Real64 const UAMax,               // maximum UA-Value = design heating capacity
    6898             :                                 Real64 &DesCoilInletWaterTempUsed // estimated coil design inlet water temperature
    6899             : )
    6900             : {
    6901             :     // SUBROUTINE INFORMATION:
    6902             : 
    6903             :     // PURPOSE OF THIS SUBROUTINE:
    6904             :     // returns estimated coil inlet water temperature given UA value for assumed
    6905             :     // maximum effectiveness value for heating coil
    6906             : 
    6907             :     // METHODOLOGY EMPLOYED:
    6908             :     // applies energy balance around the water coil and estimates coil water inlet temperature
    6909             :     // assuming coil effectiveness of 0.8
    6910             : 
    6911             :     // REFERENCES:
    6912             :     // na
    6913             : 
    6914             :     // Using/Aliasing
    6915             : 
    6916             :     // Locals
    6917             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    6918             : 
    6919             :     // SUBROUTINE PARAMETER DEFINITIONS:
    6920             :     static constexpr std::string_view RoutineName("EstimateCoilInletWaterTemp");
    6921           0 :     constexpr Real64 EffectivenessMaxAssumed(0.80);
    6922             : 
    6923             :     // INTERFACE BLOCK SPECIFICATIONS
    6924             :     // na
    6925             : 
    6926             :     // DERIVED TYPE DEFINITIONS
    6927             :     // na
    6928             : 
    6929             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6930             :     Real64 WaterMassFlowRate;
    6931             :     Real64 AirMassFlow;
    6932             :     Real64 TempAirIn;
    6933             :     Real64 TempAirOut; // [C]
    6934             :     Real64 Win;
    6935             :     Real64 TempWaterIn;
    6936             :     Real64 UA;
    6937             :     Real64 CapacitanceAir;
    6938             :     Real64 CapacitanceWater;
    6939             :     Real64 CapacitanceMin;
    6940             :     Real64 CapacitanceMax;
    6941             :     Real64 NTU;
    6942             :     Real64 ETA;
    6943             :     Real64 A;
    6944             :     Real64 CapRatio;
    6945             :     Real64 E1;
    6946             :     Real64 E2;
    6947             :     Real64 Effec;
    6948             :     Real64 Cp;
    6949             : 
    6950           0 :     UA = UAMax;
    6951           0 :     DesCoilInletWaterTempUsed = DesCoilHWInletTempMin;
    6952           0 :     TempAirIn = state.dataWaterCoils->WaterCoil(CoilNum).InletAirTemp;
    6953           0 :     Win = state.dataWaterCoils->WaterCoil(CoilNum).InletAirHumRat;
    6954           0 :     TempWaterIn = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterTemp;
    6955             :     // adjust mass flow rates for cycling fan cycling coil operation
    6956           0 :     if (FanOpMode == CycFanCycCoil) {
    6957           0 :         if (PartLoadRatio > 0.0) {
    6958           0 :             AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate / PartLoadRatio;
    6959           0 :             WaterMassFlowRate = min(state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate / PartLoadRatio,
    6960           0 :                                     state.dataWaterCoils->WaterCoil(CoilNum).MaxWaterMassFlowRate);
    6961             :         } else {
    6962           0 :             AirMassFlow = 0.0;
    6963           0 :             WaterMassFlowRate = 0.0;
    6964           0 :             return;
    6965             :         }
    6966             :     } else {
    6967           0 :         AirMassFlow = state.dataWaterCoils->WaterCoil(CoilNum).InletAirMassFlowRate;
    6968           0 :         WaterMassFlowRate = state.dataWaterCoils->WaterCoil(CoilNum).InletWaterMassFlowRate;
    6969             :     }
    6970           0 :     if (WaterMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) { // if the coil is operating
    6971           0 :         CapacitanceAir = PsyCpAirFnW(Win) * AirMassFlow;
    6972           0 :         Cp = GetSpecificHeatGlycol(state,
    6973           0 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidName,
    6974             :                                    TempWaterIn,
    6975           0 :                                    state.dataPlnt->PlantLoop(state.dataWaterCoils->WaterCoil(CoilNum).WaterPlantLoc.loopNum).FluidIndex,
    6976             :                                    RoutineName);
    6977           0 :         CapacitanceWater = Cp * WaterMassFlowRate;
    6978           0 :         CapacitanceMin = min(CapacitanceAir, CapacitanceWater);
    6979           0 :         CapacitanceMax = max(CapacitanceAir, CapacitanceWater);
    6980             :     } else {
    6981           0 :         CapacitanceAir = 0.0;
    6982           0 :         CapacitanceWater = 0.0;
    6983           0 :         return;
    6984             :     }
    6985             :     // calculate DesCoilInletWaterTempUsed
    6986           0 :     if (((CapacitanceAir > 0.0) && (CapacitanceWater > 0.0))) {
    6987             : 
    6988           0 :         if (UA <= 0.0) {
    6989           0 :             ShowWarningError(state, "UA is zero for COIL:Heating:Water " + state.dataWaterCoils->WaterCoil(CoilNum).Name);
    6990           0 :             return;
    6991             :         }
    6992           0 :         NTU = UA / CapacitanceMin;
    6993           0 :         ETA = std::pow(NTU, 0.22);
    6994           0 :         CapRatio = CapacitanceMin / CapacitanceMax;
    6995           0 :         A = CapRatio * NTU / ETA;
    6996             : 
    6997           0 :         if (A > 20.0) {
    6998           0 :             A = ETA * 1.0 / CapRatio;
    6999             :         } else {
    7000           0 :             E1 = std::exp(-A);
    7001           0 :             A = ETA * (1.0 - E1) / CapRatio;
    7002             :         }
    7003             : 
    7004           0 :         if (A > 20.0) {
    7005           0 :             Effec = 1.0;
    7006             :         } else {
    7007           0 :             E2 = std::exp(-A);
    7008           0 :             Effec = 1.0 - E2;
    7009             :         }
    7010           0 :         TempAirOut = TempAirIn + Effec * CapacitanceMin * (TempWaterIn - TempAirIn) / CapacitanceAir;
    7011             :         // this formulation assumes coil effectiveness of 0.80 to increase the estimated coil water inlet temperatures
    7012           0 :         DesCoilInletWaterTempUsed = CapacitanceAir * (TempAirOut - TempAirIn) / (CapacitanceMin * EffectivenessMaxAssumed) + TempAirIn;
    7013             :         // water coil should not be sized at coil water inlet temperature lower than 46.0C (for convergence problem in Regulafalsi)
    7014           0 :         DesCoilInletWaterTempUsed = max(DesCoilInletWaterTempUsed, DesCoilHWInletTempMin);
    7015             :     }
    7016             : }
    7017             : 
    7018             : // End of Coil Utility subroutines
    7019             : // *****************************************************************************
    7020             : 
    7021        2313 : } // namespace EnergyPlus::WaterCoils

Generated by: LCOV version 1.13