LCOV - code coverage report
Current view: top level - EnergyPlus - CondenserLoopTowers.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 2204 3501 63.0 %
Date: 2024-08-23 23:50:59 Functions: 35 38 92.1 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cassert>
      50             : #include <cmath>
      51             : 
      52             : // ObjexxFCL Headers
      53             : #include <ObjexxFCL/Array.functions.hh>
      54             : #include <ObjexxFCL/Fmath.hh>
      55             : #include <ObjexxFCL/string.functions.hh>
      56             : 
      57             : // EnergyPlus Headers
      58             : #include <EnergyPlus/Autosizing/Base.hh>
      59             : #include <EnergyPlus/BranchNodeConnections.hh>
      60             : #include <EnergyPlus/CondenserLoopTowers.hh>
      61             : #include <EnergyPlus/CurveManager.hh>
      62             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      63             : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      64             : #include <EnergyPlus/DataEnvironment.hh>
      65             : #include <EnergyPlus/DataHVACGlobals.hh>
      66             : #include <EnergyPlus/DataIPShortCuts.hh>
      67             : #include <EnergyPlus/DataLoopNode.hh>
      68             : #include <EnergyPlus/DataPrecisionGlobals.hh>
      69             : #include <EnergyPlus/DataSizing.hh>
      70             : #include <EnergyPlus/DataWater.hh>
      71             : #include <EnergyPlus/FaultsManager.hh>
      72             : #include <EnergyPlus/FluidProperties.hh>
      73             : #include <EnergyPlus/General.hh>
      74             : #include <EnergyPlus/GeneralRoutines.hh>
      75             : #include <EnergyPlus/GlobalNames.hh>
      76             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      77             : #include <EnergyPlus/NodeInputManager.hh>
      78             : #include <EnergyPlus/OutAirNodeManager.hh>
      79             : #include <EnergyPlus/OutputProcessor.hh>
      80             : #include <EnergyPlus/OutputReportPredefined.hh>
      81             : #include <EnergyPlus/Plant/DataPlant.hh>
      82             : #include <EnergyPlus/PlantUtilities.hh>
      83             : #include <EnergyPlus/Psychrometrics.hh>
      84             : #include <EnergyPlus/ScheduleManager.hh>
      85             : #include <EnergyPlus/UtilityRoutines.hh>
      86             : #include <EnergyPlus/WaterManager.hh>
      87             : 
      88             : namespace EnergyPlus {
      89             : 
      90             : namespace CondenserLoopTowers {
      91             : 
      92             :     // Module containing the routines dealing with the objects COOLING TOWER:SINGLE SPEED,
      93             :     // COOLING TOWER:TWO SPEED, and COOLING TOWER:VARIABLE SPEED
      94             : 
      95             :     // MODULE INFORMATION:
      96             :     //       AUTHOR         Dan Fisher
      97             :     //       DATE WRITTEN   April 1998
      98             :     //       MODIFIED       Shirey, Raustad: Dec 2000; Shirey, Sept 2002, Raustad Mar 2005
      99             :     //                      B Griffith Aug 2006, added water consumption and water system interactions
     100             :     //                      T Hong, Aug 2008. Added fluid bypass for single speed cooling tower
     101             :     //                      Chandan Sharma, FSEC, February 2010, Added basin heater
     102             :     //                      A Flament, July 2010, added multi-cell capability for the 3 types of cooling tower
     103             :     //       RE-ENGINEERED  na
     104             : 
     105             :     // PURPOSE OF THIS MODULE:
     106             :     // Model the performance of cooling towers
     107             : 
     108             :     std::string const cCoolingTower_SingleSpeed("CoolingTower:SingleSpeed");
     109             :     std::string const cCoolingTower_TwoSpeed("CoolingTower:TwoSpeed");
     110             :     std::string const cCoolingTower_VariableSpeed("CoolingTower:VariableSpeed");
     111             :     std::string const cCoolingTower_VariableSpeedMerkel("CoolingTower:VariableSpeed:Merkel");
     112             : 
     113         270 :     CoolingTower *CoolingTower::factory(EnergyPlusData &state, std::string_view objectName)
     114             :     {
     115             :         // Process the input data for towers if it hasn't been done already
     116         270 :         if (state.dataCondenserLoopTowers->GetInput) {
     117         244 :             GetTowerInput(state);
     118         244 :             state.dataCondenserLoopTowers->GetInput = false;
     119             :         }
     120             :         // Now look for this particular tower in the list
     121         270 :         auto thisObj = std::find_if(state.dataCondenserLoopTowers->towers.begin(),
     122         270 :                                     state.dataCondenserLoopTowers->towers.end(),
     123         299 :                                     [&objectName](const CoolingTower &myObj) { return myObj.Name == objectName; });
     124         270 :         if (thisObj != state.dataCondenserLoopTowers->towers.end()) return thisObj;
     125             :         // If we didn't find it, fatal
     126             :         ShowFatalError(state, format("CoolingTowerFactory: Error getting inputs for tower named: {}", objectName)); // LCOV_EXCL_LINE
     127             :         // Shut up the compiler
     128             :         return nullptr; // LCOV_EXCL_LINE
     129             :     }
     130             : 
     131     8767027 :     void CoolingTower::simulate(EnergyPlusData &state,
     132             :                                 [[maybe_unused]] const PlantLocation &calledFromLocation,
     133             :                                 [[maybe_unused]] bool const FirstHVACIteration,
     134             :                                 Real64 &CurLoad,
     135             :                                 bool const RunFlag)
     136             :     {
     137     8767027 :         this->initialize(state);
     138     8767027 :         switch (this->TowerType) {
     139     7761854 :         case DataPlant::PlantEquipmentType::CoolingTower_SingleSpd:
     140     7761854 :             this->calculateSingleSpeedTower(state, CurLoad, RunFlag);
     141     7761854 :             break;
     142      298469 :         case DataPlant::PlantEquipmentType::CoolingTower_TwoSpd:
     143      298469 :             this->calculateTwoSpeedTower(state, CurLoad, RunFlag);
     144      298469 :             break;
     145      625884 :         case DataPlant::PlantEquipmentType::CoolingTower_VarSpd:
     146      625884 :             this->calculateVariableSpeedTower(state, CurLoad, RunFlag);
     147      625884 :             break;
     148       80820 :         case DataPlant::PlantEquipmentType::CoolingTower_VarSpdMerkel:
     149       80820 :             this->calculateMerkelVariableSpeedTower(state, CurLoad, RunFlag);
     150       80820 :             break;
     151           0 :         default:
     152           0 :             ShowFatalError(state, format("Plant Equipment Type specified for {} is not a Cooling Tower.", this->Name));
     153             :         }
     154     8767027 :         this->calculateWaterUsage(state);
     155     8767027 :         this->update(state);
     156     8767027 :         this->report(state, RunFlag);
     157     8767027 :     }
     158             : 
     159        1372 :     void CoolingTower::getDesignCapacities([[maybe_unused]] EnergyPlusData &state,
     160             :                                            [[maybe_unused]] const PlantLocation &calledFromLocation,
     161             :                                            Real64 &MaxLoad,
     162             :                                            Real64 &MinLoad,
     163             :                                            Real64 &OptLoad)
     164             :     {
     165        1372 :         MinLoad = 0.0;
     166        1372 :         MaxLoad = this->TowerNominalCapacity * this->HeatRejectCapNomCapSizingRatio;
     167        1372 :         OptLoad = this->TowerNominalCapacity;
     168        1372 :     }
     169             : 
     170         270 :     void CoolingTower::getSizingFactor(Real64 &SizFactor)
     171             :     {
     172         270 :         SizFactor = this->SizFac;
     173         270 :     }
     174             : 
     175        1372 :     void CoolingTower::onInitLoopEquip(EnergyPlusData &state, [[maybe_unused]] const PlantLocation &calledFromLocation)
     176             :     {
     177        1372 :         this->initialize(state);
     178        1372 :         if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_VarSpdMerkel) {
     179          10 :             this->SizeVSMerkelTower(state);
     180             :         } else {
     181        1362 :             this->SizeTower(state);
     182             :         }
     183        1372 :     }
     184             : 
     185         244 :     void GetTowerInput(EnergyPlusData &state)
     186             :     {
     187             : 
     188             :         // SUBROUTINE INFORMATION:
     189             :         //       AUTHOR:          Dan Fisher
     190             :         //       DATE WRITTEN:    April 1998
     191             :         //       MODIFIED         Don Shirey, Jan 2001 and Sept/Oct 2002; Richard Raustad, FSEC, Feb 2005 (added VS tower)
     192             :         //                        B. Griffith, Aug. 2006 water consumption modeling and water system connections
     193             :         //                        T Hong, Aug. 2008: added fluid bypass for single speed tower
     194             :         //                        A Flament, July 2010, added multi-cell capability for the 3 types of cooling tower
     195             : 
     196             :         // PURPOSE OF THIS SUBROUTINE:
     197             :         // Obtains input data for cooling towers and stores it in towers data structure. Additional structure
     198             :         // (VSTower) stores the coefficients for each VS tower.
     199             : 
     200             :         // METHODOLOGY EMPLOYED:
     201             :         // Uses "Get" routines to read in the data.
     202             : 
     203             :         // SUBROUTINE PARAMETER DEFINITIONS:
     204             :         static constexpr std::string_view OutputFormat("{:5.2F}");
     205             : 
     206             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     207             :         int TowerNum;                      // Tower number, reference counter for towers data array
     208         244 :         int NumVSCoolToolsModelCoeffs = 0; // Number of CoolTools VS cooling tower coefficient objects
     209         244 :         int NumVSYorkCalcModelCoeffs = 0;  // Number of YorkCalc VS cooling tower coefficient objects
     210             :         int VSModelCoeffNum;               // Specific variable-speed tower coefficient object of interest
     211             :         int NumAlphas;                     // Number of elements in the alpha array
     212             :         int NumNums;                       // Number of elements in the numeric array
     213             :         int NumAlphas2;                    // Number of elements in the alpha2 array
     214             :         int NumNums2;                      // Number of elements in the numeric2 array
     215             :         int IOStat;                        // IO Status when calling get input subroutine
     216             :         int CoeffNum;                      // Index for reading user defined VS tower coefficients
     217         244 :         bool ErrorsFound(false);           // Logical flag set .TRUE. if errors found while getting input data
     218         244 :         Array1D<Real64> NumArray(33);      // Numeric input data array
     219         244 :         Array1D<Real64> NumArray2(43);     // Numeric input data array for VS tower coefficients
     220         244 :         Array1D_string AlphArray(16);      // Character string input data array
     221         244 :         Array1D_string AlphArray2(1);      // Character string input data array for VS tower coefficients
     222             : 
     223         244 :         std::unordered_map<std::string, std::string> UniqueSimpleTowerNames;
     224             : 
     225         244 :         constexpr std::array<std::string_view, static_cast<int>(EvapLoss::Num)> EvapLossNamesUC{"LOSSFACTOR", "SATURATEDEXIT"};
     226         244 :         constexpr std::array<std::string_view, static_cast<int>(PIM::Num)> PIMNamesUC{"NOMINALCAPACITY", "UFACTORTIMESAREAANDDESIGNWATERFLOWRATE"};
     227         244 :         constexpr std::array<std::string_view, static_cast<int>(Blowdown::Num)> BlowDownNamesUC = {"CONCENTRATIONRATIO", "SCHEDULEDRATE"};
     228         244 :         constexpr std::array<std::string_view, static_cast<int>(CellCtrl::Num)> CellCtrlNamesUC = {"MINIMALCELL", "MAXIMALCELL"};
     229             : 
     230             :         // Get number of all cooling towers specified in the input data file (idf)
     231         244 :         int NumSingleSpeedTowers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCoolingTower_SingleSpeed);
     232         244 :         int NumTwoSpeedTowers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCoolingTower_TwoSpeed);
     233         244 :         int NumVariableSpeedTowers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCoolingTower_VariableSpeed);
     234         244 :         int NumVSMerkelTowers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCoolingTower_VariableSpeedMerkel);
     235         244 :         int NumSimpleTowers = NumSingleSpeedTowers + NumTwoSpeedTowers + NumVariableSpeedTowers + NumVSMerkelTowers;
     236             : 
     237         244 :         if (NumSimpleTowers <= 0)
     238           0 :             ShowFatalError(state,
     239             :                            "No Cooling Tower objects found in input, however, a branch object has specified a cooling tower. Search the input for "
     240             :                            "CoolingTower to determine the cause for this error.");
     241             : 
     242         244 :         state.dataCondenserLoopTowers->GetInput = false;
     243             :         // See if load distribution manager has already gotten the input
     244         244 :         if (allocated(state.dataCondenserLoopTowers->towers)) return;
     245             : 
     246             :         // Allocate data structures to hold tower input data, report data and tower inlet conditions
     247         244 :         state.dataCondenserLoopTowers->towers.allocate(NumSimpleTowers);
     248         244 :         UniqueSimpleTowerNames.reserve(NumSimpleTowers);
     249             :         // Allocate variable-speed tower structure with data specific to this type
     250         244 :         if (NumVariableSpeedTowers > 0) {
     251             :             // Allow users to input model coefficients other than default
     252          16 :             NumVSCoolToolsModelCoeffs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoolingTowerPerformance:CoolTools");
     253          16 :             NumVSYorkCalcModelCoeffs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "CoolingTowerPerformance:YorkCalc");
     254             :         }
     255             : 
     256         244 :         std::string &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     257             : 
     258             :         // Load data structures with cooling tower input data
     259         244 :         cCurrentModuleObject = cCoolingTower_SingleSpeed;
     260         475 :         for (int SingleSpeedTowerNumber = 1; SingleSpeedTowerNumber <= NumSingleSpeedTowers; ++SingleSpeedTowerNumber) {
     261         231 :             TowerNum = SingleSpeedTowerNumber;
     262         462 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     263             :                                                                      cCurrentModuleObject,
     264             :                                                                      SingleSpeedTowerNumber,
     265             :                                                                      AlphArray,
     266             :                                                                      NumAlphas,
     267             :                                                                      NumArray,
     268             :                                                                      NumNums,
     269             :                                                                      IOStat,
     270             :                                                                      _,
     271         231 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     272         231 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     273         231 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     274         231 :             GlobalNames::VerifyUniqueInterObjectName(
     275         462 :                 state, UniqueSimpleTowerNames, AlphArray(1), cCurrentModuleObject, state.dataIPShortCut->cAlphaFieldNames(1), ErrorsFound);
     276         231 :             auto &tower = state.dataCondenserLoopTowers->towers(TowerNum);
     277         231 :             tower.Name = AlphArray(1);
     278         231 :             tower.TowerType = DataPlant::PlantEquipmentType::CoolingTower_SingleSpd;
     279         231 :             tower.TowerMassFlowRateMultiplier = 2.5;
     280         231 :             tower.WaterInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     281         231 :                                                                           AlphArray(2),
     282             :                                                                           ErrorsFound,
     283             :                                                                           DataLoopNode::ConnectionObjectType::CoolingTowerSingleSpeed,
     284         231 :                                                                           tower.Name,
     285             :                                                                           DataLoopNode::NodeFluidType::Water,
     286             :                                                                           DataLoopNode::ConnectionType::Inlet,
     287             :                                                                           NodeInputManager::CompFluidStream::Primary,
     288             :                                                                           DataLoopNode::ObjectIsNotParent);
     289         231 :             tower.WaterOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     290         231 :                                                                            AlphArray(3),
     291             :                                                                            ErrorsFound,
     292             :                                                                            DataLoopNode::ConnectionObjectType::CoolingTowerSingleSpeed,
     293         231 :                                                                            tower.Name,
     294             :                                                                            DataLoopNode::NodeFluidType::Water,
     295             :                                                                            DataLoopNode::ConnectionType::Outlet,
     296             :                                                                            NodeInputManager::CompFluidStream::Primary,
     297             :                                                                            DataLoopNode::ObjectIsNotParent);
     298         231 :             BranchNodeConnections::TestCompSet(state, cCurrentModuleObject, tower.Name, AlphArray(2), AlphArray(3), "Chilled Water Nodes");
     299         231 :             tower.DesignWaterFlowRate = NumArray(1);
     300         231 :             if (tower.DesignWaterFlowRate == DataSizing::AutoSize) {
     301         108 :                 tower.DesignWaterFlowRateWasAutoSized = true;
     302             :             }
     303         231 :             tower.HighSpeedAirFlowRate = NumArray(2);
     304         231 :             if (tower.HighSpeedAirFlowRate == DataSizing::AutoSize) {
     305         113 :                 tower.HighSpeedAirFlowRateWasAutoSized = true;
     306             :             }
     307         231 :             tower.HighSpeedFanPower = NumArray(3);
     308         231 :             if (tower.HighSpeedFanPower == DataSizing::AutoSize) {
     309         110 :                 tower.HighSpeedFanPowerWasAutoSized = true;
     310             :             }
     311         231 :             tower.HighSpeedTowerUA = NumArray(4);
     312         231 :             if (tower.HighSpeedTowerUA == DataSizing::AutoSize) {
     313         110 :                 tower.HighSpeedTowerUAWasAutoSized = true;
     314             :             }
     315         231 :             tower.FreeConvAirFlowRate = NumArray(5);
     316         231 :             if (tower.FreeConvAirFlowRate == DataSizing::AutoSize) {
     317          57 :                 tower.FreeConvAirFlowRateWasAutoSized = true;
     318             :             }
     319         231 :             tower.FreeConvAirFlowRateSizingFactor = NumArray(6);
     320         231 :             tower.FreeConvTowerUA = NumArray(7);
     321         231 :             if (tower.FreeConvTowerUA == DataSizing::AutoSize) {
     322          57 :                 tower.FreeConvTowerUAWasAutoSized = true;
     323             :             }
     324         231 :             tower.FreeConvTowerUASizingFactor = NumArray(8);
     325         231 :             tower.HeatRejectCapNomCapSizingRatio = NumArray(9);
     326         231 :             tower.TowerNominalCapacity = NumArray(10);
     327         231 :             if (tower.TowerNominalCapacity == DataSizing::AutoSize) {
     328           0 :                 tower.TowerNominalCapacityWasAutoSized = true;
     329             :             }
     330         231 :             tower.TowerFreeConvNomCap = NumArray(11);
     331         231 :             if (tower.TowerFreeConvNomCap == DataSizing::AutoSize) {
     332          13 :                 tower.TowerFreeConvNomCapWasAutoSized = true;
     333             :             }
     334         231 :             tower.TowerFreeConvNomCapSizingFactor = NumArray(12);
     335         231 :             if (NumAlphas >= 4) {
     336         231 :                 tower.PerformanceInputMethod_Num = static_cast<PIM>(getEnumValue(PIMNamesUC, Util::makeUPPER(AlphArray(4))));
     337         231 :                 if (tower.PerformanceInputMethod_Num == PIM::Invalid) {
     338           0 :                     ShowSevereError(state, format("{}={}", cCurrentModuleObject, AlphArray(1)));
     339           0 :                     ShowContinueError(state, format("Invalid, {} = {}", state.dataIPShortCut->cAlphaFieldNames(4), AlphArray(4)));
     340           0 :                     ErrorsFound = true;
     341             :                 }
     342             :             } else {
     343             :                 // Since Performance Input Method has been omitted then assume it to be UA and DESIGN WATER FLOW RATE
     344           0 :                 tower.PerformanceInputMethod_Num = PIM::UFactor;
     345             :             }
     346             :             // cooling tower design inlet conditions
     347         231 :             tower.DesInletAirDBTemp = NumArray(13);
     348         231 :             if (tower.DesInletAirDBTemp == 0) {
     349           0 :                 tower.DesInletAirDBTemp = 35.0;
     350           0 :                 tower.TowerInletCondsAutoSize = true;
     351             :             }
     352         231 :             tower.DesInletAirWBTemp = NumArray(14);
     353         231 :             if (tower.DesInletAirWBTemp == 0) {
     354           0 :                 tower.DesInletAirWBTemp = 25.6;
     355           0 :                 tower.TowerInletCondsAutoSize = true;
     356             :             }
     357         231 :             tower.DesApproach = NumArray(15);
     358         231 :             if (tower.DesApproach == DataSizing::AutoSize || tower.DesApproach == 0) {
     359         231 :                 tower.DesApproach = 3.9;
     360         231 :                 tower.TowerInletCondsAutoSize = true;
     361             :             }
     362         231 :             tower.DesRange = NumArray(16);
     363         231 :             if (tower.DesRange == DataSizing::AutoSize || tower.DesRange == 0) {
     364         231 :                 tower.DesRange = 5.5;
     365         231 :                 tower.TowerInletCondsAutoSize = true;
     366             :             }
     367             :             // set tower design water outlet and inlet temperatures
     368         231 :             tower.DesOutletWaterTemp = tower.DesInletAirWBTemp + tower.DesApproach;
     369         231 :             tower.DesInletWaterTemp = tower.DesOutletWaterTemp + tower.DesRange;
     370             :             //   Basin heater power as a function of temperature must be greater than or equal to 0
     371         231 :             tower.BasinHeaterPowerFTempDiff = NumArray(17);
     372         231 :             if (NumArray(17) < 0.0) {
     373           0 :                 ShowSevereError(
     374             :                     state,
     375           0 :                     format("{}, \"{}\" basin heater power as a function of temperature difference must be >= 0", cCurrentModuleObject, tower.Name));
     376           0 :                 ErrorsFound = true;
     377             :             }
     378             : 
     379         231 :             tower.BasinHeaterSetPointTemp = NumArray(18);
     380             : 
     381         231 :             if (tower.BasinHeaterPowerFTempDiff > 0.0) {
     382           0 :                 if (NumNums < 18) {
     383           0 :                     tower.BasinHeaterSetPointTemp = 2.0;
     384             :                 }
     385           0 :                 if (tower.BasinHeaterSetPointTemp < 2.0) {
     386           0 :                     ShowWarningError(state,
     387           0 :                                      format("{}:\"{}\", {} is less than 2 deg C. Freezing could occur.",
     388             :                                             cCurrentModuleObject,
     389           0 :                                             tower.Name,
     390           0 :                                             state.dataIPShortCut->cNumericFieldNames(18)));
     391             :                 }
     392             :             }
     393             : 
     394         231 :             if (!AlphArray(5).empty()) {
     395           0 :                 tower.BasinHeaterSchedulePtr = ScheduleManager::GetScheduleIndex(state, AlphArray(5));
     396           0 :                 if (tower.BasinHeaterSchedulePtr == 0) {
     397           0 :                     ShowWarningError(state,
     398           0 :                                      format("{}, \"{}\" basin heater schedule name \"{}\" was not found. Basin heater operation will not be modeled "
     399             :                                             "and the simulation continues",
     400             :                                             cCurrentModuleObject,
     401           0 :                                             tower.Name,
     402             :                                             AlphArray(5)));
     403             :                 }
     404             :             }
     405             : 
     406             :             // begin water use and systems get input
     407         231 :             tower.EvapLossMode = static_cast<EvapLoss>(getEnumValue(EvapLossNamesUC, Util::makeUPPER(AlphArray(6))));
     408             : 
     409         231 :             tower.UserEvapLossFactor = NumArray(19);        //  N11 , \field Evaporation Loss Factor
     410         231 :             tower.DriftLossFraction = NumArray(20) / 100.0; //  N12, \field Drift Loss Percent
     411         231 :             tower.ConcentrationRatio = NumArray(21);        //  N13, \field Blowdown Concentration Ratio
     412         231 :             tower.SizFac = NumArray(25);                    //  N17  \field Sizing Factor
     413         231 :             if (tower.SizFac <= 0.0) tower.SizFac = 1.0;
     414             : 
     415         231 :             tower.BlowdownMode = static_cast<Blowdown>(getEnumValue(BlowDownNamesUC, Util::makeUPPER(AlphArray(7))));
     416         231 :             tower.SchedIDBlowdown = ScheduleManager::GetScheduleIndex(state, AlphArray(8));
     417         231 :             if ((tower.SchedIDBlowdown == 0) && (tower.BlowdownMode == Blowdown::Schedule)) {
     418           0 :                 ShowSevereError(state, format("Invalid, {} = \"{}\"", state.dataIPShortCut->cAlphaFieldNames(8), AlphArray(8)));
     419           0 :                 ShowContinueError(state, format("Entered in {} = \"{}\"", cCoolingTower_SingleSpeed, tower.Name));
     420           0 :                 ErrorsFound = true;
     421             :             }
     422             : 
     423         231 :             if (AlphArray(9).empty()) {
     424         229 :                 tower.SuppliedByWaterSystem = false;
     425             :             } else { // water from storage tank
     426           4 :                 WaterManager::SetupTankDemandComponent(
     427           4 :                     state, AlphArray(1), cCurrentModuleObject, AlphArray(9), ErrorsFound, tower.WaterTankID, tower.WaterTankDemandARRID);
     428           2 :                 tower.SuppliedByWaterSystem = true;
     429             :             }
     430             : 
     431             :             //   outdoor air inlet node
     432             : 
     433         231 :             if (state.dataIPShortCut->lAlphaFieldBlanks(10)) {
     434         195 :                 tower.OutdoorAirInletNodeNum = 0;
     435             :             } else {
     436          36 :                 tower.OutdoorAirInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     437          36 :                                                                                    AlphArray(10),
     438             :                                                                                    ErrorsFound,
     439             :                                                                                    DataLoopNode::ConnectionObjectType::CoolingTowerSingleSpeed,
     440          36 :                                                                                    tower.Name,
     441             :                                                                                    DataLoopNode::NodeFluidType::Air,
     442             :                                                                                    DataLoopNode::ConnectionType::OutsideAirReference,
     443             :                                                                                    NodeInputManager::CompFluidStream::Primary,
     444             :                                                                                    DataLoopNode::ObjectIsNotParent);
     445          36 :                 if (!OutAirNodeManager::CheckOutAirNodeNumber(state, tower.OutdoorAirInletNodeNum)) {
     446           0 :                     ShowSevereError(state,
     447           0 :                                     format("{}, \"{}\" Outdoor Air Inlet Node Name not valid Outdoor Air Node= {}",
     448             :                                            cCurrentModuleObject,
     449           0 :                                            tower.Name,
     450             :                                            AlphArray(10)));
     451           0 :                     ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
     452           0 :                     ErrorsFound = true;
     453             :                 }
     454             :             }
     455             : 
     456             :             //   fluid bypass for single speed tower
     457         231 :             if (state.dataIPShortCut->lAlphaFieldBlanks(11) || AlphArray(11).empty()) {
     458         192 :                 tower.CapacityControl = CapacityCtrl::FanCycling; // FanCycling
     459             :             } else {
     460          39 :                 tower.CapacityControl = static_cast<CapacityCtrl>(getEnumValue(CapacityCtrlNamesUC, Util::makeUPPER(AlphArray(11))));
     461          39 :                 if (tower.CapacityControl == CapacityCtrl::Invalid) {
     462           0 :                     tower.CapacityControl = CapacityCtrl::FanCycling;
     463           0 :                     ShowWarningError(state,
     464           0 :                                      format("{}, \"{}\" The Capacity Control is not specified correctly. The default Fan Cycling is used.",
     465             :                                             cCurrentModuleObject,
     466           0 :                                             tower.Name));
     467             :                 }
     468             :             }
     469             : 
     470             :             // added for multi-cell
     471         231 :             tower.NumCell = NumArray(22);
     472         231 :             if ((NumNums < 22) && (tower.NumCell == 0)) {
     473             :                 // assume Number of Cells not entered and should be defaulted
     474           0 :                 tower.NumCell = 1;
     475             :             }
     476         231 :             tower.MinFracFlowRate = NumArray(23);
     477         231 :             if ((NumNums < 23) && (tower.MinFracFlowRate == 0.0)) {
     478             :                 // assume Cell Minimum Water Flow Rate Fraction not entered and should be defaulted
     479           0 :                 tower.MinFracFlowRate = 0.33;
     480             :             }
     481         231 :             tower.MaxFracFlowRate = NumArray(24);
     482         231 :             if ((NumNums < 24) && (tower.MaxFracFlowRate == 0.0)) {
     483             :                 // assume Cell Maximum Water Flow Rate Fraction not entered and should be defaulted
     484           0 :                 tower.MaxFracFlowRate = 2.5;
     485             :             }
     486             : 
     487             :             //   cell control for single speed tower
     488         231 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(12)) {
     489           2 :                 tower.cellCtrl = static_cast<CellCtrl>(getEnumValue(CellCtrlNamesUC, Util::makeUPPER(AlphArray(12))));
     490             :             }
     491             : 
     492             :             //   High speed air flow rate must be greater than free convection air flow rate.
     493             :             //   Can't tell yet if autosized, check later in initialize.
     494         231 :             if (tower.HighSpeedAirFlowRate <= tower.FreeConvAirFlowRate && tower.HighSpeedAirFlowRate != DataSizing::AutoSize) {
     495           0 :                 ShowSevereError(
     496             :                     state,
     497           0 :                     format("{} \"{}\". Free convection air flow rate must be less than the design air flow rate.", cCurrentModuleObject, tower.Name));
     498           0 :                 ErrorsFound = true;
     499             :             }
     500             : 
     501             :             //   Check various inputs if Performance Input Method = "UA and Design Water Flow Rate"
     502         231 :             if (tower.PerformanceInputMethod_Num == PIM::UFactor) {
     503         228 :                 if (tower.DesignWaterFlowRate == 0.0) {
     504           0 :                     ShowSevereError(state,
     505           0 :                                     format("{} \"{}\". Tower performance input method requires a design water flow rate greater than zero.",
     506             :                                            cCurrentModuleObject,
     507           0 :                                            tower.Name));
     508           0 :                     ErrorsFound = true;
     509             :                 }
     510         228 :                 if (tower.HighSpeedTowerUA <= tower.FreeConvTowerUA && tower.HighSpeedTowerUA != DataSizing::AutoSize) {
     511           0 :                     ShowSevereError(state,
     512           0 :                                     format("{} \"{}\". Free convection UA must be less than the design tower UA.", cCurrentModuleObject, tower.Name));
     513           0 :                     ErrorsFound = true;
     514             :                 }
     515         228 :                 if (tower.FreeConvTowerUA > 0.0 && tower.FreeConvAirFlowRate == 0.0) {
     516           0 :                     ShowSevereError(
     517             :                         state,
     518           0 :                         format("{} \"{}\". Free convection air flow rate must be greater than zero when free convection UA is greater than zero.",
     519             :                                cCurrentModuleObject,
     520           0 :                                tower.Name));
     521           0 :                     ErrorsFound = true;
     522             :                 }
     523           3 :             } else if (tower.PerformanceInputMethod_Num == PIM::NominalCapacity) {
     524           3 :                 if (tower.TowerNominalCapacity == 0.0) {
     525           0 :                     ShowSevereError(
     526             :                         state,
     527           0 :                         format("{} \"{}\". Tower performance input method requires valid nominal capacity.", cCurrentModuleObject, tower.Name));
     528           0 :                     ErrorsFound = true;
     529             :                 }
     530           3 :                 if (tower.DesignWaterFlowRate != 0.0) {
     531           0 :                     if (tower.DesignWaterFlowRate > 0.0) {
     532           0 :                         ShowWarningError(state,
     533           0 :                                          format("{} \"{}\". Nominal capacity input method and design water flow rate have been specified.",
     534             :                                                 cCurrentModuleObject,
     535           0 :                                                 tower.Name));
     536             :                     } else {
     537           0 :                         ShowSevereError(
     538             :                             state,
     539           0 :                             format("{} \"{}\". Nominal capacity input method has been specified and design water flow rate is being autosized.",
     540             :                                    cCurrentModuleObject,
     541           0 :                                    tower.Name));
     542             :                     }
     543           0 :                     ShowContinueError(state, "Design water flow rate will be set according to nominal tower capacity.");
     544             :                 }
     545           3 :                 if (tower.HighSpeedTowerUA != 0.0) {
     546           0 :                     if (tower.HighSpeedTowerUA > 0.0) {
     547           0 :                         ShowWarningError(
     548             :                             state,
     549           0 :                             format("{} \"{}\". Nominal tower capacity and design tower UA have been specified.", cCurrentModuleObject, tower.Name));
     550             :                     } else {
     551           0 :                         ShowSevereError(state,
     552           0 :                                         format("{} \"{}\". Nominal tower capacity has been specified and design tower UA is being autosized.",
     553             :                                                cCurrentModuleObject,
     554           0 :                                                tower.Name));
     555             :                     }
     556           0 :                     ShowContinueError(state, "Design tower UA will be set according to nominal tower capacity.");
     557             :                 }
     558           3 :                 if (tower.FreeConvTowerUA != 0.0) {
     559           0 :                     if (tower.FreeConvTowerUA > 0.0) {
     560           0 :                         ShowWarningError(state,
     561           0 :                                          format("{} \"{}\". Nominal capacity input method and free convection UA have been specified.",
     562             :                                                 cCurrentModuleObject,
     563           0 :                                                 tower.Name));
     564             :                     } else {
     565           0 :                         ShowSevereError(
     566             :                             state,
     567           0 :                             format("{} \"{}\". Nominal capacity input method has been specified and free convection UA is being autosized.",
     568             :                                    cCurrentModuleObject,
     569           0 :                                    tower.Name));
     570             :                     }
     571           0 :                     ShowContinueError(state, "Free convection UA will be set according to nominal tower capacity.");
     572             :                 }
     573           3 :                 if (tower.TowerFreeConvNomCap >= tower.TowerNominalCapacity) {
     574           0 :                     ShowSevereError(state,
     575           0 :                                     format("{} \"{}\". Free convection nominal capacity must be less than the nominal (design) tower capacity.",
     576             :                                            cCurrentModuleObject,
     577           0 :                                            tower.Name));
     578           0 :                     ErrorsFound = true;
     579             :                 }
     580           3 :                 if (tower.TowerFreeConvNomCap > 0.0 && tower.FreeConvAirFlowRate == 0.0) {
     581           0 :                     ShowSevereError(
     582             :                         state,
     583           0 :                         format("{} \"{}\". Free convection air flow must be greater than zero when tower free convection capacity is specified.",
     584             :                                cCurrentModuleObject,
     585           0 :                                tower.Name));
     586           0 :                     ErrorsFound = true;
     587             :                 }
     588             :             } else { // Tower performance input method is not specified as a valid "choice"
     589           0 :                 ShowSevereError(state,
     590           0 :                                 format("{} \"{}{}",
     591             :                                        cCurrentModuleObject,
     592           0 :                                        tower.Name,
     593             :                                        ". Tower Performance Input Method must be \"UFactorTimesAreaAndDesignWaterFlowRate\" or \"NominalCapacity\""));
     594           0 :                 ShowContinueError(state, format("Tower Performanace Input Method currently specified as: {}", AlphArray(4)));
     595           0 :                 ErrorsFound = true;
     596             :             }
     597         231 :             if (NumAlphas > 12) {
     598           1 :                 tower.EndUseSubcategory = AlphArray(13);
     599             :             } else {
     600         230 :                 tower.EndUseSubcategory = "General";
     601             :             }
     602             :         } // End Single-Speed Tower Loop
     603             : 
     604         244 :         cCurrentModuleObject = cCoolingTower_TwoSpeed;
     605         257 :         for (int TwoSpeedTowerNumber = 1; TwoSpeedTowerNumber <= NumTwoSpeedTowers; ++TwoSpeedTowerNumber) {
     606          13 :             TowerNum = NumSingleSpeedTowers + TwoSpeedTowerNumber;
     607          26 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     608             :                                                                      cCurrentModuleObject,
     609             :                                                                      TwoSpeedTowerNumber,
     610             :                                                                      AlphArray,
     611             :                                                                      NumAlphas,
     612             :                                                                      NumArray,
     613             :                                                                      NumNums,
     614             :                                                                      IOStat,
     615             :                                                                      _,
     616          13 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     617          13 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     618          13 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     619          13 :             GlobalNames::VerifyUniqueInterObjectName(
     620          26 :                 state, UniqueSimpleTowerNames, AlphArray(1), cCurrentModuleObject, state.dataIPShortCut->cAlphaFieldNames(1), ErrorsFound);
     621             : 
     622          13 :             auto &tower = state.dataCondenserLoopTowers->towers(TowerNum);
     623          13 :             tower.Name = AlphArray(1);
     624          13 :             tower.TowerType = DataPlant::PlantEquipmentType::CoolingTower_TwoSpd;
     625          13 :             tower.TowerMassFlowRateMultiplier = 2.5;
     626          13 :             tower.WaterInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     627          13 :                                                                           AlphArray(2),
     628             :                                                                           ErrorsFound,
     629             :                                                                           DataLoopNode::ConnectionObjectType::CoolingTowerTwoSpeed,
     630          13 :                                                                           tower.Name,
     631             :                                                                           DataLoopNode::NodeFluidType::Water,
     632             :                                                                           DataLoopNode::ConnectionType::Inlet,
     633             :                                                                           NodeInputManager::CompFluidStream::Primary,
     634             :                                                                           DataLoopNode::ObjectIsNotParent);
     635          13 :             tower.WaterOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     636          13 :                                                                            AlphArray(3),
     637             :                                                                            ErrorsFound,
     638             :                                                                            DataLoopNode::ConnectionObjectType::CoolingTowerTwoSpeed,
     639          13 :                                                                            tower.Name,
     640             :                                                                            DataLoopNode::NodeFluidType::Water,
     641             :                                                                            DataLoopNode::ConnectionType::Outlet,
     642             :                                                                            NodeInputManager::CompFluidStream::Primary,
     643             :                                                                            DataLoopNode::ObjectIsNotParent);
     644          13 :             BranchNodeConnections::TestCompSet(state, cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Chilled Water Nodes");
     645             : 
     646          13 :             if (NumAlphas >= 4) {
     647          13 :                 tower.PerformanceInputMethod_Num = static_cast<PIM>(getEnumValue(PIMNamesUC, Util::makeUPPER(AlphArray(4))));
     648             :             } else {
     649             :                 // Since Performance Input Method has been omitted then assume it to be UA and DESIGN WATER FLOW RATE
     650           0 :                 tower.PerformanceInputMethod_Num = PIM::UFactor;
     651             :             }
     652          13 :             tower.DesignWaterFlowRate = NumArray(1);
     653          13 :             if (tower.DesignWaterFlowRate == DataSizing::AutoSize) {
     654           8 :                 tower.DesignWaterFlowRateWasAutoSized = true;
     655             :             }
     656          13 :             tower.HighSpeedAirFlowRate = NumArray(2);
     657          13 :             if (tower.HighSpeedAirFlowRate == DataSizing::AutoSize) {
     658           9 :                 tower.HighSpeedAirFlowRateWasAutoSized = true;
     659             :             }
     660          13 :             tower.HighSpeedFanPower = NumArray(3);
     661          13 :             if (tower.HighSpeedFanPower == DataSizing::AutoSize) {
     662           9 :                 tower.HighSpeedFanPowerWasAutoSized = true;
     663             :             }
     664          13 :             tower.HighSpeedTowerUA = NumArray(4);
     665          13 :             if (tower.HighSpeedTowerUA == DataSizing::AutoSize) {
     666           8 :                 tower.HighSpeedTowerUAWasAutoSized = true;
     667             :             }
     668          13 :             tower.LowSpeedAirFlowRate = NumArray(5);
     669          13 :             if (tower.LowSpeedAirFlowRate == DataSizing::AutoSize) {
     670           9 :                 tower.LowSpeedAirFlowRateWasAutoSized = true;
     671             :             }
     672             : 
     673          13 :             tower.LowSpeedAirFlowRateSizingFactor = NumArray(6);
     674          13 :             tower.LowSpeedFanPower = NumArray(7);
     675          13 :             if (tower.LowSpeedFanPower == DataSizing::AutoSize) {
     676           9 :                 tower.LowSpeedFanPowerWasAutoSized = true;
     677             :             }
     678          13 :             tower.LowSpeedFanPowerSizingFactor = NumArray(8);
     679          13 :             tower.LowSpeedTowerUA = NumArray(9);
     680          13 :             if (tower.LowSpeedTowerUA == DataSizing::AutoSize) {
     681           8 :                 tower.LowSpeedTowerUAWasAutoSized = true;
     682             :             }
     683          13 :             tower.LowSpeedTowerUASizingFactor = NumArray(10);
     684          13 :             tower.FreeConvAirFlowRate = NumArray(11);
     685          13 :             if (tower.FreeConvAirFlowRate == DataSizing::AutoSize) {
     686           7 :                 tower.FreeConvAirFlowRateWasAutoSized = true;
     687             :             }
     688          13 :             tower.FreeConvAirFlowRateSizingFactor = NumArray(12);
     689          13 :             tower.FreeConvTowerUA = NumArray(13);
     690          13 :             if (tower.FreeConvTowerUA == DataSizing::AutoSize) {
     691           6 :                 tower.FreeConvTowerUAWasAutoSized = true;
     692             :             }
     693          13 :             tower.FreeConvTowerUASizingFactor = NumArray(14);
     694          13 :             tower.HeatRejectCapNomCapSizingRatio = NumArray(15);
     695          13 :             tower.TowerNominalCapacity = NumArray(16);
     696             : 
     697          13 :             tower.TowerLowSpeedNomCap = NumArray(17);
     698          13 :             if (tower.TowerLowSpeedNomCap == DataSizing::AutoSize) {
     699           3 :                 tower.TowerLowSpeedNomCapWasAutoSized = true;
     700             :             }
     701          13 :             tower.TowerLowSpeedNomCapSizingFactor = NumArray(18);
     702          13 :             tower.TowerFreeConvNomCap = NumArray(19);
     703          13 :             if (tower.TowerFreeConvNomCap == DataSizing::AutoSize) {
     704           3 :                 tower.TowerFreeConvNomCapWasAutoSized = true;
     705             :             }
     706          13 :             tower.TowerFreeConvNomCapSizingFactor = NumArray(20);
     707             :             // cooling tower design inlet conditions
     708          13 :             tower.DesInletAirDBTemp = NumArray(21);
     709          13 :             if (tower.DesInletAirDBTemp == 0) {
     710           0 :                 tower.DesInletAirDBTemp = 35.0;
     711           0 :                 tower.TowerInletCondsAutoSize = true;
     712             :             }
     713          13 :             tower.DesInletAirWBTemp = NumArray(22);
     714          13 :             if (tower.DesInletAirWBTemp == 0) {
     715           0 :                 tower.DesInletAirWBTemp = 25.6;
     716           0 :                 tower.TowerInletCondsAutoSize = true;
     717             :             }
     718          13 :             tower.DesApproach = NumArray(23);
     719          13 :             if (tower.DesApproach == DataSizing::AutoSize || tower.DesApproach == 0) {
     720          13 :                 tower.DesApproach = 3.9;
     721          13 :                 tower.TowerInletCondsAutoSize = true;
     722             :             }
     723          13 :             tower.DesRange = NumArray(24);
     724          13 :             if (tower.DesRange == DataSizing::AutoSize || tower.DesRange == 0) {
     725          13 :                 tower.DesRange = 5.5;
     726          13 :                 tower.TowerInletCondsAutoSize = true;
     727             :             }
     728             :             // set tower design water outlet and inlet temperatures
     729          13 :             tower.DesOutletWaterTemp = tower.DesInletAirWBTemp + tower.DesApproach;
     730          13 :             tower.DesInletWaterTemp = tower.DesOutletWaterTemp + tower.DesRange;
     731             :             //   Basin heater power as a function of temperature must be greater than or equal to 0
     732          13 :             tower.BasinHeaterPowerFTempDiff = NumArray(25);
     733          13 :             if (NumArray(25) < 0.0) {
     734           0 :                 ShowSevereError(
     735             :                     state,
     736           0 :                     format("{}, \"{}\" basin heater power as a function of temperature difference must be >= 0", cCurrentModuleObject, tower.Name));
     737           0 :                 ErrorsFound = true;
     738             :             }
     739             : 
     740          13 :             tower.BasinHeaterSetPointTemp = NumArray(26);
     741          13 :             if (tower.BasinHeaterPowerFTempDiff > 0.0) {
     742           0 :                 if (NumNums < 26) {
     743           0 :                     tower.BasinHeaterSetPointTemp = 2.0;
     744             :                 }
     745           0 :                 if (tower.BasinHeaterSetPointTemp < 2.0) {
     746           0 :                     ShowWarningError(state,
     747           0 :                                      format("{}:\"{}\", {} is less than 2 deg C. Freezing could occur.",
     748             :                                             cCurrentModuleObject,
     749           0 :                                             tower.Name,
     750           0 :                                             state.dataIPShortCut->cNumericFieldNames(26)));
     751             :                 }
     752             :             }
     753             : 
     754          13 :             if (!AlphArray(5).empty()) {
     755           0 :                 tower.BasinHeaterSchedulePtr = ScheduleManager::GetScheduleIndex(state, AlphArray(5));
     756           0 :                 if (tower.BasinHeaterSchedulePtr == 0) {
     757           0 :                     ShowWarningError(state,
     758           0 :                                      format("{}, \"{}\" basin heater schedule name \"{}\" was not found. Basin heater operation will not be modeled "
     759             :                                             "and the simulation continues",
     760             :                                             cCurrentModuleObject,
     761           0 :                                             tower.Name,
     762             :                                             AlphArray(5)));
     763             :                 }
     764             :             }
     765             : 
     766             :             // begin water use and systems get input
     767          13 :             tower.EvapLossMode = static_cast<EvapLoss>(getEnumValue(EvapLossNamesUC, Util::makeUPPER(AlphArray(6))));
     768          13 :             tower.UserEvapLossFactor = NumArray(27);        //  N23 , \field Evaporation Loss Factor
     769          13 :             tower.DriftLossFraction = NumArray(28) / 100.0; //  N24, \field Drift Loss Percent
     770          13 :             tower.ConcentrationRatio = NumArray(29);        //  N17, \field Blowdown Concentration Ratio
     771          13 :             tower.SizFac = NumArray(33);                    //  N21  \field Sizing Factor
     772          13 :             if (tower.SizFac <= 0.0) tower.SizFac = 1.0;
     773             : 
     774          13 :             tower.BlowdownMode = static_cast<Blowdown>(getEnumValue(BlowDownNamesUC, Util::makeUPPER(AlphArray(7))));
     775          13 :             tower.SchedIDBlowdown = ScheduleManager::GetScheduleIndex(state, AlphArray(8));
     776          13 :             if ((tower.SchedIDBlowdown == 0) && (tower.BlowdownMode == Blowdown::Schedule)) {
     777           0 :                 ShowSevereError(state, format("Invalid, {} = \"{}\"", state.dataIPShortCut->cAlphaFieldNames(8), AlphArray(8)));
     778           0 :                 ShowContinueError(state, format("Entered in {} = \"{}\"", cCoolingTower_TwoSpeed, tower.Name));
     779           0 :                 ErrorsFound = true;
     780             :             }
     781             : 
     782             :             // added for multi-cell
     783          13 :             tower.NumCell = NumArray(30);
     784          13 :             if ((NumNums < 30) && (tower.NumCell == 0)) {
     785             :                 // assume Number of Cells not entered and should be defaulted
     786           0 :                 tower.NumCell = 1;
     787             :             }
     788          13 :             tower.MinFracFlowRate = NumArray(31);
     789          13 :             if ((NumNums < 31) && (tower.MinFracFlowRate == 0.0)) {
     790             :                 // assume Cell Minimum Water Flow Rate Fraction not entered and should be defaulted
     791           0 :                 tower.MinFracFlowRate = 0.33;
     792             :             }
     793          13 :             tower.MaxFracFlowRate = NumArray(32);
     794          13 :             if ((NumNums < 32) && (tower.MaxFracFlowRate == 0.0)) {
     795             :                 // assume Cell Maximum Water Flow Rate Fraction not entered and should be defaulted
     796           0 :                 tower.MaxFracFlowRate = 2.5;
     797             :             }
     798             : 
     799             :             //   cell control for two speed tower
     800          13 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(11)) {
     801           3 :                 tower.cellCtrl = static_cast<CellCtrl>(getEnumValue(CellCtrlNamesUC, Util::makeUPPER(AlphArray(11))));
     802             :             }
     803             : 
     804          13 :             if (state.dataIPShortCut->lAlphaFieldBlanks(9)) {
     805          13 :                 tower.SuppliedByWaterSystem = false;
     806             :             } else { // water from storage tank
     807           0 :                 WaterManager::SetupTankDemandComponent(
     808           0 :                     state, AlphArray(1), cCurrentModuleObject, AlphArray(9), ErrorsFound, tower.WaterTankID, tower.WaterTankDemandARRID);
     809           0 :                 tower.SuppliedByWaterSystem = true;
     810             :             }
     811             : 
     812             :             //   outdoor air inlet node
     813          13 :             if (state.dataIPShortCut->lAlphaFieldBlanks(10)) {
     814           7 :                 tower.OutdoorAirInletNodeNum = 0;
     815             :             } else {
     816           6 :                 tower.OutdoorAirInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     817           6 :                                                                                    AlphArray(10),
     818             :                                                                                    ErrorsFound,
     819             :                                                                                    DataLoopNode::ConnectionObjectType::CoolingTowerTwoSpeed,
     820           6 :                                                                                    tower.Name,
     821             :                                                                                    DataLoopNode::NodeFluidType::Air,
     822             :                                                                                    DataLoopNode::ConnectionType::OutsideAirReference,
     823             :                                                                                    NodeInputManager::CompFluidStream::Primary,
     824             :                                                                                    DataLoopNode::ObjectIsNotParent);
     825           6 :                 if (!OutAirNodeManager::CheckOutAirNodeNumber(state, tower.OutdoorAirInletNodeNum)) {
     826           0 :                     ShowSevereError(state,
     827           0 :                                     format("{}, \"{}\" Outdoor Air Inlet Node Name not valid Outdoor Air Node= {}",
     828             :                                            cCurrentModuleObject,
     829           0 :                                            tower.Name,
     830             :                                            AlphArray(10)));
     831           0 :                     ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
     832           0 :                     ErrorsFound = true;
     833             :                 }
     834             :             }
     835             : 
     836             :             //   High speed air flow rate must be greater than low speed air flow rate.
     837             :             //   Can't tell yet if autosized, check later in initialize.
     838          13 :             if (tower.HighSpeedAirFlowRate <= tower.LowSpeedAirFlowRate && tower.HighSpeedAirFlowRate != DataSizing::AutoSize) {
     839           0 :                 ShowSevereError(
     840             :                     state,
     841           0 :                     format("{} \"{}\". Low speed air flow rate must be less than the high speed air flow rate.", cCurrentModuleObject, tower.Name));
     842           0 :                 ErrorsFound = true;
     843             :             }
     844             :             //   Low speed air flow rate must be greater than free convection air flow rate.
     845             :             //   Can't tell yet if autosized, check later in initialize.
     846          13 :             if (tower.LowSpeedAirFlowRate <= tower.FreeConvAirFlowRate && tower.LowSpeedAirFlowRate != DataSizing::AutoSize) {
     847           0 :                 ShowSevereError(state,
     848           0 :                                 format("{} \"{}\". Free convection air flow rate must be less than the low speed air flow rate.",
     849             :                                        cCurrentModuleObject,
     850           0 :                                        tower.Name));
     851           0 :                 ErrorsFound = true;
     852             :             }
     853             : 
     854             :             //   Check various inputs if Performance Input Method = "UA and Design Water Flow Rate"
     855          13 :             if (tower.PerformanceInputMethod_Num == PIM::UFactor) {
     856           8 :                 if (tower.DesignWaterFlowRate == 0.0) {
     857           0 :                     ShowSevereError(state,
     858           0 :                                     format("{} \"{}\". Tower performance input method requires a design water flow rate greater than zero.",
     859             :                                            cCurrentModuleObject,
     860           0 :                                            tower.Name));
     861           0 :                     ErrorsFound = true;
     862             :                 }
     863           8 :                 if (tower.HighSpeedTowerUA <= tower.LowSpeedTowerUA && tower.HighSpeedTowerUA != DataSizing::AutoSize) {
     864           0 :                     ShowSevereError(state,
     865           0 :                                     format("{} \"{}\". Tower UA at low fan speed must be less than the tower UA at high fan speed.",
     866             :                                            cCurrentModuleObject,
     867           0 :                                            tower.Name));
     868           0 :                     ErrorsFound = true;
     869             :                 }
     870           8 :                 if (tower.LowSpeedTowerUA <= tower.FreeConvTowerUA && tower.LowSpeedTowerUA != DataSizing::AutoSize) {
     871           0 :                     ShowSevereError(state,
     872           0 :                                     format("{} \"{}\". Tower UA at free convection air flow rate must be less than the tower UA at low fan speed.",
     873             :                                            cCurrentModuleObject,
     874           0 :                                            tower.Name));
     875           0 :                     ErrorsFound = true;
     876             :                 }
     877           8 :                 if (tower.FreeConvTowerUA > 0.0 && tower.FreeConvAirFlowRate == 0.0) {
     878           0 :                     ShowSevereError(
     879             :                         state,
     880           0 :                         format("{} \"{}\". Free convection air flow rate must be greater than zero when free convection UA is greater than zero.",
     881             :                                cCurrentModuleObject,
     882           0 :                                tower.Name));
     883           0 :                     ErrorsFound = true;
     884             :                 }
     885           5 :             } else if (tower.PerformanceInputMethod_Num == PIM::NominalCapacity) {
     886           5 :                 if (tower.TowerNominalCapacity == 0.0) {
     887           0 :                     ShowSevereError(state,
     888           0 :                                     format("{} \"{}\". Tower performance input method requires valid high-speed nominal capacity.",
     889             :                                            cCurrentModuleObject,
     890           0 :                                            tower.Name));
     891           0 :                     ErrorsFound = true;
     892             :                 }
     893           5 :                 if (tower.TowerLowSpeedNomCap == 0.0) {
     894           0 :                     ShowSevereError(state,
     895           0 :                                     format("{} \"{}\". Tower performance input method requires valid low-speed nominal capacity.",
     896             :                                            cCurrentModuleObject,
     897           0 :                                            tower.Name));
     898           0 :                     ErrorsFound = true;
     899             :                 }
     900           5 :                 if (tower.DesignWaterFlowRate != 0.0) {
     901           0 :                     if (tower.DesignWaterFlowRate > 0.0) {
     902           0 :                         ShowWarningError(state,
     903           0 :                                          format("{} \"{}\". Nominal capacity input method and design water flow rate have been specified.",
     904             :                                                 cCurrentModuleObject,
     905           0 :                                                 tower.Name));
     906             :                     } else {
     907           0 :                         ShowSevereError(
     908             :                             state,
     909           0 :                             format("{} \"{}\". Nominal capacity input method has been specified and design water flow rate is being autosized.",
     910             :                                    cCurrentModuleObject,
     911           0 :                                    tower.Name));
     912             :                     }
     913           0 :                     ShowContinueError(state, "Design water flow rate will be set according to nominal tower capacity.");
     914             :                 }
     915           5 :                 if (tower.HighSpeedTowerUA != 0.0) {
     916           0 :                     if (tower.HighSpeedTowerUA > 0.0) {
     917           0 :                         ShowWarningError(state,
     918           0 :                                          format("{} \"{}\". Nominal capacity input method and tower UA at high fan speed have been specified.",
     919             :                                                 cCurrentModuleObject,
     920           0 :                                                 tower.Name));
     921             :                     } else {
     922           0 :                         ShowSevereError(
     923             :                             state,
     924           0 :                             format("{} \"{}\". Nominal capacity input method has been specified and tower UA at high fan speed is being autosized.",
     925             :                                    cCurrentModuleObject,
     926           0 :                                    tower.Name));
     927             :                     }
     928           0 :                     ShowContinueError(state, "Tower UA at high fan speed will be set according to nominal tower capacity.");
     929             :                 }
     930           5 :                 if (tower.LowSpeedTowerUA != 0.0) {
     931           0 :                     if (tower.LowSpeedTowerUA > 0.0) {
     932           0 :                         ShowWarningError(state,
     933           0 :                                          format("{} \"{}\". Nominal capacity input method and tower UA at low fan speed have been specified.",
     934             :                                                 cCurrentModuleObject,
     935           0 :                                                 tower.Name));
     936             :                     } else {
     937           0 :                         ShowSevereError(
     938             :                             state,
     939           0 :                             format("{} \"{}\". Nominal capacity input method has been specified and tower UA at low fan speed is being autosized.",
     940             :                                    cCurrentModuleObject,
     941           0 :                                    tower.Name));
     942             :                     }
     943           0 :                     ShowContinueError(state, "Tower UA at low fan speed will be set according to nominal tower capacity.");
     944             :                 }
     945           5 :                 if (tower.FreeConvTowerUA != 0.0) {
     946           0 :                     if (tower.FreeConvTowerUA > 0.0) {
     947           0 :                         ShowWarningError(state,
     948           0 :                                          format("{} \"{}\". Nominal capacity input method and free convection UA have been specified.",
     949             :                                                 cCurrentModuleObject,
     950           0 :                                                 tower.Name));
     951             :                     } else {
     952           0 :                         ShowSevereError(
     953             :                             state,
     954           0 :                             format("{} \"{}\". Nominal capacity input method has been specified and free convection UA is being autosized.",
     955             :                                    cCurrentModuleObject,
     956           0 :                                    tower.Name));
     957             :                     }
     958           0 :                     ShowContinueError(state, "Free convection UA will be set according to nominal tower capacity.");
     959             :                 }
     960           5 :                 if (tower.TowerLowSpeedNomCap >= tower.TowerNominalCapacity) {
     961           0 :                     ShowSevereError(state,
     962           0 :                                     format("{} \"{}\". Low-speed nominal capacity must be less than the high-speed nominal capacity.",
     963             :                                            cCurrentModuleObject,
     964           0 :                                            tower.Name));
     965           0 :                     ErrorsFound = true;
     966             :                 }
     967           5 :                 if (!tower.TowerLowSpeedNomCapWasAutoSized) {
     968           5 :                     if (tower.TowerFreeConvNomCap >= tower.TowerLowSpeedNomCap) {
     969           0 :                         ShowSevereError(state,
     970           0 :                                         format("{} \"{}\". Free convection nominal capacity must be less than the low-speed nominal capacity.",
     971             :                                                cCurrentModuleObject,
     972           0 :                                                tower.Name));
     973           0 :                         ErrorsFound = true;
     974             :                     }
     975             :                 }
     976           5 :                 if (tower.TowerFreeConvNomCap > 0.0 && tower.FreeConvAirFlowRate == 0.0) {
     977           0 :                     ShowSevereError(
     978             :                         state,
     979           0 :                         format("{} \"{}\". Free convection air flow must be greater than zero when tower free convection capacity is specified.",
     980             :                                cCurrentModuleObject,
     981           0 :                                tower.Name));
     982           0 :                     ErrorsFound = true;
     983             :                 }
     984             :             } else { // Tower performance input method is not specified as a valid "choice"
     985           0 :                 ShowSevereError(
     986             :                     state,
     987           0 :                     format("{} \"{}{}",
     988             :                            cCurrentModuleObject,
     989           0 :                            tower.Name,
     990             :                            R"(". Tower Performance Input Method must be "UFactorTimesAreaAndDesignWaterFlowRate" or "NominalCapacity".)"));
     991           0 :                 ShowContinueError(state, format("Tower Performanace Input Method currently specified as: {}", AlphArray(4)));
     992           0 :                 ErrorsFound = true;
     993             :             }
     994          13 :             if (NumAlphas > 11) {
     995           2 :                 tower.EndUseSubcategory = AlphArray(12);
     996             :             } else {
     997          11 :                 tower.EndUseSubcategory = "General";
     998             :             }
     999             :         } // End Two-Speed Tower Loop
    1000             : 
    1001         244 :         cCurrentModuleObject = cCoolingTower_VariableSpeed;
    1002         268 :         for (int VariableSpeedTowerNumber = 1; VariableSpeedTowerNumber <= NumVariableSpeedTowers; ++VariableSpeedTowerNumber) {
    1003          24 :             TowerNum = NumSingleSpeedTowers + NumTwoSpeedTowers + VariableSpeedTowerNumber;
    1004          48 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1005             :                                                                      cCurrentModuleObject,
    1006             :                                                                      VariableSpeedTowerNumber,
    1007             :                                                                      AlphArray,
    1008             :                                                                      NumAlphas,
    1009             :                                                                      NumArray,
    1010             :                                                                      NumNums,
    1011             :                                                                      IOStat,
    1012             :                                                                      _,
    1013          24 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    1014          24 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    1015          24 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    1016          24 :             GlobalNames::VerifyUniqueInterObjectName(
    1017          48 :                 state, UniqueSimpleTowerNames, AlphArray(1), cCurrentModuleObject, state.dataIPShortCut->cAlphaFieldNames(1), ErrorsFound);
    1018             : 
    1019          24 :             auto &tower = state.dataCondenserLoopTowers->towers(TowerNum);
    1020          24 :             tower.VSTower = VariableSpeedTowerNumber;
    1021          24 :             tower.Name = AlphArray(1);
    1022          24 :             tower.TowerType = DataPlant::PlantEquipmentType::CoolingTower_VarSpd;
    1023          24 :             tower.WaterInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
    1024          24 :                                                                           AlphArray(2),
    1025             :                                                                           ErrorsFound,
    1026             :                                                                           DataLoopNode::ConnectionObjectType::CoolingTowerVariableSpeed,
    1027          24 :                                                                           AlphArray(1),
    1028             :                                                                           DataLoopNode::NodeFluidType::Water,
    1029             :                                                                           DataLoopNode::ConnectionType::Inlet,
    1030             :                                                                           NodeInputManager::CompFluidStream::Primary,
    1031             :                                                                           DataLoopNode::ObjectIsNotParent);
    1032          24 :             tower.WaterOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
    1033          24 :                                                                            AlphArray(3),
    1034             :                                                                            ErrorsFound,
    1035             :                                                                            DataLoopNode::ConnectionObjectType::CoolingTowerVariableSpeed,
    1036          24 :                                                                            AlphArray(1),
    1037             :                                                                            DataLoopNode::NodeFluidType::Water,
    1038             :                                                                            DataLoopNode::ConnectionType::Outlet,
    1039             :                                                                            NodeInputManager::CompFluidStream::Primary,
    1040             :                                                                            DataLoopNode::ObjectIsNotParent);
    1041          24 :             BranchNodeConnections::TestCompSet(state, cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Chilled Water Nodes");
    1042             : 
    1043          36 :             if ((Util::SameString(AlphArray(4), "CoolToolsUserDefined") || Util::SameString(AlphArray(4), "YorkCalcUserDefined")) &&
    1044          12 :                 state.dataIPShortCut->lAlphaFieldBlanks(5)) {
    1045           0 :                 ShowSevereError(state,
    1046           0 :                                 format("{}, \"{}\" a {} must be specified when {} is specified as CoolToolsUserDefined or YorkCalcUserDefined",
    1047             :                                        cCurrentModuleObject,
    1048           0 :                                        tower.Name,
    1049           0 :                                        state.dataIPShortCut->cAlphaFieldNames(5),
    1050           0 :                                        state.dataIPShortCut->cAlphaFieldNames(4)));
    1051           0 :                 ErrorsFound = true;
    1052          36 :             } else if ((Util::SameString(AlphArray(4), "CoolToolsCrossFlow") || Util::SameString(AlphArray(4), "YorkCalc")) &&
    1053          12 :                        !state.dataIPShortCut->lAlphaFieldBlanks(5)) {
    1054           0 :                 ShowWarningError(state,
    1055           0 :                                  format("{}, \"{}\" a Tower Model Coefficient Name is specified and the Tower Model Type is not specified as "
    1056             :                                         "CoolToolsUserDefined or YorkCalcUserDefined. The CoolingTowerPerformance:CoolTools "
    1057             :                                         "(orCoolingTowerPerformance:YorkCalc) data object will not be used.",
    1058             :                                         cCurrentModuleObject,
    1059           0 :                                         tower.Name));
    1060             :             } else {
    1061          24 :                 tower.ModelCoeffObjectName = AlphArray(5);
    1062             :             }
    1063             : 
    1064          24 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(6)) {
    1065          23 :                 tower.FanPowerfAirFlowCurve = Curve::GetCurveIndex(state, AlphArray(6));
    1066          23 :                 if (tower.FanPowerfAirFlowCurve == 0) {
    1067           0 :                     ShowWarningError(
    1068             :                         state,
    1069           0 :                         format(
    1070             :                             "{}, \"{}\" the Fan Power Ratio as a function of Air Flow Rate Ratio Curve Name specified as {} was not found. Fan Power "
    1071             :                             "as a function of Air Flow Rate Ratio will default to Fan Power = (Air Flow Rate Ratio)^3 and the simulation continues.",
    1072             :                             cCurrentModuleObject,
    1073           0 :                             tower.Name,
    1074             :                             AlphArray(6)));
    1075             :                 }
    1076             :             }
    1077             : 
    1078          24 :             auto &vstower = state.dataCondenserLoopTowers->towers(tower.VSTower);
    1079             : 
    1080          24 :             if (Util::SameString(AlphArray(4), "CoolToolsCrossFlow")) {
    1081          10 :                 tower.TowerModelType = ModelType::CoolToolsXFModel;
    1082             :                 //     set cross-flow model coefficients
    1083             :                 //       Outputs approach in C
    1084          10 :                 vstower.Coeff[0] = 0.52049709836241;
    1085          10 :                 vstower.Coeff[1] = -10.617046395344;
    1086          10 :                 vstower.Coeff[2] = 10.7292974722538;
    1087          10 :                 vstower.Coeff[3] = -2.74988377158227;
    1088          10 :                 vstower.Coeff[4] = 4.73629943913743;
    1089          10 :                 vstower.Coeff[5] = -8.25759700874711;
    1090          10 :                 vstower.Coeff[6] = 1.57640938114136;
    1091          10 :                 vstower.Coeff[7] = 6.51119643791324;
    1092          10 :                 vstower.Coeff[8] = 1.50433525206692;
    1093          10 :                 vstower.Coeff[9] = -3.2888529287801;
    1094          10 :                 vstower.Coeff[10] = 0.0257786145353773;
    1095          10 :                 vstower.Coeff[11] = 0.182464289315254;
    1096          10 :                 vstower.Coeff[12] = -0.0818947291400898;
    1097          10 :                 vstower.Coeff[13] = -0.215010003996285;
    1098          10 :                 vstower.Coeff[14] = 0.0186741309635284;
    1099          10 :                 vstower.Coeff[15] = 0.0536824177590012;
    1100          10 :                 vstower.Coeff[16] = -0.00270968955115031;
    1101          10 :                 vstower.Coeff[17] = 0.00112277498589279;
    1102          10 :                 vstower.Coeff[18] = -0.00127758497497718;
    1103          10 :                 vstower.Coeff[19] = 0.0000760420796601607;
    1104          10 :                 vstower.Coeff[20] = 1.43600088336017;
    1105          10 :                 vstower.Coeff[21] = -0.5198695909109;
    1106          10 :                 vstower.Coeff[22] = 0.117339576910507;
    1107          10 :                 vstower.Coeff[23] = 1.50492810819924;
    1108          10 :                 vstower.Coeff[24] = -0.135898905926974;
    1109          10 :                 vstower.Coeff[25] = -0.152577581866506;
    1110          10 :                 vstower.Coeff[26] = -0.0533843828114562;
    1111          10 :                 vstower.Coeff[27] = 0.00493294869565511;
    1112          10 :                 vstower.Coeff[28] = -0.00796260394174197;
    1113          10 :                 vstower.Coeff[29] = 0.000222619828621544;
    1114          10 :                 vstower.Coeff[30] = -0.0543952001568055;
    1115          10 :                 vstower.Coeff[31] = 0.00474266879161693;
    1116          10 :                 vstower.Coeff[32] = -0.0185854671815598;
    1117          10 :                 vstower.Coeff[33] = 0.00115667701293848;
    1118          10 :                 vstower.Coeff[34] = 0.000807370664460284;
    1119             : 
    1120             :                 //       set minimum and maximum boundaries for CoolTools crossflow model input variables
    1121          10 :                 vstower.MinInletAirWBTemp = -1.0;
    1122          10 :                 vstower.MaxInletAirWBTemp = 26.6667;
    1123          10 :                 vstower.MinRangeTemp = 1.1111;
    1124          10 :                 vstower.MaxRangeTemp = 11.1111;
    1125          10 :                 vstower.MinApproachTemp = 1.1111;
    1126          10 :                 vstower.MaxApproachTemp = 11.1111;
    1127          10 :                 vstower.MinWaterFlowRatio = 0.75;
    1128          10 :                 vstower.MaxWaterFlowRatio = 1.25;
    1129             : 
    1130          14 :             } else if (Util::SameString(AlphArray(4), "YorkCalc")) {
    1131           2 :                 tower.TowerModelType = ModelType::YorkCalcModel;
    1132             :                 //     set counter-flow model coefficients
    1133             :                 //       Outputs approach in C
    1134           2 :                 vstower.Coeff[0] = -0.359741205;
    1135           2 :                 vstower.Coeff[1] = -0.055053608;
    1136           2 :                 vstower.Coeff[2] = 0.0023850432;
    1137           2 :                 vstower.Coeff[3] = 0.173926877;
    1138           2 :                 vstower.Coeff[4] = -0.0248473764;
    1139           2 :                 vstower.Coeff[5] = 0.00048430224;
    1140           2 :                 vstower.Coeff[6] = -0.005589849456;
    1141           2 :                 vstower.Coeff[7] = 0.0005770079712;
    1142           2 :                 vstower.Coeff[8] = -0.00001342427256;
    1143           2 :                 vstower.Coeff[9] = 2.84765801111111;
    1144           2 :                 vstower.Coeff[10] = -0.121765149;
    1145           2 :                 vstower.Coeff[11] = 0.0014599242;
    1146           2 :                 vstower.Coeff[12] = 1.680428651;
    1147           2 :                 vstower.Coeff[13] = -0.0166920786;
    1148           2 :                 vstower.Coeff[14] = -0.0007190532;
    1149           2 :                 vstower.Coeff[15] = -0.025485194448;
    1150           2 :                 vstower.Coeff[16] = 0.0000487491696;
    1151           2 :                 vstower.Coeff[17] = 0.00002719234152;
    1152           2 :                 vstower.Coeff[18] = -0.0653766255555556;
    1153           2 :                 vstower.Coeff[19] = -0.002278167;
    1154           2 :                 vstower.Coeff[20] = 0.0002500254;
    1155           2 :                 vstower.Coeff[21] = -0.0910565458;
    1156           2 :                 vstower.Coeff[22] = 0.00318176316;
    1157           2 :                 vstower.Coeff[23] = 0.000038621772;
    1158           2 :                 vstower.Coeff[24] = -0.0034285382352;
    1159           2 :                 vstower.Coeff[25] = 0.00000856589904;
    1160           2 :                 vstower.Coeff[26] = -0.000001516821552;
    1161             : 
    1162             :                 //       set minimum and maximum boundaries for YorkCalc model input variables
    1163           2 :                 vstower.MinInletAirWBTemp = -34.4;
    1164           2 :                 vstower.MaxInletAirWBTemp = 29.4444;
    1165           2 :                 vstower.MinRangeTemp = 1.1111;
    1166           2 :                 vstower.MaxRangeTemp = 22.2222;
    1167           2 :                 vstower.MinApproachTemp = 1.1111;
    1168           2 :                 vstower.MaxApproachTemp = 40.0;
    1169           2 :                 vstower.MinWaterFlowRatio = 0.75;
    1170           2 :                 vstower.MaxWaterFlowRatio = 1.25;
    1171           2 :                 vstower.MaxLiquidToGasRatio = 8.0;
    1172             : 
    1173          12 :             } else if (Util::SameString(AlphArray(4), "CoolToolsUserDefined")) {
    1174           1 :                 tower.TowerModelType = ModelType::CoolToolsUserDefined;
    1175             :                 // Nested Get-input routines below.  Should pull out of here and read in beforehand.
    1176           1 :                 for (VSModelCoeffNum = 1; VSModelCoeffNum <= NumVSCoolToolsModelCoeffs; ++VSModelCoeffNum) {
    1177           1 :                     state.dataInputProcessing->inputProcessor->getObjectItem(
    1178             :                         state, "CoolingTowerPerformance:CoolTools", VSModelCoeffNum, AlphArray2, NumAlphas2, NumArray2, NumNums2, IOStat);
    1179           1 :                     if (!Util::SameString(AlphArray2(1), tower.ModelCoeffObjectName)) continue;
    1180           1 :                     vstower.FoundModelCoeff = true;
    1181             :                     // verify the correct number of coefficients for the CoolTools model
    1182           1 :                     if (NumNums2 != 43) {
    1183           0 :                         ShowSevereError(state,
    1184           0 :                                         format("CoolingTower:VariableSpeed \"{}\". The number of numeric inputs for object "
    1185             :                                                "CoolingTowerPerformance:CoolTools \"{}\" must equal 43.",
    1186           0 :                                                tower.Name,
    1187           0 :                                                tower.ModelCoeffObjectName));
    1188           0 :                         ErrorsFound = true;
    1189             :                     } else {
    1190             : 
    1191           1 :                         vstower.MinInletAirWBTemp = NumArray2(1);
    1192           1 :                         vstower.MaxInletAirWBTemp = NumArray2(2);
    1193           1 :                         vstower.MinRangeTemp = NumArray2(3);
    1194           1 :                         vstower.MaxRangeTemp = NumArray2(4);
    1195           1 :                         vstower.MinApproachTemp = NumArray2(5);
    1196           1 :                         vstower.MaxApproachTemp = NumArray2(6);
    1197           1 :                         vstower.MinWaterFlowRatio = NumArray2(7);
    1198           1 :                         vstower.MaxWaterFlowRatio = NumArray2(8);
    1199             : 
    1200          36 :                         for (CoeffNum = 9; CoeffNum <= NumNums2; ++CoeffNum) {
    1201          35 :                             vstower.Coeff[CoeffNum - 9] = NumArray2(CoeffNum);
    1202             :                         }
    1203             :                     }
    1204           1 :                     break;
    1205             :                 }
    1206           1 :                 if (!vstower.FoundModelCoeff) {
    1207           0 :                     ShowSevereError(state,
    1208           0 :                                     format("CoolingTower:VariableSpeed \"{}\". User defined name for variable speed cooling tower model coefficients "
    1209             :                                            "object not found = {}",
    1210           0 :                                            tower.Name,
    1211           0 :                                            tower.ModelCoeffObjectName));
    1212           0 :                     ErrorsFound = true;
    1213             :                 }
    1214          11 :             } else if (Util::SameString(AlphArray(4), "YorkCalcUserDefined")) {
    1215          11 :                 tower.TowerModelType = ModelType::YorkCalcUserDefined;
    1216             :                 // Nested Get-input routines below.  Should pull out of here and read in beforehand.
    1217          11 :                 for (VSModelCoeffNum = 1; VSModelCoeffNum <= NumVSYorkCalcModelCoeffs; ++VSModelCoeffNum) {
    1218          11 :                     state.dataInputProcessing->inputProcessor->getObjectItem(
    1219             :                         state, "CoolingTowerPerformance:YorkCalc", VSModelCoeffNum, AlphArray2, NumAlphas2, NumArray2, NumNums2, IOStat);
    1220          11 :                     if (!Util::SameString(AlphArray2(1), tower.ModelCoeffObjectName)) continue;
    1221          11 :                     vstower.FoundModelCoeff = true;
    1222             :                     // verify the correct number of coefficients for the YorkCalc model
    1223          11 :                     if (NumNums2 != 36) {
    1224           0 :                         ShowSevereError(state,
    1225           0 :                                         format("CoolingTower:VariableSpeed \"{}\". The number of numeric inputs for object "
    1226             :                                                "CoolingTowerPerformance:YorkCalc \"{}\" must equal 36.",
    1227           0 :                                                tower.Name,
    1228           0 :                                                tower.ModelCoeffObjectName));
    1229           0 :                         ErrorsFound = true;
    1230             :                     } else {
    1231             : 
    1232          11 :                         vstower.MinInletAirWBTemp = NumArray2(1);
    1233          11 :                         vstower.MaxInletAirWBTemp = NumArray2(2);
    1234          11 :                         vstower.MinRangeTemp = NumArray2(3);
    1235          11 :                         vstower.MaxRangeTemp = NumArray2(4);
    1236          11 :                         vstower.MinApproachTemp = NumArray2(5);
    1237          11 :                         vstower.MaxApproachTemp = NumArray2(6);
    1238          11 :                         vstower.MinWaterFlowRatio = NumArray2(7);
    1239          11 :                         vstower.MaxWaterFlowRatio = NumArray2(8);
    1240          11 :                         vstower.MaxLiquidToGasRatio = NumArray2(9);
    1241             : 
    1242         308 :                         for (CoeffNum = 10; CoeffNum <= NumNums2; ++CoeffNum) {
    1243         297 :                             vstower.Coeff[CoeffNum - 10] = NumArray2(CoeffNum);
    1244             :                         }
    1245             :                     }
    1246          11 :                     break;
    1247             :                 }
    1248             : 
    1249          11 :                 if (!vstower.FoundModelCoeff) {
    1250           0 :                     ShowSevereError(state,
    1251           0 :                                     format("{} \"{}\". User defined name for variable speed cooling tower model coefficients object not found = {}",
    1252             :                                            cCurrentModuleObject,
    1253           0 :                                            tower.Name,
    1254           0 :                                            tower.ModelCoeffObjectName));
    1255           0 :                     ErrorsFound = true;
    1256             :                 }
    1257             :             } else {
    1258           0 :                 ShowSevereError(state, format("{} \"{}\". Illegal Tower Model Type = {}", cCurrentModuleObject, tower.Name, AlphArray(5)));
    1259           0 :                 ShowContinueError(state,
    1260             :                                   R"( Tower Model Type must be "CoolToolsCrossFlow", "YorkCalc", "CoolToolsUserDefined", or "YorkCalcUserDefined.)");
    1261           0 :                 ErrorsFound = true;
    1262             :             }
    1263             : 
    1264          24 :             tower.TowerMassFlowRateMultiplier = vstower.MaxWaterFlowRatio;
    1265             : 
    1266             :             //   check user defined minimums to be greater than 0
    1267          24 :             if (vstower.MinApproachTemp < 0.0) {
    1268           0 :                 ShowSevereError(state, format("{} \"{}\". User defined minimum approach temperature must be > 0", cCurrentModuleObject, tower.Name));
    1269           0 :                 ErrorsFound = true;
    1270             :             }
    1271          24 :             if (vstower.MinRangeTemp < 0.0) {
    1272           0 :                 ShowSevereError(state, format("{} \"{}\". User defined minimum range temperature must be > 0", cCurrentModuleObject, tower.Name));
    1273           0 :                 ErrorsFound = true;
    1274             :             }
    1275          24 :             if (vstower.MinWaterFlowRatio < 0.0) {
    1276           0 :                 ShowSevereError(state, format("{} \"{}\". User defined minimum water flow rate ratio must be > 0", cCurrentModuleObject, tower.Name));
    1277           0 :                 ErrorsFound = true;
    1278             :             }
    1279             : 
    1280             :             //   check that the user defined maximums are greater than the minimums
    1281          24 :             if (vstower.MaxApproachTemp < vstower.MinApproachTemp) {
    1282           0 :                 ShowSevereError(state,
    1283           0 :                                 format("{} \"{}\". User defined maximum approach temperature must be > the minimum approach temperature",
    1284             :                                        cCurrentModuleObject,
    1285           0 :                                        tower.Name));
    1286           0 :                 ErrorsFound = true;
    1287             :             }
    1288          24 :             if (vstower.MaxRangeTemp < vstower.MinRangeTemp) {
    1289           0 :                 ShowSevereError(state,
    1290           0 :                                 format("{} \"{}\". User defined maximum range temperature must be > the minimum range temperature",
    1291             :                                        cCurrentModuleObject,
    1292           0 :                                        tower.Name));
    1293           0 :                 ErrorsFound = true;
    1294             :             }
    1295          24 :             if (vstower.MaxWaterFlowRatio < vstower.MinWaterFlowRatio) {
    1296           0 :                 ShowSevereError(state,
    1297           0 :                                 format("{} \"{}\". User defined maximum water flow rate ratio must be > the minimum water flow rate ratio",
    1298             :                                        cCurrentModuleObject,
    1299           0 :                                        tower.Name));
    1300           0 :                 ErrorsFound = true;
    1301             :             }
    1302             : 
    1303          24 :             tower.DesignInletWB = NumArray(1);
    1304          24 :             if (NumArray(1) < vstower.MinInletAirWBTemp || NumArray(1) > vstower.MaxInletAirWBTemp) {
    1305           0 :                 ShowSevereError(state,
    1306           0 :                                 cCurrentModuleObject.append(", \"")
    1307           0 :                                     .append(tower.Name)
    1308           0 :                                     .append("\" the design inlet air wet-bulb temperature of ")
    1309           0 :                                     .append(format(OutputFormat, tower.DesignInletWB))
    1310           0 :                                     .append(" must be within the model limits of ")
    1311           0 :                                     .append(format(OutputFormat, vstower.MinInletAirWBTemp))
    1312           0 :                                     .append(" and ")
    1313           0 :                                     .append(format(OutputFormat, vstower.MaxInletAirWBTemp))
    1314           0 :                                     .append(" degrees C"));
    1315           0 :                 ErrorsFound = true;
    1316             :             }
    1317             : 
    1318          24 :             tower.DesignApproach = NumArray(2);
    1319          24 :             if (NumArray(2) < vstower.MinApproachTemp || NumArray(2) > vstower.MaxApproachTemp) {
    1320           0 :                 ShowSevereError(state,
    1321           0 :                                 cCurrentModuleObject.append(", \"")
    1322           0 :                                     .append(tower.Name)
    1323           0 :                                     .append("\" the design approach temperature of ")
    1324           0 :                                     .append(format(OutputFormat, tower.DesignApproach))
    1325           0 :                                     .append(" must be within the model limits of ")
    1326           0 :                                     .append(format(OutputFormat, vstower.MinApproachTemp))
    1327           0 :                                     .append(" and ")
    1328           0 :                                     .append(format(OutputFormat, vstower.MaxApproachTemp))
    1329           0 :                                     .append(" degrees C"));
    1330           0 :                 ErrorsFound = true;
    1331             :             }
    1332             : 
    1333          24 :             tower.DesignRange = NumArray(3);
    1334          24 :             if (NumArray(3) < vstower.MinRangeTemp || NumArray(3) > vstower.MaxRangeTemp) {
    1335           0 :                 ShowSevereError(state,
    1336           0 :                                 cCurrentModuleObject.append(", \"")
    1337           0 :                                     .append(tower.Name)
    1338           0 :                                     .append("\" the design range temperature of ")
    1339           0 :                                     .append(format(OutputFormat, tower.DesignRange))
    1340           0 :                                     .append(" must be within the model limits of ")
    1341           0 :                                     .append(format(OutputFormat, vstower.MinRangeTemp))
    1342           0 :                                     .append(" and ")
    1343           0 :                                     .append(format(OutputFormat, vstower.MaxRangeTemp))
    1344           0 :                                     .append(" degrees C"));
    1345           0 :                 ErrorsFound = true;
    1346             :             }
    1347             : 
    1348          24 :             tower.DesignWaterFlowRate = NumArray(4);
    1349          24 :             if (tower.DesignWaterFlowRate == DataSizing::AutoSize) {
    1350          13 :                 tower.DesignWaterFlowRateWasAutoSized = true;
    1351             :             }
    1352          24 :             if (NumArray(4) <= 0.0 && NumArray(4) != DataSizing::AutoSize) {
    1353           0 :                 ShowSevereError(state, format("{}, \"{}\" design water flow rate must be > 0", cCurrentModuleObject, tower.Name));
    1354           0 :                 ErrorsFound = true;
    1355             :             }
    1356             : 
    1357          24 :             tower.HighSpeedAirFlowRate = NumArray(5);
    1358          24 :             if (tower.HighSpeedAirFlowRate == DataSizing::AutoSize) {
    1359          24 :                 tower.HighSpeedAirFlowRateWasAutoSized = true;
    1360             :             }
    1361          24 :             if (NumArray(5) <= 0.0 && NumArray(5) != DataSizing::AutoSize) {
    1362           0 :                 ShowSevereError(state, format("{}, \"{}\" design air flow rate must be > 0", cCurrentModuleObject, tower.Name));
    1363           0 :                 ErrorsFound = true;
    1364             :             }
    1365             : 
    1366          24 :             tower.HighSpeedFanPower = NumArray(6);
    1367          24 :             if (tower.HighSpeedFanPower == DataSizing::AutoSize) {
    1368          13 :                 tower.HighSpeedFanPowerWasAutoSized = true;
    1369             :             }
    1370          24 :             if (NumArray(6) <= 0.0 && NumArray(6) != DataSizing::AutoSize) {
    1371           0 :                 ShowSevereError(state, format("{}, \"{}\" design fan power must be > 0", cCurrentModuleObject, tower.Name));
    1372           0 :                 ErrorsFound = true;
    1373             :             }
    1374             : 
    1375             :             //   minimum air flow rate fraction must be >= 0.2 and <= 0.5, below this value the tower fan cycles to maintain the setpoint
    1376          24 :             tower.MinimumVSAirFlowFrac = NumArray(7);
    1377          24 :             tower.MinimumVSAirFlowFrac = NumArray(7);
    1378          24 :             if (NumArray(7) < 0.2 || NumArray(7) > 0.5) {
    1379           0 :                 ShowSevereError(state,
    1380           0 :                                 format("{}, \"{}\" minimum VS air flow rate ratio must be >= 0.2 and <= 0.5", cCurrentModuleObject, tower.Name));
    1381           0 :                 ErrorsFound = true;
    1382             :             }
    1383             : 
    1384             :             //   fraction of tower capacity in free convection regime must be >= to 0 and <= 0.2
    1385          24 :             tower.FreeConvectionCapacityFraction = NumArray(8);
    1386          24 :             if (NumArray(8) < 0.0 || NumArray(8) > 0.2) {
    1387           0 :                 ShowSevereError(state,
    1388           0 :                                 format("{}, \"{}\" fraction of tower capacity in free convection regime must be >= 0 and <= 0.2",
    1389             :                                        cCurrentModuleObject,
    1390           0 :                                        tower.Name));
    1391           0 :                 ErrorsFound = true;
    1392             :             }
    1393             : 
    1394             :             //   Basin heater power as a function of temperature must be greater than or equal to 0
    1395          24 :             tower.BasinHeaterPowerFTempDiff = NumArray(9);
    1396          24 :             if (NumArray(9) < 0.0) {
    1397           0 :                 ShowSevereError(
    1398             :                     state,
    1399           0 :                     format("{}, \"{}\" basin heater power as a function of temperature difference must be >= 0", cCurrentModuleObject, tower.Name));
    1400           0 :                 ErrorsFound = true;
    1401             :             }
    1402             : 
    1403          24 :             tower.BasinHeaterSetPointTemp = NumArray(10);
    1404          24 :             if (tower.BasinHeaterPowerFTempDiff > 0.0) {
    1405          12 :                 if (NumNums < 10) {
    1406           0 :                     tower.BasinHeaterSetPointTemp = 2.0;
    1407             :                 }
    1408          12 :                 if (tower.BasinHeaterSetPointTemp < 2.0) {
    1409           0 :                     ShowWarningError(state,
    1410           0 :                                      format("{}:\"{}\", {} is less than 2 deg C. Freezing could occur.",
    1411             :                                             cCurrentModuleObject,
    1412           0 :                                             tower.Name,
    1413           0 :                                             state.dataIPShortCut->cNumericFieldNames(10)));
    1414             :                 }
    1415             :             }
    1416             : 
    1417             :             // Performance Input Method for Variable Speed Towers is assigned to be UA AND DESIGN WATER FLOW RATE
    1418             :             // for autosizing calculations (see SizeTower)
    1419          24 :             tower.PerformanceInputMethod_Num = PIM::UFactor;
    1420             : 
    1421          24 :             if (!AlphArray(7).empty()) {
    1422           0 :                 tower.BasinHeaterSchedulePtr = ScheduleManager::GetScheduleIndex(state, AlphArray(7));
    1423           0 :                 if (tower.BasinHeaterSchedulePtr == 0) {
    1424           0 :                     ShowWarningError(state,
    1425           0 :                                      format("{}, \"{}\" basin heater schedule name \"{}\" was not found. Basin heater operation will not be modeled "
    1426             :                                             "and the simulation continues",
    1427             :                                             cCurrentModuleObject,
    1428           0 :                                             tower.Name,
    1429             :                                             AlphArray(7)));
    1430             :                 }
    1431             :             }
    1432             : 
    1433             :             // begin water use and systems get input
    1434          24 :             tower.EvapLossMode = static_cast<EvapLoss>(getEnumValue(EvapLossNamesUC, Util::makeUPPER(AlphArray(8))));
    1435          24 :             tower.UserEvapLossFactor = NumArray(11);        //  N11 , \field Evaporation Loss Factor
    1436          24 :             tower.DriftLossFraction = NumArray(12) / 100.0; //  N12, \field Drift Loss Percent
    1437          24 :             tower.ConcentrationRatio = NumArray(13);        //  N13, \field Blowdown Concentration Ratio
    1438          24 :             tower.SizFac = NumArray(17);                    //  N14  \field Sizing Factor
    1439          24 :             if (tower.SizFac <= 0.0) tower.SizFac = 1.0;
    1440             : 
    1441          24 :             tower.BlowdownMode = static_cast<Blowdown>(getEnumValue(BlowDownNamesUC, Util::makeUPPER(AlphArray(9))));
    1442          24 :             tower.SchedIDBlowdown = ScheduleManager::GetScheduleIndex(state, AlphArray(10));
    1443          24 :             if ((tower.SchedIDBlowdown == 0) && (tower.BlowdownMode == Blowdown::Schedule)) {
    1444           0 :                 ShowSevereError(state, format("Invalid, {} = \"{}\"", state.dataIPShortCut->cAlphaFieldNames(10), AlphArray(10)));
    1445           0 :                 ShowContinueError(state, format("Entered in {} = \"{}\"", cCoolingTower_VariableSpeed, tower.Name));
    1446           0 :                 ErrorsFound = true;
    1447             :             }
    1448             : 
    1449             :             // added for multi-cell
    1450          24 :             tower.NumCell = NumArray(14);
    1451          24 :             if ((NumNums < 14) && (tower.NumCell == 0)) {
    1452             :                 // assume Number of Cells not entered and should be defaulted
    1453           0 :                 tower.NumCell = 1;
    1454             :             }
    1455          24 :             tower.MinFracFlowRate = NumArray(15);
    1456          24 :             if ((NumNums < 15) && (tower.MinFracFlowRate == 0.0)) {
    1457             :                 // assume Cell Minimum Water Flow Rate Fraction not entered and should be defaulted
    1458           0 :                 tower.MinFracFlowRate = 0.33;
    1459             :             }
    1460          24 :             tower.MaxFracFlowRate = NumArray(16);
    1461          24 :             if ((NumNums < 16) && (tower.MaxFracFlowRate == 0.0)) {
    1462             :                 // assume Cell Maximum Water Flow Rate Fraction not entered and should be defaulted
    1463           0 :                 tower.MaxFracFlowRate = 2.5;
    1464             :             }
    1465             : 
    1466             :             //   cell control for variable speed tower
    1467          24 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(13)) {
    1468          12 :                 tower.cellCtrl = static_cast<CellCtrl>(getEnumValue(CellCtrlNamesUC, Util::makeUPPER(AlphArray(13))));
    1469             :             }
    1470             : 
    1471          24 :             if (state.dataIPShortCut->lAlphaFieldBlanks(11)) {
    1472          24 :                 tower.SuppliedByWaterSystem = false;
    1473             :             } else { // water from storage tank
    1474           0 :                 WaterManager::SetupTankDemandComponent(
    1475           0 :                     state, AlphArray(1), cCurrentModuleObject, AlphArray(11), ErrorsFound, tower.WaterTankID, tower.WaterTankDemandARRID);
    1476           0 :                 tower.SuppliedByWaterSystem = true;
    1477             :             }
    1478             : 
    1479             :             //   outdoor air inlet node
    1480          24 :             if (state.dataIPShortCut->lAlphaFieldBlanks(12)) {
    1481          24 :                 tower.OutdoorAirInletNodeNum = 0;
    1482             :             } else {
    1483           0 :                 tower.OutdoorAirInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
    1484           0 :                                                                                    AlphArray(12),
    1485             :                                                                                    ErrorsFound,
    1486             :                                                                                    DataLoopNode::ConnectionObjectType::CoolingTowerVariableSpeed,
    1487           0 :                                                                                    tower.Name,
    1488             :                                                                                    DataLoopNode::NodeFluidType::Air,
    1489             :                                                                                    DataLoopNode::ConnectionType::OutsideAirReference,
    1490             :                                                                                    NodeInputManager::CompFluidStream::Primary,
    1491             :                                                                                    DataLoopNode::ObjectIsNotParent);
    1492           0 :                 if (!OutAirNodeManager::CheckOutAirNodeNumber(state, tower.OutdoorAirInletNodeNum)) {
    1493           0 :                     ShowSevereError(state,
    1494           0 :                                     format("{}, \"{}\" Outdoor Air Inlet Node Name not valid Outdoor Air Node= {}",
    1495             :                                            cCurrentModuleObject,
    1496           0 :                                            tower.Name,
    1497             :                                            AlphArray(12)));
    1498           0 :                     ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
    1499           0 :                     ErrorsFound = true;
    1500             :                 }
    1501             :             }
    1502          24 :             if (NumAlphas > 13) {
    1503           1 :                 tower.EndUseSubcategory = AlphArray(14);
    1504             :             } else {
    1505          23 :                 tower.EndUseSubcategory = "General";
    1506             :             }
    1507             : 
    1508             :         } // End Variable-Speed Tower Loop
    1509             : 
    1510         244 :         cCurrentModuleObject = cCoolingTower_VariableSpeedMerkel;
    1511         246 :         for (int MerkelVSTowerNum = 1; MerkelVSTowerNum <= NumVSMerkelTowers; ++MerkelVSTowerNum) {
    1512           2 :             TowerNum = NumSingleSpeedTowers + NumTwoSpeedTowers + NumVariableSpeedTowers + MerkelVSTowerNum;
    1513           4 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1514             :                                                                      cCurrentModuleObject,
    1515             :                                                                      MerkelVSTowerNum,
    1516             :                                                                      AlphArray,
    1517             :                                                                      NumAlphas,
    1518             :                                                                      NumArray,
    1519             :                                                                      NumNums,
    1520             :                                                                      IOStat,
    1521           2 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    1522           2 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    1523           2 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    1524           2 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    1525           2 :             GlobalNames::VerifyUniqueInterObjectName(
    1526           4 :                 state, UniqueSimpleTowerNames, AlphArray(1), cCurrentModuleObject, state.dataIPShortCut->cAlphaFieldNames(1), ErrorsFound);
    1527           2 :             auto &tower = state.dataCondenserLoopTowers->towers(TowerNum);
    1528           2 :             tower.Name = AlphArray(1);
    1529           2 :             tower.TowerType = DataPlant::PlantEquipmentType::CoolingTower_VarSpdMerkel;
    1530           2 :             tower.WaterInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
    1531           2 :                                                                           AlphArray(2),
    1532             :                                                                           ErrorsFound,
    1533             :                                                                           DataLoopNode::ConnectionObjectType::CoolingTowerVariableSpeedMerkel,
    1534           2 :                                                                           AlphArray(1),
    1535             :                                                                           DataLoopNode::NodeFluidType::Water,
    1536             :                                                                           DataLoopNode::ConnectionType::Inlet,
    1537             :                                                                           NodeInputManager::CompFluidStream::Primary,
    1538             :                                                                           DataLoopNode::ObjectIsNotParent);
    1539           2 :             tower.WaterOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
    1540           2 :                                                                            AlphArray(3),
    1541             :                                                                            ErrorsFound,
    1542             :                                                                            DataLoopNode::ConnectionObjectType::CoolingTowerVariableSpeedMerkel,
    1543           2 :                                                                            AlphArray(1),
    1544             :                                                                            DataLoopNode::NodeFluidType::Water,
    1545             :                                                                            DataLoopNode::ConnectionType::Outlet,
    1546             :                                                                            NodeInputManager::CompFluidStream::Primary,
    1547             :                                                                            DataLoopNode::ObjectIsNotParent);
    1548           2 :             BranchNodeConnections::TestCompSet(state, cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Chilled Water Nodes");
    1549             : 
    1550           2 :             if (Util::SameString(AlphArray(4), "UFactorTimesAreaAndDesignWaterFlowRate")) {
    1551           0 :                 tower.PerformanceInputMethod_Num = PIM::UFactor;
    1552           2 :             } else if (Util::SameString(AlphArray(4), "NominalCapacity")) {
    1553           2 :                 tower.PerformanceInputMethod_Num = PIM::NominalCapacity;
    1554             :             } else {
    1555           0 :                 ShowSevereError(state, format("{}={}", cCurrentModuleObject, AlphArray(1)));
    1556           0 :                 ShowContinueError(state, format("Invalid, {} = {}", state.dataIPShortCut->cAlphaFieldNames(4), AlphArray(4)));
    1557           0 :                 ErrorsFound = true;
    1558             :             }
    1559             : 
    1560           2 :             tower.FanPowerfAirFlowCurve = Curve::GetCurveIndex(state, AlphArray(5));
    1561           2 :             if (tower.FanPowerfAirFlowCurve == 0) {
    1562           0 :                 ShowSevereError(state, format("{}={}", cCurrentModuleObject, AlphArray(1)));
    1563           0 :                 ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(5), AlphArray(5)));
    1564           0 :                 ShowContinueError(state, "Curve name not found.");
    1565           0 :                 ErrorsFound = true;
    1566             :             }
    1567             : 
    1568           2 :             tower.HeatRejectCapNomCapSizingRatio = NumArray(1);
    1569           2 :             tower.TowerNominalCapacity = NumArray(2);
    1570           2 :             if (tower.TowerNominalCapacity == DataSizing::AutoSize) {
    1571           2 :                 tower.TowerNominalCapacityWasAutoSized = true;
    1572             :             }
    1573           2 :             tower.TowerFreeConvNomCap = NumArray(3);
    1574           2 :             if (tower.TowerFreeConvNomCap == DataSizing::AutoSize) {
    1575           2 :                 tower.TowerFreeConvNomCapWasAutoSized = true;
    1576             :             }
    1577           2 :             tower.TowerFreeConvNomCapSizingFactor = NumArray(4);
    1578           2 :             tower.DesignWaterFlowRate = NumArray(5);
    1579           2 :             if (tower.DesignWaterFlowRate == DataSizing::AutoSize) {
    1580           2 :                 tower.DesignWaterFlowRateWasAutoSized = true;
    1581             :             }
    1582           2 :             tower.DesignWaterFlowPerUnitNomCap = NumArray(6);
    1583           2 :             tower.HighSpeedAirFlowRate = NumArray(7);
    1584           2 :             if (tower.HighSpeedAirFlowRate == DataSizing::AutoSize) {
    1585           2 :                 tower.HighSpeedAirFlowRateWasAutoSized = true;
    1586             :             }
    1587           2 :             tower.DefaultedDesignAirFlowScalingFactor = state.dataIPShortCut->lNumericFieldBlanks(8);
    1588           2 :             tower.DesignAirFlowPerUnitNomCap = NumArray(8);
    1589           2 :             tower.MinimumVSAirFlowFrac = NumArray(9);
    1590           2 :             tower.HighSpeedFanPower = NumArray(10);
    1591           2 :             if (tower.HighSpeedFanPower == DataSizing::AutoSize) {
    1592           2 :                 tower.HighSpeedFanPowerWasAutoSized = true;
    1593             :             }
    1594           2 :             tower.DesignFanPowerPerUnitNomCap = NumArray(11);
    1595           2 :             tower.FreeConvAirFlowRate = NumArray(12);
    1596           2 :             if (tower.FreeConvAirFlowRate == DataSizing::AutoSize) {
    1597           2 :                 tower.FreeConvAirFlowRateWasAutoSized = true;
    1598             :             }
    1599           2 :             tower.FreeConvAirFlowRateSizingFactor = NumArray(13);
    1600           2 :             tower.HighSpeedTowerUA = NumArray(14);
    1601           2 :             if (tower.HighSpeedTowerUA == DataSizing::AutoSize) {
    1602           0 :                 tower.HighSpeedTowerUAWasAutoSized = true;
    1603             :             }
    1604           2 :             tower.FreeConvTowerUA = NumArray(15);
    1605           2 :             if (tower.FreeConvTowerUA == DataSizing::AutoSize) {
    1606           0 :                 tower.FreeConvTowerUAWasAutoSized = true;
    1607             :             }
    1608           2 :             tower.FreeConvTowerUASizingFactor = NumArray(16);
    1609             : 
    1610           2 :             tower.UAModFuncAirFlowRatioCurvePtr = Curve::GetCurveIndex(state, AlphArray(6));
    1611           2 :             if (tower.UAModFuncAirFlowRatioCurvePtr == 0) {
    1612           0 :                 ShowSevereError(state, format("{}={}", cCurrentModuleObject, AlphArray(1)));
    1613           0 :                 ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(6), AlphArray(6)));
    1614           0 :                 ShowContinueError(state, "Curve name not found.");
    1615           0 :                 ErrorsFound = true;
    1616             :             }
    1617             : 
    1618           2 :             tower.UAModFuncWetBulbDiffCurvePtr = Curve::GetCurveIndex(state, AlphArray(7));
    1619           2 :             if (tower.UAModFuncWetBulbDiffCurvePtr == 0) {
    1620           0 :                 ShowSevereError(state, format("{}={}", cCurrentModuleObject, AlphArray(1)));
    1621           0 :                 ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(7), AlphArray(7)));
    1622           0 :                 ShowContinueError(state, "Curve name not found.");
    1623           0 :                 ErrorsFound = true;
    1624             :             }
    1625             : 
    1626           2 :             tower.UAModFuncWaterFlowRatioCurvePtr = Curve::GetCurveIndex(state, AlphArray(8));
    1627           2 :             if (tower.UAModFuncWaterFlowRatioCurvePtr == 0) {
    1628           0 :                 ShowSevereError(state, format("{}={}", cCurrentModuleObject, AlphArray(1)));
    1629           0 :                 ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(8), AlphArray(8)));
    1630           0 :                 ShowContinueError(state, "Curve name not found.");
    1631           0 :                 ErrorsFound = true;
    1632             :             }
    1633             :             // cooling tower design inlet conditions
    1634           2 :             tower.DesInletAirDBTemp = NumArray(17);
    1635           2 :             if (tower.DesInletAirDBTemp == 0) {
    1636           0 :                 tower.DesInletAirDBTemp = 35.0;
    1637           0 :                 tower.TowerInletCondsAutoSize = true;
    1638             :             }
    1639           2 :             tower.DesInletAirWBTemp = NumArray(18);
    1640           2 :             if (tower.DesInletAirWBTemp == 0) {
    1641           0 :                 tower.DesInletAirWBTemp = 25.6;
    1642           0 :                 tower.TowerInletCondsAutoSize = true;
    1643             :             }
    1644           2 :             tower.DesApproach = NumArray(19);
    1645           2 :             if (tower.DesApproach == DataSizing::AutoSize || tower.DesApproach == 0) {
    1646           2 :                 tower.DesApproach = 3.9;
    1647           2 :                 tower.TowerInletCondsAutoSize = true;
    1648             :             }
    1649           2 :             tower.DesRange = NumArray(20);
    1650           2 :             if (tower.DesRange == DataSizing::AutoSize || tower.DesRange == 0) {
    1651           2 :                 tower.DesRange = 5.5;
    1652           2 :                 tower.TowerInletCondsAutoSize = true;
    1653             :             }
    1654             :             // set tower design water outlet and inlet temperatures
    1655           2 :             tower.DesOutletWaterTemp = tower.DesInletAirWBTemp + tower.DesApproach;
    1656           2 :             tower.DesInletWaterTemp = tower.DesOutletWaterTemp + tower.DesRange;
    1657             :             //   Basin heater power as a function of temperature must be greater than or equal to 0
    1658           2 :             tower.BasinHeaterPowerFTempDiff = NumArray(21);
    1659           2 :             if (NumArray(21) < 0.0) {
    1660           0 :                 ShowSevereError(
    1661             :                     state,
    1662           0 :                     format("{}, \"{}\" basin heater power as a function of temperature difference must be >= 0", cCurrentModuleObject, tower.Name));
    1663           0 :                 ErrorsFound = true;
    1664             :             }
    1665             : 
    1666           2 :             tower.BasinHeaterSetPointTemp = NumArray(22);
    1667           2 :             if (tower.BasinHeaterPowerFTempDiff > 0.0) {
    1668           0 :                 if (NumNums < 22) {
    1669           0 :                     tower.BasinHeaterSetPointTemp = 2.0;
    1670             :                 }
    1671           0 :                 if (tower.BasinHeaterSetPointTemp < 2.0) {
    1672           0 :                     ShowWarningError(state,
    1673           0 :                                      format("{}:\"{}\", {} is less than 2 deg C. Freezing could occur.",
    1674             :                                             cCurrentModuleObject,
    1675           0 :                                             tower.Name,
    1676           0 :                                             state.dataIPShortCut->cNumericFieldNames(22)));
    1677             :                 }
    1678             :             }
    1679             : 
    1680           2 :             if (!AlphArray(9).empty()) {
    1681           0 :                 tower.BasinHeaterSchedulePtr = ScheduleManager::GetScheduleIndex(state, AlphArray(9));
    1682           0 :                 if (tower.BasinHeaterSchedulePtr == 0) {
    1683           0 :                     ShowWarningError(state,
    1684           0 :                                      format("{}, \"{}\" basin heater schedule name \"{}\" was not found. Basin heater operation will not be modeled "
    1685             :                                             "and the simulation continues",
    1686             :                                             cCurrentModuleObject,
    1687           0 :                                             tower.Name,
    1688             :                                             AlphArray(9)));
    1689             :                 }
    1690             :             }
    1691             : 
    1692             :             // begin water use and systems get input
    1693           2 :             tower.EvapLossMode = static_cast<EvapLoss>(getEnumValue(EvapLossNamesUC, Util::makeUPPER(AlphArray(10))));
    1694           2 :             tower.UserEvapLossFactor = NumArray(23);        //  N23 , \field Evaporation Loss Factor
    1695           2 :             tower.DriftLossFraction = NumArray(24) / 100.0; //  N24, \field Drift Loss Percent
    1696           2 :             tower.ConcentrationRatio = NumArray(25);        //  N25, \field Blowdown Concentration Ratio
    1697           2 :             tower.SizFac = NumArray(29);                    //  N29  \field Sizing Factor
    1698           2 :             if (tower.SizFac <= 0.0) tower.SizFac = 1.0;
    1699             : 
    1700           2 :             tower.BlowdownMode = static_cast<Blowdown>(getEnumValue(BlowDownNamesUC, Util::makeUPPER(AlphArray(11))));
    1701           2 :             tower.SchedIDBlowdown = ScheduleManager::GetScheduleIndex(state, AlphArray(12));
    1702           2 :             if ((tower.SchedIDBlowdown == 0) && (tower.BlowdownMode == Blowdown::Schedule)) {
    1703           0 :                 ShowSevereError(state, format("Invalid, {} = \"{}\"", state.dataIPShortCut->cAlphaFieldNames(12), AlphArray(12)));
    1704           0 :                 ShowContinueError(state, format("Entered in {} = \"{}\"", cCoolingTower_VariableSpeedMerkel, tower.Name));
    1705           0 :                 ErrorsFound = true;
    1706             :             }
    1707             : 
    1708             :             // added for multi-cell
    1709           2 :             tower.NumCell = NumArray(26);
    1710           2 :             if ((NumNums < 26) && (tower.NumCell == 0)) {
    1711             :                 // assume Number of Cells not entered and should be defaulted
    1712           0 :                 tower.NumCell = 1;
    1713             :             }
    1714           2 :             tower.MinFracFlowRate = NumArray(27);
    1715           2 :             if ((NumNums < 27) && (tower.MinFracFlowRate == 0.0)) {
    1716             :                 // assume Cell Minimum Water Flow Rate Fraction not entered and should be defaulted
    1717           0 :                 tower.MinFracFlowRate = 0.33;
    1718             :             }
    1719           2 :             tower.MaxFracFlowRate = NumArray(28);
    1720           2 :             if ((NumNums < 28) && (tower.MaxFracFlowRate == 0.0)) {
    1721             :                 // assume Cell Maximum Water Flow Rate Fraction not entered and should be defaulted
    1722           0 :                 tower.MaxFracFlowRate = 2.5;
    1723             :             }
    1724           2 :             tower.TowerMassFlowRateMultiplier = tower.MaxFracFlowRate;
    1725             :             //   cell control for variable speed Merkel tower
    1726           2 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(15)) {
    1727           0 :                 tower.cellCtrl = static_cast<CellCtrl>(getEnumValue(CellCtrlNamesUC, Util::makeUPPER(AlphArray(15))));
    1728             :             }
    1729             : 
    1730           2 :             if (state.dataIPShortCut->lAlphaFieldBlanks(13)) {
    1731           2 :                 tower.SuppliedByWaterSystem = false;
    1732             :             } else { // water from storage tank
    1733           0 :                 WaterManager::SetupTankDemandComponent(
    1734           0 :                     state, AlphArray(1), cCurrentModuleObject, AlphArray(13), ErrorsFound, tower.WaterTankID, tower.WaterTankDemandARRID);
    1735           0 :                 tower.SuppliedByWaterSystem = true;
    1736             :             }
    1737             : 
    1738             :             //   outdoor air inlet node
    1739           2 :             if (state.dataIPShortCut->lAlphaFieldBlanks(14)) {
    1740           2 :                 tower.OutdoorAirInletNodeNum = 0;
    1741             :             } else {
    1742           0 :                 tower.OutdoorAirInletNodeNum =
    1743           0 :                     NodeInputManager::GetOnlySingleNode(state,
    1744           0 :                                                         AlphArray(14),
    1745             :                                                         ErrorsFound,
    1746             :                                                         DataLoopNode::ConnectionObjectType::CoolingTowerVariableSpeedMerkel,
    1747           0 :                                                         tower.Name,
    1748             :                                                         DataLoopNode::NodeFluidType::Air,
    1749             :                                                         DataLoopNode::ConnectionType::OutsideAirReference,
    1750             :                                                         NodeInputManager::CompFluidStream::Primary,
    1751             :                                                         DataLoopNode::ObjectIsNotParent);
    1752           0 :                 if (!OutAirNodeManager::CheckOutAirNodeNumber(state, tower.OutdoorAirInletNodeNum)) {
    1753           0 :                     ShowSevereError(state,
    1754           0 :                                     format("{}, \"{}\" Outdoor Air Inlet Node Name not valid Outdoor Air Node= {}",
    1755             :                                            cCurrentModuleObject,
    1756           0 :                                            tower.Name,
    1757             :                                            AlphArray(14)));
    1758           0 :                     ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
    1759           0 :                     ErrorsFound = true;
    1760             :                 }
    1761             :             }
    1762           2 :             if (NumAlphas > 15) {
    1763           0 :                 tower.EndUseSubcategory = AlphArray(16);
    1764             :             } else {
    1765           2 :                 tower.EndUseSubcategory = "General";
    1766             :             }
    1767             : 
    1768             :         } // end merkel vs tower loop
    1769             : 
    1770         244 :         if (ErrorsFound) {
    1771           0 :             ShowFatalError(state, "Errors found in getting cooling tower input.");
    1772             :         }
    1773         244 :     }
    1774             : 
    1775         270 :     void CoolingTower::oneTimeInit(EnergyPlusData &state)
    1776             :     {
    1777             :         // Locate the tower on the plant loops for later usage
    1778         270 :         bool ErrorsFound = false;
    1779         270 :         PlantUtilities::ScanPlantLoopsForObject(state, this->Name, this->TowerType, this->plantLoc, ErrorsFound, _, _, _, _, _);
    1780         270 :         if (ErrorsFound) {
    1781           0 :             ShowFatalError(state, "initialize: Program terminated due to previous condition(s).");
    1782             :         }
    1783             : 
    1784             :         // check if setpoint on outlet node
    1785         517 :         this->SetpointIsOnOutlet = !((state.dataLoopNodes->Node(this->WaterOutletNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) &&
    1786         247 :                                      (state.dataLoopNodes->Node(this->WaterOutletNodeNum).TempSetPointHi == DataLoopNode::SensedNodeFlagValue));
    1787         270 :     }
    1788             : 
    1789        1749 :     void CoolingTower::initEachEnvironment(EnergyPlusData &state)
    1790             :     {
    1791             :         static constexpr std::string_view RoutineName("CoolingTower::initEachEnvironment");
    1792        1749 :         Real64 const rho = FluidProperties::GetDensityGlycol(state,
    1793        1749 :                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1794             :                                                              Constant::InitConvTemp,
    1795        1749 :                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1796             :                                                              RoutineName);
    1797        1749 :         this->DesWaterMassFlowRate = this->DesignWaterFlowRate * rho;
    1798        1749 :         this->DesWaterMassFlowRatePerCell = this->DesWaterMassFlowRate / this->NumCell;
    1799        1749 :         PlantUtilities::InitComponentNodes(state, 0.0, this->DesWaterMassFlowRate, this->WaterInletNodeNum, this->WaterOutletNodeNum);
    1800        1749 :     }
    1801             : 
    1802     8768399 :     void CoolingTower::initialize(EnergyPlusData &state)
    1803             :     {
    1804             : 
    1805             :         // SUBROUTINE INFORMATION:
    1806             :         //       AUTHOR         Fred Buhl
    1807             :         //       DATE WRITTEN   May 2002
    1808             :         //       MODIFIED       Don Shirey Sept/Oct 2002, F Buhl Oct 2002
    1809             :         //       RE-ENGINEERED  R. Raustad, Oct 2005, moved Max/MinAvail to Init and allowed more than design
    1810             :         //                      water flow rate to pass through towers (up to 2.5 and 1.25 times the design flow
    1811             :         //                      for 1 or 2-speed and variable speed towers, respectively). Flow multiplier for
    1812             :         //                      VS Tower is defaulted to 1.25 and can be reassigned by user.
    1813             : 
    1814             :         // PURPOSE OF THIS SUBROUTINE:
    1815             :         // This subroutine is for initializations of the Cooling Tower components and for
    1816             :         // final checking of tower inputs (post autosizing)
    1817             : 
    1818             :         // METHODOLOGY EMPLOYED:
    1819             :         // Uses the status flags to trigger initializations.
    1820             : 
    1821     8768399 :         if (this->oneTimeFlag) {
    1822         270 :             this->setupOutputVariables(state);
    1823         270 :             this->oneTimeInit(state);
    1824         270 :             this->oneTimeFlag = false;
    1825             :         }
    1826             : 
    1827             :         // Begin environment initializations
    1828     8768399 :         if (this->envrnFlag && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
    1829        1749 :             this->initEachEnvironment(state);
    1830        1749 :             this->envrnFlag = false;
    1831             :         }
    1832             : 
    1833     8768399 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    1834     8711886 :             this->envrnFlag = true;
    1835             :         }
    1836             : 
    1837             :         // Each time initializations
    1838     8768399 :         this->WaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    1839             : 
    1840     8768399 :         if (this->OutdoorAirInletNodeNum != 0) {
    1841     1684628 :             this->AirTemp = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).Temp;
    1842     1684628 :             this->AirHumRat = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).HumRat;
    1843     1684628 :             this->AirPress = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).Press;
    1844     1684628 :             this->AirWetBulb = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).OutAirWetBulb;
    1845             :         } else {
    1846     7083771 :             this->AirTemp = state.dataEnvrn->OutDryBulbTemp;
    1847     7083771 :             this->AirHumRat = state.dataEnvrn->OutHumRat;
    1848     7083771 :             this->AirPress = state.dataEnvrn->OutBaroPress;
    1849     7083771 :             this->AirWetBulb = state.dataEnvrn->OutWetBulbTemp;
    1850             :         }
    1851             : 
    1852     8768399 :         this->WaterMassFlowRate =
    1853     8768399 :             PlantUtilities::RegulateCondenserCompFlowReqOp(state, this->plantLoc, this->DesWaterMassFlowRate * this->TowerMassFlowRateMultiplier);
    1854             : 
    1855     8768399 :         PlantUtilities::SetComponentFlowRate(state, this->WaterMassFlowRate, this->WaterInletNodeNum, this->WaterOutletNodeNum, this->plantLoc);
    1856             : 
    1857             :         // Added for fluid bypass. 8/2008
    1858     8768399 :         this->BypassFraction = 0.0;
    1859     8768399 :         this->BasinHeaterPower = 0.0;
    1860     8768399 :         this->airFlowRateRatio = 0.0;
    1861     8768399 :     }
    1862             : 
    1863         270 :     void CoolingTower::setupOutputVariables(EnergyPlusData &state)
    1864             :     {
    1865             :         // Set up output variables CurrentModuleObject='CoolingTower:SingleSpeed'
    1866         270 :         if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_SingleSpd) {
    1867         462 :             SetupOutputVariable(state,
    1868             :                                 "Cooling Tower Inlet Temperature",
    1869             :                                 Constant::Units::C,
    1870         231 :                                 this->InletWaterTemp,
    1871             :                                 OutputProcessor::TimeStepType::System,
    1872             :                                 OutputProcessor::StoreType::Average,
    1873         231 :                                 this->Name);
    1874         462 :             SetupOutputVariable(state,
    1875             :                                 "Cooling Tower Outlet Temperature",
    1876             :                                 Constant::Units::C,
    1877         231 :                                 this->OutletWaterTemp,
    1878             :                                 OutputProcessor::TimeStepType::System,
    1879             :                                 OutputProcessor::StoreType::Average,
    1880         231 :                                 this->Name);
    1881         462 :             SetupOutputVariable(state,
    1882             :                                 "Cooling Tower Mass Flow Rate",
    1883             :                                 Constant::Units::kg_s,
    1884         231 :                                 this->WaterMassFlowRate,
    1885             :                                 OutputProcessor::TimeStepType::System,
    1886             :                                 OutputProcessor::StoreType::Average,
    1887         231 :                                 this->Name);
    1888         462 :             SetupOutputVariable(state,
    1889             :                                 "Cooling Tower Heat Transfer Rate",
    1890             :                                 Constant::Units::W,
    1891         231 :                                 this->Qactual,
    1892             :                                 OutputProcessor::TimeStepType::System,
    1893             :                                 OutputProcessor::StoreType::Average,
    1894         231 :                                 this->Name);
    1895         462 :             SetupOutputVariable(state,
    1896             :                                 "Cooling Tower Fan Electricity Rate",
    1897             :                                 Constant::Units::W,
    1898         231 :                                 this->FanPower,
    1899             :                                 OutputProcessor::TimeStepType::System,
    1900             :                                 OutputProcessor::StoreType::Average,
    1901         231 :                                 this->Name);
    1902         462 :             SetupOutputVariable(state,
    1903             :                                 "Cooling Tower Fan Electricity Energy",
    1904             :                                 Constant::Units::J,
    1905         231 :                                 this->FanEnergy,
    1906             :                                 OutputProcessor::TimeStepType::System,
    1907             :                                 OutputProcessor::StoreType::Sum,
    1908         231 :                                 this->Name,
    1909             :                                 Constant::eResource::Electricity,
    1910             :                                 OutputProcessor::Group::Plant,
    1911             :                                 OutputProcessor::EndUseCat::HeatRejection,
    1912             :                                 this->EndUseSubcategory);
    1913             :             // Added for fluid bypass
    1914         462 :             SetupOutputVariable(state,
    1915             :                                 "Cooling Tower Bypass Fraction",
    1916             :                                 Constant::Units::None,
    1917         231 :                                 this->BypassFraction,
    1918             :                                 OutputProcessor::TimeStepType::System,
    1919             :                                 OutputProcessor::StoreType::Average,
    1920         231 :                                 this->Name);
    1921         231 :             SetupOutputVariable(state,
    1922             :                                 "Cooling Tower Operating Cells Count",
    1923             :                                 Constant::Units::None,
    1924         231 :                                 this->NumCellOn,
    1925             :                                 OutputProcessor::TimeStepType::System,
    1926             :                                 OutputProcessor::StoreType::Average,
    1927         231 :                                 this->Name);
    1928         462 :             SetupOutputVariable(state,
    1929             :                                 "Cooling Tower Fan Cycling Ratio",
    1930             :                                 Constant::Units::None,
    1931         231 :                                 this->FanCyclingRatio,
    1932             :                                 OutputProcessor::TimeStepType::System,
    1933             :                                 OutputProcessor::StoreType::Average,
    1934         231 :                                 this->Name);
    1935         231 :             if (this->BasinHeaterPowerFTempDiff > 0.0) {
    1936           0 :                 SetupOutputVariable(state,
    1937             :                                     "Cooling Tower Basin Heater Electricity Rate",
    1938             :                                     Constant::Units::W,
    1939           0 :                                     this->BasinHeaterPower,
    1940             :                                     OutputProcessor::TimeStepType::System,
    1941             :                                     OutputProcessor::StoreType::Average,
    1942           0 :                                     this->Name);
    1943           0 :                 SetupOutputVariable(state,
    1944             :                                     "Cooling Tower Basin Heater Electricity Energy",
    1945             :                                     Constant::Units::J,
    1946           0 :                                     this->BasinHeaterConsumption,
    1947             :                                     OutputProcessor::TimeStepType::System,
    1948             :                                     OutputProcessor::StoreType::Sum,
    1949           0 :                                     this->Name,
    1950             :                                     Constant::eResource::Electricity,
    1951             :                                     OutputProcessor::Group::Plant,
    1952             :                                     OutputProcessor::EndUseCat::HeatRejection,
    1953             :                                     "BasinHeater");
    1954             :             }
    1955             :         }
    1956             : 
    1957             :         // CurrentModuleObject='CoolingTower:TwoSpeed'
    1958         270 :         if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_TwoSpd) {
    1959          26 :             SetupOutputVariable(state,
    1960             :                                 "Cooling Tower Inlet Temperature",
    1961             :                                 Constant::Units::C,
    1962          13 :                                 this->InletWaterTemp,
    1963             :                                 OutputProcessor::TimeStepType::System,
    1964             :                                 OutputProcessor::StoreType::Average,
    1965          13 :                                 this->Name);
    1966          26 :             SetupOutputVariable(state,
    1967             :                                 "Cooling Tower Outlet Temperature",
    1968             :                                 Constant::Units::C,
    1969          13 :                                 this->OutletWaterTemp,
    1970             :                                 OutputProcessor::TimeStepType::System,
    1971             :                                 OutputProcessor::StoreType::Average,
    1972          13 :                                 this->Name);
    1973          26 :             SetupOutputVariable(state,
    1974             :                                 "Cooling Tower Mass Flow Rate",
    1975             :                                 Constant::Units::kg_s,
    1976          13 :                                 this->WaterMassFlowRate,
    1977             :                                 OutputProcessor::TimeStepType::System,
    1978             :                                 OutputProcessor::StoreType::Average,
    1979          13 :                                 this->Name);
    1980          26 :             SetupOutputVariable(state,
    1981             :                                 "Cooling Tower Heat Transfer Rate",
    1982             :                                 Constant::Units::W,
    1983          13 :                                 this->Qactual,
    1984             :                                 OutputProcessor::TimeStepType::System,
    1985             :                                 OutputProcessor::StoreType::Average,
    1986          13 :                                 this->Name);
    1987          26 :             SetupOutputVariable(state,
    1988             :                                 "Cooling Tower Fan Electricity Rate",
    1989             :                                 Constant::Units::W,
    1990          13 :                                 this->FanPower,
    1991             :                                 OutputProcessor::TimeStepType::System,
    1992             :                                 OutputProcessor::StoreType::Average,
    1993          13 :                                 this->Name);
    1994          26 :             SetupOutputVariable(state,
    1995             :                                 "Cooling Tower Fan Electricity Energy",
    1996             :                                 Constant::Units::J,
    1997          13 :                                 this->FanEnergy,
    1998             :                                 OutputProcessor::TimeStepType::System,
    1999             :                                 OutputProcessor::StoreType::Sum,
    2000          13 :                                 this->Name,
    2001             :                                 Constant::eResource::Electricity,
    2002             :                                 OutputProcessor::Group::Plant,
    2003             :                                 OutputProcessor::EndUseCat::HeatRejection,
    2004             :                                 this->EndUseSubcategory);
    2005          26 :             SetupOutputVariable(state,
    2006             :                                 "Cooling Tower Fan Cycling Ratio",
    2007             :                                 Constant::Units::None,
    2008          13 :                                 this->FanCyclingRatio,
    2009             :                                 OutputProcessor::TimeStepType::System,
    2010             :                                 OutputProcessor::StoreType::Average,
    2011          13 :                                 this->Name);
    2012          13 :             SetupOutputVariable(state,
    2013             :                                 "Cooling Tower Fan Speed Level",
    2014             :                                 Constant::Units::None,
    2015          13 :                                 this->SpeedSelected,
    2016             :                                 OutputProcessor::TimeStepType::System,
    2017             :                                 OutputProcessor::StoreType::Average,
    2018          13 :                                 this->Name);
    2019          13 :             SetupOutputVariable(state,
    2020             :                                 "Cooling Tower Operating Cells Count",
    2021             :                                 Constant::Units::None,
    2022          13 :                                 this->NumCellOn,
    2023             :                                 OutputProcessor::TimeStepType::System,
    2024             :                                 OutputProcessor::StoreType::Average,
    2025          13 :                                 this->Name);
    2026          13 :             if (this->BasinHeaterPowerFTempDiff > 0.0) {
    2027           0 :                 SetupOutputVariable(state,
    2028             :                                     "Cooling Tower Basin Heater Electricity Rate",
    2029             :                                     Constant::Units::W,
    2030           0 :                                     this->BasinHeaterPower,
    2031             :                                     OutputProcessor::TimeStepType::System,
    2032             :                                     OutputProcessor::StoreType::Average,
    2033           0 :                                     this->Name);
    2034           0 :                 SetupOutputVariable(state,
    2035             :                                     "Cooling Tower Basin Heater Electricity Energy",
    2036             :                                     Constant::Units::J,
    2037           0 :                                     this->BasinHeaterConsumption,
    2038             :                                     OutputProcessor::TimeStepType::System,
    2039             :                                     OutputProcessor::StoreType::Sum,
    2040           0 :                                     this->Name,
    2041             :                                     Constant::eResource::Electricity,
    2042             :                                     OutputProcessor::Group::Plant,
    2043             :                                     OutputProcessor::EndUseCat::HeatRejection,
    2044             :                                     "BasinHeater");
    2045             :             }
    2046             :         }
    2047             : 
    2048             :         // CurrentModuleObject='CoolingTower:VariableSpeed'
    2049         270 :         if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_VarSpd) {
    2050          48 :             SetupOutputVariable(state,
    2051             :                                 "Cooling Tower Inlet Temperature",
    2052             :                                 Constant::Units::C,
    2053          24 :                                 this->InletWaterTemp,
    2054             :                                 OutputProcessor::TimeStepType::System,
    2055             :                                 OutputProcessor::StoreType::Average,
    2056          24 :                                 this->Name);
    2057          48 :             SetupOutputVariable(state,
    2058             :                                 "Cooling Tower Outlet Temperature",
    2059             :                                 Constant::Units::C,
    2060          24 :                                 this->OutletWaterTemp,
    2061             :                                 OutputProcessor::TimeStepType::System,
    2062             :                                 OutputProcessor::StoreType::Average,
    2063          24 :                                 this->Name);
    2064          48 :             SetupOutputVariable(state,
    2065             :                                 "Cooling Tower Mass Flow Rate",
    2066             :                                 Constant::Units::kg_s,
    2067          24 :                                 this->WaterMassFlowRate,
    2068             :                                 OutputProcessor::TimeStepType::System,
    2069             :                                 OutputProcessor::StoreType::Average,
    2070          24 :                                 this->Name);
    2071          48 :             SetupOutputVariable(state,
    2072             :                                 "Cooling Tower Heat Transfer Rate",
    2073             :                                 Constant::Units::W,
    2074          24 :                                 this->Qactual,
    2075             :                                 OutputProcessor::TimeStepType::System,
    2076             :                                 OutputProcessor::StoreType::Average,
    2077          24 :                                 this->Name);
    2078          48 :             SetupOutputVariable(state,
    2079             :                                 "Cooling Tower Fan Electricity Rate",
    2080             :                                 Constant::Units::W,
    2081          24 :                                 this->FanPower,
    2082             :                                 OutputProcessor::TimeStepType::System,
    2083             :                                 OutputProcessor::StoreType::Average,
    2084          24 :                                 this->Name);
    2085          48 :             SetupOutputVariable(state,
    2086             :                                 "Cooling Tower Fan Electricity Energy",
    2087             :                                 Constant::Units::J,
    2088          24 :                                 this->FanEnergy,
    2089             :                                 OutputProcessor::TimeStepType::System,
    2090             :                                 OutputProcessor::StoreType::Sum,
    2091          24 :                                 this->Name,
    2092             :                                 Constant::eResource::Electricity,
    2093             :                                 OutputProcessor::Group::Plant,
    2094             :                                 OutputProcessor::EndUseCat::HeatRejection,
    2095             :                                 this->EndUseSubcategory);
    2096          48 :             SetupOutputVariable(state,
    2097             :                                 "Cooling Tower Air Flow Rate Ratio",
    2098             :                                 Constant::Units::None,
    2099          24 :                                 this->AirFlowRatio,
    2100             :                                 OutputProcessor::TimeStepType::System,
    2101             :                                 OutputProcessor::StoreType::Average,
    2102          24 :                                 this->Name);
    2103          48 :             SetupOutputVariable(state,
    2104             :                                 "Cooling Tower Fan Part Load Ratio",
    2105             :                                 Constant::Units::None,
    2106          24 :                                 this->FanCyclingRatio,
    2107             :                                 OutputProcessor::TimeStepType::System,
    2108             :                                 OutputProcessor::StoreType::Average,
    2109          24 :                                 this->Name);
    2110          24 :             SetupOutputVariable(state,
    2111             :                                 "Cooling Tower Operating Cells Count",
    2112             :                                 Constant::Units::None,
    2113          24 :                                 this->NumCellOn,
    2114             :                                 OutputProcessor::TimeStepType::System,
    2115             :                                 OutputProcessor::StoreType::Average,
    2116          24 :                                 this->Name);
    2117          24 :             if (this->BasinHeaterPowerFTempDiff > 0.0) {
    2118          24 :                 SetupOutputVariable(state,
    2119             :                                     "Cooling Tower Basin Heater Electricity Rate",
    2120             :                                     Constant::Units::W,
    2121          12 :                                     this->BasinHeaterPower,
    2122             :                                     OutputProcessor::TimeStepType::System,
    2123             :                                     OutputProcessor::StoreType::Average,
    2124          12 :                                     this->Name);
    2125          24 :                 SetupOutputVariable(state,
    2126             :                                     "Cooling Tower Basin Heater Electricity Energy",
    2127             :                                     Constant::Units::J,
    2128          12 :                                     this->BasinHeaterConsumption,
    2129             :                                     OutputProcessor::TimeStepType::System,
    2130             :                                     OutputProcessor::StoreType::Sum,
    2131          12 :                                     this->Name,
    2132             :                                     Constant::eResource::Electricity,
    2133             :                                     OutputProcessor::Group::Plant,
    2134             :                                     OutputProcessor::EndUseCat::HeatRejection,
    2135             :                                     "BasinHeater");
    2136             :             }
    2137             :         }
    2138             : 
    2139             :         // CurrentModuleObject='CoolingTower:VariableSpeed:Merkel'
    2140         270 :         if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_VarSpdMerkel) {
    2141           4 :             SetupOutputVariable(state,
    2142             :                                 "Cooling Tower Inlet Temperature",
    2143             :                                 Constant::Units::C,
    2144           2 :                                 this->InletWaterTemp,
    2145             :                                 OutputProcessor::TimeStepType::System,
    2146             :                                 OutputProcessor::StoreType::Average,
    2147           2 :                                 this->Name);
    2148           4 :             SetupOutputVariable(state,
    2149             :                                 "Cooling Tower Outlet Temperature",
    2150             :                                 Constant::Units::C,
    2151           2 :                                 this->OutletWaterTemp,
    2152             :                                 OutputProcessor::TimeStepType::System,
    2153             :                                 OutputProcessor::StoreType::Average,
    2154           2 :                                 this->Name);
    2155           4 :             SetupOutputVariable(state,
    2156             :                                 "Cooling Tower Mass Flow Rate",
    2157             :                                 Constant::Units::kg_s,
    2158           2 :                                 this->WaterMassFlowRate,
    2159             :                                 OutputProcessor::TimeStepType::System,
    2160             :                                 OutputProcessor::StoreType::Average,
    2161           2 :                                 this->Name);
    2162           4 :             SetupOutputVariable(state,
    2163             :                                 "Cooling Tower Heat Transfer Rate",
    2164             :                                 Constant::Units::W,
    2165           2 :                                 this->Qactual,
    2166             :                                 OutputProcessor::TimeStepType::System,
    2167             :                                 OutputProcessor::StoreType::Average,
    2168           2 :                                 this->Name);
    2169           4 :             SetupOutputVariable(state,
    2170             :                                 "Cooling Tower Fan Electricity Rate",
    2171             :                                 Constant::Units::W,
    2172           2 :                                 this->FanPower,
    2173             :                                 OutputProcessor::TimeStepType::System,
    2174             :                                 OutputProcessor::StoreType::Average,
    2175           2 :                                 this->Name);
    2176           4 :             SetupOutputVariable(state,
    2177             :                                 "Cooling Tower Fan Electricity Energy",
    2178             :                                 Constant::Units::J,
    2179           2 :                                 this->FanEnergy,
    2180             :                                 OutputProcessor::TimeStepType::System,
    2181             :                                 OutputProcessor::StoreType::Sum,
    2182           2 :                                 this->Name,
    2183             :                                 Constant::eResource::Electricity,
    2184             :                                 OutputProcessor::Group::Plant,
    2185             :                                 OutputProcessor::EndUseCat::HeatRejection,
    2186             :                                 this->EndUseSubcategory);
    2187           4 :             SetupOutputVariable(state,
    2188             :                                 "Cooling Tower Fan Speed Ratio",
    2189             :                                 Constant::Units::None,
    2190           2 :                                 this->AirFlowRatio,
    2191             :                                 OutputProcessor::TimeStepType::System,
    2192             :                                 OutputProcessor::StoreType::Average,
    2193           2 :                                 this->Name);
    2194             : 
    2195           2 :             SetupOutputVariable(state,
    2196             :                                 "Cooling Tower Operating Cells Count",
    2197             :                                 Constant::Units::None,
    2198           2 :                                 this->NumCellOn,
    2199             :                                 OutputProcessor::TimeStepType::System,
    2200             :                                 OutputProcessor::StoreType::Average,
    2201           2 :                                 this->Name);
    2202           2 :             if (this->BasinHeaterPowerFTempDiff > 0.0) {
    2203           0 :                 SetupOutputVariable(state,
    2204             :                                     "Cooling Tower Basin Heater Electricity Rate",
    2205             :                                     Constant::Units::W,
    2206           0 :                                     this->BasinHeaterPower,
    2207             :                                     OutputProcessor::TimeStepType::System,
    2208             :                                     OutputProcessor::StoreType::Average,
    2209           0 :                                     this->Name);
    2210           0 :                 SetupOutputVariable(state,
    2211             :                                     "Cooling Tower Basin Heater Electricity Energy",
    2212             :                                     Constant::Units::J,
    2213           0 :                                     this->BasinHeaterConsumption,
    2214             :                                     OutputProcessor::TimeStepType::System,
    2215             :                                     OutputProcessor::StoreType::Sum,
    2216           0 :                                     this->Name,
    2217             :                                     Constant::eResource::Electricity,
    2218             :                                     OutputProcessor::Group::Plant,
    2219             :                                     OutputProcessor::EndUseCat::HeatRejection,
    2220             :                                     "BasinHeater");
    2221             :             }
    2222             :         }
    2223             :         // setup common water reporting for all types of towers.
    2224         270 :         if (this->SuppliedByWaterSystem) {
    2225           4 :             SetupOutputVariable(state,
    2226             :                                 "Cooling Tower Make Up Water Volume Flow Rate",
    2227             :                                 Constant::Units::m3_s,
    2228           2 :                                 this->MakeUpVdot,
    2229             :                                 OutputProcessor::TimeStepType::System,
    2230             :                                 OutputProcessor::StoreType::Average,
    2231           2 :                                 this->Name);
    2232           4 :             SetupOutputVariable(state,
    2233             :                                 "Cooling Tower Make Up Water Volume",
    2234             :                                 Constant::Units::m3,
    2235           2 :                                 this->MakeUpVol,
    2236             :                                 OutputProcessor::TimeStepType::System,
    2237             :                                 OutputProcessor::StoreType::Sum,
    2238           2 :                                 this->Name);
    2239           4 :             SetupOutputVariable(state,
    2240             :                                 "Cooling Tower Storage Tank Water Volume Flow Rate",
    2241             :                                 Constant::Units::m3_s,
    2242           2 :                                 this->TankSupplyVdot,
    2243             :                                 OutputProcessor::TimeStepType::System,
    2244             :                                 OutputProcessor::StoreType::Average,
    2245           2 :                                 this->Name);
    2246           4 :             SetupOutputVariable(state,
    2247             :                                 "Cooling Tower Storage Tank Water Volume",
    2248             :                                 Constant::Units::m3,
    2249           2 :                                 this->TankSupplyVol,
    2250             :                                 OutputProcessor::TimeStepType::System,
    2251             :                                 OutputProcessor::StoreType::Sum,
    2252           2 :                                 this->Name,
    2253             :                                 Constant::eResource::Water,
    2254             :                                 OutputProcessor::Group::Plant,
    2255             :                                 OutputProcessor::EndUseCat::HeatRejection);
    2256           4 :             SetupOutputVariable(state,
    2257             :                                 "Cooling Tower Starved Storage Tank Water Volume Flow Rate",
    2258             :                                 Constant::Units::m3_s,
    2259           2 :                                 this->StarvedMakeUpVdot,
    2260             :                                 OutputProcessor::TimeStepType::System,
    2261             :                                 OutputProcessor::StoreType::Average,
    2262           2 :                                 this->Name);
    2263           4 :             SetupOutputVariable(state,
    2264             :                                 "Cooling Tower Starved Storage Tank Water Volume",
    2265             :                                 Constant::Units::m3,
    2266           2 :                                 this->StarvedMakeUpVol,
    2267             :                                 OutputProcessor::TimeStepType::System,
    2268             :                                 OutputProcessor::StoreType::Sum,
    2269           2 :                                 this->Name);
    2270           4 :             SetupOutputVariable(state,
    2271             :                                 "Cooling Tower Make Up Mains Water Volume",
    2272             :                                 Constant::Units::m3,
    2273           2 :                                 this->StarvedMakeUpVol,
    2274             :                                 OutputProcessor::TimeStepType::System,
    2275             :                                 OutputProcessor::StoreType::Sum,
    2276           2 :                                 this->Name,
    2277             :                                 Constant::eResource::MainsWater,
    2278             :                                 OutputProcessor::Group::Plant,
    2279             :                                 OutputProcessor::EndUseCat::HeatRejection);
    2280             :         } else { // tower water from mains and gets metered
    2281         536 :             SetupOutputVariable(state,
    2282             :                                 "Cooling Tower Make Up Water Volume Flow Rate",
    2283             :                                 Constant::Units::m3_s,
    2284         268 :                                 this->MakeUpVdot,
    2285             :                                 OutputProcessor::TimeStepType::System,
    2286             :                                 OutputProcessor::StoreType::Average,
    2287         268 :                                 this->Name);
    2288         536 :             SetupOutputVariable(state,
    2289             :                                 "Cooling Tower Make Up Water Volume",
    2290             :                                 Constant::Units::m3,
    2291         268 :                                 this->MakeUpVol,
    2292             :                                 OutputProcessor::TimeStepType::System,
    2293             :                                 OutputProcessor::StoreType::Sum,
    2294         268 :                                 this->Name,
    2295             :                                 Constant::eResource::Water,
    2296             :                                 OutputProcessor::Group::Plant,
    2297             :                                 OutputProcessor::EndUseCat::HeatRejection);
    2298         536 :             SetupOutputVariable(state,
    2299             :                                 "Cooling Tower Make Up Mains Water Volume",
    2300             :                                 Constant::Units::m3,
    2301         268 :                                 this->MakeUpVol,
    2302             :                                 OutputProcessor::TimeStepType::System,
    2303             :                                 OutputProcessor::StoreType::Sum,
    2304         268 :                                 this->Name,
    2305             :                                 Constant::eResource::MainsWater,
    2306             :                                 OutputProcessor::Group::Plant,
    2307             :                                 OutputProcessor::EndUseCat::HeatRejection);
    2308             :         }
    2309             : 
    2310         540 :         SetupOutputVariable(state,
    2311             :                             "Cooling Tower Water Evaporation Volume Flow Rate",
    2312             :                             Constant::Units::m3_s,
    2313         270 :                             this->EvaporationVdot,
    2314             :                             OutputProcessor::TimeStepType::System,
    2315             :                             OutputProcessor::StoreType::Average,
    2316         270 :                             this->Name);
    2317         540 :         SetupOutputVariable(state,
    2318             :                             "Cooling Tower Water Evaporation Volume",
    2319             :                             Constant::Units::m3,
    2320         270 :                             this->EvaporationVol,
    2321             :                             OutputProcessor::TimeStepType::System,
    2322             :                             OutputProcessor::StoreType::Sum,
    2323         270 :                             this->Name);
    2324         540 :         SetupOutputVariable(state,
    2325             :                             "Cooling Tower Water Drift Volume Flow Rate",
    2326             :                             Constant::Units::m3_s,
    2327         270 :                             this->DriftVdot,
    2328             :                             OutputProcessor::TimeStepType::System,
    2329             :                             OutputProcessor::StoreType::Average,
    2330         270 :                             this->Name);
    2331         540 :         SetupOutputVariable(state,
    2332             :                             "Cooling Tower Water Drift Volume",
    2333             :                             Constant::Units::m3,
    2334         270 :                             this->DriftVol,
    2335             :                             OutputProcessor::TimeStepType::System,
    2336             :                             OutputProcessor::StoreType::Sum,
    2337         270 :                             this->Name);
    2338         540 :         SetupOutputVariable(state,
    2339             :                             "Cooling Tower Water Blowdown Volume Flow Rate",
    2340             :                             Constant::Units::m3_s,
    2341         270 :                             this->BlowdownVdot,
    2342             :                             OutputProcessor::TimeStepType::System,
    2343             :                             OutputProcessor::StoreType::Average,
    2344         270 :                             this->Name);
    2345         540 :         SetupOutputVariable(state,
    2346             :                             "Cooling Tower Water Blowdown Volume",
    2347             :                             Constant::Units::m3,
    2348         270 :                             this->BlowdownVol,
    2349             :                             OutputProcessor::TimeStepType::System,
    2350             :                             OutputProcessor::StoreType::Sum,
    2351         270 :                             this->Name);
    2352         540 :         SetupOutputVariable(state,
    2353             :                             "Cooling Tower Approach",
    2354             :                             Constant::Units::C,
    2355         270 :                             this->coolingTowerApproach,
    2356             :                             OutputProcessor::TimeStepType::System,
    2357             :                             OutputProcessor::StoreType::Average,
    2358         270 :                             this->Name);
    2359         540 :         SetupOutputVariable(state,
    2360             :                             "Cooling Tower Range",
    2361             :                             Constant::Units::C,
    2362         270 :                             this->coolingTowerRange,
    2363             :                             OutputProcessor::TimeStepType::System,
    2364             :                             OutputProcessor::StoreType::Average,
    2365         270 :                             this->Name);
    2366         270 :     }
    2367             : 
    2368        1362 :     void CoolingTower::SizeTower(EnergyPlusData &state)
    2369             :     {
    2370             : 
    2371             :         // SUBROUTINE INFORMATION:
    2372             :         //       AUTHOR         Fred Buhl
    2373             :         //       DATE WRITTEN   May 2002
    2374             :         //       MODIFIED       Don Shirey, Sept/Oct 2002; Richard Raustad, Feb 2005
    2375             : 
    2376             :         // PURPOSE OF THIS SUBROUTINE:
    2377             :         // This subroutine is for sizing Cooling Tower Components for which capacities and flow rates
    2378             :         // have not been specified in the input. This subroutine also calculates tower UA if the user
    2379             :         // has specified tower performance via the "Nominal Capacity" method.
    2380             : 
    2381             :         // METHODOLOGY EMPLOYED:
    2382             :         // Obtains condenser flow rate from the plant sizing array. If tower performance is specified
    2383             :         // via the "Nominal Capacity" method, the water flow rate is directly proportional to capacity.
    2384             : 
    2385             :         // SUBROUTINE PARAMETER DEFINITIONS:
    2386             : 
    2387        1362 :         int constexpr MaxIte(500);    // Maximum number of iterations
    2388        1362 :         Real64 constexpr Acc(0.0001); // Accuracy of result
    2389             :         static constexpr std::string_view RoutineName("SizeTower");
    2390             : 
    2391             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2392             :         int SolFla;                       // Flag of solver
    2393        1362 :         Real64 DesTowerLoad(0.0);         // Design tower load [W]
    2394             :         Real64 UA0;                       // Lower bound for UA [W/C]
    2395             :         Real64 UA1;                       // Upper bound for UA [W/C]
    2396             :         Real64 UA;                        // Calculated UA value
    2397             :         Real64 DesTowerInletWaterTemp;    // design tower inlet water temperature
    2398             :         Real64 DesTowerExitWaterTemp;     // design tower exit water temperature
    2399             :         Real64 DesTowerWaterDeltaT;       // design tower temperature range
    2400             :         Real64 DesTowerApproachFromPlant; // design tower approach temperature from plant sizing object
    2401        1362 :         Real64 TolTemp(0.04);             // DeltaT and DesApproach diffs tollerance between plant sizing data and user input in cooling tower
    2402             :         // for warning message reporting purpose only
    2403             : 
    2404        1362 :         Real64 tmpDesignWaterFlowRate = this->DesignWaterFlowRate;
    2405        1362 :         Real64 tmpHighSpeedFanPower = this->HighSpeedFanPower;
    2406        1362 :         Real64 tmpHighSpeedAirFlowRate = this->HighSpeedAirFlowRate;
    2407        1362 :         Real64 tmpLowSpeedAirFlowRate = this->LowSpeedAirFlowRate;
    2408             : 
    2409        1362 :         auto &PlantSizData(state.dataSize->PlantSizData);
    2410             : 
    2411             :         // Find the appropriate Plant Sizing object
    2412        1362 :         int PltSizCondNum = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).PlantSizNum;
    2413             : 
    2414        1362 :         if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_SingleSpd ||
    2415         185 :             this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_TwoSpd) {
    2416        1242 :             if (this->TowerInletCondsAutoSize) {
    2417        1242 :                 if (PltSizCondNum > 0) {
    2418             :                     // use plant sizing data
    2419         697 :                     DesTowerExitWaterTemp = PlantSizData(PltSizCondNum).ExitTemp;
    2420         697 :                     DesTowerInletWaterTemp = DesTowerExitWaterTemp + PlantSizData(PltSizCondNum).DeltaT;
    2421         697 :                     DesTowerWaterDeltaT = PlantSizData(PltSizCondNum).DeltaT;
    2422             :                 } else {
    2423             :                     // set hard wired input assumptions
    2424             :                     // AssumedDeltaT = 11.0;
    2425             :                     // AssumedExitTemp = 21.0;
    2426         545 :                     DesTowerWaterDeltaT = 11.0;
    2427         545 :                     DesTowerExitWaterTemp = 21.0;
    2428         545 :                     DesTowerInletWaterTemp = DesTowerExitWaterTemp + DesTowerWaterDeltaT;
    2429             :                 }
    2430             :             } else {
    2431             :                 // use tower sizing data
    2432           0 :                 DesTowerExitWaterTemp = this->DesOutletWaterTemp;
    2433           0 :                 DesTowerInletWaterTemp = this->DesInletWaterTemp;
    2434           0 :                 DesTowerWaterDeltaT = this->DesRange;
    2435           0 :                 if (PltSizCondNum > 0) {
    2436             :                     // check the tower range against the plant sizing data
    2437           0 :                     if (std::abs(DesTowerWaterDeltaT - PlantSizData(PltSizCondNum).DeltaT) > TolTemp) {
    2438           0 :                         ShowWarningError(state,
    2439           0 :                                          format("Error when autosizing the load for cooling tower = {}. Tower Design Range Temperature is different "
    2440             :                                                 "from the Design Loop Delta Temperature.",
    2441           0 :                                                 this->Name));
    2442           0 :                         ShowContinueError(state, format("Tower Design Range Temperature specified in tower = {}", this->Name));
    2443           0 :                         ShowContinueError(state,
    2444           0 :                                           format("is inconsistent with Design Loop Delta Temperature specified in Sizing:Plant object = {}.",
    2445           0 :                                                  PlantSizData(PltSizCondNum).PlantLoopName));
    2446           0 :                         ShowContinueError(state, format("..The Design Range Temperature specified in tower is = {:.2T}", this->DesRange));
    2447           0 :                         ShowContinueError(state,
    2448           0 :                                           format("..The Design Loop Delta Temperature specified in plant sizing data is = {:.2T}",
    2449           0 :                                                  PlantSizData(PltSizCondNum).DeltaT));
    2450             :                     }
    2451             :                     // check if the tower approach is different from plant sizing data
    2452           0 :                     DesTowerApproachFromPlant = PlantSizData(PltSizCondNum).ExitTemp - this->DesInletAirWBTemp;
    2453           0 :                     if (std::abs(DesTowerApproachFromPlant - this->DesApproach) > TolTemp) {
    2454           0 :                         ShowWarningError(state,
    2455           0 :                                          format("Error when autosizing the UA for cooling tower = {}. Tower Design Approach Temperature is "
    2456             :                                                 "inconsistent with Approach from Plant Sizing Data.",
    2457           0 :                                                 this->Name));
    2458           0 :                         ShowContinueError(state,
    2459           0 :                                           format("The Design Approach Temperature from inputs specified in Sizing:Plant object = {}",
    2460           0 :                                                  PlantSizData(PltSizCondNum).PlantLoopName));
    2461           0 :                         ShowContinueError(state, format("is inconsistent with Design Approach Temperature specified in tower = {}.", this->Name));
    2462           0 :                         ShowContinueError(state,
    2463           0 :                                           format("..The Design Approach Temperature from inputs specified is = {:.2T}", DesTowerApproachFromPlant));
    2464           0 :                         ShowContinueError(state, format("..The Design Approach Temperature specified in tower is = {:.2T}", this->DesApproach));
    2465             :                     }
    2466             :                 }
    2467             :             }
    2468             :         } else { // CoolingTower_VariableSpeed
    2469         120 :             if (PltSizCondNum > 0) {
    2470             :                 // use plant sizing data
    2471         120 :                 DesTowerExitWaterTemp = PlantSizData(PltSizCondNum).ExitTemp;
    2472         120 :                 DesTowerInletWaterTemp = DesTowerExitWaterTemp + PlantSizData(PltSizCondNum).DeltaT;
    2473         120 :                 DesTowerWaterDeltaT = PlantSizData(PltSizCondNum).DeltaT;
    2474             :             } else {
    2475             :                 // set hard wired input assumptions
    2476           0 :                 DesTowerWaterDeltaT = 11.0;
    2477           0 :                 DesTowerExitWaterTemp = 21.0;
    2478           0 :                 DesTowerInletWaterTemp = DesTowerExitWaterTemp + DesTowerWaterDeltaT;
    2479             :             }
    2480             :         }
    2481             : 
    2482        1362 :         if (this->PerformanceInputMethod_Num == PIM::UFactor && (!this->HighSpeedTowerUAWasAutoSized)) {
    2483         710 :             if (PltSizCondNum > 0) {
    2484         205 :                 Real64 const rho = FluidProperties::GetDensityGlycol(state,
    2485         205 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2486             :                                                                      DesTowerExitWaterTemp,
    2487         205 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2488             :                                                                      RoutineName);
    2489         205 :                 Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    2490         205 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2491             :                                                                          DesTowerExitWaterTemp,
    2492         205 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2493             :                                                                          RoutineName);
    2494         205 :                 DesTowerLoad = rho * Cp * this->DesignWaterFlowRate * DesTowerWaterDeltaT;
    2495         205 :                 this->TowerNominalCapacity = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    2496             : 
    2497             :             } else {
    2498         505 :                 Real64 AssumedDeltaT = DesTowerWaterDeltaT;
    2499         505 :                 Real64 AssumedExitTemp = DesTowerExitWaterTemp;
    2500             : 
    2501         505 :                 Real64 const rho = FluidProperties::GetDensityGlycol(state,
    2502         505 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2503             :                                                                      AssumedExitTemp,
    2504         505 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2505             :                                                                      RoutineName);
    2506         505 :                 Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    2507         505 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2508             :                                                                          AssumedExitTemp,
    2509         505 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2510             :                                                                          RoutineName);
    2511             : 
    2512         505 :                 DesTowerLoad = rho * Cp * this->DesignWaterFlowRate * AssumedDeltaT;
    2513         505 :                 this->TowerNominalCapacity = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    2514             :             }
    2515             :         }
    2516             : 
    2517        1362 :         if (this->DesignWaterFlowRateWasAutoSized) {
    2518         667 :             if (PltSizCondNum > 0) {
    2519         667 :                 if (PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    2520         424 :                     tmpDesignWaterFlowRate = PlantSizData(PltSizCondNum).DesVolFlowRate * this->SizFac;
    2521         424 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
    2522             :                 } else {
    2523         243 :                     tmpDesignWaterFlowRate = 0.0;
    2524         243 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
    2525             :                 }
    2526         667 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2527         258 :                     BaseSizer::reportSizerOutput(state,
    2528         129 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2529             :                                                  this->Name,
    2530             :                                                  "Design Water Flow Rate [m3/s]",
    2531             :                                                  this->DesignWaterFlowRate);
    2532             :                 }
    2533         667 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2534          22 :                     BaseSizer::reportSizerOutput(state,
    2535          11 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2536             :                                                  this->Name,
    2537             :                                                  "Initial Design Water Flow Rate [m3/s]",
    2538             :                                                  this->DesignWaterFlowRate);
    2539             :                 }
    2540             :             } else {
    2541           0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2542           0 :                     ShowSevereError(state, format("Autosizing error for cooling tower object = {}", this->Name));
    2543           0 :                     ShowFatalError(state, "Autosizing of cooling tower condenser flow rate requires a loop Sizing:Plant object.");
    2544             :                 }
    2545             :             }
    2546             :         }
    2547             : 
    2548        1362 :         if (this->PerformanceInputMethod_Num == PIM::NominalCapacity) {
    2549             :             // Design water flow rate is assumed to be 3 gpm per ton (SI equivalent 5.382E-8 m3/s per watt)
    2550          40 :             this->DesignWaterFlowRate = 5.382e-8 * this->TowerNominalCapacity;
    2551          40 :             tmpDesignWaterFlowRate = this->DesignWaterFlowRate;
    2552          40 :             if (Util::SameString(DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)], "CoolingTower:SingleSpeed")) {
    2553          15 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2554           6 :                     BaseSizer::reportSizerOutput(state,
    2555           3 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2556             :                                                  this->Name,
    2557             :                                                  "Design Water Flow Rate based on tower nominal capacity [m3/s]",
    2558             :                                                  this->DesignWaterFlowRate);
    2559             :                 }
    2560          15 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2561           0 :                     BaseSizer::reportSizerOutput(state,
    2562           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2563             :                                                  this->Name,
    2564             :                                                  "Initial Design Water Flow Rate based on tower nominal capacity [m3/s]",
    2565             :                                                  this->DesignWaterFlowRate);
    2566             :                 }
    2567          25 :             } else if (Util::SameString(DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)], "CoolingTower:TwoSpeed")) {
    2568          25 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2569          10 :                     BaseSizer::reportSizerOutput(state,
    2570           5 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2571             :                                                  this->Name,
    2572             :                                                  "Design Water Flow Rate based on tower high-speed nominal capacity [m3/s]",
    2573             :                                                  this->DesignWaterFlowRate);
    2574             :                 }
    2575          25 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2576           0 :                     BaseSizer::reportSizerOutput(state,
    2577           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2578             :                                                  this->Name,
    2579             :                                                  "Initial Design Water Flow Rate based on tower high-speed nominal capacity [m3/s]",
    2580             :                                                  this->DesignWaterFlowRate);
    2581             :                 }
    2582             :             }
    2583             :         }
    2584             : 
    2585        1362 :         PlantUtilities::RegisterPlantCompDesignFlow(state, this->WaterInletNodeNum, tmpDesignWaterFlowRate);
    2586             : 
    2587        1362 :         if (this->HighSpeedFanPowerWasAutoSized) {
    2588             :             // We assume the nominal fan power is 0.0105 times the design load
    2589         682 :             if (this->PerformanceInputMethod_Num == PIM::NominalCapacity) {
    2590           5 :                 this->HighSpeedFanPower = 0.0105 * this->TowerNominalCapacity;
    2591           5 :                 tmpHighSpeedFanPower = this->HighSpeedFanPower;
    2592             :             } else {
    2593         677 :                 if (PltSizCondNum > 0) {
    2594         677 :                     if (PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    2595         431 :                         Real64 const rho = FluidProperties::GetDensityGlycol(state,
    2596         431 :                                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2597             :                                                                              Constant::InitConvTemp,
    2598         431 :                                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2599             :                                                                              RoutineName);
    2600         431 :                         Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    2601         431 :                                                                                  state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2602             :                                                                                  DesTowerExitWaterTemp,
    2603         431 :                                                                                  state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2604             :                                                                                  RoutineName);
    2605         431 :                         DesTowerLoad = rho * Cp * tmpDesignWaterFlowRate * DesTowerWaterDeltaT;
    2606         431 :                         tmpHighSpeedFanPower = 0.0105 * DesTowerLoad;
    2607         431 :                         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
    2608             :                     } else {
    2609         246 :                         tmpHighSpeedFanPower = 0.0;
    2610         246 :                         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
    2611             :                     }
    2612             :                 } else {
    2613           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2614           0 :                         ShowSevereError(state, "Autosizing of cooling tower fan power requires a loop Sizing:Plant object.");
    2615           0 :                         ShowFatalError(state, format(" Occurs in cooling tower object= {}", this->Name));
    2616             :                     }
    2617             :                 }
    2618             :             }
    2619         682 :             if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_SingleSpd ||
    2620         110 :                 this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_VarSpd) {
    2621         637 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2622         246 :                     BaseSizer::reportSizerOutput(state,
    2623         123 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2624             :                                                  this->Name,
    2625             :                                                  "Fan Power at Design Air Flow Rate [W]",
    2626             :                                                  this->HighSpeedFanPower);
    2627             :                 }
    2628         637 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2629          22 :                     BaseSizer::reportSizerOutput(state,
    2630          11 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2631             :                                                  this->Name,
    2632             :                                                  "Initial Fan Power at Design Air Flow Rate [W]",
    2633             :                                                  this->HighSpeedFanPower);
    2634             :                 }
    2635          45 :             } else if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_TwoSpd) {
    2636          45 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2637          18 :                     BaseSizer::reportSizerOutput(state,
    2638           9 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2639             :                                                  this->Name,
    2640             :                                                  "Fan Power at High Fan Speed [W]",
    2641             :                                                  this->HighSpeedFanPower);
    2642             :                 }
    2643          45 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2644           0 :                     BaseSizer::reportSizerOutput(state,
    2645           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2646             :                                                  this->Name,
    2647             :                                                  "Initial Fan Power at High Fan Speed [W]",
    2648             :                                                  this->HighSpeedFanPower);
    2649             :                 }
    2650             :             }
    2651             :         }
    2652             : 
    2653        1362 :         if (this->HighSpeedAirFlowRateWasAutoSized) {
    2654             :             // Plant Sizing Object is not required to AUTOSIZE this field since its simply a multiple of another field.
    2655         752 :             tmpHighSpeedAirFlowRate = tmpHighSpeedFanPower * 0.5 * (101325.0 / state.dataEnvrn->StdBaroPress) / 190.0;
    2656         752 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedAirFlowRate = tmpHighSpeedAirFlowRate;
    2657             : 
    2658         752 :             if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_SingleSpd ||
    2659         165 :                 this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_VarSpd) {
    2660         707 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2661         274 :                     BaseSizer::reportSizerOutput(state,
    2662         137 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2663             :                                                  this->Name,
    2664             :                                                  "Design Air Flow Rate [m3/s]",
    2665             :                                                  this->HighSpeedAirFlowRate);
    2666             :                 }
    2667         707 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2668          22 :                     BaseSizer::reportSizerOutput(state,
    2669          11 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2670             :                                                  this->Name,
    2671             :                                                  "Initial Design Air Flow Rate [m3/s]",
    2672             :                                                  this->HighSpeedAirFlowRate);
    2673             :                 }
    2674          45 :             } else if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_TwoSpd) {
    2675          45 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2676          18 :                     BaseSizer::reportSizerOutput(state,
    2677           9 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2678             :                                                  this->Name,
    2679             :                                                  "Air Flow Rate at High Fan Speed [m3/s]",
    2680             :                                                  this->HighSpeedAirFlowRate);
    2681             :                 }
    2682          45 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2683           0 :                     BaseSizer::reportSizerOutput(state,
    2684           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2685             :                                                  this->Name,
    2686             :                                                  "Initial Air Flow Rate at High Fan Speed [m3/s]",
    2687             :                                                  this->HighSpeedAirFlowRate);
    2688             :                 }
    2689             :             }
    2690             :         }
    2691             : 
    2692        1362 :         if (this->HighSpeedTowerUAWasAutoSized) {
    2693         612 :             if (PltSizCondNum > 0) {
    2694         612 :                 if (PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    2695         391 :                     Real64 const rho = FluidProperties::GetDensityGlycol(state,
    2696         391 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2697             :                                                                          Constant::InitConvTemp,
    2698         391 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2699             :                                                                          RoutineName);
    2700         391 :                     Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    2701         391 :                                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2702             :                                                                              DesTowerExitWaterTemp,
    2703         391 :                                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2704             :                                                                              RoutineName);
    2705         391 :                     DesTowerLoad = rho * Cp * tmpDesignWaterFlowRate * DesTowerWaterDeltaT;
    2706             :                     // This conditional statement is to trap when the user specified condenser/tower water design setpoint
    2707             :                     //  temperature is less than design inlet air wet bulb temperature
    2708         391 :                     if (PlantSizData(PltSizCondNum).ExitTemp <= this->DesInletAirWBTemp) {
    2709           0 :                         ShowSevereError(state,
    2710           0 :                                         format("Error when autosizing the UA value for cooling tower = {}. Design Loop Exit Temperature must be "
    2711             :                                                "greater than {:.2T} C when autosizing the tower UA.",
    2712           0 :                                                this->Name,
    2713           0 :                                                this->DesInletAirWBTemp));
    2714           0 :                         ShowContinueError(state,
    2715           0 :                                           format("The Design Loop Exit Temperature specified in Sizing:Plant object = {} ({:.2T} C)",
    2716           0 :                                                  PlantSizData(PltSizCondNum).PlantLoopName,
    2717           0 :                                                  PlantSizData(PltSizCondNum).ExitTemp));
    2718           0 :                         ShowContinueError(
    2719             :                             state,
    2720           0 :                             format("is less than or equal to the design inlet air wet-bulb temperature of {:.2T} C.", this->DesInletAirWBTemp));
    2721           0 :                         ShowContinueError(state,
    2722           0 :                                           format("If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design "
    2723             :                                                  "Setpoint must be > {:.2T} C if autosizing the cooling tower.",
    2724           0 :                                                  this->DesInletAirWBTemp));
    2725           0 :                         ShowFatalError(state, format("Autosizing of cooling tower fails for tower = {}.", this->Name));
    2726             :                     }
    2727             : 
    2728         391 :                     Real64 const solveDesignWaterMassFlow = rho * tmpDesignWaterFlowRate; // design water mass flow rate
    2729         391 :                     UA0 = 0.0001 * DesTowerLoad;                                          // Assume deltaT = 10000K (limit)
    2730         391 :                     UA1 = DesTowerLoad;                                                   // Assume deltaT = 1K
    2731         391 :                     this->WaterTemp = DesTowerInletWaterTemp;
    2732         391 :                     this->AirTemp = this->DesInletAirDBTemp;    // 35.0;
    2733         391 :                     this->AirWetBulb = this->DesInletAirWBTemp; // 25.6;
    2734         391 :                     this->AirPress = state.dataEnvrn->StdBaroPress;
    2735         391 :                     this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    2736       19360 :                     auto f1 = [&state, this, DesTowerLoad, solveDesignWaterMassFlow, tmpHighSpeedAirFlowRate, Cp](Real64 UA) {
    2737             :                         Real64 const OutWaterTemp =
    2738        9680 :                             this->calculateSimpleTowerOutletTemp(state, solveDesignWaterMassFlow, tmpHighSpeedAirFlowRate, UA);
    2739        9680 :                         Real64 const CoolingOutput = Cp * solveDesignWaterMassFlow * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    2740        9680 :                         return (DesTowerLoad - CoolingOutput) / DesTowerLoad;
    2741         391 :                     };
    2742         391 :                     General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f1, UA0, UA1);
    2743         391 :                     if (SolFla == -1) {
    2744           0 :                         ShowSevereError(state, "Iteration limit exceeded in calculating tower UA");
    2745           0 :                         ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    2746         391 :                     } else if (SolFla == -2) {
    2747           0 :                         ShowSevereError(state, "Bad starting values for UA");
    2748           0 :                         ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    2749             :                     }
    2750             : 
    2751         391 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    2752         140 :                         this->HighSpeedTowerUA = UA;
    2753             :                     }
    2754         391 :                     this->TowerNominalCapacity = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    2755             :                 } else {
    2756         221 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    2757           0 :                         this->HighSpeedTowerUA = 0.0;
    2758             :                     }
    2759             :                 }
    2760         612 :                 if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_SingleSpd) {
    2761         572 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2762         220 :                         BaseSizer::reportSizerOutput(state,
    2763         110 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2764             :                                                      this->Name,
    2765             :                                                      "U-Factor Times Area Value at Design Air Flow Rate [W/C]",
    2766             :                                                      this->HighSpeedTowerUA);
    2767             :                     }
    2768         572 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2769          22 :                         BaseSizer::reportSizerOutput(state,
    2770          11 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2771             :                                                      this->Name,
    2772             :                                                      "Initial U-Factor Times Area Value at Design Air Flow Rate [W/C]",
    2773             :                                                      this->HighSpeedTowerUA);
    2774             :                     }
    2775          40 :                 } else if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_TwoSpd) {
    2776          40 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2777          16 :                         BaseSizer::reportSizerOutput(state,
    2778           8 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2779             :                                                      this->Name,
    2780             :                                                      "U-Factor Times Area Value at High Fan Speed [W/C]",
    2781             :                                                      this->HighSpeedTowerUA);
    2782             :                     }
    2783          40 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2784           0 :                         BaseSizer::reportSizerOutput(state,
    2785           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2786             :                                                      this->Name,
    2787             :                                                      "Initial U-Factor Times Area Value at High Fan Speed [W/C]",
    2788             :                                                      this->HighSpeedTowerUA);
    2789             :                     }
    2790             :                 }
    2791             :             } else {
    2792           0 :                 if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow) {
    2793             : 
    2794           0 :                     Real64 const rho = FluidProperties::GetDensityGlycol(state,
    2795           0 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2796             :                                                                          Constant::InitConvTemp,
    2797           0 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2798             :                                                                          RoutineName);
    2799           0 :                     Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    2800           0 :                                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2801             :                                                                              DesTowerExitWaterTemp,
    2802           0 :                                                                              state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2803             :                                                                              RoutineName);
    2804           0 :                     DesTowerLoad = rho * Cp * tmpDesignWaterFlowRate * DesTowerWaterDeltaT;
    2805             :                     // This conditional statement is to trap when the user specified condenser/tower water design setpoint
    2806             :                     //  temperature is less than design inlet air wet bulb temperature
    2807             :                     // Note JM 2018-11-22
    2808             :                     // * If actually user-specified:
    2809             :                     //  this->DesOutletWaterTemp = this->DesInletAirWBTemp
    2810             :                     //                                           + this->DesApproach;
    2811             :                     //  DesTowerExitWaterTemp = this->DesOutletWaterTemp;
    2812             :                     //  => This basically means that approach is negative, which is impossible (must be > 0 per IDD)
    2813             :                     // * If not, hardcoded above to 21C
    2814           0 :                     if (DesTowerExitWaterTemp <= this->DesInletAirWBTemp) {
    2815           0 :                         ShowSevereError(state,
    2816           0 :                                         format("Error when autosizing the UA value for cooling tower = {}. Design Tower Exit Temperature must be "
    2817             :                                                "greater than {:.2T} C when autosizing the tower UA.",
    2818           0 :                                                this->Name,
    2819           0 :                                                this->DesInletAirWBTemp));
    2820           0 :                         ShowContinueError(state, format("The User-specified Design Loop Exit Temperature={:.2T}", DesTowerExitWaterTemp));
    2821           0 :                         ShowContinueError(
    2822             :                             state,
    2823           0 :                             format("is less than or equal to the design inlet air wet-bulb temperature of {:.2T} C.", this->DesInletAirWBTemp));
    2824             : 
    2825           0 :                         if (this->TowerInletCondsAutoSize) {
    2826           0 :                             ShowContinueError(state,
    2827           0 :                                               format("Because you did not specify the Design Approach Temperature, and you do not have a "
    2828             :                                                      "Sizing:Plant object, it was defaulted to {:.2T} C.",
    2829             :                                                      DesTowerExitWaterTemp));
    2830             :                         } else {
    2831             :                             // Should never get there...
    2832           0 :                             ShowContinueError(state,
    2833           0 :                                               format("The Design Loop Exit Temperature is the sum of the design air inlet wet-bulb temperature= "
    2834             :                                                      "{:.2T} C plus the cooling tower design approach temperature = {:.2T}C.",
    2835           0 :                                                      this->DesInletAirWBTemp,
    2836           0 :                                                      this->DesApproach));
    2837             :                         }
    2838           0 :                         ShowContinueError(state,
    2839           0 :                                           format("If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design "
    2840             :                                                  "Setpoint must be > {:.2T} C if autosizing the cooling tower.",
    2841           0 :                                                  this->DesInletAirWBTemp));
    2842           0 :                         ShowFatalError(state, format("Autosizing of cooling tower fails for tower = {}.", this->Name));
    2843             :                     }
    2844             : 
    2845           0 :                     Real64 const solveWaterMassFlow = rho * tmpDesignWaterFlowRate; // design water mass flow rate
    2846           0 :                     UA0 = 0.0001 * DesTowerLoad;                                    // Assume deltaT = 10000K (limit)
    2847           0 :                     UA1 = DesTowerLoad;                                             // Assume deltaT = 1K
    2848           0 :                     this->WaterTemp = DesTowerInletWaterTemp;
    2849           0 :                     this->AirTemp = this->DesInletAirDBTemp;    // 35.0;
    2850           0 :                     this->AirWetBulb = this->DesInletAirWBTemp; // 25.6;
    2851           0 :                     this->AirPress = state.dataEnvrn->StdBaroPress;
    2852           0 :                     this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    2853           0 :                     auto f = [&state, this, DesTowerLoad, solveWaterMassFlow, tmpHighSpeedAirFlowRate, Cp](Real64 UA) {
    2854           0 :                         Real64 const OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterMassFlow, tmpHighSpeedAirFlowRate, UA);
    2855           0 :                         Real64 const CoolingOutput = Cp * solveWaterMassFlow * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    2856           0 :                         return (DesTowerLoad - CoolingOutput) / DesTowerLoad;
    2857           0 :                     };
    2858           0 :                     General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    2859           0 :                     if (SolFla == -1) {
    2860           0 :                         ShowSevereError(state, "Iteration limit exceeded in calculating tower UA");
    2861           0 :                         ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    2862           0 :                     } else if (SolFla == -2) {
    2863           0 :                         ShowSevereError(state, "Bad starting values for UA");
    2864           0 :                         ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    2865             :                     }
    2866             : 
    2867           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    2868           0 :                         this->HighSpeedTowerUA = UA;
    2869             :                     }
    2870           0 :                     this->TowerNominalCapacity = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    2871             :                 } else {
    2872           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    2873           0 :                         this->HighSpeedTowerUA = 0.0;
    2874             :                     }
    2875             :                 }
    2876           0 :                 if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_SingleSpd) {
    2877           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2878           0 :                         BaseSizer::reportSizerOutput(state,
    2879           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2880             :                                                      this->Name,
    2881             :                                                      "U-Factor Times Area Value at Design Air Flow Rate [W/C]",
    2882             :                                                      this->HighSpeedTowerUA);
    2883             :                     }
    2884           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2885           0 :                         BaseSizer::reportSizerOutput(state,
    2886           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2887             :                                                      this->Name,
    2888             :                                                      "Initial U-Factor Times Area Value at Design Air Flow Rate [W/C]",
    2889             :                                                      this->HighSpeedTowerUA);
    2890             :                     }
    2891           0 :                 } else if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_TwoSpd) {
    2892           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2893           0 :                         BaseSizer::reportSizerOutput(state,
    2894           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2895             :                                                      this->Name,
    2896             :                                                      "U-Factor Times Area Value at High Fan Speed [W/C]",
    2897             :                                                      this->HighSpeedTowerUA);
    2898             :                     }
    2899           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2900           0 :                         BaseSizer::reportSizerOutput(state,
    2901           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2902             :                                                      this->Name,
    2903             :                                                      "Initial U-Factor Times Area Value at High Fan Speed [W/C]",
    2904             :                                                      this->HighSpeedTowerUA);
    2905             :                     }
    2906             :                 }
    2907             :             }
    2908             :         }
    2909             : 
    2910        1362 :         if (this->PerformanceInputMethod_Num == PIM::NominalCapacity) {
    2911          40 :             if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow) {
    2912             :                 // nominal capacity doesn't include compressor heat; predefined factor was 1.25 W heat rejection per W of delivered cooling but now is
    2913             :                 // a user input
    2914          40 :                 Real64 const rho = FluidProperties::GetDensityGlycol(state,
    2915          40 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2916             :                                                                      29.44,
    2917          40 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2918             :                                                                      RoutineName); // 85F design exiting water temp
    2919          40 :                 Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    2920          40 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    2921             :                                                                          29.44,
    2922          40 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    2923             :                                                                          RoutineName); // 85F design exiting water temp
    2924             : 
    2925          40 :                 DesTowerLoad = this->TowerNominalCapacity * this->HeatRejectCapNomCapSizingRatio;
    2926          40 :                 Real64 const solveWaterFlowRate = rho * tmpDesignWaterFlowRate; // design water mass flow rate
    2927          40 :                 UA0 = 0.0001 * DesTowerLoad;                                    // Assume deltaT = 10000K (limit)
    2928          40 :                 UA1 = DesTowerLoad;                                             // Assume deltaT = 1K
    2929          40 :                 this->WaterTemp = this->DesInletWaterTemp;                      // 35.0; // 95F design inlet water temperature
    2930          40 :                 this->AirTemp = this->DesInletAirDBTemp;                        // 95F design inlet air dry-bulb temp
    2931          40 :                 this->AirWetBulb = this->DesInletAirWBTemp;                     // 78F design inlet air wet-bulb temp
    2932          40 :                 this->AirPress = state.dataEnvrn->StdBaroPress;
    2933          40 :                 this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    2934        2010 :                 auto f = [&state, this, DesTowerLoad, solveWaterFlowRate, tmpHighSpeedAirFlowRate, Cp](Real64 UA) {
    2935        1005 :                     Real64 const OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlowRate, tmpHighSpeedAirFlowRate, UA);
    2936        1005 :                     Real64 const CoolingOutput = Cp * solveWaterFlowRate * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    2937        1005 :                     return (DesTowerLoad - CoolingOutput) / DesTowerLoad;
    2938          40 :                 };
    2939          40 :                 General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    2940          40 :                 if (SolFla == -1) {
    2941           0 :                     ShowSevereError(state, "Iteration limit exceeded in calculating tower UA");
    2942           0 :                     ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    2943          40 :                 } else if (SolFla == -2) {
    2944           0 :                     ShowSevereError(state, "Bad starting values for UA");
    2945           0 :                     ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    2946             :                 }
    2947          40 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    2948           8 :                     this->HighSpeedTowerUA = UA;
    2949             :                 }
    2950             :             } else {
    2951           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    2952           0 :                     this->HighSpeedTowerUA = 0.0;
    2953             :                 }
    2954             :             }
    2955          40 :             if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_SingleSpd) {
    2956          15 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2957           6 :                     BaseSizer::reportSizerOutput(state,
    2958           3 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2959             :                                                  this->Name,
    2960             :                                                  "U-Factor Times Area Value at Design Air Flow Rate [W/C]",
    2961             :                                                  this->HighSpeedTowerUA);
    2962             :                 }
    2963          15 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2964           0 :                     BaseSizer::reportSizerOutput(state,
    2965           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2966             :                                                  this->Name,
    2967             :                                                  "Initial U-Factor Times Area Value at Design Air Flow Rate [W/C]",
    2968             :                                                  this->HighSpeedTowerUA);
    2969             :                 }
    2970          25 :             } else if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_TwoSpd) {
    2971          25 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2972          10 :                     BaseSizer::reportSizerOutput(state,
    2973           5 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2974             :                                                  this->Name,
    2975             :                                                  "U-Factor Times Area Value at High Fan Speed [W/C]",
    2976             :                                                  this->HighSpeedTowerUA);
    2977             :                 }
    2978          25 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    2979           0 :                     BaseSizer::reportSizerOutput(state,
    2980           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2981             :                                                  this->Name,
    2982             :                                                  "Initial U-Factor Times Area Value at High Fan Speed [W/C]",
    2983             :                                                  this->HighSpeedTowerUA);
    2984             :                 }
    2985             :             }
    2986             :         }
    2987             : 
    2988        1362 :         if (this->LowSpeedAirFlowRateWasAutoSized) {
    2989             : 
    2990          45 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    2991           9 :                 this->LowSpeedAirFlowRate = this->LowSpeedAirFlowRateSizingFactor * this->HighSpeedAirFlowRate;
    2992           9 :                 tmpLowSpeedAirFlowRate = this->LowSpeedAirFlowRate;
    2993           9 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    2994          18 :                     BaseSizer::reportSizerOutput(state,
    2995           9 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    2996             :                                                  this->Name,
    2997             :                                                  "Low Fan Speed Air Flow Rate [m3/s]",
    2998             :                                                  this->LowSpeedAirFlowRate);
    2999             :                 }
    3000           9 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3001           0 :                     BaseSizer::reportSizerOutput(state,
    3002           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3003             :                                                  this->Name,
    3004             :                                                  "Initial Low Fan Speed Air Flow Rate [m3/s]",
    3005             :                                                  this->LowSpeedAirFlowRate);
    3006             :                 }
    3007             :             } else {
    3008          36 :                 tmpLowSpeedAirFlowRate = this->LowSpeedAirFlowRateSizingFactor * tmpHighSpeedAirFlowRate;
    3009             :             }
    3010             :         }
    3011             : 
    3012        1362 :         if (this->LowSpeedFanPowerWasAutoSized) {
    3013          45 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3014           9 :                 this->LowSpeedFanPower = this->LowSpeedFanPowerSizingFactor * this->HighSpeedFanPower;
    3015           9 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3016          18 :                     BaseSizer::reportSizerOutput(state,
    3017           9 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3018             :                                                  this->Name,
    3019             :                                                  "Fan Power at Low Fan Speed [W]",
    3020             :                                                  this->LowSpeedFanPower);
    3021             :                 }
    3022           9 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3023           0 :                     BaseSizer::reportSizerOutput(state,
    3024           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3025             :                                                  this->Name,
    3026             :                                                  "Initial Fan Power at Low Fan Speed [W]",
    3027             :                                                  this->LowSpeedFanPower);
    3028             :                 }
    3029             :             }
    3030             :         }
    3031             : 
    3032        1362 :         if (this->LowSpeedTowerUAWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3033           8 :             this->LowSpeedTowerUA = this->LowSpeedTowerUASizingFactor * this->HighSpeedTowerUA;
    3034           8 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3035          16 :                 BaseSizer::reportSizerOutput(state,
    3036           8 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3037             :                                              this->Name,
    3038             :                                              "U-Factor Times Area Value at Low Fan Speed [W/K]",
    3039             :                                              this->LowSpeedTowerUA);
    3040             :             }
    3041           8 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3042           0 :                 BaseSizer::reportSizerOutput(state,
    3043           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3044             :                                              this->Name,
    3045             :                                              "Initial U-Factor Times Area Value at Low Fan Speed [W/K]",
    3046             :                                              this->LowSpeedTowerUA);
    3047             :             }
    3048             :         }
    3049             : 
    3050        1362 :         if (this->PerformanceInputMethod_Num == PIM::NominalCapacity) {
    3051          40 :             if (this->TowerLowSpeedNomCapWasAutoSized) {
    3052           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3053           0 :                     this->TowerLowSpeedNomCap = this->TowerLowSpeedNomCapSizingFactor * this->TowerNominalCapacity;
    3054           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3055           0 :                         BaseSizer::reportSizerOutput(state,
    3056           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3057             :                                                      this->Name,
    3058             :                                                      "Low Speed Nominal Capacity [W]",
    3059             :                                                      this->TowerLowSpeedNomCap);
    3060             :                     }
    3061           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3062           0 :                         BaseSizer::reportSizerOutput(state,
    3063           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3064             :                                                      this->Name,
    3065             :                                                      "Initial Low Speed Nominal Capacity [W]",
    3066             :                                                      this->TowerLowSpeedNomCap);
    3067             :                     }
    3068             :                 }
    3069             :             }
    3070          40 :             if (this->TowerFreeConvNomCapWasAutoSized) {
    3071           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3072           0 :                     this->TowerFreeConvNomCap = this->TowerFreeConvNomCapSizingFactor * this->TowerNominalCapacity;
    3073           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3074           0 :                         BaseSizer::reportSizerOutput(state,
    3075           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3076             :                                                      this->Name,
    3077             :                                                      "Free Convection Nominal Capacity [W]",
    3078             :                                                      this->TowerFreeConvNomCap);
    3079             :                     }
    3080           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3081           0 :                         BaseSizer::reportSizerOutput(state,
    3082           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3083             :                                                      this->Name,
    3084             :                                                      "Initial Free Convection Nominal Capacity [W]",
    3085             :                                                      this->TowerFreeConvNomCap);
    3086             :                     }
    3087             :                 }
    3088             :             }
    3089             :         }
    3090             : 
    3091        1402 :         if (this->PerformanceInputMethod_Num == PIM::NominalCapacity &&
    3092        1402 :             Util::SameString(DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)], "CoolingTower:TwoSpeed")) {
    3093          25 :             if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow && this->TowerLowSpeedNomCap > 0.0) {
    3094             : 
    3095             :                 // nominal capacity doesn't include compressor heat; predefined factor was 1.25 W heat rejection per W of evap cooling but now is a
    3096             :                 // user input
    3097          25 :                 Real64 const rho = FluidProperties::GetDensityGlycol(state,
    3098          25 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3099             :                                                                      29.44,
    3100          25 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3101             :                                                                      RoutineName); // 85F design exiting water temp
    3102          25 :                 Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    3103          25 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3104             :                                                                          29.44,
    3105          25 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3106             :                                                                          RoutineName); // 85F design exiting water temp
    3107          25 :                 DesTowerLoad = this->TowerLowSpeedNomCap * this->HeatRejectCapNomCapSizingRatio;
    3108          25 :                 Real64 const solveWaterFlow = rho * tmpDesignWaterFlowRate; // design water mass flow rate
    3109          25 :                 UA0 = 0.0001 * DesTowerLoad;                                // Assume deltaT = 10000K (limit)
    3110          25 :                 UA1 = DesTowerLoad;                                         // Assume deltaT = 1K
    3111          25 :                 this->WaterTemp = this->DesInletWaterTemp;                  // 35.0; // 95F design inlet water temperature
    3112          25 :                 this->AirTemp = this->DesInletAirDBTemp;                    // 35.0; // 95F design inlet air dry-bulb temp
    3113          25 :                 this->AirWetBulb = this->DesInletAirWBTemp;                 // 25.6; // 78F design inlet air wet-bulb temp
    3114          25 :                 this->AirPress = state.dataEnvrn->StdBaroPress;
    3115          25 :                 this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    3116         700 :                 auto f = [&state, this, DesTowerLoad, solveWaterFlow, tmpLowSpeedAirFlowRate, Cp](Real64 UA) {
    3117         350 :                     Real64 const OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlow, tmpLowSpeedAirFlowRate, UA);
    3118         350 :                     Real64 const CoolingOutput = Cp * solveWaterFlow * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    3119         350 :                     return (DesTowerLoad - CoolingOutput) / DesTowerLoad;
    3120          25 :                 };
    3121          25 :                 General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    3122          25 :                 if (SolFla == -1) {
    3123           0 :                     ShowSevereError(state, "Iteration limit exceeded in calculating tower UA");
    3124           0 :                     ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    3125          25 :                 } else if (SolFla == -2) {
    3126           0 :                     ShowSevereError(state, "Bad starting values for UA");
    3127           0 :                     ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    3128             :                 }
    3129          25 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3130           5 :                     this->LowSpeedTowerUA = UA;
    3131             :                 }
    3132          25 :             } else {
    3133           0 :                 this->LowSpeedTowerUA = 0.0;
    3134             :             }
    3135          25 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3136          10 :                 BaseSizer::reportSizerOutput(state,
    3137           5 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3138             :                                              this->Name,
    3139             :                                              "Low Fan Speed U-Factor Times Area Value [W/K]",
    3140             :                                              this->LowSpeedTowerUA);
    3141             :             }
    3142          25 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3143           0 :                 BaseSizer::reportSizerOutput(state,
    3144           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3145             :                                              this->Name,
    3146             :                                              "Initial Low Fan Speed U-Factor Times Area Value [W/K]",
    3147             :                                              this->LowSpeedTowerUA);
    3148             :             }
    3149             :         }
    3150             : 
    3151        1362 :         if (this->FreeConvAirFlowRateWasAutoSized) {
    3152         336 :             this->FreeConvAirFlowRate = this->FreeConvAirFlowRateSizingFactor * tmpHighSpeedAirFlowRate;
    3153         336 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3154          80 :                 this->FreeConvAirFlowRate = this->FreeConvAirFlowRateSizingFactor * this->HighSpeedAirFlowRate;
    3155          80 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3156         128 :                     BaseSizer::reportSizerOutput(state,
    3157          64 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3158             :                                                  this->Name,
    3159             :                                                  "Free Convection Regime Air Flow Rate [m3/s]",
    3160             :                                                  this->FreeConvAirFlowRate);
    3161             :                 }
    3162          80 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3163          16 :                     BaseSizer::reportSizerOutput(state,
    3164           8 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3165             :                                                  this->Name,
    3166             :                                                  "Initial Free Convection Regime Air Flow Rate [m3/s]",
    3167             :                                                  this->FreeConvAirFlowRate);
    3168             :                 }
    3169             :             }
    3170             :         }
    3171             : 
    3172        1362 :         if (this->FreeConvTowerUAWasAutoSized) {
    3173         331 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3174          79 :                 this->FreeConvTowerUA = this->FreeConvTowerUASizingFactor * this->HighSpeedTowerUA;
    3175          79 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3176         126 :                     BaseSizer::reportSizerOutput(state,
    3177          63 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3178             :                                                  this->Name,
    3179             :                                                  "Free Convection U-Factor Times Area Value [W/K]",
    3180             :                                                  this->FreeConvTowerUA);
    3181             :                 }
    3182          79 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3183          16 :                     BaseSizer::reportSizerOutput(state,
    3184           8 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3185             :                                                  this->Name,
    3186             :                                                  "Initial Free Convection U-Factor Times Area Value [W/K]",
    3187             :                                                  this->FreeConvTowerUA);
    3188             :                 }
    3189             :             }
    3190             :         }
    3191             : 
    3192        1362 :         if (this->PerformanceInputMethod_Num == PIM::NominalCapacity) {
    3193          40 :             if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow && this->TowerFreeConvNomCap > 0.0) {
    3194             :                 // nominal capacity doesn't include compressor heat; predefined factor was 1.25 W heat rejection per W of evap cooling but now user
    3195             :                 // input
    3196          25 :                 Real64 const rho = FluidProperties::GetDensityGlycol(state,
    3197          25 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3198             :                                                                      29.44,
    3199          25 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3200             :                                                                      RoutineName); // 85F design exiting water temp
    3201          25 :                 Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    3202          25 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3203             :                                                                          29.44,
    3204          25 :                                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3205             :                                                                          RoutineName); // 85F design exiting water temp
    3206          25 :                 DesTowerLoad = this->TowerFreeConvNomCap * this->HeatRejectCapNomCapSizingRatio;
    3207          25 :                 Real64 const solveWaterFlow = rho * this->DesignWaterFlowRate; // design water mass flow rate
    3208          25 :                 UA0 = 0.0001 * DesTowerLoad;                                   // Assume deltaT = 10000K (limit)
    3209          25 :                 UA1 = DesTowerLoad;                                            // Assume deltaT = 1K
    3210          25 :                 this->WaterTemp = this->DesInletWaterTemp;                     // 35.0; // 95F design inlet water temperature
    3211          25 :                 this->AirTemp = this->DesInletAirDBTemp;                       // 35.0; // 95F design inlet air dry-bulb temp
    3212          25 :                 this->AirWetBulb = this->DesInletAirWBTemp;                    // 25.6; // 78F design inlet air wet-bulb temp
    3213          25 :                 this->AirPress = state.dataEnvrn->StdBaroPress;
    3214          25 :                 this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    3215         560 :                 auto f = [&state, this, DesTowerLoad, solveWaterFlow, Cp](Real64 UA) {
    3216         280 :                     Real64 const OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlow, this->FreeConvAirFlowRate, UA);
    3217         280 :                     Real64 const CoolingOutput = Cp * solveWaterFlow * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    3218         280 :                     return (DesTowerLoad - CoolingOutput) / DesTowerLoad;
    3219          25 :                 };
    3220          25 :                 General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    3221          25 :                 if (SolFla == -1) {
    3222           0 :                     ShowSevereError(state, "Iteration limit exceeded in calculating tower UA");
    3223           0 :                     ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    3224          25 :                 } else if (SolFla == -2) {
    3225           0 :                     ShowSevereError(state, "Bad starting values for UA calculations");
    3226           0 :                     ShowContinueError(state, "Tower inlet design water temperature assumed to be 35.0 C.");
    3227           0 :                     ShowContinueError(state, "Tower inlet design air dry-bulb temperature assumed to be 35.0 C.");
    3228           0 :                     ShowContinueError(state, "Tower inlet design air wet-bulb temperature assumed to be 25.6 C.");
    3229           0 :                     ShowContinueError(state,
    3230           0 :                                       format("Tower load assumed to be {:.3T} times free convection capacity of {:.0T} W.",
    3231           0 :                                              this->HeatRejectCapNomCapSizingRatio,
    3232           0 :                                              this->TowerFreeConvNomCap));
    3233             : 
    3234             :                     Real64 OutWaterTemp; // outlet water temperature during sizing [C]
    3235             : 
    3236           0 :                     OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlow, this->FreeConvAirFlowRate, UA0);
    3237           0 :                     Real64 CoolingOutput = Cp * solveWaterFlow * (this->WaterTemp - OutWaterTemp); // tower capacity during sizing [W]
    3238           0 :                     ShowContinueError(state, format("Tower capacity at lower UA guess ({:.4T}) = {:.0T} W.", UA0, CoolingOutput));
    3239             : 
    3240           0 :                     OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlow, this->FreeConvAirFlowRate, UA1);
    3241           0 :                     CoolingOutput = Cp * solveWaterFlow * (this->WaterTemp - OutWaterTemp);
    3242           0 :                     ShowContinueError(state, format("Tower capacity at upper UA guess ({:.4T}) = {:.0T} W.", UA1, CoolingOutput));
    3243             : 
    3244           0 :                     if (CoolingOutput < DesTowerLoad) {
    3245           0 :                         ShowContinueError(state, "Free convection capacity should be less than tower capacity at upper UA guess.");
    3246             :                     }
    3247           0 :                     ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    3248             :                 }
    3249          25 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3250           5 :                     this->FreeConvTowerUA = UA;
    3251             :                 }
    3252          25 :             } else {
    3253          15 :                 this->FreeConvTowerUA = 0.0;
    3254             :             }
    3255          40 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3256          16 :                 BaseSizer::reportSizerOutput(state,
    3257           8 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3258             :                                              this->Name,
    3259             :                                              "U-Factor Times Area Value at Free Convection Air Flow Rate [W/C]",
    3260             :                                              this->FreeConvTowerUA);
    3261             :             }
    3262          40 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3263           0 :                 BaseSizer::reportSizerOutput(state,
    3264           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3265             :                                              this->Name,
    3266             :                                              "Initial U-Factor Times Area Value at Free Convection Air Flow Rate [W/C]",
    3267             :                                              this->FreeConvTowerUA);
    3268             :             }
    3269             :         }
    3270             : 
    3271             :         // calibrate variable speed tower model based on user input by finding calibration water flow rate ratio that
    3272             :         // yields an approach temperature that matches user input
    3273        1362 :         if (Util::SameString(DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)], "CoolingTower:VariableSpeed")) {
    3274             : 
    3275             :             //   check range for water flow rate ratio (make sure RegulaFalsi converges)
    3276         120 :             Real64 MaxWaterFlowRateRatio = 0.5; // maximum water flow rate ratio which yields desired approach temp
    3277         120 :             Real64 Tapproach = 0.0;             // temporary tower approach temp variable [C]
    3278         120 :             Real64 const FlowRateRatioStep = (state.dataCondenserLoopTowers->towers(this->VSTower).MaxWaterFlowRatio -
    3279         120 :                                               state.dataCondenserLoopTowers->towers(this->VSTower).MinWaterFlowRatio) /
    3280         120 :                                              10.0;
    3281         120 :             bool ModelCalibrated = true;
    3282         120 :             Real64 ModelWaterFlowRatioMax = state.dataCondenserLoopTowers->towers(this->VSTower).MaxWaterFlowRatio *
    3283         120 :                                             4.0; // maximum water flow rate ratio used for model calibration
    3284             :             //   find a flow rate large enough to provide an approach temperature > than the user defined approach
    3285         120 :             Real64 WaterFlowRateRatio(0.0); // tower water flow rate ratio
    3286        1285 :             while (Tapproach < this->DesignApproach && MaxWaterFlowRateRatio <= ModelWaterFlowRatioMax) {
    3287        1165 :                 WaterFlowRateRatio = MaxWaterFlowRateRatio;
    3288        1165 :                 Tapproach = this->calculateVariableSpeedApproach(state, WaterFlowRateRatio, 1.0, this->DesignInletWB, this->DesignRange);
    3289        1165 :                 if (Tapproach < this->DesignApproach) {
    3290        1045 :                     MaxWaterFlowRateRatio += FlowRateRatioStep;
    3291             :                 }
    3292             :                 // a water flow rate large enough to provide an approach temperature > than the user defined approach does not exist
    3293             :                 // within the tolerances specified by the user
    3294        1165 :                 if ((MaxWaterFlowRateRatio == 0.5 && Tapproach > this->DesignApproach) || MaxWaterFlowRateRatio >= ModelWaterFlowRatioMax) {
    3295           0 :                     ModelCalibrated = false;
    3296           0 :                     break;
    3297             :                 }
    3298             :             }
    3299             : 
    3300         120 :             Real64 WaterFlowRatio(0.0); // tower water flow rate ratio found during model calibration
    3301             : 
    3302         120 :             if (ModelCalibrated) {
    3303        1020 :                 auto f = [&state, this](Real64 FlowRatio) {
    3304         510 :                     Real64 Tact = this->calculateVariableSpeedApproach(state, FlowRatio, 1.0, this->DesignInletWB, this->DesignRange);
    3305         510 :                     return this->DesignApproach - Tact;
    3306         120 :                 };
    3307         120 :                 General::SolveRoot(state, Acc, MaxIte, SolFla, WaterFlowRatio, f, DataPrecisionGlobals::constant_pointfive, MaxWaterFlowRateRatio);
    3308             : 
    3309         120 :                 if (SolFla == -1) {
    3310           0 :                     ShowSevereError(state, "Iteration limit exceeded in calculating tower water flow ratio during calibration");
    3311           0 :                     ShowContinueError(state,
    3312             :                                       "Inlet air wet-bulb, range, and/or approach temperature does not allow calibration of water flow rate ratio "
    3313             :                                       "for this variable-speed cooling tower.");
    3314           0 :                     ShowFatalError(state, format("Cooling tower calibration failed for tower {}", this->Name));
    3315         120 :                 } else if (SolFla == -2) {
    3316           0 :                     ShowSevereError(state, "Bad starting values for cooling tower water flow rate ratio calibration.");
    3317           0 :                     ShowContinueError(state,
    3318             :                                       "Inlet air wet-bulb, range, and/or approach temperature does not allow calibration of water flow rate ratio "
    3319             :                                       "for this variable-speed cooling tower.");
    3320           0 :                     ShowFatalError(state, format("Cooling tower calibration failed for tower {}.", this->Name));
    3321             :                 }
    3322             :             } else {
    3323           0 :                 ShowSevereError(state, "Bad starting values for cooling tower water flow rate ratio calibration.");
    3324           0 :                 ShowContinueError(state, "Design inlet air wet-bulb or range temperature must be modified to achieve the design approach");
    3325           0 :                 ShowContinueError(state,
    3326           0 :                                   format("A water flow rate ratio of {:.6F} was calculated to yield an approach temperature of {:.2F}.",
    3327             :                                          WaterFlowRateRatio,
    3328             :                                          Tapproach));
    3329           0 :                 ShowFatalError(state, format("Cooling tower calibration failed for tower {}.", this->Name));
    3330             :             }
    3331             : 
    3332         120 :             this->CalibratedWaterFlowRate = this->DesignWaterFlowRate / WaterFlowRatio;
    3333             : 
    3334         240 :             if (WaterFlowRatio < state.dataCondenserLoopTowers->towers(this->VSTower).MinWaterFlowRatio ||
    3335         120 :                 WaterFlowRatio > state.dataCondenserLoopTowers->towers(this->VSTower).MaxWaterFlowRatio) {
    3336           0 :                 ShowWarningError(state,
    3337           0 :                                  format("CoolingTower:VariableSpeed, \"{}\" the calibrated water flow rate ratio is determined to be {:9.6F}. This "
    3338             :                                         "is outside the valid range of {:.2F} to {:.2F}.",
    3339           0 :                                         this->Name,
    3340             :                                         WaterFlowRatio,
    3341           0 :                                         state.dataCondenserLoopTowers->towers(this->VSTower).MinWaterFlowRatio,
    3342           0 :                                         state.dataCondenserLoopTowers->towers(this->VSTower).MaxWaterFlowRatio));
    3343             :             }
    3344             : 
    3345         120 :             Real64 const rho = FluidProperties::GetDensityGlycol(state,
    3346         120 :                                                                  state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3347         120 :                                                                  (this->DesignInletWB + this->DesignApproach + this->DesignRange),
    3348         120 :                                                                  state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3349             :                                                                  RoutineName);
    3350         120 :             Real64 const Cp = FluidProperties::GetSpecificHeatGlycol(state,
    3351         120 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3352         120 :                                                                      (this->DesignInletWB + this->DesignApproach + this->DesignRange),
    3353         120 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3354             :                                                                      RoutineName);
    3355             : 
    3356         120 :             this->TowerNominalCapacity = ((rho * tmpDesignWaterFlowRate) * Cp * this->DesignRange);
    3357         120 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3358          48 :                 BaseSizer::reportSizerOutput(state,
    3359          24 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3360             :                                              this->Name,
    3361             :                                              "Nominal Capacity [W]",
    3362             :                                              this->TowerNominalCapacity);
    3363             :             }
    3364         120 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3365           0 :                 BaseSizer::reportSizerOutput(state,
    3366           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3367             :                                              this->Name,
    3368             :                                              "Initial Nominal Capacity [W]",
    3369             :                                              this->TowerNominalCapacity);
    3370             :             }
    3371         120 :             this->FreeConvAirFlowRate = this->MinimumVSAirFlowFrac * this->HighSpeedAirFlowRate;
    3372             : 
    3373         120 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3374          48 :                 BaseSizer::reportSizerOutput(state,
    3375          24 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3376             :                                              this->Name,
    3377             :                                              "Air Flow Rate in free convection regime [m3/s]",
    3378             :                                              this->FreeConvAirFlowRate);
    3379             :             }
    3380         120 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3381           0 :                 BaseSizer::reportSizerOutput(state,
    3382           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3383             :                                              this->Name,
    3384             :                                              "Initial Air Flow Rate in free convection regime [m3/s]",
    3385             :                                              this->FreeConvAirFlowRate);
    3386             :             }
    3387         120 :             this->TowerFreeConvNomCap = this->TowerNominalCapacity * this->FreeConvectionCapacityFraction;
    3388             : 
    3389         120 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3390          48 :                 BaseSizer::reportSizerOutput(state,
    3391          24 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3392             :                                              this->Name,
    3393             :                                              "Tower capacity in free convection regime at design conditions [W]",
    3394             :                                              this->TowerFreeConvNomCap);
    3395             :             }
    3396         120 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3397           0 :                 BaseSizer::reportSizerOutput(state,
    3398           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3399             :                                              this->Name,
    3400             :                                              "Initial Tower capacity in free convection regime at design conditions [W]",
    3401             :                                              this->TowerFreeConvNomCap);
    3402             :             }
    3403             :         }
    3404        1362 :         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3405             :             // create predefined report
    3406         536 :             OutputReportPredefined::PreDefTableEntry(
    3407         536 :                 state, state.dataOutRptPredefined->pdchMechType, this->Name, DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)]);
    3408         268 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, this->Name, this->TowerNominalCapacity);
    3409             : 
    3410             :             // create std 229 new table for cooling towers and fluid coolers
    3411         536 :             OutputReportPredefined::PreDefTableEntry(
    3412         536 :                 state, state.dataOutRptPredefined->pdchCTFCType, this->Name, DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)]);
    3413         536 :             OutputReportPredefined::PreDefTableEntry(state,
    3414         268 :                                                      state.dataOutRptPredefined->pdchCTFCCondLoopName,
    3415             :                                                      this->Name,
    3416         536 :                                                      this->plantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(this->plantLoc.loopNum).Name : "N/A");
    3417         536 :             OutputReportPredefined::PreDefTableEntry(
    3418             :                 state,
    3419         268 :                 state.dataOutRptPredefined->pdchCTFCCondLoopBranchName,
    3420             :                 this->Name,
    3421         268 :                 this->plantLoc.loopNum > 0
    3422         536 :                     ? state.dataPlnt->PlantLoop(plantLoc.loopNum).LoopSide(plantLoc.loopSideNum).Branch(plantLoc.branchNum).Name
    3423             :                     : "N/A");
    3424         536 :             OutputReportPredefined::PreDefTableEntry(
    3425             :                 state,
    3426         268 :                 state.dataOutRptPredefined->pdchCTFCFluidType,
    3427             :                 this->Name,
    3428         268 :                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName); // Fluid Name more reasonable than FluidType
    3429         268 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCTFCRange, this->Name, this->DesignRange);
    3430         268 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCTFCApproach, this->Name, this->DesignApproach);
    3431         536 :             OutputReportPredefined::PreDefTableEntry(
    3432         268 :                 state, state.dataOutRptPredefined->pdchCTFCDesFanPwr, this->Name, this->HighSpeedFanPower); // eqival to Design Fan Power?
    3433         268 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCTFCDesInletAirWBT, this->Name, this->DesInletAirWBTemp);
    3434         536 :             OutputReportPredefined::PreDefTableEntry(
    3435         268 :                 state, state.dataOutRptPredefined->pdchCTFCDesWaterFlowRate, this->Name, this->DesignWaterFlowRate);
    3436         268 :             OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCTFCLevWaterSPTemp, this->Name, this->DesOutletWaterTemp);
    3437             :         }
    3438             : 
    3439             :         // input error checking
    3440        1362 :         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3441         268 :             bool ErrorsFound = false;
    3442         268 :             if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_SingleSpd) {
    3443         231 :                 if (this->DesignWaterFlowRate > 0.0) {
    3444         231 :                     if (this->FreeConvAirFlowRate >= this->HighSpeedAirFlowRate) {
    3445           0 :                         ShowSevereError(state,
    3446           0 :                                         format("{} \"{}\". Free convection air flow rate must be less than the design air flow rate.",
    3447             :                                                cCoolingTower_SingleSpeed,
    3448           0 :                                                this->Name));
    3449           0 :                         ErrorsFound = true;
    3450             :                     }
    3451         231 :                     if (this->FreeConvTowerUA >= this->HighSpeedTowerUA) {
    3452           0 :                         ShowSevereError(
    3453             :                             state,
    3454           0 :                             format("{} \"{}\". Free convection UA must be less than the design tower UA.", cCoolingTower_SingleSpeed, this->Name));
    3455           0 :                         ErrorsFound = true;
    3456             :                     }
    3457             :                 }
    3458             :             }
    3459             : 
    3460         268 :             if (this->TowerType == DataPlant::PlantEquipmentType::CoolingTower_TwoSpd) {
    3461          13 :                 if (this->DesignWaterFlowRate > 0.0) {
    3462          13 :                     if (this->HighSpeedAirFlowRate <= this->LowSpeedAirFlowRate) {
    3463           0 :                         ShowSevereError(state,
    3464           0 :                                         format("{} \"{}\". Low speed air flow rate must be less than the high speed air flow rate.",
    3465             :                                                cCoolingTower_TwoSpeed,
    3466           0 :                                                this->Name));
    3467           0 :                         ErrorsFound = true;
    3468             :                     }
    3469          13 :                     if (this->LowSpeedAirFlowRate <= this->FreeConvAirFlowRate) {
    3470           0 :                         ShowSevereError(state,
    3471           0 :                                         format("{} \"{}\". Free convection air flow rate must be less than the low speed air flow rate.",
    3472             :                                                cCoolingTower_TwoSpeed,
    3473           0 :                                                this->Name));
    3474           0 :                         ErrorsFound = true;
    3475             :                     }
    3476          13 :                     if (this->HighSpeedTowerUA <= this->LowSpeedTowerUA) {
    3477           0 :                         ShowSevereError(state,
    3478           0 :                                         format("{} \"{}\". Tower UA at low fan speed must be less than the tower UA at high fan speed.",
    3479             :                                                cCoolingTower_TwoSpeed,
    3480           0 :                                                this->Name));
    3481           0 :                         ErrorsFound = true;
    3482             :                     }
    3483          13 :                     if (this->LowSpeedTowerUA <= this->FreeConvTowerUA) {
    3484           0 :                         ShowSevereError(
    3485             :                             state,
    3486           0 :                             format("{} \"{}\". Tower UA at free convection air flow rate must be less than the tower UA at low fan speed.",
    3487             :                                    cCoolingTower_TwoSpeed,
    3488           0 :                                    this->Name));
    3489           0 :                         ErrorsFound = true;
    3490             :                     }
    3491             :                 }
    3492             :             }
    3493         268 :             if (ErrorsFound) {
    3494           0 :                 ShowFatalError(state, "initialize: Program terminated due to previous condition(s).");
    3495             :             }
    3496             :         }
    3497        1362 :     }
    3498             : 
    3499          10 :     void CoolingTower::SizeVSMerkelTower(EnergyPlusData &state)
    3500             :     {
    3501             : 
    3502             :         // SUBROUTINE PARAMETER DEFINITIONS:
    3503          10 :         int constexpr MaxIte(500);    // Maximum number of iterations
    3504          10 :         Real64 constexpr Acc(0.0001); // Accuracy of result
    3505             :         static constexpr std::string_view RoutineName("SizeTower");
    3506             : 
    3507             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3508             :         int SolFla; // Flag of solver
    3509             :         Real64 tmpHighSpeedFanPower;
    3510             : 
    3511             :         Real64 UA0;                       // Lower bound for UA [W/C]
    3512             :         Real64 UA1;                       // Upper bound for UA [W/C]
    3513             :         Real64 DesTowerLoad;              // Design tower load [W]
    3514          10 :         Real64 Cp(0);                     // local specific heat for fluid
    3515          10 :         Real64 rho(0);                    // local density for fluid
    3516             :         Real64 UA;                        // Calculated UA value
    3517             :         Real64 DesTowerInletWaterTemp;    // design tower inlet water temperature
    3518             :         Real64 DesTowerExitWaterTemp;     // design tower exit water temperature
    3519             :         Real64 DesTowerWaterDeltaT;       // design tower temperature range
    3520             :         Real64 DesTowerApproachFromPlant; // design tower approach temperature from plant sizing object
    3521          10 :         Real64 TolTemp(0.04);             // DeltaT and DesApproach diffs tollerance between plant sizing data and user input in cooling tower
    3522             :         // for warning message reporting purpose only
    3523             : 
    3524             :         // Find the appropriate Plant Sizing object
    3525          10 :         int PltSizCondNum = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).PlantSizNum;
    3526             : 
    3527          10 :         Real64 tmpNomTowerCap = this->TowerNominalCapacity;
    3528          10 :         Real64 tmpDesignWaterFlowRate = this->DesignWaterFlowRate;
    3529          10 :         Real64 tmpTowerFreeConvNomCap = this->TowerFreeConvNomCap;
    3530          10 :         Real64 tmpDesignAirFlowRate = this->HighSpeedAirFlowRate;
    3531          10 :         Real64 tmpFreeConvAirFlowRate = this->FreeConvAirFlowRate;
    3532          10 :         Real64 DesTowerInletAirWBTemp = this->DesInletAirWBTemp;
    3533          10 :         Real64 DesTowerInletAirDBTemp = this->DesInletAirDBTemp;
    3534             : 
    3535          10 :         auto const &PlantSizData(state.dataSize->PlantSizData);
    3536             : 
    3537          10 :         if (this->TowerInletCondsAutoSize) {
    3538          10 :             if (PltSizCondNum > 0) {
    3539             :                 // use plant sizing data
    3540          10 :                 DesTowerExitWaterTemp = PlantSizData(PltSizCondNum).ExitTemp;
    3541          10 :                 DesTowerInletWaterTemp = DesTowerExitWaterTemp + PlantSizData(PltSizCondNum).DeltaT;
    3542          10 :                 DesTowerWaterDeltaT = PlantSizData(PltSizCondNum).DeltaT;
    3543             :             } else {
    3544             :                 // set default values to replace hard wired input assumptions
    3545           0 :                 DesTowerExitWaterTemp = this->DesOutletWaterTemp;
    3546           0 :                 DesTowerInletWaterTemp = this->DesInletWaterTemp;
    3547           0 :                 DesTowerWaterDeltaT = this->DesRange;
    3548             :             }
    3549             :         } else {
    3550             :             // use tower sizing data
    3551           0 :             DesTowerExitWaterTemp = this->DesOutletWaterTemp;
    3552           0 :             DesTowerInletWaterTemp = this->DesInletWaterTemp;
    3553           0 :             DesTowerWaterDeltaT = this->DesRange;
    3554           0 :             if (PltSizCondNum > 0) {
    3555             :                 // check the tower range against the plant sizing data
    3556           0 :                 if (std::abs(DesTowerWaterDeltaT - PlantSizData(PltSizCondNum).DeltaT) > TolTemp) {
    3557           0 :                     ShowWarningError(state,
    3558           0 :                                      format("Error when autosizing the load for cooling tower = {}. Tower Design Range Temperature is different from "
    3559             :                                             "the Design Loop Delta Temperature.",
    3560           0 :                                             this->Name));
    3561           0 :                     ShowContinueError(state, format("Tower Design Range Temperature specified in tower = {}", this->Name));
    3562           0 :                     ShowContinueError(state,
    3563           0 :                                       format("is inconsistent with Design Loop Delta Temperature specified in Sizing:Plant object = {}.",
    3564           0 :                                              PlantSizData(PltSizCondNum).PlantLoopName));
    3565           0 :                     ShowContinueError(state, format("..The Design Range Temperature specified in tower is = {:.2T}", this->DesRange));
    3566           0 :                     ShowContinueError(state,
    3567           0 :                                       format("..The Design Loop Delta Temperature specified iin plant sizing data is = {:.2T}",
    3568           0 :                                              PlantSizData(PltSizCondNum).DeltaT));
    3569             :                 }
    3570             :                 // check if the tower approach is different from plant sizing data
    3571           0 :                 DesTowerApproachFromPlant = PlantSizData(PltSizCondNum).ExitTemp - this->DesInletAirWBTemp;
    3572           0 :                 if (std::abs(DesTowerApproachFromPlant - this->DesApproach) > TolTemp) {
    3573           0 :                     ShowWarningError(state,
    3574           0 :                                      format("Error when autosizing the UA for cooling tower = {}. Tower Design Approach Temperature is inconsistent "
    3575             :                                             "with Approach from Plant Sizing Data.",
    3576           0 :                                             this->Name));
    3577           0 :                     ShowContinueError(state,
    3578           0 :                                       format("The Design Approach Temperature from inputs specified in Sizing:Plant object = {}",
    3579           0 :                                              PlantSizData(PltSizCondNum).PlantLoopName));
    3580           0 :                     ShowContinueError(state, format("is inconsistent with Design Approach Temperature specified in tower = {}.", this->Name));
    3581           0 :                     ShowContinueError(state,
    3582           0 :                                       format("..The Design Approach Temperature from inputs specified is = {:.2T}", DesTowerApproachFromPlant));
    3583           0 :                     ShowContinueError(state, format("..The Design Approach Temperature specified in tower is = {:.2T}", this->DesApproach));
    3584             :                 }
    3585             :             }
    3586             :         }
    3587             : 
    3588          10 :         if (this->PerformanceInputMethod_Num == PIM::NominalCapacity) {
    3589             : 
    3590          10 :             if (PltSizCondNum > 0) { // get nominal capacity from PlantSizData(PltSizCondNum)%DeltaT and PlantSizData(PltSizCondNum)%DesVolFlowRate
    3591          10 :                 if (PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    3592           6 :                     rho = FluidProperties::GetDensityGlycol(state,
    3593           6 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3594             :                                                             DesTowerExitWaterTemp,
    3595           6 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3596             :                                                             RoutineName);
    3597           6 :                     Cp = FluidProperties::GetSpecificHeatGlycol(state,
    3598           6 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3599             :                                                                 DesTowerExitWaterTemp,
    3600           6 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3601             :                                                                 RoutineName);
    3602           6 :                     DesTowerLoad = rho * Cp * PlantSizData(PltSizCondNum).DesVolFlowRate * DesTowerWaterDeltaT * this->SizFac;
    3603           6 :                     tmpNomTowerCap = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    3604             :                 } else {
    3605           4 :                     if (this->TowerNominalCapacityWasAutoSized) tmpNomTowerCap = 0.0;
    3606             :                 }
    3607             :             } else {                                  // PltSizCondNum = 0
    3608           0 :                 if (!this->TowerInletCondsAutoSize) { // can use design data entered into tower object
    3609           0 :                     if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow) {
    3610           0 :                         rho = FluidProperties::GetDensityGlycol(state,
    3611           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3612             :                                                                 DesTowerExitWaterTemp,
    3613           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3614             :                                                                 RoutineName);
    3615           0 :                         Cp = FluidProperties::GetSpecificHeatGlycol(state,
    3616           0 :                                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3617             :                                                                     DesTowerExitWaterTemp,
    3618           0 :                                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3619             :                                                                     RoutineName);
    3620           0 :                         DesTowerLoad = rho * Cp * this->DesignWaterFlowRate * DesTowerWaterDeltaT * this->SizFac;
    3621           0 :                         tmpNomTowerCap = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    3622             :                     } else {
    3623           0 :                         if (this->TowerNominalCapacityWasAutoSized) tmpNomTowerCap = 0.0;
    3624             :                     }
    3625             :                 } else { // do not have enough data to size.
    3626           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize && this->TowerNominalCapacityWasAutoSized) {
    3627           0 :                         ShowSevereError(state, format("Autosizing error for cooling tower object = {}", this->Name));
    3628           0 :                         ShowFatalError(state, "Autosizing of cooling tower nominal capacity requires a loop Sizing:Plant object.");
    3629             :                     }
    3630             :                 }
    3631             :             }
    3632          10 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3633           2 :                 if (this->TowerNominalCapacityWasAutoSized) {
    3634           2 :                     this->TowerNominalCapacity = tmpNomTowerCap;
    3635           2 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3636           4 :                         BaseSizer::reportSizerOutput(state,
    3637           2 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3638             :                                                      this->Name,
    3639             :                                                      "Design Nominal Capacity [W]",
    3640             :                                                      tmpNomTowerCap);
    3641             :                     }
    3642           2 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3643           0 :                         BaseSizer::reportSizerOutput(state,
    3644           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3645             :                                                      this->Name,
    3646             :                                                      "Initial Design Nominal Capacity [W]",
    3647             :                                                      this->TowerNominalCapacity);
    3648             :                     }
    3649             :                 } else { // Hard-sized with sizing data
    3650           0 :                     if (this->TowerNominalCapacity > 0.0 && tmpNomTowerCap > 0.0) {
    3651           0 :                         Real64 NomCapUser(0.0);
    3652           0 :                         NomCapUser = this->TowerNominalCapacity;
    3653           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3654           0 :                             BaseSizer::reportSizerOutput(state,
    3655           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3656             :                                                          this->Name,
    3657             :                                                          "Design Nominal Capacity [W]",
    3658             :                                                          tmpNomTowerCap,
    3659             :                                                          "User-Specified Nominal Capacity [W]",
    3660             :                                                          NomCapUser);
    3661           0 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    3662           0 :                                 if ((std::abs(tmpNomTowerCap - NomCapUser) / NomCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
    3663           0 :                                     ShowMessage(state, format("SizeVSMerkelTower: Potential issue with equipment sizing for {}", this->Name));
    3664           0 :                                     ShowContinueError(state, format("User-Specified Nominal Capacity of {:.2R} [W]", NomCapUser));
    3665           0 :                                     ShowContinueError(state, format("differs from Design Size Nominal Capacity of {:.2R} [W]", tmpNomTowerCap));
    3666           0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3667           0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3668             :                                 }
    3669             :                             }
    3670           0 :                             tmpNomTowerCap = NomCapUser;
    3671             :                         }
    3672             :                     }
    3673             :                 }
    3674             :             }
    3675             : 
    3676          10 :             tmpTowerFreeConvNomCap = tmpNomTowerCap * this->TowerFreeConvNomCapSizingFactor;
    3677          10 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3678           2 :                 if (this->TowerFreeConvNomCapWasAutoSized) {
    3679           2 :                     this->TowerFreeConvNomCap = tmpTowerFreeConvNomCap;
    3680           2 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3681           4 :                         BaseSizer::reportSizerOutput(state,
    3682           2 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3683             :                                                      this->Name,
    3684             :                                                      "Design Free Convection Nominal Capacity [W]",
    3685             :                                                      this->TowerFreeConvNomCap);
    3686             :                     }
    3687           2 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3688           0 :                         BaseSizer::reportSizerOutput(state,
    3689           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3690             :                                                      this->Name,
    3691             :                                                      "Initial Design Free Convection Nominal Capacity [W]",
    3692             :                                                      this->TowerFreeConvNomCap);
    3693             :                     }
    3694             :                 } else { // Hard-sized with sizing data
    3695           0 :                     if (this->TowerFreeConvNomCap > 0.0 && tmpTowerFreeConvNomCap > 0.0) {
    3696           0 :                         Real64 NomCapUser(0.0);
    3697           0 :                         NomCapUser = this->TowerFreeConvNomCap;
    3698           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3699           0 :                             BaseSizer::reportSizerOutput(state,
    3700           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3701             :                                                          this->Name,
    3702             :                                                          "Design Free Convection Nominal Capacity [W]",
    3703             :                                                          tmpTowerFreeConvNomCap,
    3704             :                                                          "User-Specified Free Convection Nominal Capacity [W]",
    3705             :                                                          NomCapUser);
    3706           0 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    3707           0 :                                 if ((std::abs(tmpTowerFreeConvNomCap - NomCapUser) / NomCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
    3708           0 :                                     ShowMessage(state, format("SizeVSMerkelTower: Potential issue with equipment sizing for {}", this->Name));
    3709           0 :                                     ShowContinueError(state, format("User-Specified Free Convection Nominal Capacity of {:.2R} [W]", NomCapUser));
    3710           0 :                                     ShowContinueError(
    3711             :                                         state,
    3712           0 :                                         format("differs from Design Size Free Convection Nominal Capacity of {:.2R} [W]", tmpTowerFreeConvNomCap));
    3713           0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3714           0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3715             :                                 }
    3716             :                             }
    3717           0 :                             tmpTowerFreeConvNomCap = NomCapUser;
    3718             :                         }
    3719             :                     }
    3720             :                 }
    3721             :             }
    3722             : 
    3723          10 :             tmpDesignWaterFlowRate = tmpNomTowerCap * this->DesignWaterFlowPerUnitNomCap;
    3724          10 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3725           2 :                 if (this->DesignWaterFlowRateWasAutoSized) {
    3726             :                     // for nominal cap input method, get design water flow rate from nominal cap and scalable sizing factor
    3727             : 
    3728           2 :                     this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
    3729           2 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3730           4 :                         BaseSizer::reportSizerOutput(state,
    3731           2 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3732             :                                                      this->Name,
    3733             :                                                      "Design Water Flow Rate [m3/s]",
    3734             :                                                      this->DesignWaterFlowRate);
    3735             :                     }
    3736           2 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3737           0 :                         BaseSizer::reportSizerOutput(state,
    3738           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3739             :                                                      this->Name,
    3740             :                                                      "Initial Design Water Flow Rate [m3/s]",
    3741             :                                                      this->DesignWaterFlowRate);
    3742             :                     }
    3743             : 
    3744             :                 } else { // Hard-sized with sizing data
    3745           0 :                     if (this->DesignWaterFlowRate > 0.0 && tmpDesignWaterFlowRate > 0.0) {
    3746           0 :                         Real64 NomDesWaterFlowUser(0.0);
    3747           0 :                         NomDesWaterFlowUser = this->DesignWaterFlowRate;
    3748           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3749           0 :                             BaseSizer::reportSizerOutput(state,
    3750           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3751             :                                                          this->Name,
    3752             :                                                          "Design Water Flow Rate [m3/s]",
    3753             :                                                          this->DesignWaterFlowRate,
    3754             :                                                          "User-Specified Design Water Flow Rate [m3/s]",
    3755             :                                                          NomDesWaterFlowUser);
    3756           0 :                             if (state.dataGlobal->DisplayExtraWarnings) {
    3757           0 :                                 if ((std::abs(tmpDesignWaterFlowRate - NomDesWaterFlowUser) / NomDesWaterFlowUser) >
    3758           0 :                                     state.dataSize->AutoVsHardSizingThreshold) {
    3759           0 :                                     ShowMessage(state, format("SizeVSMerkelTower: Potential issue with equipment sizing for {}", this->Name));
    3760           0 :                                     ShowContinueError(state, format("User-Specified Design Water Flow Rate of {:.2R} [m3/s]", NomDesWaterFlowUser));
    3761           0 :                                     ShowContinueError(state, format("differs from Design Water Flow Rate of {:.2R} [m3/s]", tmpDesignWaterFlowRate));
    3762           0 :                                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3763           0 :                                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3764             :                                 }
    3765             :                             }
    3766           0 :                             tmpDesignWaterFlowRate = NomDesWaterFlowUser;
    3767             :                         }
    3768             :                     }
    3769             :                 }
    3770             :             }
    3771             : 
    3772          10 :             PlantUtilities::RegisterPlantCompDesignFlow(state, this->WaterInletNodeNum, tmpDesignWaterFlowRate);
    3773             : 
    3774          10 :             if (this->DefaultedDesignAirFlowScalingFactor) {
    3775           0 :                 tmpDesignAirFlowRate = tmpNomTowerCap * this->DesignAirFlowPerUnitNomCap * (101325.0 / state.dataEnvrn->StdBaroPress);
    3776             :             } else {
    3777          10 :                 tmpDesignAirFlowRate = tmpNomTowerCap * this->DesignAirFlowPerUnitNomCap;
    3778             :             }
    3779          10 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3780           2 :                 if (this->HighSpeedAirFlowRateWasAutoSized) {
    3781           2 :                     this->HighSpeedAirFlowRate = tmpDesignAirFlowRate;
    3782           2 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3783           4 :                         BaseSizer::reportSizerOutput(state,
    3784           2 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3785             :                                                      this->Name,
    3786             :                                                      "Design Air Flow Rate [m3/s]",
    3787             :                                                      this->HighSpeedAirFlowRate);
    3788             :                     }
    3789           2 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3790           0 :                         BaseSizer::reportSizerOutput(state,
    3791           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3792             :                                                      this->Name,
    3793             :                                                      "Initial Design Air Flow Rate [m3/s]",
    3794             :                                                      this->HighSpeedAirFlowRate);
    3795             :                     }
    3796             :                 } else { // Hard-sized with sizing data
    3797           0 :                     Real64 DesignAirFlowRateUser(0.0);
    3798           0 :                     DesignAirFlowRateUser = this->HighSpeedAirFlowRate;
    3799           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3800           0 :                         BaseSizer::reportSizerOutput(state,
    3801           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3802             :                                                      this->Name,
    3803             :                                                      "Design Air Flow Rate [m3/s]",
    3804             :                                                      tmpDesignAirFlowRate,
    3805             :                                                      "User-Specified Design Air Flow Rate [m3/s]",
    3806             :                                                      DesignAirFlowRateUser);
    3807           0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    3808           0 :                             if ((std::abs(tmpDesignAirFlowRate - DesignAirFlowRateUser) / DesignAirFlowRateUser) >
    3809           0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    3810           0 :                                 ShowMessage(state, format("SizeVSMerkelTower: Potential issue with equipment sizing for {}", this->Name));
    3811           0 :                                 ShowContinueError(state, format("User-Specified Design Air Flow Rate of {:.2R} [m3/s]", DesignAirFlowRateUser));
    3812           0 :                                 ShowContinueError(state, format("differs from Design Air Flow Rate of {:.2R} [m3/s]", tmpDesignAirFlowRate));
    3813           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3814           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3815             :                             }
    3816             :                         }
    3817           0 :                         tmpDesignAirFlowRate = DesignAirFlowRateUser;
    3818             :                     }
    3819             :                 }
    3820             :             }
    3821          10 :             tmpFreeConvAirFlowRate = tmpDesignAirFlowRate * this->FreeConvAirFlowRateSizingFactor;
    3822             : 
    3823          10 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3824           2 :                 if (this->FreeConvAirFlowRateWasAutoSized) {
    3825           2 :                     this->FreeConvAirFlowRate = tmpFreeConvAirFlowRate;
    3826           2 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3827           4 :                         BaseSizer::reportSizerOutput(state,
    3828           2 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3829             :                                                      this->Name,
    3830             :                                                      "Design Free Convection Regime Air Flow Rate [m3/s]",
    3831             :                                                      this->FreeConvAirFlowRate);
    3832             :                     }
    3833           2 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3834           0 :                         BaseSizer::reportSizerOutput(state,
    3835           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3836             :                                                      this->Name,
    3837             :                                                      "Initial Design Free Convection Regime Air Flow Rate [m3/s]",
    3838             :                                                      this->FreeConvAirFlowRate);
    3839             :                     }
    3840             :                 } else { // Hard-sized with sizing data
    3841           0 :                     Real64 FreeConvAirFlowUser(0.0);
    3842           0 :                     FreeConvAirFlowUser = this->FreeConvAirFlowRate;
    3843           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3844           0 :                         BaseSizer::reportSizerOutput(state,
    3845           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3846             :                                                      this->Name,
    3847             :                                                      "Design Free Convection Regime Air Flow Rate [m3/s]",
    3848             :                                                      tmpFreeConvAirFlowRate,
    3849             :                                                      "User-Specified Design Free Convection Regime Air Flow Rate [m3/s]",
    3850             :                                                      FreeConvAirFlowUser);
    3851           0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    3852           0 :                             if ((std::abs(tmpFreeConvAirFlowRate - FreeConvAirFlowUser) / FreeConvAirFlowUser) >
    3853           0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    3854           0 :                                 ShowMessage(state, format("SizeVSMerkelTower: Potential issue with equipment sizing for {}", this->Name));
    3855           0 :                                 ShowContinueError(
    3856             :                                     state,
    3857           0 :                                     format("User-Specified Design Free Convection Regime Air Flow Rate of {:.2R} [m3/s]", FreeConvAirFlowUser));
    3858           0 :                                 ShowContinueError(
    3859             :                                     state,
    3860           0 :                                     format("differs from Design Free Convection Regime Air Flow Rate of {:.2R} [m3/s]", tmpFreeConvAirFlowRate));
    3861           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3862           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3863             :                             }
    3864             :                         }
    3865           0 :                         tmpFreeConvAirFlowRate = FreeConvAirFlowUser;
    3866             :                     }
    3867             :                 }
    3868             :             }
    3869             : 
    3870             :             // now calcuate UA values from nominal capacities and flow rates
    3871          10 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3872           2 :                 if (PltSizCondNum > 0) { // user has a plant sizing object
    3873           2 :                     Cp = FluidProperties::GetSpecificHeatGlycol(state,
    3874           2 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3875             :                                                                 DesTowerExitWaterTemp,
    3876           2 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3877             :                                                                 RoutineName);
    3878           2 :                     this->WaterTemp = DesTowerInletWaterTemp;
    3879             :                 } else { // probably no plant sizing object
    3880           0 :                     Cp = FluidProperties::GetSpecificHeatGlycol(state,
    3881           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3882             :                                                                 Constant::InitConvTemp,
    3883           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3884             :                                                                 RoutineName);
    3885           0 :                     this->WaterTemp = DesTowerInletWaterTemp; // 35.0; // design condition
    3886             :                 }
    3887           2 :                 rho = FluidProperties::GetDensityGlycol(state,
    3888           2 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    3889             :                                                         Constant::InitConvTemp,
    3890           2 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    3891             :                                                         RoutineName);
    3892             : 
    3893             :                 // full speed fan tower UA
    3894           2 :                 Real64 const solveLoad = tmpNomTowerCap * this->HeatRejectCapNomCapSizingRatio;
    3895           2 :                 Real64 const solveWaterFlow = rho * tmpDesignWaterFlowRate; // design water mass flow rate
    3896           2 :                 UA0 = 0.0001 * solveLoad;                                   // Assume deltaT = 10000K (limit)
    3897           2 :                 UA1 = solveLoad;                                            // Assume deltaT = 1K
    3898             : 
    3899           2 :                 this->AirTemp = this->DesInletAirDBTemp;    // 35.0;
    3900           2 :                 this->AirWetBulb = this->DesInletAirWBTemp; // 25.6;
    3901           2 :                 this->AirPress = state.dataEnvrn->StdBaroPress;
    3902           2 :                 this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    3903         144 :                 auto f = [&state, this, solveLoad, solveWaterFlow, tmpDesignAirFlowRate, Cp](Real64 UA) {
    3904          72 :                     Real64 const OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlow, tmpDesignAirFlowRate, UA);
    3905          72 :                     Real64 const CoolingOutput = Cp * solveWaterFlow * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    3906          72 :                     return (solveLoad - CoolingOutput) / solveLoad;
    3907           2 :                 };
    3908           2 :                 General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    3909           2 :                 if (SolFla == -1) {
    3910           0 :                     ShowSevereError(state, "Iteration limit exceeded in calculating tower UA");
    3911           0 :                     ShowFatalError(state, format("calculating cooling tower UA failed for tower {}", this->Name));
    3912           2 :                 } else if (SolFla == -2) {
    3913           0 :                     ShowSevereError(state, "Bad starting values for UA");
    3914           0 :                     ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    3915             :                 }
    3916           2 :                 this->HighSpeedTowerUA = UA;
    3917           2 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3918           4 :                     BaseSizer::reportSizerOutput(state,
    3919           2 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3920             :                                                  this->Name,
    3921             :                                                  "U-Factor Times Area Value at Full Speed Air Flow Rate [W/C]",
    3922             :                                                  this->HighSpeedTowerUA);
    3923             :                 }
    3924           2 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3925           0 :                     BaseSizer::reportSizerOutput(state,
    3926           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3927             :                                                  this->Name,
    3928             :                                                  "Initial U-Factor Times Area Value at Full Speed Air Flow Rate [W/C]",
    3929             :                                                  this->HighSpeedTowerUA);
    3930             :                 }
    3931             :                 // free convection tower UA
    3932           2 :                 Real64 const solveLoad1 = tmpTowerFreeConvNomCap * this->HeatRejectCapNomCapSizingRatio;
    3933           2 :                 Real64 solveWaterFlow1 = rho * tmpDesignWaterFlowRate; // design water mass flow rate
    3934           2 :                 UA0 = 0.0001 * solveLoad1;                             // Assume deltaT = 10000K (limit)
    3935           2 :                 UA0 = max(UA0, 1.0);                                   // limit to 1.0
    3936           2 :                 UA1 = solveLoad1;                                      // Assume deltaT = 1K
    3937           2 :                 this->AirTemp = this->DesInletAirDBTemp;               // 35.0;
    3938           2 :                 this->AirWetBulb = this->DesInletAirWBTemp;            // 25.6;
    3939           2 :                 this->AirPress = state.dataEnvrn->StdBaroPress;
    3940           2 :                 this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    3941         124 :                 auto f2 = [&state, this, solveLoad1, solveWaterFlow1, tmpFreeConvAirFlowRate, Cp](Real64 UA) {
    3942          62 :                     Real64 const OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlow1, tmpFreeConvAirFlowRate, UA);
    3943          62 :                     Real64 const CoolingOutput = Cp * solveWaterFlow1 * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    3944          62 :                     return (solveLoad1 - CoolingOutput) / solveLoad1;
    3945           2 :                 };
    3946           2 :                 General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f2, UA0, UA1);
    3947           2 :                 if (SolFla == -1) {
    3948           0 :                     ShowSevereError(state, "Iteration limit exceeded in calculating tower free convection UA");
    3949           0 :                     ShowFatalError(state, format("calculating cooling tower UA failed for tower {}", this->Name));
    3950           2 :                 } else if (SolFla == -2) {
    3951           0 :                     ShowSevereError(state, "Bad starting values for UA");
    3952           0 :                     ShowFatalError(state, format("Autosizing of cooling tower UA failed for free convection tower {}", this->Name));
    3953             :                 }
    3954           2 :                 this->FreeConvTowerUA = UA;
    3955           2 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3956           4 :                     BaseSizer::reportSizerOutput(state,
    3957           2 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3958             :                                                  this->Name,
    3959             :                                                  "U-Factor Times Area Value at Free Convection Air Flow Rate [W/C]",
    3960             :                                                  this->FreeConvTowerUA);
    3961             :                 }
    3962           2 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3963           0 :                     BaseSizer::reportSizerOutput(state,
    3964           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3965             :                                                  this->Name,
    3966             :                                                  "Initial U-Factor Times Area Value at Free Convection Air Flow Rate [W/C]",
    3967             :                                                  this->FreeConvTowerUA);
    3968             :                 }
    3969             :             }
    3970           0 :         } else if (this->PerformanceInputMethod_Num == PIM::UFactor) {
    3971             :             // UA input method
    3972             : 
    3973           0 :             if (this->DesignWaterFlowRateWasAutoSized) { // get from plant sizing
    3974             :                 // UA input method using plant sizing for flow rate, whereas Nominal capacity method uses scalable sizing factor per cap
    3975           0 :                 if (PltSizCondNum > 0) {
    3976           0 :                     if (PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    3977           0 :                         tmpDesignWaterFlowRate = PlantSizData(PltSizCondNum).DesVolFlowRate * this->SizFac;
    3978           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    3979           0 :                             this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
    3980           0 :                             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    3981           0 :                                 BaseSizer::reportSizerOutput(state,
    3982           0 :                                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3983             :                                                              this->Name,
    3984             :                                                              "Design Water Flow Rate [m3/s]",
    3985             :                                                              this->DesignWaterFlowRate);
    3986             :                             }
    3987           0 :                             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    3988           0 :                                 BaseSizer::reportSizerOutput(state,
    3989           0 :                                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    3990             :                                                              this->Name,
    3991             :                                                              "Initial Design Water Flow Rate [m3/s]",
    3992             :                                                              this->DesignWaterFlowRate);
    3993             :                             }
    3994             :                         }
    3995             :                     } else {
    3996           0 :                         tmpDesignWaterFlowRate = 0.0;
    3997             :                     }
    3998             : 
    3999             :                 } else {
    4000           0 :                     if (!this->TowerInletCondsAutoSize) {
    4001           0 :                         if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow) {
    4002           0 :                             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4003           0 :                                 this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
    4004           0 :                                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4005           0 :                                     BaseSizer::reportSizerOutput(state,
    4006           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4007             :                                                                  this->Name,
    4008             :                                                                  "Design Water Flow Rate [m3/s]",
    4009             :                                                                  this->DesignWaterFlowRate);
    4010             :                                 }
    4011           0 :                                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4012           0 :                                     BaseSizer::reportSizerOutput(state,
    4013           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4014             :                                                                  this->Name,
    4015             :                                                                  "Initial Design Water Flow Rate [m3/s]",
    4016             :                                                                  this->DesignWaterFlowRate);
    4017             :                                 }
    4018             :                             }
    4019             :                         } else {
    4020           0 :                             tmpDesignWaterFlowRate = 0.0;
    4021             :                         }
    4022             :                     } else {
    4023           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4024           0 :                             ShowSevereError(state, format("Autosizing error for cooling tower object = {}", this->Name));
    4025           0 :                             ShowFatalError(state, "Autosizing of cooling tower nominal capacity requires a loop Sizing:Plant object.");
    4026             :                         }
    4027             :                     }
    4028             :                 }
    4029             :             }
    4030           0 :             PlantUtilities::RegisterPlantCompDesignFlow(state, this->WaterInletNodeNum, tmpDesignWaterFlowRate);
    4031             : 
    4032           0 :             if (this->HighSpeedTowerUAWasAutoSized) {
    4033             :                 // get nominal capacity from PlantSizData(PltSizCondNum)%DeltaT and PlantSizData(PltSizCondNum)%DesVolFlowRate
    4034           0 :                 if (PltSizCondNum > 0) {
    4035           0 :                     if (PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    4036           0 :                         rho = FluidProperties::GetDensityGlycol(state,
    4037           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4038             :                                                                 DesTowerExitWaterTemp,
    4039           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4040             :                                                                 RoutineName);
    4041           0 :                         Cp = FluidProperties::GetSpecificHeatGlycol(state,
    4042           0 :                                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4043             :                                                                     DesTowerExitWaterTemp,
    4044           0 :                                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4045             :                                                                     RoutineName);
    4046           0 :                         DesTowerLoad = rho * Cp * PlantSizData(PltSizCondNum).DesVolFlowRate * DesTowerWaterDeltaT * this->SizFac;
    4047           0 :                         tmpNomTowerCap = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    4048           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4049           0 :                             this->TowerNominalCapacity = tmpNomTowerCap;
    4050           0 :                             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4051           0 :                                 BaseSizer::reportSizerOutput(state,
    4052           0 :                                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4053             :                                                              this->Name,
    4054             :                                                              "Nominal Capacity [W]",
    4055             :                                                              this->TowerNominalCapacity);
    4056             :                             }
    4057           0 :                             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4058           0 :                                 BaseSizer::reportSizerOutput(state,
    4059           0 :                                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4060             :                                                              this->Name,
    4061             :                                                              "Initial Nominal Capacity [W]",
    4062             :                                                              this->TowerNominalCapacity);
    4063             :                             }
    4064             :                         }
    4065             :                     } else {
    4066           0 :                         tmpNomTowerCap = 0.0;
    4067           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4068           0 :                             this->TowerNominalCapacity = tmpNomTowerCap;
    4069           0 :                             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4070           0 :                                 BaseSizer::reportSizerOutput(state,
    4071           0 :                                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4072             :                                                              this->Name,
    4073             :                                                              "Nominal Capacity [W]",
    4074             :                                                              this->TowerNominalCapacity);
    4075             :                             }
    4076           0 :                             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4077           0 :                                 BaseSizer::reportSizerOutput(state,
    4078           0 :                                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4079             :                                                              this->Name,
    4080             :                                                              "Initial Nominal Capacity [W]",
    4081             :                                                              this->TowerNominalCapacity);
    4082             :                             }
    4083             :                         }
    4084             :                     }
    4085             :                 } else {
    4086           0 :                     if (!this->TowerInletCondsAutoSize) {
    4087           0 :                         if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow) {
    4088           0 :                             rho = FluidProperties::GetDensityGlycol(state,
    4089           0 :                                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4090             :                                                                     DesTowerExitWaterTemp,
    4091           0 :                                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4092             :                                                                     RoutineName);
    4093           0 :                             Cp = FluidProperties::GetSpecificHeatGlycol(state,
    4094           0 :                                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4095             :                                                                         DesTowerExitWaterTemp,
    4096           0 :                                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4097             :                                                                         RoutineName);
    4098           0 :                             DesTowerLoad = rho * Cp * this->DesignWaterFlowRate * DesTowerWaterDeltaT * this->SizFac;
    4099           0 :                             tmpNomTowerCap = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    4100           0 :                             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4101           0 :                                 this->TowerNominalCapacity = tmpNomTowerCap;
    4102           0 :                                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4103           0 :                                     BaseSizer::reportSizerOutput(state,
    4104           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4105             :                                                                  this->Name,
    4106             :                                                                  "Nominal Capacity [W]",
    4107             :                                                                  this->TowerNominalCapacity);
    4108             :                                 }
    4109           0 :                                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4110           0 :                                     BaseSizer::reportSizerOutput(state,
    4111           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4112             :                                                                  this->Name,
    4113             :                                                                  "Initial Nominal Capacity [W]",
    4114             :                                                                  this->TowerNominalCapacity);
    4115             :                                 }
    4116             :                             }
    4117             :                         } else {
    4118           0 :                             tmpNomTowerCap = 0.0;
    4119           0 :                             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4120           0 :                                 this->TowerNominalCapacity = tmpNomTowerCap;
    4121           0 :                                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4122           0 :                                     BaseSizer::reportSizerOutput(state,
    4123           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4124             :                                                                  this->Name,
    4125             :                                                                  "Nominal Capacity [W]",
    4126             :                                                                  this->TowerNominalCapacity);
    4127             :                                 }
    4128           0 :                                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4129           0 :                                     BaseSizer::reportSizerOutput(state,
    4130           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4131             :                                                                  this->Name,
    4132             :                                                                  "Initial Nominal Capacity [W]",
    4133             :                                                                  this->TowerNominalCapacity);
    4134             :                                 }
    4135             :                             }
    4136             :                         }
    4137             :                     } else {
    4138           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4139           0 :                             ShowSevereError(state, format("Autosizing error for cooling tower object = {}", this->Name));
    4140           0 :                             ShowFatalError(state, "Autosizing of cooling tower nominal capacity requires a loop Sizing:Plant object.");
    4141             :                         }
    4142             :                     }
    4143             :                 }
    4144           0 :                 if (this->TowerFreeConvNomCapWasAutoSized) {
    4145           0 :                     tmpTowerFreeConvNomCap = tmpNomTowerCap * this->TowerFreeConvNomCapSizingFactor;
    4146           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4147           0 :                         this->TowerFreeConvNomCap = tmpTowerFreeConvNomCap;
    4148           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4149           0 :                             BaseSizer::reportSizerOutput(state,
    4150           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4151             :                                                          this->Name,
    4152             :                                                          "Free Convection Nominal Capacity [W]",
    4153             :                                                          this->TowerFreeConvNomCap);
    4154             :                         }
    4155           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4156           0 :                             BaseSizer::reportSizerOutput(state,
    4157           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4158             :                                                          this->Name,
    4159             :                                                          "Initial Free Convection Nominal Capacity [W]",
    4160             :                                                          this->TowerFreeConvNomCap);
    4161             :                         }
    4162             :                     }
    4163             :                 }
    4164           0 :                 if (this->HighSpeedAirFlowRateWasAutoSized) {
    4165           0 :                     if (this->DefaultedDesignAirFlowScalingFactor) {
    4166           0 :                         tmpDesignAirFlowRate = tmpNomTowerCap * this->DesignAirFlowPerUnitNomCap * (101325.0 / state.dataEnvrn->StdBaroPress);
    4167             :                     } else {
    4168           0 :                         tmpDesignAirFlowRate = tmpNomTowerCap * this->DesignAirFlowPerUnitNomCap;
    4169             :                     }
    4170           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4171           0 :                         this->HighSpeedAirFlowRate = tmpDesignAirFlowRate;
    4172           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4173           0 :                             BaseSizer::reportSizerOutput(state,
    4174           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4175             :                                                          this->Name,
    4176             :                                                          "Design Air Flow Rate [m3/s]",
    4177             :                                                          this->HighSpeedAirFlowRate);
    4178             :                         }
    4179           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4180           0 :                             BaseSizer::reportSizerOutput(state,
    4181           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4182             :                                                          this->Name,
    4183             :                                                          "Initial Design Air Flow Rate [m3/s]",
    4184             :                                                          this->HighSpeedAirFlowRate);
    4185             :                         }
    4186             :                     }
    4187             :                 }
    4188           0 :                 if (this->FreeConvAirFlowRateWasAutoSized) {
    4189           0 :                     tmpFreeConvAirFlowRate = tmpDesignAirFlowRate * this->FreeConvAirFlowRateSizingFactor;
    4190           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4191           0 :                         this->FreeConvAirFlowRate = tmpFreeConvAirFlowRate;
    4192           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4193           0 :                             BaseSizer::reportSizerOutput(state,
    4194           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4195             :                                                          this->Name,
    4196             :                                                          "Free Convection Regime Air Flow Rate [m3/s]",
    4197             :                                                          this->FreeConvAirFlowRate);
    4198             :                         }
    4199           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4200           0 :                             BaseSizer::reportSizerOutput(state,
    4201           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4202             :                                                          this->Name,
    4203             :                                                          "Initial Free Convection Regime Air Flow Rate [m3/s]",
    4204             :                                                          this->FreeConvAirFlowRate);
    4205             :                         }
    4206             :                     }
    4207             :                 }
    4208             :                 // now calcuate UA values from nominal capacities and flow rates
    4209           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4210           0 :                     rho = FluidProperties::GetDensityGlycol(state,
    4211           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4212             :                                                             Constant::InitConvTemp,
    4213           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4214             :                                                             RoutineName);
    4215           0 :                     Cp = FluidProperties::GetSpecificHeatGlycol(state,
    4216           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4217             :                                                                 DesTowerExitWaterTemp,
    4218           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4219             :                                                                 RoutineName);
    4220             :                     // full speed fan tower UA
    4221           0 :                     Real64 const solveLoad = tmpNomTowerCap * this->HeatRejectCapNomCapSizingRatio;
    4222           0 :                     Real64 const solveWaterFlow = rho * tmpDesignWaterFlowRate; // design water mass flow rate
    4223           0 :                     UA0 = 0.0001 * solveLoad;                                   // Assume deltaT = 10000K (limit)
    4224           0 :                     UA1 = solveLoad;                                            // Assume deltaT = 1K
    4225           0 :                     this->WaterTemp = DesTowerInletWaterTemp;
    4226           0 :                     this->AirTemp = this->DesInletAirDBTemp;    // 35.0;
    4227           0 :                     this->AirWetBulb = this->DesInletAirWBTemp; // 25.6;
    4228           0 :                     this->AirPress = state.dataEnvrn->StdBaroPress;
    4229           0 :                     this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    4230           0 :                     auto f = [&state, this, solveLoad, solveWaterFlow, tmpDesignAirFlowRate, Cp](Real64 UA) {
    4231           0 :                         Real64 const OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlow, tmpDesignAirFlowRate, UA);
    4232           0 :                         Real64 const CoolingOutput = Cp * solveWaterFlow * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    4233           0 :                         return (solveLoad - CoolingOutput) / solveLoad;
    4234           0 :                     };
    4235           0 :                     General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    4236           0 :                     if (SolFla == -1) {
    4237           0 :                         ShowSevereError(state, "Iteration limit exceeded in calculating tower UA");
    4238           0 :                         ShowFatalError(state, format("calculating cooling tower UA failed for tower {}", this->Name));
    4239           0 :                     } else if (SolFla == -2) {
    4240           0 :                         ShowSevereError(state, "Bad starting values for UA");
    4241           0 :                         ShowFatalError(state, format("Autosizing of cooling tower UA failed for tower {}", this->Name));
    4242             :                     }
    4243           0 :                     this->HighSpeedTowerUA = UA;
    4244           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4245           0 :                         BaseSizer::reportSizerOutput(state,
    4246           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4247             :                                                      this->Name,
    4248             :                                                      "U-Factor Times Area Value at Full Speed Air Flow Rate [W/C]",
    4249             :                                                      this->HighSpeedTowerUA);
    4250             :                     }
    4251           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4252           0 :                         BaseSizer::reportSizerOutput(state,
    4253           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4254             :                                                      this->Name,
    4255             :                                                      "Initial U-Factor Times Area Value at Full Speed Air Flow Rate [W/C]",
    4256             :                                                      this->HighSpeedTowerUA);
    4257             :                     }
    4258             :                     // free convection tower UA
    4259           0 :                     Real64 const solveLoad2 = tmpTowerFreeConvNomCap * this->HeatRejectCapNomCapSizingRatio;
    4260           0 :                     Real64 const solveWaterFlow2 = rho * tmpDesignWaterFlowRate; // design water mass flow rate
    4261           0 :                     UA0 = 0.0001 * solveLoad2;                                   // Assume deltaT = 10000K (limit)
    4262           0 :                     UA1 = solveLoad2;                                            // Assume deltaT = 1K
    4263           0 :                     this->WaterTemp = DesTowerInletWaterTemp;
    4264           0 :                     this->AirTemp = DesTowerInletAirDBTemp;    // 35.0;
    4265           0 :                     this->AirWetBulb = DesTowerInletAirWBTemp; // 25.6;
    4266           0 :                     this->AirPress = state.dataEnvrn->StdBaroPress;
    4267           0 :                     this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    4268           0 :                     auto f3 = [&state, this, solveLoad2, solveWaterFlow2, tmpFreeConvAirFlowRate, Cp](Real64 UA) {
    4269           0 :                         Real64 const OutWaterTemp = this->calculateSimpleTowerOutletTemp(state, solveWaterFlow2, tmpFreeConvAirFlowRate, UA);
    4270           0 :                         Real64 const CoolingOutput = Cp * solveWaterFlow2 * (this->WaterTemp - OutWaterTemp); // tower cooling output [W]
    4271           0 :                         return (solveLoad2 - CoolingOutput) / solveLoad2;
    4272           0 :                     };
    4273           0 :                     General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f3, UA0, UA1);
    4274           0 :                     if (SolFla == -1) {
    4275           0 :                         ShowSevereError(state, "Iteration limit exceeded in calculating tower free convection UA");
    4276           0 :                         ShowFatalError(state, format("calculating cooling tower UA failed for tower {}", this->Name));
    4277           0 :                     } else if (SolFla == -2) {
    4278           0 :                         ShowSevereError(state, "Bad starting values for UA");
    4279           0 :                         ShowFatalError(state, format("Autosizing of cooling tower UA failed for free convection tower {}", this->Name));
    4280             :                     }
    4281           0 :                     this->LowSpeedTowerUA = UA;
    4282           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4283           0 :                         BaseSizer::reportSizerOutput(state,
    4284           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4285             :                                                      this->Name,
    4286             :                                                      "U-Factor Times Area Value at Free Convection Air Flow Rate [W/C]",
    4287             :                                                      this->FreeConvTowerUA);
    4288             :                     }
    4289           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4290           0 :                         BaseSizer::reportSizerOutput(state,
    4291           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4292             :                                                      this->Name,
    4293             :                                                      "Initial U-Factor Times Area Value at Free Convection Air Flow Rate [W/C]",
    4294             :                                                      this->FreeConvTowerUA);
    4295             :                     }
    4296             :                 }
    4297             : 
    4298             :             } else { // full speed UA given
    4299             : 
    4300           0 :                 if (this->FreeConvTowerUAWasAutoSized) { // determine from scalable sizing factor
    4301           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4302           0 :                         this->FreeConvTowerUA = this->HighSpeedTowerUA * this->FreeConvTowerUASizingFactor;
    4303           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4304           0 :                             BaseSizer::reportSizerOutput(state,
    4305           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4306             :                                                          this->Name,
    4307             :                                                          "U-Factor Times Area Value at Free Convection Air Flow Rate [W/C]",
    4308             :                                                          this->FreeConvTowerUA);
    4309             :                         }
    4310           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4311           0 :                             BaseSizer::reportSizerOutput(state,
    4312           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4313             :                                                          this->Name,
    4314             :                                                          "Initial U-Factor Times Area Value at Free Convection Air Flow Rate [W/C]",
    4315             :                                                          this->FreeConvTowerUA);
    4316             :                         }
    4317             :                     }
    4318             :                 }
    4319             :                 Real64 OutWaterTemp;
    4320           0 :                 if (this->HighSpeedAirFlowRateWasAutoSized) { // given UA but not air flow rate
    4321             :                     // need an air flow rate to find capacity from UA but flow rate is scaled off capacity
    4322             :                     // get nominal capacity from PlantSizData(PltSizCondNum)%DeltaT and PlantSizData(PltSizCondNum)%DesVolFlowRate
    4323           0 :                     if (PltSizCondNum > 0) {
    4324           0 :                         if (PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    4325           0 :                             rho = FluidProperties::GetDensityGlycol(state,
    4326           0 :                                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4327             :                                                                     DesTowerExitWaterTemp,
    4328           0 :                                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4329             :                                                                     RoutineName);
    4330           0 :                             Cp = FluidProperties::GetSpecificHeatGlycol(state,
    4331           0 :                                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4332             :                                                                         DesTowerExitWaterTemp,
    4333           0 :                                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4334             :                                                                         RoutineName);
    4335           0 :                             DesTowerLoad = rho * Cp * PlantSizData(PltSizCondNum).DesVolFlowRate * DesTowerWaterDeltaT;
    4336           0 :                             tmpNomTowerCap = DesTowerLoad / this->HeatRejectCapNomCapSizingRatio;
    4337           0 :                             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4338           0 :                                 this->TowerNominalCapacity = tmpNomTowerCap;
    4339           0 :                                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4340           0 :                                     BaseSizer::reportSizerOutput(state,
    4341           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4342             :                                                                  this->Name,
    4343             :                                                                  "Nominal Capacity [W]",
    4344             :                                                                  this->TowerNominalCapacity);
    4345             :                                 }
    4346           0 :                                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4347           0 :                                     BaseSizer::reportSizerOutput(state,
    4348           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4349             :                                                                  this->Name,
    4350             :                                                                  "Initial Nominal Capacity [W]",
    4351             :                                                                  this->TowerNominalCapacity);
    4352             :                                 }
    4353             :                             }
    4354             :                         } else {
    4355           0 :                             tmpNomTowerCap = rho = Cp = 0.0; // rho and Cp added: Used below
    4356           0 :                             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4357           0 :                                 this->TowerNominalCapacity = tmpNomTowerCap;
    4358           0 :                                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4359           0 :                                     BaseSizer::reportSizerOutput(state,
    4360           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4361             :                                                                  this->Name,
    4362             :                                                                  "Nominal Capacity [W]",
    4363             :                                                                  this->TowerNominalCapacity);
    4364             :                                 }
    4365           0 :                                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4366           0 :                                     BaseSizer::reportSizerOutput(state,
    4367           0 :                                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4368             :                                                                  this->Name,
    4369             :                                                                  "Initial Nominal Capacity [W]",
    4370             :                                                                  this->TowerNominalCapacity);
    4371             :                                 }
    4372             :                             }
    4373             :                         }
    4374             : 
    4375             :                     } else {
    4376           0 :                         tmpNomTowerCap = 0.0; // Suppress uninitialized warnings
    4377           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4378           0 :                             ShowSevereError(state, format("Autosizing error for cooling tower object = {}", this->Name));
    4379           0 :                             ShowFatalError(state, "Autosizing of cooling tower nominal capacity requires a loop Sizing:Plant object.");
    4380             :                         }
    4381             :                     }
    4382             : 
    4383           0 :                     if (this->DefaultedDesignAirFlowScalingFactor) {
    4384           0 :                         tmpDesignAirFlowRate = tmpNomTowerCap * this->DesignAirFlowPerUnitNomCap * (101325.0 / state.dataEnvrn->StdBaroPress);
    4385             :                     } else {
    4386           0 :                         tmpDesignAirFlowRate = tmpNomTowerCap * this->DesignAirFlowPerUnitNomCap;
    4387             :                     }
    4388           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4389           0 :                         this->HighSpeedAirFlowRate = tmpDesignAirFlowRate;
    4390           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4391           0 :                             BaseSizer::reportSizerOutput(state,
    4392           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4393             :                                                          this->Name,
    4394             :                                                          "Design Air Flow Rate [m3/s]",
    4395             :                                                          this->HighSpeedAirFlowRate);
    4396             :                         }
    4397           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4398           0 :                             BaseSizer::reportSizerOutput(state,
    4399           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4400             :                                                          this->Name,
    4401             :                                                          "Initial Design Air Flow Rate [m3/s]",
    4402             :                                                          this->HighSpeedAirFlowRate);
    4403             :                         }
    4404             :                     }
    4405             : 
    4406             :                 } else { // UA and Air flow rate given, so find Nominal Cap from running model
    4407             : 
    4408           0 :                     rho = FluidProperties::GetDensityGlycol(state,
    4409           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4410             :                                                             DesTowerExitWaterTemp,
    4411           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4412             :                                                             RoutineName);
    4413           0 :                     Cp = FluidProperties::GetSpecificHeatGlycol(state,
    4414           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4415             :                                                                 DesTowerExitWaterTemp,
    4416           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4417             :                                                                 RoutineName);
    4418             : 
    4419           0 :                     this->WaterTemp = DesTowerInletWaterTemp;
    4420           0 :                     this->AirTemp = DesTowerInletAirDBTemp;    // 35.0;
    4421           0 :                     this->AirWetBulb = DesTowerInletAirWBTemp; // 25.6;
    4422           0 :                     this->AirPress = state.dataEnvrn->StdBaroPress;
    4423           0 :                     this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    4424             :                     OutWaterTemp =
    4425           0 :                         this->calculateSimpleTowerOutletTemp(state, rho * tmpDesignWaterFlowRate, this->HighSpeedAirFlowRate, this->HighSpeedTowerUA);
    4426           0 :                     tmpNomTowerCap = Cp * rho * tmpDesignWaterFlowRate * (this->WaterTemp - OutWaterTemp);
    4427           0 :                     tmpNomTowerCap /= this->HeatRejectCapNomCapSizingRatio;
    4428           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4429           0 :                         this->TowerNominalCapacity = tmpNomTowerCap;
    4430           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4431           0 :                             BaseSizer::reportSizerOutput(state,
    4432           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4433             :                                                          this->Name,
    4434             :                                                          "Nominal Capacity [W]",
    4435             :                                                          this->TowerNominalCapacity);
    4436             :                         }
    4437           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4438           0 :                             BaseSizer::reportSizerOutput(state,
    4439           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4440             :                                                          this->Name,
    4441             :                                                          "Initial Nominal Capacity [W]",
    4442             :                                                          this->TowerNominalCapacity);
    4443             :                         }
    4444             :                     }
    4445             : 
    4446             :                 } // both UA and air flow rate given
    4447             : 
    4448           0 :                 if (this->FreeConvAirFlowRateWasAutoSized) {
    4449           0 :                     tmpFreeConvAirFlowRate = tmpDesignAirFlowRate * this->FreeConvAirFlowRateSizingFactor;
    4450           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4451           0 :                         this->FreeConvAirFlowRate = tmpFreeConvAirFlowRate;
    4452           0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4453           0 :                             BaseSizer::reportSizerOutput(state,
    4454           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4455             :                                                          this->Name,
    4456             :                                                          "Free Convection Regime Air Flow Rate [m3/s]",
    4457             :                                                          this->FreeConvAirFlowRate);
    4458             :                         }
    4459           0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4460           0 :                             BaseSizer::reportSizerOutput(state,
    4461           0 :                                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4462             :                                                          this->Name,
    4463             :                                                          "Initial Free Convection Regime Air Flow Rate [m3/s]",
    4464             :                                                          this->FreeConvAirFlowRate);
    4465             :                         }
    4466             :                     }
    4467             :                 }
    4468             : 
    4469             :                 OutWaterTemp =
    4470           0 :                     this->calculateSimpleTowerOutletTemp(state, rho * tmpDesignWaterFlowRate, tmpFreeConvAirFlowRate, this->FreeConvTowerUA);
    4471           0 :                 tmpTowerFreeConvNomCap = Cp * rho * tmpDesignWaterFlowRate * (this->WaterTemp - OutWaterTemp);
    4472           0 :                 tmpTowerFreeConvNomCap /= this->HeatRejectCapNomCapSizingRatio;
    4473           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4474           0 :                     this->TowerFreeConvNomCap = tmpTowerFreeConvNomCap;
    4475           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4476           0 :                         BaseSizer::reportSizerOutput(state,
    4477           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4478             :                                                      this->Name,
    4479             :                                                      "Free Convection Nominal Capacity [W]",
    4480             :                                                      this->TowerFreeConvNomCap);
    4481             :                     }
    4482           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4483           0 :                         BaseSizer::reportSizerOutput(state,
    4484           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4485             :                                                      this->Name,
    4486             :                                                      "Initial Free Convection Nominal Capacity [W]",
    4487             :                                                      this->TowerFreeConvNomCap);
    4488             :                     }
    4489             :                 }
    4490             :             }
    4491             :         }
    4492             : 
    4493          10 :         tmpHighSpeedFanPower = tmpNomTowerCap * this->DesignFanPowerPerUnitNomCap;
    4494          10 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    4495           2 :             if (this->HighSpeedFanPowerWasAutoSized) {
    4496             : 
    4497           2 :                 this->HighSpeedFanPower = tmpHighSpeedFanPower;
    4498           2 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4499           4 :                     BaseSizer::reportSizerOutput(state,
    4500           2 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4501             :                                                  this->Name,
    4502             :                                                  "Design Fan Power [W]",
    4503             :                                                  this->HighSpeedFanPower);
    4504             :                 }
    4505           2 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    4506           0 :                     BaseSizer::reportSizerOutput(state,
    4507           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4508             :                                                  this->Name,
    4509             :                                                  "Initial Design Fan Power [W]",
    4510             :                                                  this->HighSpeedFanPower);
    4511             :                 }
    4512             :             } else { // Hard-sized with sizing data
    4513           0 :                 Real64 HighSpeedFanPowerUser(0.0);
    4514           0 :                 HighSpeedFanPowerUser = this->HighSpeedAirFlowRate;
    4515           0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    4516           0 :                     BaseSizer::reportSizerOutput(state,
    4517           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    4518             :                                                  this->Name,
    4519             :                                                  "Design Fan Power [W]",
    4520             :                                                  tmpHighSpeedFanPower,
    4521             :                                                  "User-Specified Design Fan Power [W]",
    4522             :                                                  HighSpeedFanPowerUser);
    4523           0 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    4524           0 :                         if ((std::abs(tmpHighSpeedFanPower - HighSpeedFanPowerUser) / HighSpeedFanPowerUser) >
    4525           0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    4526           0 :                             ShowMessage(state, format("SizeVSMerkelTower: Potential issue with equipment sizing for {}", this->Name));
    4527           0 :                             ShowContinueError(state, format("User-Specified Design Fan Power of {:.2R} [W]", HighSpeedFanPowerUser));
    4528           0 :                             ShowContinueError(state, format("differs from Design Fan Power of {:.2R} [W]", tmpHighSpeedFanPower));
    4529           0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    4530           0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    4531             :                         }
    4532             :                     }
    4533             :                 }
    4534             :             }
    4535             :         }
    4536          10 :     } // namespace CondenserLoopTowers
    4537             : 
    4538     7761854 :     void CoolingTower::calculateSingleSpeedTower(EnergyPlusData &state, Real64 &MyLoad, bool RunFlag)
    4539             :     {
    4540             : 
    4541             :         // SUBROUTINE INFORMATION:
    4542             :         //       AUTHOR         Dan Fisher
    4543             :         //       DATE WRITTEN   Sept. 1998
    4544             :         //       MODIFIED       Aug. 2008, T Hong, Added fluid bypass for single speed cooling tower
    4545             :         //                      The OutletWaterTemp from calculateSimpleTowerOutletTemp can be lower than 0 degreeC
    4546             :         //                      which may not be allowed in practice if water is the tower fluid.
    4547             :         //                      Chandan Sharma, FSEC, February 2010, Added basin heater
    4548             :         //                      Jul. 2010, A Flament, added multi-cell capability for the 3 types of cooling tower
    4549             :         //                      Jun. 2016, R Zhang, Applied the condenser supply water temperature sensor fault model
    4550             :         //                      Jul. 2016, R Zhang, Applied the cooling tower fouling fault model
    4551             :         //       RE-ENGINEERED  Jan. 2001, Richard Raustad
    4552             : 
    4553             :         // PURPOSE OF THIS SUBROUTINE:
    4554             :         // To simulate the operation of a single-speed fan cooling tower.
    4555             : 
    4556             :         // METHODOLOGY EMPLOYED:
    4557             :         // The cooling tower is modeled using effectiveness-NTU relationships for
    4558             :         // counterflow heat exchangers based on Merkel's theory.
    4559             :         // The subroutine calculates the period of time required to meet a
    4560             :         // leaving water temperature setpoint. It assumes that part-load
    4561             :         // operation represents a linear interpolation of two steady-state regimes.
    4562             :         // Cyclic losses are neglected. The period of time required to meet the
    4563             :         // leaving water temperature setpoint is used to determine the required
    4564             :         // fan power and energy. Free convection regime is also modeled. This
    4565             :         // occurs when the pump is operating and the fan is off. If free convection
    4566             :         // regime cooling is all that is required for a given time step, the leaving
    4567             :         // water temperature is allowed to fall below the leaving water temperature
    4568             :         // setpoint (free cooling). At times when the cooling tower fan is required,
    4569             :         // the leaving water temperature is at or above the setpoint.
    4570             :         // A RunFlag is passed by the upper level manager to indicate the ON/OFF status,
    4571             :         // or schedule, of the cooling tower. If the tower is OFF, outlet water
    4572             :         // temperature and flow rate are passed through the model from inlet node to
    4573             :         // outlet node without intervention (with the exception of free convection
    4574             :         // where water temperature is allowed to float below the outlet water set
    4575             :         // point). Reports are also updated with fan power and energy being zero.
    4576             :         // When the RunFlag indicates an ON condition for the cooling tower, the
    4577             :         // mass flow rate and water temperature are read from the inlet node of the
    4578             :         // cooling tower (water-side). The outdoor air wet-bulb temperature is used
    4579             :         // as the entering condition to the cooling tower (air-side). Input deck
    4580             :         // parameters are read for the free convection regime (pump ON and fan OFF)
    4581             :         // and a leaving water temperature is calculated. If the leaving water temperature
    4582             :         // is at or below the setpoint, the calculated leaving water temperature is
    4583             :         // placed on the outlet node and no fan power is used. If the calculated leaving
    4584             :         // water temperature is above the setpoint, the cooling tower fan is turned on
    4585             :         // and design parameters are used to again calculate the leaving water temperature.
    4586             :         // If the calculated leaving water temperature is below the setpoint, a fan
    4587             :         // run-time fraction is calculated and used to determine fan power. The leaving
    4588             :         // water temperature setpoint is placed on the outlet node. If the calculated
    4589             :         // leaving water temperature is at or above the setpoint, the calculated
    4590             :         // leaving water temperature is placed on the outlet node and the fan runs at
    4591             :         // full power. Water mass flow rate is passed from inlet node to outlet node
    4592             :         // with no intervention.
    4593             :         // If a tower has multiple cells, the specified inputs of or the autosized capacity
    4594             :         //  and air/water flow rates are for the entire tower. The number of cells to operate
    4595             :         //  is first determined based on the user entered minimal and maximal water flow fractions
    4596             :         //  per cell. If the loads are not met, more cells (if available) will operate to meet
    4597             :         //  the loads. Inside each cell, the capacity controls still apply. Each cell operates
    4598             :         //  in the same way.
    4599             : 
    4600             :         // REFERENCES:
    4601             :         // ASHRAE HVAC1KIT: A Toolkit for Primary HVAC System Energy Calculation. 1999.
    4602             : 
    4603             :         // SUBROUTINE PARAMETER DEFINITIONS:
    4604             :         static constexpr std::string_view RoutineName("calculateSingleSpeedTower");
    4605     7761854 :         int constexpr MaxIteration(100); // Maximum fluid bypass iteration calculations
    4606             :         static constexpr std::string_view MaxItChar("100");
    4607     7761854 :         Real64 constexpr BypassFractionThreshold(0.01); // Threshold to stop bypass iteration
    4608     7761854 :         Real64 constexpr OWTLowerLimit(0.0);            // The limit of tower exit fluid temperature used in the fluid bypass
    4609             :         //  calculation to avoid fluid freezing. For water, it is 0 degreeC,
    4610             :         //  for glycols, it can be much lower. The fluid type is stored at the loop.
    4611             :         //  Current choices are Water and Steam, needs to expand for glycols
    4612             : 
    4613             :         // set inlet and outlet nodes
    4614     7761854 :         this->Qactual = 0.0;
    4615     7761854 :         this->FanPower = 0.0;
    4616     7761854 :         this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    4617             : 
    4618     7761854 :         Real64 freeConvTowerUA = this->FreeConvTowerUA;
    4619     7761854 :         Real64 highSpeedTowerUA = this->HighSpeedTowerUA;
    4620             : 
    4621             :         // water temperature setpoint
    4622     7761854 :         Real64 TempSetPoint = 0.0;
    4623     7761854 :         switch (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopDemandCalcScheme) {
    4624     7654001 :         case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    4625     7654001 :             if (this->SetpointIsOnOutlet) {
    4626      329043 :                 TempSetPoint = state.dataLoopNodes->Node(this->WaterOutletNodeNum).TempSetPoint;
    4627             :             } else {
    4628     7324958 :                 TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPoint;
    4629             :             }
    4630     7654001 :         } break;
    4631      107853 :         case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    4632      107853 :             if (this->SetpointIsOnOutlet) {
    4633       29668 :                 TempSetPoint = state.dataLoopNodes->Node(this->WaterOutletNodeNum).TempSetPointHi;
    4634             :             } else {
    4635       78185 :                 TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPointHi;
    4636             :             }
    4637      107853 :         } break;
    4638           0 :         default:
    4639           0 :             break;
    4640             :         }
    4641             : 
    4642             :         // If there is a fault of condenser SWT Sensor
    4643     7761854 :         if (this->FaultyCondenserSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    4644           0 :             (!state.dataGlobal->KickOffSimulation)) {
    4645           0 :             int FaultIndex = this->FaultyCondenserSWTIndex;
    4646           0 :             Real64 TowerOutletTemp_ff = TempSetPoint;
    4647             : 
    4648             :             // calculate the sensor offset using fault information
    4649           0 :             this->FaultyCondenserSWTOffset = state.dataFaultsMgr->FaultsCondenserSWTSensor(FaultIndex).CalFaultOffsetAct(state);
    4650             :             // update the TempSetPoint
    4651           0 :             TempSetPoint = TowerOutletTemp_ff - this->FaultyCondenserSWTOffset;
    4652             :         }
    4653             : 
    4654             :         // If there is a fault of cooling tower fouling
    4655     7765094 :         if (this->FaultyTowerFoulingFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    4656        3240 :             (!state.dataGlobal->KickOffSimulation)) {
    4657        3240 :             int FaultIndex = this->FaultyTowerFoulingIndex;
    4658        3240 :             Real64 FreeConvTowerUA_ff = this->FreeConvTowerUA;
    4659        3240 :             Real64 HighSpeedTowerUA_ff = this->HighSpeedTowerUA;
    4660             : 
    4661             :             // calculate the Faulty Tower Fouling Factor using fault information
    4662        3240 :             this->FaultyTowerFoulingFactor = state.dataFaultsMgr->FaultsTowerFouling(FaultIndex).CalFaultyTowerFoulingFactor(state);
    4663             : 
    4664             :             // update the tower UA values at faulty cases
    4665        3240 :             freeConvTowerUA = FreeConvTowerUA_ff * this->FaultyTowerFoulingFactor;
    4666        3240 :             highSpeedTowerUA = HighSpeedTowerUA_ff * this->FaultyTowerFoulingFactor;
    4667             :         }
    4668             : 
    4669             :         // Added for fluid bypass. First assume no fluid bypass
    4670     7761854 :         int BypassFlag = 0; // Flag indicator for fluid bypass (0 - no bypass, 1 - bypass)
    4671     7761854 :         Real64 BypassFraction2 = 0.0;
    4672     7761854 :         this->BypassFraction = 0.0;
    4673             : 
    4674             :         // Added for multi-cell. Determine the number of cells operating
    4675     7761854 :         int NumCellMin(0);
    4676     7761854 :         int NumCellMax(0);
    4677     7761854 :         Real64 WaterMassFlowRatePerCellMin = 0.0;
    4678     7761854 :         if (this->DesWaterMassFlowRate > 0.0) {
    4679     7756819 :             WaterMassFlowRatePerCellMin = this->DesWaterMassFlowRate * this->MinFracFlowRate / this->NumCell;
    4680     7756819 :             Real64 WaterMassFlowRatePerCellMax = this->DesWaterMassFlowRate * this->MaxFracFlowRate / this->NumCell;
    4681             : 
    4682             :             // round it up to the nearest integer
    4683     7756819 :             NumCellMin = min(int((this->WaterMassFlowRate / WaterMassFlowRatePerCellMax) + 0.9999), this->NumCell);
    4684     7756819 :             NumCellMax = min(int((this->WaterMassFlowRate / WaterMassFlowRatePerCellMin) + 0.9999), this->NumCell);
    4685             :         }
    4686             :         // cap min at 1
    4687     7761854 :         if (NumCellMin <= 0) NumCellMin = 1;
    4688     7761854 :         if (NumCellMax <= 0) NumCellMax = 1;
    4689     7761854 :         if (this->cellCtrl == CellCtrl::MinCell) {
    4690       40284 :             this->NumCellOn = NumCellMin;
    4691             :         } else {
    4692     7721570 :             this->NumCellOn = NumCellMax;
    4693             :         }
    4694     7761854 :         Real64 WaterMassFlowRatePerCell = this->WaterMassFlowRate / this->NumCellOn;
    4695             : 
    4696             :         // Do not RETURN here if flow rate is less than SmallMassFlow. Check basin heater and then RETURN.
    4697             : 
    4698     7761854 :         bool returnFlagSet = false;
    4699     7761854 :         this->checkMassFlowAndLoad(state, MyLoad, RunFlag, returnFlagSet);
    4700     7761854 :         if (returnFlagSet) return;
    4701             : 
    4702     3494827 :         bool IncrNumCellFlag = true; // determine if yes or no we increase the number of cells // set value to true to enter in the loop
    4703             : 
    4704     3494827 :         Real64 UAdesign = 0.0; // UA value at design conditions (entered by user or calculated)
    4705             :         Real64 OutletWaterTempOFF;
    4706     3494827 :         Real64 FanModeFrac = 0.0;
    4707     3494827 :         Real64 AirFlowRate = 0.0;
    4708     7002638 :         while (IncrNumCellFlag) {
    4709     3507811 :             IncrNumCellFlag = false;
    4710             : 
    4711             :             //   Initialize local variables to the free convection design values
    4712     3507811 :             UAdesign = freeConvTowerUA / this->NumCell;
    4713     3507811 :             AirFlowRate = this->FreeConvAirFlowRate / this->NumCell;
    4714     3507811 :             OutletWaterTempOFF = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    4715     3507811 :             this->OutletWaterTemp = OutletWaterTempOFF;
    4716     3507811 :             FanModeFrac = 0.0;
    4717             : 
    4718     3507811 :             OutletWaterTempOFF = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRate, UAdesign);
    4719             : 
    4720             :             //   Assume Setpoint was met using free convection regime (pump ON and fan OFF)
    4721     3507811 :             this->FanPower = 0.0;
    4722     3507811 :             this->OutletWaterTemp = OutletWaterTempOFF;
    4723             : 
    4724     3507811 :             if (OutletWaterTempOFF > TempSetPoint) {
    4725             :                 //     Setpoint was not met (or free conv. not used), turn on cooling tower fan
    4726     3496809 :                 UAdesign = highSpeedTowerUA / this->NumCell;
    4727     3496809 :                 AirFlowRate = this->HighSpeedAirFlowRate / this->NumCell;
    4728             : 
    4729             :                 // The fan power is for all cells operating
    4730     3496809 :                 Real64 const FanPowerOn = this->HighSpeedFanPower * this->NumCellOn / this->NumCell;
    4731             : 
    4732     3496809 :                 this->OutletWaterTemp = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRate, UAdesign);
    4733             : 
    4734     3496809 :                 if (this->OutletWaterTemp <= TempSetPoint) {
    4735      725497 :                     if (this->CapacityControl == CapacityCtrl::FanCycling || this->OutletWaterTemp <= OWTLowerLimit) {
    4736             :                         //           Setpoint was met with pump ON and fan ON, calculate run-time fraction
    4737      725387 :                         FanModeFrac = (TempSetPoint - OutletWaterTempOFF) / (this->OutletWaterTemp - OutletWaterTempOFF);
    4738      725387 :                         this->FanPower = FanModeFrac * FanPowerOn;
    4739      725387 :                         this->OutletWaterTemp = TempSetPoint;
    4740             :                     } else {
    4741             :                         // FluidBypass, fan runs at full speed for the entire time step
    4742         110 :                         FanModeFrac = 1.0;
    4743         110 :                         this->FanPower = FanPowerOn;
    4744         110 :                         BypassFlag = 1;
    4745             :                     }
    4746             :                 } else {
    4747             :                     //         Setpoint was not met, cooling tower ran at full capacity
    4748     2771312 :                     FanModeFrac = 1.0;
    4749     2771312 :                     this->FanPower = FanPowerOn;
    4750             :                     // if possible increase the number of cells and do the calculations again with the new water mass flow rate per cell
    4751     2771312 :                     if (this->NumCellOn < this->NumCell && (this->WaterMassFlowRate / (this->NumCellOn + 1)) >= WaterMassFlowRatePerCellMin) {
    4752       12984 :                         ++this->NumCellOn;
    4753       12984 :                         WaterMassFlowRatePerCell = this->WaterMassFlowRate / this->NumCellOn;
    4754       12984 :                         IncrNumCellFlag = true;
    4755             :                     }
    4756             :                 }
    4757       11002 :             } else if (OutletWaterTempOFF < TempSetPoint) {
    4758             :                 // Need to bypass in free convection cooling mode if bypass is allowed
    4759       11002 :                 if (this->CapacityControl == CapacityCtrl::FluidBypass) {
    4760          54 :                     if (OutletWaterTempOFF > OWTLowerLimit) {
    4761          54 :                         BypassFlag = 1;
    4762             :                     }
    4763             :                 }
    4764             :             }
    4765             :         }
    4766             : 
    4767             :         // Calculate bypass fraction since OWTLowerLimit < OutletWaterTemp < TempSetPoint.
    4768             :         // The iteraction ends when the numer of iteraction exceeds the limit or the difference
    4769             :         //  between the new and old bypass fractions is less than the threshold.
    4770     3494827 :         if (BypassFlag == 1) {
    4771             :             // Inlet water temperature lower than setpoint, assume 100% bypass, tower fan off
    4772         164 :             if (this->InletWaterTemp <= TempSetPoint) {
    4773           0 :                 this->FanPower = 0.0;
    4774           0 :                 this->BypassFraction = 1.0;
    4775           0 :                 this->OutletWaterTemp = this->InletWaterTemp;
    4776             :             } else {
    4777         164 :                 if (std::abs(this->InletWaterTemp - this->OutletWaterTemp) <= 0.01) {
    4778             :                     // Outlet temp is close enough to inlet temp, assume 100% bypass, tower fan off
    4779           0 :                     this->BypassFraction = 1.0;
    4780           0 :                     this->FanPower = 0.0;
    4781             :                 } else {
    4782         164 :                     Real64 bypassFraction = (TempSetPoint - this->OutletWaterTemp) / (this->InletWaterTemp - this->OutletWaterTemp);
    4783         164 :                     if (bypassFraction > 1.0 || bypassFraction < 0.0) {
    4784             :                         // Bypass cannot meet setpoint, assume no bypass
    4785           0 :                         this->BypassFraction = 0.0;
    4786             :                     } else {
    4787         164 :                         int NumIteration = 0;
    4788         164 :                         Real64 BypassFractionPrev = bypassFraction;
    4789         164 :                         Real64 OutletWaterTempPrev = this->OutletWaterTemp;
    4790         500 :                         while (NumIteration < MaxIteration) {
    4791         500 :                             ++NumIteration;
    4792             :                             // need to iterate for the new OutletWaterTemp while bypassing tower water
    4793         500 :                             this->OutletWaterTemp =
    4794         500 :                                 this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell * (1.0 - bypassFraction), AirFlowRate, UAdesign);
    4795             :                             // Calc new BypassFraction based on the new OutletWaterTemp
    4796         500 :                             if (std::abs(this->OutletWaterTemp - OWTLowerLimit) <= 0.01) {
    4797           0 :                                 BypassFraction2 = bypassFraction;
    4798           0 :                                 break;
    4799         500 :                             } else if (this->OutletWaterTemp < OWTLowerLimit) {
    4800             :                                 // Set OutletWaterTemp = OWTLowerLimit, and use linear interpolation to calculate the bypassFraction
    4801          40 :                                 BypassFraction2 = BypassFractionPrev - (BypassFractionPrev - bypassFraction) * (OutletWaterTempPrev - OWTLowerLimit) /
    4802          40 :                                                                            (OutletWaterTempPrev - this->OutletWaterTemp);
    4803          80 :                                 this->OutletWaterTemp = this->calculateSimpleTowerOutletTemp(
    4804          40 :                                     state, WaterMassFlowRatePerCell * (1.0 - BypassFraction2), AirFlowRate, UAdesign);
    4805          40 :                                 if (this->OutletWaterTemp < OWTLowerLimit) {
    4806             :                                     // Use previous iteraction values
    4807          40 :                                     BypassFraction2 = BypassFractionPrev;
    4808          40 :                                     this->OutletWaterTemp = OutletWaterTempPrev;
    4809             :                                 }
    4810          40 :                                 break;
    4811             :                             } else {
    4812         460 :                                 BypassFraction2 = (TempSetPoint - this->OutletWaterTemp) / (this->InletWaterTemp - this->OutletWaterTemp);
    4813             :                             }
    4814             : 
    4815             :                             // Compare two BypassFraction to determine when to stop
    4816         460 :                             if (std::abs(BypassFraction2 - bypassFraction) <= BypassFractionThreshold) break;
    4817         336 :                             BypassFractionPrev = bypassFraction;
    4818         336 :                             OutletWaterTempPrev = this->OutletWaterTemp;
    4819         336 :                             bypassFraction = BypassFraction2;
    4820             :                         }
    4821         164 :                         if (NumIteration > MaxIteration) {
    4822           0 :                             ShowWarningError(
    4823           0 :                                 state, format("Cooling tower fluid bypass iteration exceeds maximum limit of {} for {}", MaxItChar, this->Name));
    4824             :                         }
    4825         164 :                         this->BypassFraction = BypassFraction2;
    4826             :                         // may not meet TempSetPoint due to limit of tower outlet temp to OWTLowerLimit
    4827         164 :                         this->OutletWaterTemp = (1.0 - BypassFraction2) * this->OutletWaterTemp + BypassFraction2 * this->InletWaterTemp;
    4828             :                     }
    4829             :                 }
    4830             :             }
    4831             :         }
    4832             : 
    4833             :         // output the fraction of the time step the fan is ON
    4834     3494827 :         this->FanCyclingRatio = FanModeFrac;
    4835             :         // Should this be water inlet node num?????
    4836     3494827 :         Real64 const CpWater = FluidProperties::GetSpecificHeatGlycol(state,
    4837     3494827 :                                                                       state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    4838     3494827 :                                                                       state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp,
    4839     3494827 :                                                                       state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    4840             :                                                                       RoutineName);
    4841             : 
    4842     3494827 :         this->Qactual = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    4843     3494827 :         this->airFlowRateRatio = (AirFlowRate * this->NumCell) / this->HighSpeedAirFlowRate;
    4844             :     }
    4845             : 
    4846      298469 :     void CoolingTower::calculateTwoSpeedTower(EnergyPlusData &state, Real64 &MyLoad, bool RunFlag)
    4847             :     {
    4848             : 
    4849             :         // SUBROUTINE INFORMATION:
    4850             :         //       AUTHOR         Dan Fisher
    4851             :         //       DATE WRITTEN   Sept. 1998
    4852             :         //       MODIFIED       Feb. 2010, Chandan Sharma, FSEC, Added basin heater
    4853             :         //                      Jul. 2010, A Flament, added multi-cell capability for the 3 types of cooling tower
    4854             :         //                      Jun. 2016, R Zhang, Applied the condenser supply water temperature sensor fault model
    4855             :         //                      Jul. 2016, R Zhang, Applied the cooling tower fouling fault model
    4856             : 
    4857             :         // PURPOSE OF THIS SUBROUTINE:
    4858             :         // To simulate the operation of a cooling tower with a two-speed fan.
    4859             : 
    4860             :         // METHODOLOGY EMPLOYED:
    4861             :         // The cooling tower is modeled using effectiveness-NTU relationships for
    4862             :         // counterflow heat exchangers based on Merkel's theory.
    4863             :         // The subroutine calculates the period of time required to meet a
    4864             :         // leaving water temperature setpoint. It assumes that part-load
    4865             :         // operation represents a linear interpolation of three steady-state regimes
    4866             :         // (high-speed fan operation, low-speed fan operation and free convection regime).
    4867             :         // Cyclic losses are neglected. The period of time required to meet the
    4868             :         // leaving water temperature setpoint is used to determine the required
    4869             :         // fan power and energy. Free convection regime is also modeled. This
    4870             :         // occures when the pump is operating and the fan is off. If free convection
    4871             :         // regime cooling is all that is required for a given time step, the leaving
    4872             :         // water temperature is allowed to fall below the leaving water temperature
    4873             :         // setpoint (free cooling). At times when the cooling tower fan is required,
    4874             :         // the leaving water temperature is at or above the setpoint.
    4875             :         // A RunFlag is passed by the upper level manager to indicate the ON/OFF status,
    4876             :         // or schedule, of the cooling tower. If the tower is OFF, outlet water
    4877             :         // temperature and flow rate are passed through the model from inlet node to
    4878             :         // outlet node without intervention (with the exception of free convection
    4879             :         // where water temperature is allowed to float below the outlet water set
    4880             :         // point). Reports are also updated with fan power and fan energy being zero.
    4881             :         // When the RunFlag indicates an ON condition for the cooling tower, the
    4882             :         // mass flow rate and water temperature are read from the inlet node of the
    4883             :         // cooling tower (water-side). The outdoor air wet-bulb temperature is used
    4884             :         // as the entering condition to the cooling tower (air-side). Input deck
    4885             :         // parameters are read for the free convection regime (pump ON and fan OFF)
    4886             :         // and a leaving water temperature is calculated. If the leaving water temperature
    4887             :         // is at or below the setpoint, the calculated leaving water temperature is
    4888             :         // placed on the outlet node and no fan power is used. If the calculated leaving
    4889             :         // water temperature is above the setpoint, the cooling tower fan is turned on
    4890             :         // and parameters for low fan speed are used to again calculate the leaving
    4891             :         // water temperature. If the calculated leaving water temperature is
    4892             :         // below the setpoint, a fan run-time fraction (FanModeFrac) is calculated and
    4893             :         // used to determine fan power. The leaving water temperature setpoint is placed
    4894             :         // on the outlet node. If the calculated leaving water temperature is at or above
    4895             :         // the setpoint, the cooling tower fan is turned on 'high speed' and the routine is
    4896             :         // repeated. If the calculated leaving water temperature is below the setpoint,
    4897             :         // a fan run-time fraction is calculated for the second stage fan and fan power
    4898             :         // is calculated as FanModeFrac*HighSpeedFanPower+(1-FanModeFrac)*LowSpeedFanPower.
    4899             :         // If the calculated leaving water temperature is above the leaving water temp.
    4900             :         // setpoint, the calculated leaving water temperature is placed on the outlet
    4901             :         // node and the fan runs at full power (High Speed Fan Power). Water mass flow
    4902             :         // rate is passed from inlet node to outlet node with no intervention.
    4903             :         // If a tower has multiple cells, the specified inputs of or the autosized capacity
    4904             :         //  and air/water flow rates are for the entire tower. The number of cells to operate
    4905             :         //  is first determined based on the user entered minimal and maximal water flow fractions
    4906             :         //  per cell. If the loads are not met, more cells (if available) will operate to meet
    4907             :         //  the loads. Each cell operates in same way - same fan speed etc.
    4908             :         // REFERENCES:
    4909             :         // ASHRAE HVAC1KIT: A Toolkit for Primary HVAC System Energy Calculation. 1999.
    4910             : 
    4911             :         // SUBROUTINE PARAMETER DEFINITIONS:
    4912             :         static constexpr std::string_view RoutineName("calculateTwoSpeedTower");
    4913             : 
    4914             :         // init
    4915      298469 :         this->Qactual = 0.0;
    4916      298469 :         this->FanPower = 0.0;
    4917      298469 :         this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    4918             : 
    4919      298469 :         Real64 freeConvTowerUA = this->FreeConvTowerUA;
    4920      298469 :         Real64 highSpeedTowerUA = this->HighSpeedTowerUA;
    4921             : 
    4922             :         // water temperature setpoint
    4923      298469 :         Real64 TempSetPoint = 0.0;
    4924      298469 :         switch (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopDemandCalcScheme) {
    4925      280831 :         case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    4926      280831 :             if (this->SetpointIsOnOutlet) {
    4927       31852 :                 TempSetPoint = state.dataLoopNodes->Node(this->WaterOutletNodeNum).TempSetPoint;
    4928             :             } else {
    4929      248979 :                 TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPoint;
    4930             :             }
    4931      280831 :         } break;
    4932       17638 :         case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    4933       17638 :             if (this->SetpointIsOnOutlet) {
    4934       17638 :                 TempSetPoint = state.dataLoopNodes->Node(this->WaterOutletNodeNum).TempSetPointHi;
    4935             :             } else {
    4936           0 :                 TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPointHi;
    4937             :             }
    4938       17638 :         } break;
    4939           0 :         default:
    4940           0 :             break;
    4941             :         }
    4942             : 
    4943             :         // If there is a fault of condenser SWT Sensor
    4944      301381 :         if (this->FaultyCondenserSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    4945        2912 :             (!state.dataGlobal->KickOffSimulation)) {
    4946        2912 :             int FaultIndex = this->FaultyCondenserSWTIndex;
    4947        2912 :             Real64 TowerOutletTemp_ff = TempSetPoint;
    4948             : 
    4949             :             // calculate the sensor offset using fault information
    4950        2912 :             this->FaultyCondenserSWTOffset = state.dataFaultsMgr->FaultsCondenserSWTSensor(FaultIndex).CalFaultOffsetAct(state);
    4951             :             // update the TempSetPoint
    4952        2912 :             TempSetPoint = TowerOutletTemp_ff - this->FaultyCondenserSWTOffset;
    4953             :         }
    4954             : 
    4955             :         // If there is a fault of cooling tower fouling
    4956      298469 :         if (this->FaultyTowerFoulingFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    4957           0 :             (!state.dataGlobal->KickOffSimulation)) {
    4958           0 :             int FaultIndex = this->FaultyTowerFoulingIndex;
    4959           0 :             Real64 FreeConvTowerUA_ff = this->FreeConvTowerUA;
    4960           0 :             Real64 HighSpeedTowerUA_ff = this->HighSpeedTowerUA;
    4961             : 
    4962             :             // calculate the Faulty Tower Fouling Factor using fault information
    4963           0 :             this->FaultyTowerFoulingFactor = state.dataFaultsMgr->FaultsTowerFouling(FaultIndex).CalFaultyTowerFoulingFactor(state);
    4964             : 
    4965             :             // update the tower UA values at faulty cases
    4966           0 :             freeConvTowerUA = FreeConvTowerUA_ff * this->FaultyTowerFoulingFactor;
    4967           0 :             highSpeedTowerUA = HighSpeedTowerUA_ff * this->FaultyTowerFoulingFactor;
    4968             :         }
    4969             : 
    4970             :         // Do not RETURN here if flow rate is less than SmallMassFlow. Check basin heater and then RETURN.
    4971      298469 :         if (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked)
    4972      261298 :             return; // TODO: WTF
    4973      149198 :         bool returnFlagSet = false;
    4974      149198 :         this->checkMassFlowAndLoad(state, MyLoad, RunFlag, returnFlagSet);
    4975      149198 :         if (returnFlagSet) return;
    4976             : 
    4977             :         // Added for multi-cell. Determine the number of cells operating
    4978       37171 :         Real64 WaterMassFlowRatePerCellMin = 0.0;
    4979             :         Real64 WaterMassFlowRatePerCellMax;
    4980       37171 :         int NumCellMin(0);
    4981       37171 :         int NumCellMax(0);
    4982             :         Real64 WaterMassFlowRatePerCell;
    4983       37171 :         if (this->DesWaterMassFlowRate > 0.0) {
    4984       37171 :             WaterMassFlowRatePerCellMin = this->DesWaterMassFlowRate * this->MinFracFlowRate / this->NumCell;
    4985       37171 :             WaterMassFlowRatePerCellMax = this->DesWaterMassFlowRate * this->MaxFracFlowRate / this->NumCell;
    4986             : 
    4987             :             // round it up to the nearest integer
    4988       37171 :             NumCellMin = min(int((this->WaterMassFlowRate / WaterMassFlowRatePerCellMax) + 0.9999), this->NumCell);
    4989       37171 :             NumCellMax = min(int((this->WaterMassFlowRate / WaterMassFlowRatePerCellMin) + 0.9999), this->NumCell);
    4990             :         }
    4991             : 
    4992             :         // cap min at 1
    4993       37171 :         if (NumCellMin <= 0) NumCellMin = 1;
    4994       37171 :         if (NumCellMax <= 0) NumCellMax = 1;
    4995             : 
    4996       37171 :         if (this->cellCtrl == CellCtrl::MinCell) {
    4997        3428 :             this->NumCellOn = NumCellMin;
    4998             :         } else {
    4999       33743 :             this->NumCellOn = NumCellMax;
    5000             :         }
    5001             : 
    5002       37171 :         WaterMassFlowRatePerCell = this->WaterMassFlowRate / this->NumCellOn;
    5003             : 
    5004       37171 :         bool IncrNumCellFlag = true;
    5005             : 
    5006       37171 :         Real64 AirFlowRate = 0.0;
    5007       37171 :         Real64 FanModeFrac = 0.0;
    5008       37171 :         int SpeedSel = 0;
    5009       80834 :         while (IncrNumCellFlag) {
    5010       43663 :             IncrNumCellFlag = false;
    5011             : 
    5012             :             // set local variable for tower
    5013       43663 :             Real64 UAdesign = freeConvTowerUA / this->NumCell; // where is NumCellOn?
    5014       43663 :             AirFlowRate = this->FreeConvAirFlowRate / this->NumCell;
    5015       43663 :             this->WaterMassFlowRate = state.dataLoopNodes->Node(this->WaterInletNodeNum).MassFlowRate;
    5016       43663 :             Real64 OutletWaterTemp1stStage = this->OutletWaterTemp;
    5017       43663 :             Real64 OutletWaterTemp2ndStage = this->OutletWaterTemp;
    5018       43663 :             FanModeFrac = 0.0;
    5019             : 
    5020       43663 :             Real64 OutletWaterTempOFF = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRate, UAdesign);
    5021             : 
    5022             :             //     Setpoint was met using free convection regime (pump ON and fan OFF)
    5023       43663 :             this->FanPower = 0.0;
    5024       43663 :             this->OutletWaterTemp = OutletWaterTempOFF;
    5025             : 
    5026       43663 :             if (OutletWaterTempOFF > TempSetPoint) {
    5027             :                 //     Setpoint was not met (or free conv. not used),turn on cooling tower 1st stage fan
    5028       43276 :                 UAdesign = this->LowSpeedTowerUA / this->NumCell;
    5029       43276 :                 AirFlowRate = this->LowSpeedAirFlowRate / this->NumCell;
    5030       43276 :                 Real64 const FanPowerLow = this->LowSpeedFanPower * this->NumCellOn / this->NumCell;
    5031             : 
    5032       43276 :                 OutletWaterTemp1stStage = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRate, UAdesign);
    5033             : 
    5034       43276 :                 if (OutletWaterTemp1stStage <= TempSetPoint) {
    5035             :                     //         Setpoint was met with pump ON and fan ON 1st stage, calculate fan mode fraction
    5036        5307 :                     FanModeFrac = (TempSetPoint - OutletWaterTempOFF) / (OutletWaterTemp1stStage - OutletWaterTempOFF);
    5037        5307 :                     this->FanPower = FanModeFrac * FanPowerLow;
    5038        5307 :                     this->OutletWaterTemp = TempSetPoint;
    5039        5307 :                     this->Qactual *= FanModeFrac;
    5040        5307 :                     SpeedSel = 1;
    5041             :                 } else {
    5042             :                     //         Setpoint was not met, turn on cooling tower 2nd stage fan
    5043       37969 :                     UAdesign = highSpeedTowerUA / this->NumCell;
    5044       37969 :                     AirFlowRate = this->HighSpeedAirFlowRate / this->NumCell;
    5045       37969 :                     Real64 const FanPowerHigh = this->HighSpeedFanPower * this->NumCellOn / this->NumCell;
    5046             : 
    5047       37969 :                     OutletWaterTemp2ndStage = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRate, UAdesign);
    5048             : 
    5049       37969 :                     if ((OutletWaterTemp2ndStage <= TempSetPoint) && UAdesign > 0.0) {
    5050             :                         //           Setpoint was met with pump ON and fan ON 2nd stage, calculate fan mode fraction
    5051        9034 :                         FanModeFrac = (TempSetPoint - OutletWaterTemp1stStage) / (OutletWaterTemp2ndStage - OutletWaterTemp1stStage);
    5052        9034 :                         this->FanPower = (FanModeFrac * FanPowerHigh) + (1.0 - FanModeFrac) * FanPowerLow;
    5053        9034 :                         this->OutletWaterTemp = TempSetPoint;
    5054        9034 :                         SpeedSel = 2;
    5055             :                     } else {
    5056             :                         //           Setpoint was not met, cooling tower ran at full capacity
    5057       28935 :                         this->OutletWaterTemp = OutletWaterTemp2ndStage;
    5058       28935 :                         this->FanPower = FanPowerHigh;
    5059       28935 :                         SpeedSel = 2;
    5060       28935 :                         FanModeFrac = 1.0;
    5061             :                         // if possible increase the number of cells and do the calculations again with the new water mass flow rate per cell
    5062       28935 :                         if (this->NumCellOn < this->NumCell && (this->WaterMassFlowRate / (this->NumCellOn + 1)) >= WaterMassFlowRatePerCellMin) {
    5063        6492 :                             ++this->NumCellOn;
    5064        6492 :                             WaterMassFlowRatePerCell = this->WaterMassFlowRate / this->NumCellOn;
    5065        6492 :                             IncrNumCellFlag = true;
    5066             :                         }
    5067             :                     }
    5068             :                 }
    5069             :             }
    5070             :         }
    5071             : 
    5072             :         // output the fraction of the time step the fan is ON
    5073       37171 :         this->FanCyclingRatio = FanModeFrac;
    5074       37171 :         this->SpeedSelected = SpeedSel;
    5075             : 
    5076       37171 :         Real64 const CpWater = FluidProperties::GetSpecificHeatGlycol(state,
    5077       37171 :                                                                       state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    5078       37171 :                                                                       state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp,
    5079       37171 :                                                                       state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    5080             :                                                                       RoutineName);
    5081       37171 :         this->Qactual = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    5082       37171 :         this->airFlowRateRatio = (AirFlowRate * this->NumCell) / this->HighSpeedAirFlowRate;
    5083             :     }
    5084             : 
    5085      625884 :     void CoolingTower::calculateVariableSpeedTower(EnergyPlusData &state, Real64 &MyLoad, bool RunFlag)
    5086             :     {
    5087             : 
    5088             :         // SUBROUTINE INFORMATION:
    5089             :         //       AUTHOR         Richard Raustad
    5090             :         //       DATE WRITTEN   Feb 2005
    5091             :         //       MODIFIED       Jul. 2010, A Flament, added multi-cell capability for the 3 types of cooling tower
    5092             :         //                      Jul. 2010, B Griffith, general fluid props
    5093             :         //                      Jun. 2016, R Zhang, Applied the condenser supply water temperature sensor fault model
    5094             :         //                      Jul. 2016, R Zhang, Applied the cooling tower fouling fault model
    5095             : 
    5096             :         // PURPOSE OF THIS SUBROUTINE:
    5097             :         // To simulate the operation of a variable-speed fan cooling tower.
    5098             : 
    5099             :         // METHODOLOGY EMPLOYED:
    5100             :         // For each simulation time step, a desired range temperature (Twater,inlet-Twater,setpoint) and desired approach
    5101             :         // temperature (Twater,setpoint-Tair,WB) is calculated which meets the outlet water temperature setpoint. This
    5102             :         // desired range and approach temperature also provides a balance point for the empirical model where:
    5103             :         // Tair,WB + Twater,range + Tapproach = Node(WaterInletNode)%Temp
    5104             :         // Calculation of water outlet temperature uses one of the following equations:
    5105             :         // Twater,outlet = Tair,WB + Tapproach          (1)  or
    5106             :         // Twater,outlet = Twater,inlet - Twater,range  (2)
    5107             :         // If a solution (or balance) is found, these 2 calculation methods are equal. Equation 2 is used to calculate
    5108             :         // the outlet water temperature in the free convection regime and at the minimum or maximum fan speed so that
    5109             :         // if a solution is not reached, the outlet water temperature is approximately equal to the inlet water temperature
    5110             :         // and the tower fan must be varied to meet the setpoint. Equation 1 is used when the fan speed is varied between
    5111             :         // the minimum and maximum fan speed to meet the outlet water temperature setpoint.
    5112             :         // The outlet water temperature in the free convection regime is first calculated to see if the setpoint is met.
    5113             :         // If the setpoint is met, the fan is OFF and the outlet water temperature is allowed to float below the set
    5114             :         // point temperature. If the setpoint is not met, the outlet water temperature is re-calculated at the minimum
    5115             :         // fan speed. If the setpoint is met, the fan is cycled to exactly meet the outlet water temperature setpoint.
    5116             :         // If the setpoint is not met at the minimum fan speed, the outlet water temperature is re-calculated at the
    5117             :         // maximum fan speed. If the setpoint at the maximum fan speed is not met, the fan runs at maximum speed the
    5118             :         // entire time step. If the setpoint is met at the maximum fan speed, the fan speed is varied to meet the setpoint.
    5119             :         // If a tower has multiple cells, the specified inputs of or the autosized capacity
    5120             :         //  and air/water flow rates are for the entire tower. The number of cells to operate
    5121             :         //  is first determined based on the user entered minimal and maximal water flow fractions
    5122             :         //  per cell. If the loads are not met, more cells (if available) will operate to meet
    5123             :         //  the loads. Inside each cell, the fan speed varies in the same way.
    5124             :         // REFERENCES:
    5125             :         // Benton, D.J., Bowmand, C.F., Hydeman, M., Miller, P.,
    5126             :         // "An Improved Cooling Tower Algorithm for the CoolToolsTM Simulation Model".
    5127             :         // ASHRAE Transactions 2002, V. 108, Pt. 1.
    5128             :         // York International Corporation, "YORKcalcTM Software, Chiller-Plant Energy-Estimating Program",
    5129             :         // Form 160.00-SG2 (0502). 2002.
    5130             : 
    5131             :         // SUBROUTINE PARAMETER DEFINITIONS:
    5132             : 
    5133      625884 :         int constexpr MaxIte(500);    // Maximum number of iterations
    5134      625884 :         Real64 constexpr Acc(0.0001); // Accuracy of result
    5135             :         static constexpr std::string_view RoutineName("calculateVariableSpeedTower");
    5136             : 
    5137             :         // Added for multi-cell. Determine the number of cells operating
    5138      625884 :         Real64 WaterMassFlowRatePerCellMin = 0.0;
    5139             :         Real64 WaterMassFlowRatePerCellMax;
    5140      625884 :         int NumCellMin(0);
    5141      625884 :         int NumCellMax(0);
    5142             :         Real64 WaterMassFlowRatePerCell;
    5143      625884 :         if (this->DesWaterMassFlowRate > 0.0) {
    5144      625439 :             WaterMassFlowRatePerCellMin = this->DesWaterMassFlowRate * this->MinFracFlowRate / this->NumCell;
    5145      625439 :             WaterMassFlowRatePerCellMax = this->DesWaterMassFlowRate * this->MaxFracFlowRate / this->NumCell;
    5146             : 
    5147             :             // round it up to the nearest integer
    5148      625439 :             NumCellMin = min(int((this->WaterMassFlowRate / WaterMassFlowRatePerCellMax) + 0.9999), this->NumCell);
    5149      625439 :             NumCellMax = min(int((this->WaterMassFlowRate / WaterMassFlowRatePerCellMin) + 0.9999), this->NumCell);
    5150             :         }
    5151             : 
    5152             :         // cap min at 1
    5153      625884 :         if (NumCellMin <= 0) NumCellMin = 1;
    5154      625884 :         if (NumCellMax <= 0) NumCellMax = 1;
    5155             : 
    5156      625884 :         if (this->cellCtrl == CellCtrl::MinCell) {
    5157       23390 :             this->NumCellOn = NumCellMin;
    5158             :         } else {
    5159      602494 :             this->NumCellOn = NumCellMax;
    5160             :         }
    5161             : 
    5162      625884 :         WaterMassFlowRatePerCell = this->WaterMassFlowRate / this->NumCellOn;
    5163             : 
    5164             :         // Initialize subroutine variables
    5165      625884 :         this->Qactual = 0.0;
    5166      625884 :         this->FanPower = 0.0;
    5167      625884 :         this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    5168             : 
    5169      625884 :         this->WaterUsage = 0.0;
    5170      625884 :         Real64 Twb = this->AirWetBulb;
    5171      625884 :         Real64 TwbCapped = this->AirWetBulb;
    5172             : 
    5173             :         // water temperature setpoint
    5174      625884 :         Real64 TempSetPoint(0.0); // Outlet water temperature setpoint (C)
    5175      625884 :         switch (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopDemandCalcScheme) {
    5176      625884 :         case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    5177      625884 :             TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPoint;
    5178      625884 :         } break;
    5179           0 :         case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    5180           0 :             TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPointHi;
    5181           0 :         } break;
    5182           0 :         default: {
    5183           0 :             assert(false);
    5184             :         } break;
    5185             :         }
    5186             : 
    5187             :         // If there is a fault of condenser SWT Sensor
    5188      625884 :         if (this->FaultyCondenserSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    5189           0 :             (!state.dataGlobal->KickOffSimulation)) {
    5190           0 :             int FaultIndex = this->FaultyCondenserSWTIndex;
    5191           0 :             Real64 TowerOutletTemp_ff = TempSetPoint;
    5192             : 
    5193             :             // calculate the sensor offset using fault information
    5194           0 :             this->FaultyCondenserSWTOffset = state.dataFaultsMgr->FaultsCondenserSWTSensor(FaultIndex).CalFaultOffsetAct(state);
    5195             :             // update the TempSetPoint
    5196           0 :             TempSetPoint = TowerOutletTemp_ff - this->FaultyCondenserSWTOffset;
    5197             :         }
    5198             : 
    5199      625884 :         Real64 Tr = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - TempSetPoint;
    5200      625884 :         Real64 Ta = TempSetPoint - this->AirWetBulb;
    5201             : 
    5202             :         // Do not RETURN here if flow rate is less than MassFlowTolerance. Check basin heater and then RETURN.
    5203      625884 :         if (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked)
    5204      535706 :             return; // TODO: WTF
    5205             : 
    5206      312870 :         bool returnFlagSet = false;
    5207      312870 :         this->checkMassFlowAndLoad(state, MyLoad, RunFlag, returnFlagSet);
    5208      312870 :         if (returnFlagSet) return;
    5209             : 
    5210             :         // loop to increment NumCell if we cannot meet the setpoint with the actual number of cells calculated above
    5211       90178 :         bool IncrNumCellFlag = true;
    5212             :         Real64 OutletWaterTempOFF;             // Outlet water temperature with fan OFF (C)
    5213       90178 :         Real64 OutletWaterTempON = 0.0;        // Outlet water temperature with fan ON at maximum fan speed (C)
    5214       90178 :         Real64 FreeConvectionCapFrac = 0.0;    // fraction of tower capacity in free convection
    5215       90178 :         Real64 WaterFlowRateRatioCapped = 0.0; // Water flow rate ratio passed to VS tower model
    5216             :         Real64 TrCapped;                       // range temp passed to VS tower model
    5217             :         Real64 TaCapped;                       // approach temp passed to VS tower model
    5218      186752 :         while (IncrNumCellFlag) {
    5219       96574 :             IncrNumCellFlag = false;
    5220             :             // Initialize inlet node water properties
    5221       96574 :             Real64 const WaterDensity = FluidProperties::GetDensityGlycol(state,
    5222       96574 :                                                                           state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    5223       96574 :                                                                           state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp,
    5224       96574 :                                                                           state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    5225             :                                                                           RoutineName);
    5226       96574 :             Real64 const WaterFlowRateRatio = WaterMassFlowRatePerCell / (WaterDensity * this->CalibratedWaterFlowRate / this->NumCell);
    5227             : 
    5228             :             // check independent inputs with respect to model boundaries
    5229       96574 :             this->checkModelBounds(state, Twb, Tr, Ta, WaterFlowRateRatio, TwbCapped, TrCapped, TaCapped, WaterFlowRateRatioCapped);
    5230             : 
    5231             :             //   determine the free convection capacity by finding the outlet temperature at full air flow and multiplying
    5232             :             //   the tower's full capacity temperature difference by the percentage of tower capacity in free convection
    5233             :             //   regime specified by the user
    5234             : 
    5235       96574 :             this->airFlowRateRatio = 1.0;
    5236       96574 :             OutletWaterTempOFF = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    5237       96574 :             this->OutletWaterTemp = OutletWaterTempOFF;
    5238       96574 :             FreeConvectionCapFrac = this->FreeConvectionCapacityFraction;
    5239       96574 :             OutletWaterTempON = this->calculateVariableTowerOutletTemp(state, WaterFlowRateRatioCapped, this->airFlowRateRatio, TwbCapped);
    5240             : 
    5241       96574 :             if (OutletWaterTempON > TempSetPoint) {
    5242       47867 :                 this->FanCyclingRatio = 1.0;
    5243       47867 :                 this->airFlowRateRatio = 1.0;
    5244       47867 :                 this->FanPower = this->HighSpeedFanPower * this->NumCellOn / this->NumCell;
    5245       47867 :                 this->OutletWaterTemp = OutletWaterTempON;
    5246             :                 // if possible increase the number of cells and do the calculations again with the new water mass flow rate per cell
    5247       47867 :                 if (this->NumCellOn < this->NumCell && (this->WaterMassFlowRate / (this->NumCellOn + 1)) > WaterMassFlowRatePerCellMin) {
    5248        6396 :                     ++this->NumCellOn;
    5249        6396 :                     WaterMassFlowRatePerCell = this->WaterMassFlowRate / this->NumCellOn;
    5250        6396 :                     IncrNumCellFlag = true;
    5251             :                 }
    5252             :             }
    5253             :         }
    5254             : 
    5255             :         // find the correct air ratio only if full flow is  too much
    5256       90178 :         if (OutletWaterTempON < TempSetPoint) {
    5257             :             //   outlet water temperature is calculated in the free convection regime
    5258       48707 :             OutletWaterTempOFF = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp -
    5259       48707 :                                  FreeConvectionCapFrac * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - OutletWaterTempON);
    5260             :             //   fan is OFF
    5261       48707 :             this->FanCyclingRatio = 0.0;
    5262             :             //   air flow ratio is assumed to be the fraction of tower capacity in the free convection regime (fan is OFF but air is flowing)
    5263       48707 :             this->airFlowRateRatio = FreeConvectionCapFrac;
    5264             : 
    5265             :             // Assume setpoint was met using free convection regime (pump ON and fan OFF)
    5266       48707 :             this->FanPower = 0.0;
    5267       48707 :             this->OutletWaterTemp = OutletWaterTempOFF;
    5268             : 
    5269       48707 :             if (OutletWaterTempOFF > TempSetPoint) {
    5270             :                 // Setpoint was not met, turn on cooling tower fan at minimum fan speed
    5271             : 
    5272       47621 :                 this->airFlowRateRatio = this->MinimumVSAirFlowFrac;
    5273             :                 Real64 OutletWaterTempMIN; // Outlet water temperature with fan at minimum speed (C)
    5274       47621 :                 OutletWaterTempMIN = this->calculateVariableTowerOutletTemp(state, WaterFlowRateRatioCapped, this->airFlowRateRatio, TwbCapped);
    5275             : 
    5276       47621 :                 if (OutletWaterTempMIN < TempSetPoint) {
    5277             :                     //         if setpoint was exceeded, cycle the fan at minimum air flow to meet the setpoint temperature
    5278       20074 :                     if (this->FanPowerfAirFlowCurve == 0) {
    5279           0 :                         this->FanPower = pow_3(this->airFlowRateRatio) * this->HighSpeedFanPower * this->NumCellOn / this->NumCell;
    5280             :                     } else {
    5281       20074 :                         Real64 const FanCurveValue = Curve::CurveValue(state, this->FanPowerfAirFlowCurve, this->airFlowRateRatio);
    5282       20074 :                         this->FanPower = max(0.0, (this->HighSpeedFanPower * FanCurveValue)) * this->NumCellOn / this->NumCell;
    5283             :                     }
    5284             :                     //       fan is cycling ON and OFF at the minimum fan speed. Adjust fan power and air flow rate ratio according to cycling rate
    5285       20074 :                     this->FanCyclingRatio = ((OutletWaterTempOFF - TempSetPoint) / (OutletWaterTempOFF - OutletWaterTempMIN));
    5286       20074 :                     this->FanPower *= this->FanCyclingRatio;
    5287       20074 :                     this->OutletWaterTemp = TempSetPoint;
    5288       20074 :                     this->airFlowRateRatio =
    5289       20074 :                         (this->FanCyclingRatio * this->MinimumVSAirFlowFrac) + ((1 - this->FanCyclingRatio) * FreeConvectionCapFrac);
    5290             :                 } else {
    5291             :                     //       if setpoint was not met at minimum fan speed, set fan speed to maximum
    5292       27547 :                     this->airFlowRateRatio = 1.0;
    5293             :                     //         fan will not cycle and runs the entire time step
    5294       27547 :                     this->FanCyclingRatio = 1.0;
    5295             : 
    5296       27547 :                     this->OutletWaterTemp =
    5297       27547 :                         this->calculateVariableTowerOutletTemp(state, WaterFlowRateRatioCapped, this->airFlowRateRatio, TwbCapped);
    5298             : 
    5299             :                     // Setpoint was met with pump ON and fan ON at full flow
    5300             :                     // Calculate the fraction of full air flow to exactly meet the setpoint temperature
    5301      579894 :                     auto f = [&state, this, WaterFlowRateRatioCapped, TwbCapped, Tr, Ta](Real64 FlowRatio) {
    5302      289947 :                         Real64 TapproachActual = this->calculateVariableSpeedApproach(state, WaterFlowRateRatioCapped, FlowRatio, TwbCapped, Tr);
    5303      289947 :                         return Ta - TapproachActual;
    5304       27547 :                     };
    5305       27547 :                     int SolFla = 0;
    5306       27547 :                     General::SolveRoot(state, Acc, MaxIte, SolFla, this->airFlowRateRatio, f, this->MinimumVSAirFlowFrac, 1.0);
    5307       27547 :                     if (SolFla == -1) {
    5308           0 :                         if (!state.dataGlobal->WarmupFlag)
    5309           0 :                             ShowWarningError(
    5310             :                                 state,
    5311           0 :                                 format("Cooling tower iteration limit exceeded when calculating air flow rate ratio for tower {}", this->Name));
    5312             :                         //           IF RegulaFalsi cannot find a solution then provide detailed output for debugging
    5313       27547 :                     } else if (SolFla == -2) {
    5314           0 :                         if (!state.dataGlobal->WarmupFlag) {
    5315             : 
    5316           0 :                             if (this->CoolingTowerAFRRFailedCount < 1) {
    5317           0 :                                 ++this->CoolingTowerAFRRFailedCount;
    5318           0 :                                 ShowWarningError(
    5319             :                                     state,
    5320           0 :                                     format("CoolingTower:VariableSpeed \"{}\" - Cooling tower air flow rate ratio calculation failed ", this->Name));
    5321           0 :                                 ShowContinueError(state,
    5322           0 :                                                   format("...with conditions as Twb = {:5.2F}, Trange = {:5.2F}, Tapproach = {:5.2F}, and water flow "
    5323             :                                                          "rate ratio = {:5.2F}",
    5324             :                                                          TwbCapped,
    5325             :                                                          Tr,
    5326             :                                                          Ta,
    5327             :                                                          WaterFlowRateRatioCapped));
    5328           0 :                                 ShowContinueError(state, "...a solution could not be found within the valid range of air flow rate ratios");
    5329           0 :                                 ShowContinueErrorTimeStamp(
    5330           0 :                                     state, format(" ...Valid air flow rate ratio range = {:5.2F} to 1.0.", this->MinimumVSAirFlowFrac));
    5331           0 :                                 ShowContinueError(state, "...Consider modifying the design approach or design range temperature for this tower.");
    5332             :                             } else {
    5333           0 :                                 ShowRecurringWarningErrorAtEnd(state,
    5334           0 :                                                                "CoolingTower:VariableSpeed \"" + this->Name +
    5335             :                                                                    "\" - Cooling tower air flow rate ratio calculation failed error continues.",
    5336           0 :                                                                this->CoolingTowerAFRRFailedIndex);
    5337             :                             }
    5338             :                         }
    5339             :                     }
    5340             : 
    5341             :                     //         Use theoretical cubic for determination of fan power if user has not specified a fan power ratio curve
    5342       27547 :                     if (this->FanPowerfAirFlowCurve == 0) {
    5343           0 :                         this->FanPower = pow_3(this->airFlowRateRatio) * this->HighSpeedFanPower * this->NumCellOn / this->NumCell;
    5344             :                     } else {
    5345       27547 :                         Real64 const FanCurveValue = Curve::CurveValue(state, this->FanPowerfAirFlowCurve, this->airFlowRateRatio);
    5346       27547 :                         this->FanPower = max(0.0, (this->HighSpeedFanPower * FanCurveValue)) * this->NumCellOn / this->NumCell;
    5347             :                     }
    5348             :                     //           outlet water temperature is calculated as the inlet air wet-bulb temperature plus tower approach temperature
    5349       27547 :                     this->OutletWaterTemp = Twb + Ta;
    5350             :                 }
    5351             :             }
    5352             :         }
    5353             : 
    5354       90178 :         Real64 const CpWater = FluidProperties::GetSpecificHeatGlycol(state,
    5355       90178 :                                                                       state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    5356       90178 :                                                                       state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp,
    5357       90178 :                                                                       state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    5358             :                                                                       RoutineName);
    5359       90178 :         this->Qactual = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    5360             : 
    5361             :         //   calculate end time of current time step
    5362       90178 :         Real64 const CurrentEndTime = state.dataGlobal->CurrentTime + state.dataHVACGlobal->SysTimeElapsed;
    5363             : 
    5364             :         //   Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
    5365             :         //   Wait for next time step to print warnings. If simulation iterates, print out
    5366             :         //   the warning for the last iteration only. Must wait for next time step to accomplish this.
    5367             :         //   If a warning occurs and the simulation down shifts, the warning is not valid.
    5368       90178 :         if (CurrentEndTime > this->CurrentEndTimeLast && state.dataHVACGlobal->TimeStepSys >= this->TimeStepSysLast) {
    5369           0 :             if (state.dataCondenserLoopTowers->towers(this->VSTower).PrintLGMessage) {
    5370           0 :                 ++state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountFlowFrac;
    5371             :                 //       Show single warning and pass additional info to ShowRecurringWarningErrorAtEnd
    5372           0 :                 if (state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountFlowFrac < 2) {
    5373           0 :                     ShowWarningError(state, state.dataCondenserLoopTowers->towers(this->VSTower).LGBuffer1);
    5374           0 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).LGBuffer2);
    5375             :                 } else {
    5376           0 :                     ShowRecurringWarningErrorAtEnd(state,
    5377           0 :                                                    format("{} \"{}\" - Liquid to gas ratio is out of range error continues...",
    5378           0 :                                                           DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    5379           0 :                                                           this->Name),
    5380           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).ErrIndexLG,
    5381           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).LGLast,
    5382           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).LGLast);
    5383             :                 }
    5384             :             }
    5385             :         }
    5386             : 
    5387             :         //   save last system time step and last end time of current time step (used to determine if warning is valid)
    5388       90178 :         this->TimeStepSysLast = state.dataHVACGlobal->TimeStepSys;
    5389       90178 :         this->CurrentEndTimeLast = CurrentEndTime;
    5390             : 
    5391             :         //   warn user on first occurrence if flow fraction is greater than maximum for the YorkCalc model, use recurring warning stats
    5392       90178 :         if (this->TowerModelType == ModelType::YorkCalcModel || this->TowerModelType == ModelType::YorkCalcUserDefined) {
    5393       45298 :             state.dataCondenserLoopTowers->towers(this->VSTower).PrintLGMessage = false;
    5394             :             //      Do not report error message in free convection regime
    5395       45298 :             if (this->airFlowRateRatio > this->MinimumVSAirFlowFrac) {
    5396       28778 :                 Real64 const FlowFraction = WaterFlowRateRatioCapped / this->airFlowRateRatio;
    5397             :                 //        Flow fractions greater than a MaxLiquidToGasRatio of 8 are not reliable using the YorkCalc model
    5398       28778 :                 if (FlowFraction > state.dataCondenserLoopTowers->towers(this->VSTower).MaxLiquidToGasRatio) {
    5399             :                     //          Report warnings only during actual simulation
    5400           0 :                     if (!state.dataGlobal->WarmupFlag) {
    5401           0 :                         state.dataCondenserLoopTowers->towers(this->VSTower).PrintLGMessage = true;
    5402           0 :                         state.dataCondenserLoopTowers->towers(this->VSTower).LGBuffer1 =
    5403           0 :                             format("{} \"{}\" - Liquid to gas ratio (L/G) is out of range at {:5.2F}.",
    5404           0 :                                    DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    5405           0 :                                    this->Name,
    5406           0 :                                    FlowFraction);
    5407           0 :                         state.dataCondenserLoopTowers->towers(this->VSTower).LGBuffer2 =
    5408           0 :                             format(" ...Valid maximum ratio = {:5.2F}. Occurrence info = {}, {} {}",
    5409           0 :                                    state.dataCondenserLoopTowers->towers(this->VSTower).MaxLiquidToGasRatio,
    5410           0 :                                    state.dataEnvrn->EnvironmentName,
    5411           0 :                                    state.dataEnvrn->CurMnDy,
    5412           0 :                                    General::CreateSysTimeIntervalString(state));
    5413             : 
    5414           0 :                         state.dataCondenserLoopTowers->towers(this->VSTower).LGLast = FlowFraction;
    5415             :                     }
    5416             :                 }
    5417             :             }
    5418             :         }
    5419             :     }
    5420             : 
    5421       80820 :     void CoolingTower::calculateMerkelVariableSpeedTower(EnergyPlusData &state, Real64 &MyLoad, bool RunFlag)
    5422             :     {
    5423             : 
    5424             :         // SUBROUTINE INFORMATION:
    5425             :         //       AUTHOR         B.Griffith
    5426             :         //       DATE WRITTEN   August 2013
    5427             :         //       MODIFIED       Jun. 2016, R Zhang, Applied the condenser supply water temperature sensor fault model
    5428             :         //                      Jul. 2016, R Zhang, Applied the cooling tower fouling fault model
    5429             : 
    5430             :         // PURPOSE OF THIS SUBROUTINE:
    5431             :         // Calculate variable speed tower model using Merkel's theory with UA adjustments developed by Scheier
    5432             : 
    5433             :         // METHODOLOGY EMPLOYED:
    5434             :         // Find a fan speed that operates the tower to meet MyLoad
    5435             : 
    5436             :         // SUBROUTINE PARAMETER DEFINITIONS:
    5437       80820 :         Real64 constexpr DesignWetBulb(25.56); // tower outdoor air entering wetbulb for design [C]
    5438       80820 :         int constexpr MaxIte(500);             // Maximum number of iterations for solver
    5439       80820 :         Real64 constexpr Acc(1.e-3);           // Accuracy of solver result
    5440             :         static constexpr std::string_view RoutineName("calculateMerkelVariableSpeedTower");
    5441             : 
    5442       80820 :         Real64 const CpWater = FluidProperties::GetSpecificHeatGlycol(state,
    5443       80820 :                                                                       state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    5444       80820 :                                                                       state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp,
    5445       80820 :                                                                       state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    5446             :                                                                       RoutineName);
    5447       80820 :         this->Qactual = 0.0;
    5448       80820 :         this->FanPower = 0.0;
    5449       80820 :         this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    5450             : 
    5451       80820 :         Real64 freeConvTowerUA = this->FreeConvTowerUA;
    5452       80820 :         Real64 highSpeedTowerUA = this->HighSpeedTowerUA;
    5453             : 
    5454             :         // If there is a fault of condenser SWT Sensor
    5455       80820 :         if (this->FaultyCondenserSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    5456           0 :             (!state.dataGlobal->KickOffSimulation)) {
    5457           0 :             int FaultIndex = this->FaultyCondenserSWTIndex;
    5458             :             // calculate the sensor offset using fault information
    5459           0 :             this->FaultyCondenserSWTOffset = state.dataFaultsMgr->FaultsCondenserSWTSensor(FaultIndex).CalFaultOffsetAct(state);
    5460             :         }
    5461             : 
    5462             :         // If there is a fault of cooling tower fouling
    5463       80820 :         if (this->FaultyTowerFoulingFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    5464           0 :             (!state.dataGlobal->KickOffSimulation)) {
    5465           0 :             int FaultIndex = this->FaultyTowerFoulingIndex;
    5466           0 :             Real64 FreeConvTowerUA_ff = this->FreeConvTowerUA;
    5467           0 :             Real64 HighSpeedTowerUA_ff = this->HighSpeedTowerUA;
    5468             : 
    5469             :             // calculate the Faulty Tower Fouling Factor using fault information
    5470           0 :             this->FaultyTowerFoulingFactor = state.dataFaultsMgr->FaultsTowerFouling(FaultIndex).CalFaultyTowerFoulingFactor(state);
    5471             : 
    5472             :             // update the tower UA values at faulty cases
    5473           0 :             freeConvTowerUA = FreeConvTowerUA_ff * this->FaultyTowerFoulingFactor;
    5474           0 :             highSpeedTowerUA = HighSpeedTowerUA_ff * this->FaultyTowerFoulingFactor;
    5475             :         }
    5476             : 
    5477       80820 :         Real64 WaterMassFlowRatePerCellMin = 0.0;
    5478             :         Real64 WaterMassFlowRatePerCellMax;
    5479             : 
    5480             :         // Added for multi-cell. Determine the number of cells operating
    5481       80820 :         int NumCellMin = 0;
    5482       80820 :         int NumCellMax = 0;
    5483             :         Real64 WaterMassFlowRatePerCell;
    5484             :         Real64 UAdesignPerCell;
    5485             :         Real64 AirFlowRatePerCell;
    5486       80820 :         if (this->DesWaterMassFlowRate > 0.0) {
    5487       80760 :             WaterMassFlowRatePerCellMin = this->DesWaterMassFlowRate * this->MinFracFlowRate / this->NumCell;
    5488       80760 :             WaterMassFlowRatePerCellMax = this->DesWaterMassFlowRate * this->MaxFracFlowRate / this->NumCell;
    5489             : 
    5490             :             // round it up to the nearest integer
    5491       80760 :             NumCellMin = min(int((this->WaterMassFlowRate / WaterMassFlowRatePerCellMax) + 0.9999), this->NumCell);
    5492       80760 :             NumCellMax = min(int((this->WaterMassFlowRate / WaterMassFlowRatePerCellMin) + 0.9999), this->NumCell);
    5493             :         }
    5494             : 
    5495             :         // cap min at 1
    5496       80820 :         if (NumCellMin <= 0) NumCellMin = 1;
    5497       80820 :         if (NumCellMax <= 0) NumCellMax = 1;
    5498             : 
    5499       80820 :         if (this->cellCtrl == CellCtrl::MinCell) {
    5500           0 :             this->NumCellOn = NumCellMin;
    5501             :         } else {
    5502       80820 :             this->NumCellOn = NumCellMax;
    5503             :         }
    5504             : 
    5505       80820 :         WaterMassFlowRatePerCell = this->WaterMassFlowRate / this->NumCellOn;
    5506             : 
    5507       80820 :         if ((std::abs(MyLoad) <= HVAC::SmallLoad) || !RunFlag) {
    5508             :             // tower doesn't need to do anything
    5509       50654 :             this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    5510       50654 :             this->FanPower = 0.0;
    5511       50654 :             this->airFlowRateRatio = 0.0;
    5512       50654 :             this->Qactual = 0.0;
    5513       50654 :             CalcBasinHeaterPower(
    5514       50654 :                 state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    5515       50654 :             return;
    5516       30166 :         } else if (this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance || (MyLoad > HVAC::SmallLoad)) {
    5517             :             // for multiple cells, we assume that it's a common basin
    5518           0 :             CalcBasinHeaterPower(
    5519           0 :                 state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    5520           0 :             return;
    5521             :         }
    5522             : 
    5523             :         // first find free convection cooling rate
    5524       30166 :         UAdesignPerCell = freeConvTowerUA / this->NumCell;
    5525       30166 :         AirFlowRatePerCell = this->FreeConvAirFlowRate / this->NumCell;
    5526       30166 :         this->WaterMassFlowRate = state.dataLoopNodes->Node(this->WaterInletNodeNum).MassFlowRate;
    5527       30166 :         Real64 OutletWaterTempOFF = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRatePerCell, UAdesignPerCell);
    5528             : 
    5529       30166 :         Real64 FreeConvQdot = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - OutletWaterTempOFF);
    5530       30166 :         this->FanPower = 0.0;
    5531             : 
    5532       30166 :         if (std::abs(MyLoad) <= FreeConvQdot) { // can meet load with free convection and fan off
    5533             : 
    5534          78 :             this->OutletWaterTemp = OutletWaterTempOFF;
    5535          78 :             this->airFlowRateRatio = 0.0;
    5536          78 :             this->Qactual = FreeConvQdot;
    5537          78 :             CalcBasinHeaterPower(
    5538          78 :                 state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    5539             : 
    5540          78 :             return;
    5541             :         }
    5542             : 
    5543             :         // next find full fan speed cooling rate
    5544       30088 :         UAdesignPerCell = highSpeedTowerUA / this->NumCell;
    5545       30088 :         AirFlowRatePerCell = this->HighSpeedAirFlowRate / this->NumCell;
    5546       30088 :         this->airFlowRateRatio = 1.0;
    5547       30088 :         Real64 WaterFlowRateRatio = WaterMassFlowRatePerCell / this->DesWaterMassFlowRatePerCell;
    5548       30088 :         Real64 UAwetbulbAdjFac = Curve::CurveValue(state, this->UAModFuncWetBulbDiffCurvePtr, (DesignWetBulb - this->AirWetBulb));
    5549       30088 :         Real64 UAairflowAdjFac = Curve::CurveValue(state, this->UAModFuncAirFlowRatioCurvePtr, this->airFlowRateRatio);
    5550       30088 :         Real64 UAwaterflowAdjFac = Curve::CurveValue(state, this->UAModFuncWaterFlowRatioCurvePtr, WaterFlowRateRatio);
    5551       30088 :         Real64 UAadjustedPerCell = UAdesignPerCell * UAwetbulbAdjFac * UAairflowAdjFac * UAwaterflowAdjFac;
    5552       30088 :         this->OutletWaterTemp = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRatePerCell, UAadjustedPerCell);
    5553             :         Real64 FullSpeedFanQdot =
    5554       30088 :             this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    5555       30088 :         Real64 FanPowerAdjustFac = 0.0;
    5556       30088 :         if (FullSpeedFanQdot <= std::abs(MyLoad)) { // full speed is what we want.
    5557             : 
    5558       29130 :             if ((FullSpeedFanQdot + HVAC::SmallLoad) < std::abs(MyLoad) && (this->NumCellOn < this->NumCell) &&
    5559           0 :                 ((this->WaterMassFlowRate / (this->NumCellOn + 1)) >= WaterMassFlowRatePerCellMin)) {
    5560             :                 // If full fan and not meeting setpoint, then increase number of cells until all are used or load is satisfied
    5561           0 :                 bool IncrNumCellFlag = true; // set value to true to enter in the loop
    5562           0 :                 while (IncrNumCellFlag) {
    5563           0 :                     ++this->NumCellOn;
    5564           0 :                     WaterMassFlowRatePerCell = this->WaterMassFlowRate / this->NumCellOn;
    5565           0 :                     WaterFlowRateRatio = WaterMassFlowRatePerCell / this->DesWaterMassFlowRatePerCell;
    5566           0 :                     UAwaterflowAdjFac = Curve::CurveValue(state, this->UAModFuncWaterFlowRatioCurvePtr, WaterFlowRateRatio);
    5567           0 :                     UAadjustedPerCell = UAdesignPerCell * UAwetbulbAdjFac * UAairflowAdjFac * UAwaterflowAdjFac;
    5568           0 :                     this->OutletWaterTemp =
    5569           0 :                         this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRatePerCell, UAadjustedPerCell);
    5570           0 :                     IncrNumCellFlag = (FullSpeedFanQdot + HVAC::SmallLoad) < std::abs(MyLoad) && (this->NumCellOn < this->NumCell) &&
    5571           0 :                                       ((this->WaterMassFlowRate / (this->NumCellOn + 1)) >= WaterMassFlowRatePerCellMin);
    5572             :                 }
    5573           0 :                 FullSpeedFanQdot =
    5574           0 :                     this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    5575             :             }
    5576       29130 :             this->Qactual = FullSpeedFanQdot;
    5577       29130 :             CalcBasinHeaterPower(
    5578       29130 :                 state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    5579             :             // now calculate fan power
    5580       29130 :             FanPowerAdjustFac = Curve::CurveValue(state, this->FanPowerfAirFlowCurve, this->airFlowRateRatio);
    5581       29130 :             this->FanPower = this->HighSpeedFanPower * FanPowerAdjustFac * this->NumCellOn / this->NumCell;
    5582             : 
    5583       29130 :             return;
    5584             :         }
    5585             : 
    5586             :         // next find minimum air flow ratio cooling rate
    5587         958 :         this->airFlowRateRatio = this->MinimumVSAirFlowFrac;
    5588         958 :         AirFlowRatePerCell = this->airFlowRateRatio * this->HighSpeedAirFlowRate / this->NumCell;
    5589         958 :         UAairflowAdjFac = Curve::CurveValue(state, this->UAModFuncAirFlowRatioCurvePtr, this->airFlowRateRatio);
    5590         958 :         UAadjustedPerCell = UAdesignPerCell * UAwetbulbAdjFac * UAairflowAdjFac * UAwaterflowAdjFac;
    5591         958 :         this->OutletWaterTemp = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRatePerCell, UAadjustedPerCell);
    5592             :         Real64 MinSpeedFanQdot =
    5593         958 :             this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    5594             : 
    5595         958 :         if (std::abs(MyLoad) <= MinSpeedFanQdot) { // min fan speed already exceeds load)
    5596         164 :             this->Qactual = MinSpeedFanQdot;
    5597         164 :             CalcBasinHeaterPower(
    5598         164 :                 state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    5599             :             // now calculate fan power
    5600         164 :             FanPowerAdjustFac = Curve::CurveValue(state, this->FanPowerfAirFlowCurve, this->airFlowRateRatio);
    5601         164 :             this->FanPower = this->HighSpeedFanPower * FanPowerAdjustFac * this->NumCellOn / this->NumCell;
    5602         164 :             return;
    5603             :         }
    5604             : 
    5605         794 :         if ((MinSpeedFanQdot < std::abs(MyLoad)) && (std::abs(MyLoad) < FullSpeedFanQdot)) {
    5606             :             // load can be refined by modulating fan speed, call regula-falsi
    5607        8034 :             auto f = [&state, this, MyLoad, WaterMassFlowRatePerCell, UAdesignPerCell, UAwetbulbAdjFac, UAwaterflowAdjFac, CpWater](
    5608       36200 :                          Real64 airFlowRateRatioLocal) {
    5609        7240 :                 Real64 const AirFlowRatePerCell = airFlowRateRatioLocal * this->HighSpeedAirFlowRate / this->NumCell;
    5610        7240 :                 Real64 const UAairflowAdjFac = Curve::CurveValue(state, this->UAModFuncAirFlowRatioCurvePtr, airFlowRateRatioLocal);
    5611        7240 :                 Real64 const UAadjustedPerCell = UAdesignPerCell * UAwetbulbAdjFac * UAairflowAdjFac * UAwaterflowAdjFac;
    5612             :                 Real64 OutletWaterTempTrial =
    5613        7240 :                     this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRatePerCell, UAadjustedPerCell);
    5614             :                 Real64 const Qdot =
    5615        7240 :                     this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - OutletWaterTempTrial);
    5616        7240 :                 return std::abs(MyLoad) - Qdot;
    5617         794 :             };
    5618         794 :             int SolFla = 0;
    5619         794 :             General::SolveRoot(state, Acc, MaxIte, SolFla, this->airFlowRateRatio, f, this->MinimumVSAirFlowFrac, 1.0);
    5620             : 
    5621         794 :             if (SolFla == -1) {
    5622           0 :                 if (!state.dataGlobal->WarmupFlag) {
    5623           0 :                     if (this->VSMerkelAFRErrorIter < 1) {
    5624           0 :                         ++this->VSMerkelAFRErrorIter;
    5625           0 :                         ShowWarningError(state,
    5626           0 :                                          format("{} - Iteration limit exceeded calculating variable speed fan ratio for unit = {}",
    5627             :                                                 cCoolingTower_VariableSpeedMerkel,
    5628           0 :                                                 this->Name));
    5629           0 :                         ShowContinueError(state,
    5630           0 :                                           format("Estimated air flow ratio  = {:.4R}",
    5631           0 :                                                  (std::abs(MyLoad) - MinSpeedFanQdot) / (FullSpeedFanQdot - MinSpeedFanQdot)));
    5632           0 :                         ShowContinueError(state, format("Calculated air flow ratio = {:.4R}", this->airFlowRateRatio));
    5633           0 :                         ShowContinueErrorTimeStamp(state,
    5634             :                                                    "The calculated air flow ratio will be used and the simulation continues. Occurrence info:");
    5635             :                     }
    5636           0 :                     ShowRecurringWarningErrorAtEnd(
    5637             :                         state,
    5638           0 :                         cCoolingTower_VariableSpeedMerkel + " \"" + this->Name +
    5639             :                             "\" - Iteration limit exceeded calculating air flow ratio error continues. air flow ratio statistics follow.",
    5640           0 :                         this->VSMerkelAFRErrorIterIndex,
    5641           0 :                         this->airFlowRateRatio,
    5642           0 :                         this->airFlowRateRatio);
    5643             :                 }
    5644         794 :             } else if (SolFla == -2) {
    5645           0 :                 this->airFlowRateRatio = (std::abs(MyLoad) - MinSpeedFanQdot) / (FullSpeedFanQdot - MinSpeedFanQdot);
    5646           0 :                 if (!state.dataGlobal->WarmupFlag) {
    5647           0 :                     if (this->VSMerkelAFRErrorFail < 1) {
    5648           0 :                         ++this->VSMerkelAFRErrorFail;
    5649           0 :                         ShowWarningError(state,
    5650           0 :                                          format("{} - solver failed calculating variable speed fan ratio for unit = {}",
    5651             :                                                 cCoolingTower_VariableSpeedMerkel,
    5652           0 :                                                 this->Name));
    5653           0 :                         ShowContinueError(state, format("Estimated air flow ratio  = {:.4R}", this->airFlowRateRatio));
    5654           0 :                         ShowContinueErrorTimeStamp(state, "The estimated air flow ratio will be used and the simulation continues. Occurrence info:");
    5655             :                     }
    5656           0 :                     ShowRecurringWarningErrorAtEnd(
    5657             :                         state,
    5658           0 :                         cCoolingTower_VariableSpeedMerkel + " \"" + this->Name +
    5659             :                             "\" - solver failed calculating air flow ratio error continues. air flow ratio statistics follow.",
    5660           0 :                         this->VSMerkelAFRErrorFailIndex,
    5661           0 :                         this->airFlowRateRatio,
    5662           0 :                         this->airFlowRateRatio);
    5663             :                 }
    5664             :             }
    5665             : 
    5666             :             // now rerun to get peformance with AirFlowRateRatio
    5667         794 :             AirFlowRatePerCell = this->airFlowRateRatio * this->HighSpeedAirFlowRate / this->NumCell;
    5668             : 
    5669         794 :             UAairflowAdjFac = Curve::CurveValue(state, this->UAModFuncAirFlowRatioCurvePtr, this->airFlowRateRatio);
    5670         794 :             UAadjustedPerCell = UAdesignPerCell * UAwetbulbAdjFac * UAairflowAdjFac * UAwaterflowAdjFac;
    5671             : 
    5672         794 :             this->OutletWaterTemp = this->calculateSimpleTowerOutletTemp(state, WaterMassFlowRatePerCell, AirFlowRatePerCell, UAadjustedPerCell);
    5673         794 :             this->Qactual = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    5674         794 :             CalcBasinHeaterPower(
    5675         794 :                 state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    5676             : 
    5677             :             // now calculate fan power
    5678         794 :             FanPowerAdjustFac = Curve::CurveValue(state, this->FanPowerfAirFlowCurve, this->airFlowRateRatio);
    5679         794 :             this->FanPower = this->HighSpeedFanPower * FanPowerAdjustFac * this->NumCellOn / this->NumCell;
    5680             :         }
    5681             :     }
    5682             : 
    5683     7210763 :     Real64 CoolingTower::calculateSimpleTowerOutletTemp(EnergyPlusData &state,
    5684             :                                                         Real64 const waterMassFlowRate,
    5685             :                                                         Real64 const AirFlowRate,
    5686             :                                                         Real64 const UAdesign)
    5687             :     {
    5688             : 
    5689             :         // SUBROUTINE INFORMATION:
    5690             :         //       AUTHOR         Dan Fisher
    5691             :         //       DATE WRITTEN   Sept. 1998
    5692             :         //       RE-ENGINEERED  Shirey, Raustad, Jan 2001
    5693             : 
    5694             :         // PURPOSE OF THIS SUBROUTINE:
    5695             :         // See purpose for Single Speed or Two Speed tower model
    5696             : 
    5697             :         // METHODOLOGY EMPLOYED:
    5698             :         // See methodology for Single Speed or Two Speed tower model
    5699             : 
    5700             :         // REFERENCES:
    5701             :         // Merkel, F. 1925.  Verduftungskuhlung. VDI Forschungsarbeiten, Nr 275, Berlin.
    5702             :         // ASHRAE     1999.  HVAC1KIT: A Toolkit for Primary HVAC System Energy Calculations.
    5703             : 
    5704             :         // SUBROUTINE PARAMETER DEFINITIONS:
    5705             :         static constexpr std::string_view RoutineName("calculateSimpleTowerOutletTemp");
    5706             : 
    5707             :         // initialize some local variables
    5708     7210763 :         Real64 QactualLocal = 0.0; // Actual heat transfer rate between tower water and air [W]
    5709             : 
    5710             :         // set local tower inlet and outlet temperature variables
    5711     7210763 :         this->InletWaterTemp = this->WaterTemp;
    5712     7210763 :         Real64 OutletWaterTempLocal = this->InletWaterTemp;
    5713     7210763 :         Real64 InletAirTemp = this->AirTemp;       // Dry-bulb temperature of air entering the tower [C]
    5714     7210763 :         Real64 InletAirWetBulb = this->AirWetBulb; // Wetbulb temp of entering moist air [C]
    5715             : 
    5716     7210763 :         if (UAdesign == 0.0) return OutletWaterTempLocal;
    5717             : 
    5718             :         // set water and air properties
    5719     5125254 :         Real64 AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state, this->AirPress, InletAirTemp, this->AirHumRat); // Density of air [kg/m3]
    5720     5125254 :         Real64 AirMassFlowRate = AirFlowRate * AirDensity;                                                           // Mass flow rate of air [kg/s]
    5721     5125254 :         Real64 CpAir = Psychrometrics::PsyCpAirFnW(this->AirHumRat);                                                 // Heat capacity of air [J/kg/K]
    5722     5125254 :         Real64 CpWater = FluidProperties::GetSpecificHeatGlycol(state,
    5723     5125254 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    5724             :                                                                 this->WaterTemp,
    5725     5125254 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    5726             :                                                                 RoutineName); // Heat capacity of water [J/kg/K]
    5727             :         Real64 InletAirEnthalpy =
    5728     5125254 :             Psychrometrics::PsyHFnTdbRhPb(state, this->AirWetBulb, 1.0, this->AirPress); // Enthalpy of entering moist air [J/kg]
    5729             : 
    5730             :         // initialize exiting wet bulb temperature before iterating on final solution
    5731     5125254 :         Real64 OutletAirWetBulb = InletAirWetBulb + 6.0; // Wetbulb temp of exiting moist air [C]
    5732             : 
    5733             :         // Calculate mass flow rates
    5734     5125254 :         if (waterMassFlowRate <= 0.0) {
    5735           0 :             OutletWaterTempLocal = this->InletWaterTemp;
    5736           0 :             return OutletWaterTempLocal;
    5737             :         }
    5738             : 
    5739     5125254 :         Real64 MdotCpWater = waterMassFlowRate * CpWater; // Water mass flow rate times the heat capacity [W/K]
    5740             : 
    5741     5125254 :         int Iter = 0;
    5742             :         Real64 OutletAirEnthalpy;                   // Enthalpy of exiting moist air [J/kg]
    5743     5125254 :         Real64 WetBulbError = 1.0;                  // Calculated error for exiting wet-bulb temperature between iterations [delta K/K]
    5744     5125254 :         Real64 DeltaTwb = 1.0;                      // Absolute value of difference between inlet and outlet air wet-bulb temp [C]
    5745             :         Real64 OutletAirWetBulbLast;                // temporary Wetbulb temp of exiting moist air [C]
    5746     5125254 :         int constexpr IterMax(50);                  // Maximum number of iterations allowed
    5747     5125254 :         Real64 constexpr WetBulbTolerance(0.00001); // Maximum error for exiting wet-bulb temperature between iterations [delta K/K]
    5748     5125254 :         Real64 constexpr DeltaTwbTolerance(0.001);  // Maximum error (tolerance) in DeltaTwb for iteration convergence [C]
    5749    20232999 :         while ((WetBulbError > WetBulbTolerance) && (Iter <= IterMax) && (DeltaTwb > DeltaTwbTolerance)) {
    5750    15107745 :             ++Iter;
    5751             :             //        OutletAirEnthalpy = PsyHFnTdbRhPb(OutletAirWetBulb,1.0,OutBaroPress)
    5752    15107745 :             OutletAirEnthalpy = Psychrometrics::PsyHFnTdbRhPb(state, OutletAirWetBulb, 1.0, this->AirPress);
    5753             :             // calculate the airside specific heat and capacity
    5754    15107745 :             Real64 const CpAirside =
    5755    15107745 :                 (OutletAirEnthalpy - InletAirEnthalpy) /
    5756    15107745 :                 (OutletAirWetBulb - InletAirWetBulb);               // Delta enthalpy of the tower air divides by delta air wet-bulb temp [J/kg/K]
    5757    15107745 :             Real64 const AirCapacity = AirMassFlowRate * CpAirside; // MdotCp of air through the tower
    5758             :             // calculate the minimum to maximum capacity ratios of airside and waterside
    5759    15107745 :             Real64 const CapacityRatioMin = min(AirCapacity, MdotCpWater);    // Minimum capacity of airside and waterside
    5760    15107745 :             Real64 const CapacityRatioMax = max(AirCapacity, MdotCpWater);    // Maximum capacity of airside and waterside
    5761    15107745 :             Real64 const CapacityRatio = CapacityRatioMin / CapacityRatioMax; // Ratio of minimum to maximum capacity
    5762             :             // Calculate heat transfer coefficient and number of transfer units (NTU)
    5763    15107745 :             Real64 const UAactual = UAdesign * CpAirside / CpAir;        // UA value at actual conditions [W/C]
    5764    15107745 :             Real64 const NumTransferUnits = UAactual / CapacityRatioMin; // Number of transfer Units [NTU]
    5765             :             // calculate heat exchanger effectiveness
    5766             :             Real64 effectiveness; // Effectiveness of the heat exchanger [-]
    5767    15107745 :             if (CapacityRatio <= 0.995) {
    5768    15097680 :                 Real64 Exponent = NumTransferUnits * (1.0 - CapacityRatio);
    5769    15097680 :                 if (Exponent >= 700.0) {
    5770           0 :                     effectiveness = NumTransferUnits / (1.0 + NumTransferUnits);
    5771             :                 } else {
    5772    15097680 :                     effectiveness = (1.0 - std::exp(-1.0 * NumTransferUnits * (1.0 - CapacityRatio))) /
    5773    15097680 :                                     (1.0 - CapacityRatio * std::exp(-1.0 * NumTransferUnits * (1.0 - CapacityRatio)));
    5774             :                 }
    5775             :             } else {
    5776       10065 :                 effectiveness = NumTransferUnits / (1.0 + NumTransferUnits);
    5777             :             }
    5778             :             // calculate water to air heat transfer and store last exiting WB temp of air
    5779    15107745 :             QactualLocal = effectiveness * CapacityRatioMin * (this->InletWaterTemp - InletAirWetBulb);
    5780    15107745 :             OutletAirWetBulbLast = OutletAirWetBulb;
    5781             :             // calculate new exiting wet bulb temperature of airstream
    5782    15107745 :             OutletAirWetBulb = InletAirWetBulb + QactualLocal / AirCapacity;
    5783             :             // Check error tolerance and exit if satisfied
    5784    15107745 :             DeltaTwb = std::abs(OutletAirWetBulb - InletAirWetBulb);
    5785             :             // Add KelvinConv to denominator below convert OutletAirWetBulbLast to Kelvin to avoid divide by zero.
    5786             :             // Wet bulb error units are delta K/K
    5787    15107745 :             WetBulbError = std::abs((OutletAirWetBulb - OutletAirWetBulbLast) / (OutletAirWetBulbLast + Constant::Kelvin));
    5788             :         }
    5789             : 
    5790     5125254 :         if (QactualLocal >= 0.0) {
    5791     5125174 :             OutletWaterTempLocal = this->InletWaterTemp - QactualLocal / MdotCpWater;
    5792             :         } else {
    5793          80 :             OutletWaterTempLocal = this->InletWaterTemp;
    5794             :         }
    5795     5125254 :         return OutletWaterTempLocal;
    5796             :     }
    5797             : 
    5798      171742 :     Real64 CoolingTower::calculateVariableTowerOutletTemp(EnergyPlusData &state,
    5799             :                                                           Real64 const WaterFlowRateRatio,    // current water flow rate ratio (capped if applicable)
    5800             :                                                           Real64 const airFlowRateRatioLocal, // current air flow rate ratio
    5801             :                                                           Real64 const Twb // current inlet air wet-bulb temperature (C, capped if applicable)
    5802             :     )
    5803             :     {
    5804             : 
    5805             :         // SUBROUTINE INFORMATION:
    5806             :         //       AUTHOR         Richard Raustad, FSEC
    5807             :         //       DATE WRITTEN   Feb. 2005
    5808             : 
    5809             :         // PURPOSE OF THIS SUBROUTINE:
    5810             :         // To calculate the leaving water temperature of the variable speed cooling tower.
    5811             : 
    5812             :         // METHODOLOGY EMPLOYED:
    5813             :         // The range temperature is varied to determine balance point where model output (Tapproach),
    5814             :         // range temperature and inlet air wet-bulb temperature show a balance as:
    5815             :         // Twb + Tapproach + Trange = Node(WaterInletNode)%Temp
    5816             : 
    5817             :         // REFERENCES:
    5818             :         // Benton, D.J., Bowmand, C.F., Hydeman, M., Miller, P.,
    5819             :         // "An Improved Cooling Tower Algorithm for the CoolToolsTM Simulation Model".
    5820             :         // ASHRAE Transactions 2002, V. 108, Pt. 1.
    5821             :         // York International Corporation, "YORKcalcTM Software, Chiller-Plant Energy-Estimating Program",
    5822             :         // Form 160.00-SG2 (0502). 2002.
    5823             : 
    5824             :         // SUBROUTINE PARAMETER DEFINITIONS:
    5825      171742 :         int constexpr MaxIte(500);    // Maximum number of iterations
    5826      171742 :         Real64 constexpr Acc(0.0001); // Accuracy of result
    5827             : 
    5828             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5829      171742 :         Real64 constexpr VSTowerMaxRangeTemp(22.2222); // set VS cooling tower range maximum value used for solver
    5830             : 
    5831             :         // determine tower outlet water temperature
    5832             :         Real64 Tr; // range temperature which results in an energy balance
    5833     3105424 :         auto f = [&state, this, WaterFlowRateRatio, airFlowRateRatioLocal, Twb](Real64 Trange) {
    5834             :             // call model to determine approach temperature given other independent variables (range temp is being varied to find balance)
    5835     1552712 :             Real64 Tapproach = this->calculateVariableSpeedApproach(state, WaterFlowRateRatio, airFlowRateRatioLocal, Twb, Trange);
    5836             :             // calculate residual based on a balance where Twb + Ta + Tr = Inlet Water Temp
    5837     1552712 :             return (Twb + Tapproach + Trange) - this->WaterTemp;
    5838      171742 :         };
    5839      171742 :         int SolFla = 0;
    5840      171742 :         General::SolveRoot(state, Acc, MaxIte, SolFla, Tr, f, 0.001, max(this->MaxRangeTemp, VSTowerMaxRangeTemp));
    5841             : 
    5842             :         // calculate outlet temperature
    5843      171742 :         Real64 outletWaterTempLocal = this->WaterTemp - min(Tr, this->MaxRangeTemp);
    5844             : 
    5845      171742 :         if (SolFla == -1) {
    5846           0 :             ShowSevereError(state, "Iteration limit exceeded in calculating tower nominal capacity at minimum air flow ratio");
    5847           0 :             ShowContinueError(
    5848             :                 state,
    5849             :                 "Design inlet air wet-bulb or approach temperature must be modified to achieve an acceptable range at the minimum air flow rate");
    5850           0 :             ShowContinueError(state, format("Cooling tower simulation failed to converge for tower {}", this->Name));
    5851      171742 :         } else if (SolFla == -2) {
    5852             :             // bad starting value means that solution corresponds to a range that is beyond
    5853             :             // the bounds of the model; The maximum range is used here
    5854         403 :             outletWaterTempLocal = this->WaterTemp - this->MaxRangeTemp;
    5855         403 :             ++this->VSErrorCountTRCalc;
    5856         403 :             if (this->VSErrorCountTRCalc < 2) {
    5857          18 :                 ShowWarningError(
    5858             :                     state,
    5859          18 :                     format("The range for the cooling tower {} likely exceeds the bounds of the model. The maximum range of the model is used {}.",
    5860           9 :                            this->Name,
    5861           9 :                            this->MaxRangeTemp));
    5862          18 :                 ShowContinueError(state,
    5863          18 :                                   format(" ... Occurrence info = {}, {} {}",
    5864           9 :                                          state.dataEnvrn->EnvironmentName,
    5865           9 :                                          state.dataEnvrn->CurMnDy,
    5866          18 :                                          General::CreateSysTimeIntervalString(state)));
    5867             :             } else {
    5868        1182 :                 ShowRecurringWarningErrorAtEnd(
    5869             :                     state,
    5870         788 :                     format("The range for the cooling tower {} likely exceeds the bounds of the model. The maximum range of the model is used {}",
    5871         394 :                            this->Name,
    5872         394 :                            this->MaxRangeTemp),
    5873         394 :                     this->ErrIndexTRCalc);
    5874             :             }
    5875             :         }
    5876      171742 :         return outletWaterTempLocal;
    5877             :     }
    5878             : 
    5879     1844334 :     Real64 CoolingTower::calculateVariableSpeedApproach(EnergyPlusData &state,
    5880             :                                                         Real64 const PctWaterFlow,      // Water flow ratio of cooling tower
    5881             :                                                         Real64 const airFlowRatioLocal, // Air flow ratio of cooling tower
    5882             :                                                         Real64 const Twb,               // Inlet air wet-bulb temperature [C]
    5883             :                                                         Real64 const Tr // Cooling tower range (outlet water temp minus inlet air wet-bulb temp) [C]
    5884             :     )
    5885             :     {
    5886             :         // FUNCTION INFORMATION:
    5887             :         //       AUTHOR         Richard Raustad, FSEC
    5888             :         //       DATE WRITTEN   Feb. 2005
    5889             : 
    5890             :         // PURPOSE OF THIS FUNCTION:
    5891             :         // Calculate tower approach temperature (e.g. outlet water temp minus inlet air wet-bulb temp)
    5892             :         // given air flow ratio, water flow ratio, inlet air wet-bulb temp, and tower range.
    5893             : 
    5894             :         // METHODOLOGY EMPLOYED:
    5895             :         // Calculation method used empirical models from CoolTools or York to determine performance
    5896             :         // of variable speed (variable air flow rate) cooling towers.
    5897             : 
    5898             :         // REFERENCES:
    5899             :         // Benton, D.J., Bowmand, C.F., Hydeman, M., Miller, P.,
    5900             :         // "An Improved Cooling Tower Algorithm for the CoolToolsTM Simulation Model".
    5901             :         // ASHRAE Transactions 2002, V. 108, Pt. 1.
    5902             :         // York International Corporation, "YORKcalcTM Software, Chiller-Plant Energy-Estimating Program",
    5903             :         // Form 160.00-SG2 (0502). 2002.
    5904             : 
    5905     1844334 :         auto &tower = state.dataCondenserLoopTowers->towers(this->VSTower);
    5906     1844334 :         if (this->TowerModelType == ModelType::YorkCalcModel || this->TowerModelType == ModelType::YorkCalcUserDefined) {
    5907      958365 :             Real64 PctAirFlow = airFlowRatioLocal;
    5908      958365 :             Real64 FlowFactor = PctWaterFlow / PctAirFlow;
    5909      958365 :             return tower.Coeff[0] + tower.Coeff[1] * Twb + tower.Coeff[2] * Twb * Twb + tower.Coeff[3] * Tr + tower.Coeff[4] * Twb * Tr +
    5910      958365 :                    tower.Coeff[5] * Twb * Twb * Tr + tower.Coeff[6] * Tr * Tr + tower.Coeff[7] * Twb * Tr * Tr +
    5911      958365 :                    tower.Coeff[8] * Twb * Twb * Tr * Tr + tower.Coeff[9] * FlowFactor + tower.Coeff[10] * Twb * FlowFactor +
    5912      958365 :                    tower.Coeff[11] * Twb * Twb * FlowFactor + tower.Coeff[12] * Tr * FlowFactor + tower.Coeff[13] * Twb * Tr * FlowFactor +
    5913      958365 :                    tower.Coeff[14] * Twb * Twb * Tr * FlowFactor + tower.Coeff[15] * Tr * Tr * FlowFactor +
    5914      958365 :                    tower.Coeff[16] * Twb * Tr * Tr * FlowFactor + tower.Coeff[17] * Twb * Twb * Tr * Tr * FlowFactor +
    5915      958365 :                    tower.Coeff[18] * FlowFactor * FlowFactor + tower.Coeff[19] * Twb * FlowFactor * FlowFactor +
    5916      958365 :                    tower.Coeff[20] * Twb * Twb * FlowFactor * FlowFactor + tower.Coeff[21] * Tr * FlowFactor * FlowFactor +
    5917      958365 :                    tower.Coeff[22] * Twb * Tr * FlowFactor * FlowFactor + tower.Coeff[23] * Twb * Twb * Tr * FlowFactor * FlowFactor +
    5918      958365 :                    tower.Coeff[24] * Tr * Tr * FlowFactor * FlowFactor + tower.Coeff[25] * Twb * Tr * Tr * FlowFactor * FlowFactor +
    5919      958365 :                    tower.Coeff[26] * Twb * Twb * Tr * Tr * FlowFactor * FlowFactor;
    5920             : 
    5921             :         } else { // empirical model is CoolTools format
    5922             :             //     the CoolTools model actually uses PctFanPower = AirFlowRatio^3 as an input to the model
    5923      885969 :             Real64 PctAirFlow = pow_3(airFlowRatioLocal);
    5924      885969 :             return tower.Coeff[0] + tower.Coeff[1] * PctAirFlow + tower.Coeff[2] * PctAirFlow * PctAirFlow +
    5925      885969 :                    tower.Coeff[3] * PctAirFlow * PctAirFlow * PctAirFlow + tower.Coeff[4] * PctWaterFlow +
    5926      885969 :                    tower.Coeff[5] * PctAirFlow * PctWaterFlow + tower.Coeff[6] * PctAirFlow * PctAirFlow * PctWaterFlow +
    5927      885969 :                    tower.Coeff[7] * PctWaterFlow * PctWaterFlow + tower.Coeff[8] * PctAirFlow * PctWaterFlow * PctWaterFlow +
    5928      885969 :                    tower.Coeff[9] * PctWaterFlow * PctWaterFlow * PctWaterFlow + tower.Coeff[10] * Twb + tower.Coeff[11] * PctAirFlow * Twb +
    5929      885969 :                    tower.Coeff[12] * PctAirFlow * PctAirFlow * Twb + tower.Coeff[13] * PctWaterFlow * Twb +
    5930      885969 :                    tower.Coeff[14] * PctAirFlow * PctWaterFlow * Twb + tower.Coeff[15] * PctWaterFlow * PctWaterFlow * Twb +
    5931      885969 :                    tower.Coeff[16] * Twb * Twb + tower.Coeff[17] * PctAirFlow * Twb * Twb + tower.Coeff[18] * PctWaterFlow * Twb * Twb +
    5932      885969 :                    tower.Coeff[19] * Twb * Twb * Twb + tower.Coeff[20] * Tr + tower.Coeff[21] * PctAirFlow * Tr +
    5933      885969 :                    tower.Coeff[22] * PctAirFlow * PctAirFlow * Tr + tower.Coeff[23] * PctWaterFlow * Tr +
    5934      885969 :                    tower.Coeff[24] * PctAirFlow * PctWaterFlow * Tr + tower.Coeff[25] * PctWaterFlow * PctWaterFlow * Tr +
    5935      885969 :                    tower.Coeff[26] * Twb * Tr + tower.Coeff[27] * PctAirFlow * Twb * Tr + tower.Coeff[28] * PctWaterFlow * Twb * Tr +
    5936      885969 :                    tower.Coeff[29] * Twb * Twb * Tr + tower.Coeff[30] * Tr * Tr + tower.Coeff[31] * PctAirFlow * Tr * Tr +
    5937      885969 :                    tower.Coeff[32] * PctWaterFlow * Tr * Tr + tower.Coeff[33] * Twb * Tr * Tr + tower.Coeff[34] * Tr * Tr * Tr;
    5938             :         }
    5939             :     }
    5940             : 
    5941       96574 :     void CoolingTower::checkModelBounds(EnergyPlusData &state,
    5942             :                                         Real64 Twb,                      // current inlet air wet-bulb temperature (C)
    5943             :                                         Real64 Tr,                       // requested range temperature for current time step (C)
    5944             :                                         Real64 Ta,                       // requested approach temperature for current time step (C)
    5945             :                                         Real64 WaterFlowRateRatio,       // current water flow rate ratio at water inlet node
    5946             :                                         Real64 &TwbCapped,               // bounded value of inlet air wet-bulb temperature (C)
    5947             :                                         Real64 &TrCapped,                // bounded value of range temperature (C)
    5948             :                                         Real64 &TaCapped,                // bounded value of approach temperature (C)
    5949             :                                         Real64 &WaterFlowRateRatioCapped // bounded value of water flow rate ratio
    5950             :     )
    5951             :     {
    5952             : 
    5953             :         // SUBROUTINE INFORMATION:
    5954             :         //       AUTHOR         Richard Raustad
    5955             :         //       DATE WRITTEN   Feb 2005
    5956             : 
    5957             :         // PURPOSE OF THIS SUBROUTINE:
    5958             :         // To verify that the empirical model's independent variables are within the limits used during the
    5959             :         // development of the empirical model.
    5960             : 
    5961             :         // METHODOLOGY EMPLOYED:
    5962             :         // The empirical models used for simulating a variable speed cooling tower are based on a limited data set.
    5963             :         // Extrapolation of empirical models can cause instability and the independent variables may need to be limited.
    5964             :         // The range of each independent variable is provided either by the CoolTools or York model limits, or
    5965             :         // specified by the user if the model is User Defined (in either the CoolTools or York model format).
    5966             :         // These limits are tested in this subroutine each time step and returned for use by the calling routine.
    5967             :         // The independent variables capped here may or may not be passed to the empirical model in the calling
    5968             :         // routine depending on their use.
    5969             : 
    5970             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5971       96574 :         std::string OutputChar;   // character string for warning messages
    5972       96574 :         std::string OutputCharLo; // character string for warning messages
    5973       96574 :         std::string OutputCharHi; // character string for warning messages
    5974       96574 :         std::string TrimValue;    // character string for warning messages
    5975             :         // current end time is compared with last to see if time step changed
    5976             : 
    5977             :         //   initialize capped variables in case independent variables are in bounds
    5978       96574 :         TwbCapped = Twb;
    5979       96574 :         TrCapped = Tr;
    5980       96574 :         TaCapped = Ta;
    5981       96574 :         WaterFlowRateRatioCapped = WaterFlowRateRatio;
    5982             : 
    5983             :         //   calculate end time of current time step
    5984       96574 :         Real64 CurrentEndTime = state.dataGlobal->CurrentTime + state.dataHVACGlobal->SysTimeElapsed;
    5985             : 
    5986             :         //   Print warning messages only when valid and only for the first ocurrance. Let summary provide statistics.
    5987             :         //   Wait for next time step to print warnings. If simulation iterates, print out
    5988             :         //   the warning for the last iteration only. Must wait for next time step to accomplish this.
    5989             :         //   If a warning occurs and the simulation down shifts, the warning is not valid.
    5990       96574 :         if (CurrentEndTime > this->CurrentEndTimeLast && state.dataHVACGlobal->TimeStepSys >= this->TimeStepSysLast) {
    5991       12555 :             if (state.dataCondenserLoopTowers->towers(this->VSTower).PrintTrMessage) {
    5992         334 :                 ++state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountTR;
    5993         334 :                 if (state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountTR < 2) {
    5994          15 :                     ShowWarningError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TrBuffer1);
    5995          15 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TrBuffer2);
    5996          15 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TrBuffer3);
    5997          15 :                     ShowContinueError(state, " ...Range temperatures outside model boundaries may not adversely affect tower performance.");
    5998          15 :                     ShowContinueError(state, " ...This is not an unexpected occurrence when simulating actual conditions.");
    5999             :                 } else {
    6000         957 :                     ShowRecurringWarningErrorAtEnd(state,
    6001         638 :                                                    format("{} \"{}\" - Tower range temperature is out of range error continues...",
    6002         319 :                                                           DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6003         319 :                                                           this->Name),
    6004         319 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).ErrIndexTR,
    6005         319 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).TrLast,
    6006         319 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).TrLast);
    6007             :                 }
    6008             :             }
    6009       12555 :             if (state.dataCondenserLoopTowers->towers(this->VSTower).PrintTwbMessage) {
    6010           4 :                 ++state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountIAWB;
    6011           4 :                 if (state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountIAWB < 6) {
    6012           4 :                     ShowWarningError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TwbBuffer1);
    6013           4 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TwbBuffer2);
    6014           4 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TwbBuffer3);
    6015           4 :                     ShowContinueError(state, " ...Wet-bulb temperatures outside model boundaries may not adversely affect tower performance.");
    6016             :                 } else {
    6017           0 :                     ShowRecurringWarningErrorAtEnd(state,
    6018           0 :                                                    format("{} \"{}\" - Inlet air wet-bulb temperature is out of range error continues...",
    6019           0 :                                                           DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6020           0 :                                                           this->Name),
    6021           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).ErrIndexIAWB,
    6022           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).TwbLast,
    6023           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).TwbLast);
    6024             :                 }
    6025             :             }
    6026       12555 :             if (state.dataCondenserLoopTowers->towers(this->VSTower).PrintTaMessage) {
    6027         382 :                 ++state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountTA;
    6028         382 :                 if (state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountTA < 2) {
    6029          11 :                     ShowWarningError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TaBuffer1);
    6030          11 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TaBuffer2);
    6031          11 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).TaBuffer3);
    6032          11 :                     ShowContinueError(state, " ...Approach temperatures outside model boundaries may not adversely affect tower performance.");
    6033          11 :                     ShowContinueError(state, " ...This is not an unexpected occurrence when simulating actual conditions.");
    6034             :                 } else {
    6035        1113 :                     ShowRecurringWarningErrorAtEnd(state,
    6036         742 :                                                    format("{} \"{}\" - Tower approach temperature is out of range error continues...",
    6037         371 :                                                           DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6038         371 :                                                           this->Name),
    6039         371 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).ErrIndexTA,
    6040         371 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).TaLast,
    6041         371 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).TaLast);
    6042             :                 }
    6043             :             }
    6044       12555 :             if (state.dataCondenserLoopTowers->towers(this->VSTower).PrintWFRRMessage) {
    6045          18 :                 ++state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountWFRR;
    6046          18 :                 if (state.dataCondenserLoopTowers->towers(this->VSTower).VSErrorCountWFRR < 6) {
    6047          18 :                     ShowWarningError(state, state.dataCondenserLoopTowers->towers(this->VSTower).WFRRBuffer1);
    6048          18 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).WFRRBuffer2);
    6049          18 :                     ShowContinueError(state, state.dataCondenserLoopTowers->towers(this->VSTower).WFRRBuffer3);
    6050          18 :                     ShowContinueError(state, " ...Water flow rate ratios outside model boundaries may not adversely affect tower performance.");
    6051             :                 } else {
    6052           0 :                     ShowRecurringWarningErrorAtEnd(state,
    6053           0 :                                                    format("{} \"{}\" - Water flow rate ratio is out of range error continues...",
    6054           0 :                                                           DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6055           0 :                                                           this->Name),
    6056           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).ErrIndexWFRR,
    6057           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).WaterFlowRateRatioLast,
    6058           0 :                                                    state.dataCondenserLoopTowers->towers(this->VSTower).WaterFlowRateRatioLast);
    6059             :                 }
    6060             :             }
    6061             :         }
    6062             : 
    6063             :         //   save last system time step and last end time of current time step (used to determine if warning is valid)
    6064       96574 :         this->TimeStepSysLast = state.dataHVACGlobal->TimeStepSys;
    6065       96574 :         this->CurrentEndTimeLast = CurrentEndTime;
    6066             : 
    6067             :         //   check boundaries of independent variables and post warnings to individual buffers to print at end of time step
    6068      192891 :         if (Twb < state.dataCondenserLoopTowers->towers(this->VSTower).MinInletAirWBTemp ||
    6069       96317 :             Twb > state.dataCondenserLoopTowers->towers(this->VSTower).MaxInletAirWBTemp) {
    6070         257 :             OutputChar = format("{:.2R}", Twb);
    6071         257 :             OutputCharLo = format("{:.2R}", state.dataCondenserLoopTowers->towers(this->VSTower).MinInletAirWBTemp);
    6072         257 :             OutputCharHi = format("{:.2R}", state.dataCondenserLoopTowers->towers(this->VSTower).MaxInletAirWBTemp);
    6073         257 :             if (Twb < state.dataCondenserLoopTowers->towers(this->VSTower).MinInletAirWBTemp) {
    6074         257 :                 TwbCapped = state.dataCondenserLoopTowers->towers(this->VSTower).MinInletAirWBTemp;
    6075             :             }
    6076         257 :             if (Twb > state.dataCondenserLoopTowers->towers(this->VSTower).MaxInletAirWBTemp) {
    6077           0 :                 TwbCapped = state.dataCondenserLoopTowers->towers(this->VSTower).MaxInletAirWBTemp;
    6078             :             }
    6079         257 :             if (!state.dataGlobal->WarmupFlag) {
    6080          10 :                 state.dataCondenserLoopTowers->towers(this->VSTower).PrintTwbMessage = true;
    6081          10 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TwbBuffer1 =
    6082          20 :                     format("{} \"{}\" - Inlet air wet-bulb temperature is outside model boundaries at {}.",
    6083          10 :                            DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6084          10 :                            this->Name,
    6085          10 :                            OutputChar);
    6086          10 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TwbBuffer2 =
    6087          20 :                     " ...Valid range = " + OutputCharLo + " to " + OutputCharHi + ". Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " +
    6088          40 :                     state.dataEnvrn->CurMnDy + ' ' + General::CreateSysTimeIntervalString(state);
    6089          10 :                 TrimValue = format("{:.6R}", TwbCapped);
    6090          10 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TwbBuffer3 =
    6091          20 :                     " ...Inlet air wet-bulb temperature passed to the model = " + TrimValue;
    6092          10 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TwbLast = Twb;
    6093             :             } else {
    6094         247 :                 state.dataCondenserLoopTowers->towers(this->VSTower).PrintTwbMessage = false;
    6095             :             }
    6096             :         } else {
    6097       96317 :             state.dataCondenserLoopTowers->towers(this->VSTower).PrintTwbMessage = false;
    6098             :         }
    6099             : 
    6100      182168 :         if (Tr < state.dataCondenserLoopTowers->towers(this->VSTower).MinRangeTemp ||
    6101       85594 :             Tr > state.dataCondenserLoopTowers->towers(this->VSTower).MaxRangeTemp) {
    6102       10980 :             OutputChar = format("{:.2R}", Tr);
    6103       10980 :             OutputCharLo = format("{:.2R}", state.dataCondenserLoopTowers->towers(this->VSTower).MinRangeTemp);
    6104       10980 :             OutputCharHi = format("{:.2R}", state.dataCondenserLoopTowers->towers(this->VSTower).MaxRangeTemp);
    6105       10980 :             if (Tr < state.dataCondenserLoopTowers->towers(this->VSTower).MinRangeTemp) {
    6106       10980 :                 TrCapped = state.dataCondenserLoopTowers->towers(this->VSTower).MinRangeTemp;
    6107             :             }
    6108       10980 :             if (Tr > state.dataCondenserLoopTowers->towers(this->VSTower).MaxRangeTemp) {
    6109           0 :                 TrCapped = state.dataCondenserLoopTowers->towers(this->VSTower).MaxRangeTemp;
    6110             :             }
    6111       10980 :             if (!state.dataGlobal->WarmupFlag) {
    6112        2586 :                 state.dataCondenserLoopTowers->towers(this->VSTower).PrintTrMessage = true;
    6113        2586 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TrBuffer1 =
    6114        5172 :                     format("{} \"{}\" - Tower range temperature is outside model boundaries at {}.",
    6115        2586 :                            DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6116        2586 :                            this->Name,
    6117        2586 :                            OutputChar);
    6118        2586 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TrBuffer2 =
    6119        5172 :                     " ...Valid range = " + OutputCharLo + " to " + OutputCharHi + ". Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " +
    6120       10344 :                     state.dataEnvrn->CurMnDy + ' ' + General::CreateSysTimeIntervalString(state);
    6121        2586 :                 TrimValue = format("{:.5R}", Tr);
    6122        2586 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TrBuffer3 = " ...Tower range temperature passed to the model = " + TrimValue;
    6123        2586 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TrLast = Tr;
    6124             :             } else {
    6125        8394 :                 state.dataCondenserLoopTowers->towers(this->VSTower).PrintTrMessage = false;
    6126             :             }
    6127             :         } else {
    6128       85594 :             state.dataCondenserLoopTowers->towers(this->VSTower).PrintTrMessage = false;
    6129             :         }
    6130             : 
    6131      170658 :         if (Ta < state.dataCondenserLoopTowers->towers(this->VSTower).MinApproachTemp ||
    6132       74084 :             Ta > state.dataCondenserLoopTowers->towers(this->VSTower).MaxApproachTemp) {
    6133       26326 :             OutputChar = format("{:.2R}", Ta);
    6134       26326 :             OutputCharLo = format("{:.2R}", state.dataCondenserLoopTowers->towers(this->VSTower).MinApproachTemp);
    6135       26326 :             OutputCharHi = format("{:.2R}", state.dataCondenserLoopTowers->towers(this->VSTower).MaxApproachTemp);
    6136       26326 :             if (Ta < state.dataCondenserLoopTowers->towers(this->VSTower).MinApproachTemp) {
    6137       22490 :                 TaCapped = state.dataCondenserLoopTowers->towers(this->VSTower).MinApproachTemp;
    6138             :             }
    6139       26326 :             if (Ta > state.dataCondenserLoopTowers->towers(this->VSTower).MaxApproachTemp) {
    6140        3836 :                 TaCapped = state.dataCondenserLoopTowers->towers(this->VSTower).MaxApproachTemp;
    6141             :             }
    6142       26326 :             if (!state.dataGlobal->WarmupFlag) {
    6143        4183 :                 state.dataCondenserLoopTowers->towers(this->VSTower).PrintTaMessage = true;
    6144        4183 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TaBuffer1 =
    6145        8366 :                     format("{} \"{}\" - Tower approach temperature is outside model boundaries at {}.",
    6146        4183 :                            DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6147        4183 :                            this->Name,
    6148        4183 :                            OutputChar);
    6149        4183 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TaBuffer2 =
    6150        8366 :                     " ...Valid range = " + OutputCharLo + " to " + OutputCharHi + ". Occurrence info = " + state.dataEnvrn->EnvironmentName + ", " +
    6151       16732 :                     state.dataEnvrn->CurMnDy + ' ' + General::CreateSysTimeIntervalString(state);
    6152        4183 :                 TrimValue = format("{:.5R}", Ta);
    6153        4183 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TaBuffer3 = " ...Tower approach temperature passed to the model = " + TrimValue;
    6154        4183 :                 state.dataCondenserLoopTowers->towers(this->VSTower).TaLast = Ta;
    6155             :             } else {
    6156       22143 :                 state.dataCondenserLoopTowers->towers(this->VSTower).PrintTaMessage = false;
    6157             :             }
    6158             :         } else {
    6159       70248 :             state.dataCondenserLoopTowers->towers(this->VSTower).PrintTaMessage = false;
    6160             :         }
    6161             : 
    6162       96574 :         if (this->TowerModelType == ModelType::YorkCalcModel || this->TowerModelType == ModelType::YorkCalcUserDefined) {
    6163             :             //     Water flow rate ratio warning not valid for YorkCalc model, print liquid to gas ratio
    6164             :             //     warning instead (bottom of Subroutine VariableSpeedTower)
    6165       51694 :             state.dataCondenserLoopTowers->towers(this->VSTower).PrintWFRRMessage = false;
    6166             :         } else {
    6167       88907 :             if (WaterFlowRateRatio < state.dataCondenserLoopTowers->towers(this->VSTower).MinWaterFlowRatio ||
    6168       44027 :                 WaterFlowRateRatio > state.dataCondenserLoopTowers->towers(this->VSTower).MaxWaterFlowRatio) {
    6169         853 :                 OutputChar = format("{:.2R}", WaterFlowRateRatio);
    6170         853 :                 OutputCharLo = format("{:.2R}", state.dataCondenserLoopTowers->towers(this->VSTower).MinWaterFlowRatio);
    6171         853 :                 OutputCharHi = format("{:.2R}", state.dataCondenserLoopTowers->towers(this->VSTower).MaxWaterFlowRatio);
    6172         853 :                 if (WaterFlowRateRatio < state.dataCondenserLoopTowers->towers(this->VSTower).MinWaterFlowRatio) {
    6173         853 :                     WaterFlowRateRatioCapped = state.dataCondenserLoopTowers->towers(this->VSTower).MinWaterFlowRatio;
    6174             :                 }
    6175         853 :                 if (WaterFlowRateRatio > state.dataCondenserLoopTowers->towers(this->VSTower).MaxWaterFlowRatio) {
    6176           0 :                     WaterFlowRateRatioCapped = state.dataCondenserLoopTowers->towers(this->VSTower).MaxWaterFlowRatio;
    6177             :                 }
    6178         853 :                 if (!state.dataGlobal->WarmupFlag) {
    6179          66 :                     state.dataCondenserLoopTowers->towers(this->VSTower).PrintWFRRMessage = true;
    6180          66 :                     state.dataCondenserLoopTowers->towers(this->VSTower).WFRRBuffer1 =
    6181         132 :                         format("{} \"{}\" - Water flow rate ratio is outside model boundaries at {}.",
    6182          66 :                                DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6183          66 :                                this->Name,
    6184          66 :                                OutputChar);
    6185          66 :                     state.dataCondenserLoopTowers->towers(this->VSTower).WFRRBuffer2 =
    6186         132 :                         " ...Valid range = " + OutputCharLo + " to " + OutputCharHi + ". Occurrence info = " + state.dataEnvrn->EnvironmentName +
    6187         264 :                         ", " + state.dataEnvrn->CurMnDy + ' ' + General::CreateSysTimeIntervalString(state);
    6188          66 :                     TrimValue = format("{:.5R}", WaterFlowRateRatioCapped);
    6189          66 :                     state.dataCondenserLoopTowers->towers(this->VSTower).WFRRBuffer3 = " ...Water flow rate ratio passed to the model = " + TrimValue;
    6190          66 :                     state.dataCondenserLoopTowers->towers(this->VSTower).WaterFlowRateRatioLast = WaterFlowRateRatio;
    6191             :                 } else {
    6192         787 :                     state.dataCondenserLoopTowers->towers(this->VSTower).PrintWFRRMessage = false;
    6193             :                 }
    6194             :             } else {
    6195       44027 :                 state.dataCondenserLoopTowers->towers(this->VSTower).PrintWFRRMessage = false;
    6196             :             }
    6197             :         }
    6198       96574 :     }
    6199             : 
    6200     8767027 :     void CoolingTower::calculateWaterUsage(EnergyPlusData &state)
    6201             :     {
    6202             : 
    6203             :         // SUBROUTINE INFORMATION:
    6204             :         //       AUTHOR         B. Griffith
    6205             :         //       DATE WRITTEN   August 2006
    6206             :         //       MODIFIED       T Hong, Aug. 2008. Added fluid bypass for single speed cooling tower
    6207             :         //                      A Flament, July 2010. Added multi-cell capability
    6208             : 
    6209             :         // PURPOSE OF THIS SUBROUTINE:
    6210             :         // Collect tower water useage calculations for reuse by all the tower models.
    6211             : 
    6212             :         // REFERENCES:
    6213             :         // Code for this routine started from VariableSpeedTower
    6214             : 
    6215             :         // SUBROUTINE PARAMETER DEFINITIONS:
    6216             :         static constexpr std::string_view RoutineName("calculateWaterUsage");
    6217             : 
    6218     8767027 :         Real64 EvapVdot = 0.0;
    6219     8767027 :         Real64 AverageWaterTemp = (this->InletWaterTemp + this->OutletWaterTemp) / 2.0;
    6220             : 
    6221             :         // Set water and air properties
    6222     8767027 :         if (this->EvapLossMode == EvapLoss::MoistTheory) {
    6223             : 
    6224     8750133 :             Real64 const AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state, this->AirPress, this->AirTemp, this->AirHumRat);
    6225     8750133 :             Real64 const AirMassFlowRate = this->airFlowRateRatio * this->HighSpeedAirFlowRate * AirDensity * this->NumCellOn / this->NumCell;
    6226     8750133 :             Real64 const InletAirEnthalpy = Psychrometrics::PsyHFnTdbRhPb(state, this->AirWetBulb, 1.0, this->AirPress);
    6227             : 
    6228     8750133 :             if (AirMassFlowRate > 0.0) {
    6229             :                 // Calculate outlet air conditions for determining water usage
    6230             : 
    6231     3641120 :                 Real64 const OutletAirEnthalpy = InletAirEnthalpy + this->Qactual / AirMassFlowRate;
    6232     3641120 :                 Real64 const OutletAirTSat = Psychrometrics::PsyTsatFnHPb(state, OutletAirEnthalpy, this->AirPress);
    6233     3641120 :                 Real64 const OutletAirHumRatSat = Psychrometrics::PsyWFnTdbH(state, OutletAirTSat, OutletAirEnthalpy);
    6234             : 
    6235             :                 // calculate specific humidity ratios (HUMRAT to mass of moist air not dry air)
    6236     3641120 :                 Real64 const InSpecificHumRat = this->AirHumRat / (1 + this->AirHumRat);
    6237     3641120 :                 Real64 const OutSpecificHumRat = OutletAirHumRatSat / (1 + OutletAirHumRatSat);
    6238             : 
    6239             :                 // calculate average air temp for density call
    6240     3641120 :                 Real64 const TairAvg = (this->AirTemp + OutletAirTSat) / 2.0;
    6241             : 
    6242             :                 // Amount of water evaporated, get density water at air temp or 4 C if too cold
    6243     3641120 :                 Real64 const rho = FluidProperties::GetDensityGlycol(state,
    6244     3641120 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    6245             :                                                                      max(TairAvg, 4.0),
    6246     3641120 :                                                                      state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    6247             :                                                                      RoutineName);
    6248             : 
    6249     3641120 :                 EvapVdot = (AirMassFlowRate * (OutSpecificHumRat - InSpecificHumRat)) / rho; // [m3/s]
    6250     3641120 :                 if (EvapVdot < 0.0) EvapVdot = 0.0;
    6251             :             } else {
    6252     5109013 :                 EvapVdot = 0.0;
    6253             :             }
    6254             : 
    6255       16894 :         } else if (this->EvapLossMode == EvapLoss::UserFactor) {
    6256       16894 :             Real64 const rho = FluidProperties::GetDensityGlycol(state,
    6257       16894 :                                                                  state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    6258             :                                                                  AverageWaterTemp,
    6259       16894 :                                                                  state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    6260             :                                                                  RoutineName);
    6261             : 
    6262       16894 :             EvapVdot = this->UserEvapLossFactor * (this->InletWaterTemp - this->OutletWaterTemp) * (this->WaterMassFlowRate / rho);
    6263       16894 :             if (EvapVdot < 0.0) EvapVdot = 0.0;
    6264             :         } else {
    6265             :             // should never come here
    6266             :         }
    6267             : 
    6268             :         //   amount of water lost due to drift
    6269     8767027 :         Real64 driftVdot = this->DesignWaterFlowRate * this->NumCellOn / this->NumCell * this->DriftLossFraction * this->airFlowRateRatio;
    6270             : 
    6271     8767027 :         Real64 BlowDownVdot(0.0);
    6272     8767027 :         if (this->BlowdownMode == Blowdown::Schedule) {
    6273             :             // Amount of water lost due to blow down (purging contaminants from tower basin)
    6274           0 :             if (this->SchedIDBlowdown > 0) {
    6275           0 :                 BlowDownVdot = ScheduleManager::GetCurrentScheduleValue(state, this->SchedIDBlowdown);
    6276             :             } else {
    6277           0 :                 BlowDownVdot = 0.0;
    6278             :             }
    6279     8767027 :         } else if (this->BlowdownMode == Blowdown::Concentration) {
    6280     8767027 :             if (this->ConcentrationRatio > 2.0) { // protect divide by zero
    6281     8767027 :                 BlowDownVdot = EvapVdot / (this->ConcentrationRatio - 1) - driftVdot;
    6282             :             } else {
    6283           0 :                 BlowDownVdot = EvapVdot - driftVdot;
    6284             :             }
    6285     8767027 :             if (BlowDownVdot < 0.0) BlowDownVdot = 0.0;
    6286             :         } else {
    6287             :             // should never come here
    6288             :         }
    6289             : 
    6290             :         // Added for fluid bypass
    6291     8767027 :         if (this->CapacityControl == CapacityCtrl::FluidBypass) {
    6292      359740 :             if (this->EvapLossMode == EvapLoss::UserFactor) EvapVdot *= (1 - this->BypassFraction);
    6293      359740 :             driftVdot *= (1 - this->BypassFraction);
    6294      359740 :             BlowDownVdot *= (1 - this->BypassFraction);
    6295             :         }
    6296             : 
    6297     8767027 :         Real64 const makeUpVdot = EvapVdot + driftVdot + BlowDownVdot;
    6298             : 
    6299             :         // set demand request in Water Storage if needed
    6300     8767027 :         Real64 StarvedVdot = 0.0;
    6301     8767027 :         Real64 tankSupplyVdot = 0.0;
    6302     8767027 :         if (this->SuppliedByWaterSystem) {
    6303             : 
    6304             :             // set demand request
    6305       35076 :             state.dataWaterData->WaterStorage(this->WaterTankID).VdotRequestDemand(this->WaterTankDemandARRID) = makeUpVdot;
    6306             : 
    6307       35076 :             Real64 const AvailTankVdot = state.dataWaterData->WaterStorage(this->WaterTankID)
    6308       35076 :                                              .VdotAvailDemand(this->WaterTankDemandARRID); // check what tank can currently provide
    6309             : 
    6310       35076 :             tankSupplyVdot = makeUpVdot;      // init
    6311       35076 :             if (AvailTankVdot < makeUpVdot) { // calculate starved flow
    6312       20214 :                 StarvedVdot = makeUpVdot - AvailTankVdot;
    6313       20214 :                 tankSupplyVdot = AvailTankVdot;
    6314             :             }
    6315             :         } else { // supplied by mains
    6316             :         }
    6317             : 
    6318             :         //   total water usage
    6319             :         // update report variables
    6320     8767027 :         this->EvaporationVdot = EvapVdot;
    6321     8767027 :         this->EvaporationVol = EvapVdot * (state.dataHVACGlobal->TimeStepSysSec);
    6322     8767027 :         this->DriftVdot = driftVdot;
    6323     8767027 :         this->DriftVol = driftVdot * (state.dataHVACGlobal->TimeStepSysSec);
    6324     8767027 :         this->BlowdownVdot = BlowDownVdot;
    6325     8767027 :         this->BlowdownVol = BlowDownVdot * (state.dataHVACGlobal->TimeStepSysSec);
    6326     8767027 :         this->MakeUpVdot = makeUpVdot;
    6327     8767027 :         this->MakeUpVol = makeUpVdot * (state.dataHVACGlobal->TimeStepSysSec);
    6328     8767027 :         this->TankSupplyVdot = tankSupplyVdot;
    6329     8767027 :         this->TankSupplyVol = tankSupplyVdot * (state.dataHVACGlobal->TimeStepSysSec);
    6330     8767027 :         this->StarvedMakeUpVdot = StarvedVdot;
    6331     8767027 :         this->StarvedMakeUpVol = StarvedVdot * (state.dataHVACGlobal->TimeStepSysSec);
    6332     8767027 :         this->coolingTowerApproach = this->OutletWaterTemp - this->AirWetBulb;
    6333     8767027 :         this->coolingTowerRange = this->InletWaterTemp - this->OutletWaterTemp;
    6334     8767027 :     }
    6335             : 
    6336     8767027 :     void CoolingTower::update(EnergyPlusData &state)
    6337             :     {
    6338             : 
    6339             :         // SUBROUTINE INFORMATION:
    6340             :         //       AUTHOR:          Dan Fisher
    6341             :         //       DATE WRITTEN:    October 1998
    6342             : 
    6343             :         // PURPOSE OF THIS SUBROUTINE:
    6344             :         // This subroutine is for passing results to the outlet water node.
    6345             : 
    6346             :         // set node information
    6347     8767027 :         PlantUtilities::SafeCopyPlantNode(state, this->WaterInletNodeNum, this->WaterOutletNodeNum);
    6348     8767027 :         state.dataLoopNodes->Node(this->WaterOutletNodeNum).Temp = this->OutletWaterTemp;
    6349             : 
    6350    13149774 :         if (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked ||
    6351     4382747 :             state.dataGlobal->WarmupFlag)
    6352     8144053 :             return;
    6353             : 
    6354             :         // Check flow rate through tower and compare to design flow rate, show warning if greater than Design * Mulitplier
    6355      622974 :         if (state.dataLoopNodes->Node(this->WaterOutletNodeNum).MassFlowRate > this->DesWaterMassFlowRate * this->TowerMassFlowRateMultiplier) {
    6356           0 :             ++this->HighMassFlowErrorCount;
    6357           0 :             if (this->HighMassFlowErrorCount < 2) {
    6358           0 :                 ShowWarningError(state, format("{} \"{}\"", DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)], this->Name));
    6359           0 :                 ShowContinueError(state, " Condenser Loop Mass Flow Rate is much greater than the towers design mass flow rate.");
    6360           0 :                 ShowContinueError(
    6361           0 :                     state, format(" Condenser Loop Mass Flow Rate = {:.6T}", state.dataLoopNodes->Node(this->WaterOutletNodeNum).MassFlowRate));
    6362           0 :                 ShowContinueError(state, format(" Tower Design Mass Flow Rate   = {:.6T}", this->DesWaterMassFlowRate));
    6363           0 :                 ShowContinueErrorTimeStamp(state, "");
    6364             :             } else {
    6365           0 :                 ShowRecurringWarningErrorAtEnd(
    6366             :                     state,
    6367           0 :                     format("{} \"{}\"  Condenser Loop Mass Flow Rate is much greater than the towers design mass flow rate error continues...",
    6368           0 :                            DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6369           0 :                            this->Name),
    6370           0 :                     this->HighMassFlowErrorIndex,
    6371           0 :                     state.dataLoopNodes->Node(this->WaterOutletNodeNum).MassFlowRate,
    6372           0 :                     state.dataLoopNodes->Node(this->WaterOutletNodeNum).MassFlowRate);
    6373             :             }
    6374             :         }
    6375             : 
    6376             :         // Check if OutletWaterTemp is below the minimum condenser loop temp and warn user
    6377      622974 :         Real64 const LoopMinTemp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MinTemp;
    6378      622974 :         bool const outletWaterTempTooLow = this->OutletWaterTemp < LoopMinTemp;
    6379      622974 :         bool const flowIsOn = this->WaterMassFlowRate > 0.0;
    6380      622974 :         if (outletWaterTempTooLow && flowIsOn) {
    6381         765 :             ++this->OutletWaterTempErrorCount;
    6382         765 :             if (this->OutletWaterTempErrorCount < 2) {
    6383           7 :                 ShowWarningError(state, format("{} \"{}\"", DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)], this->Name));
    6384          14 :                 ShowContinueError(
    6385             :                     state,
    6386          14 :                     format("Cooling tower water outlet temperature ({:.2F} C) is below the specified minimum condenser loop temp of {:.2F} C",
    6387           7 :                            this->OutletWaterTemp,
    6388             :                            LoopMinTemp));
    6389           7 :                 ShowContinueErrorTimeStamp(state, "");
    6390             :             } else {
    6391        2274 :                 ShowRecurringWarningErrorAtEnd(
    6392             :                     state,
    6393        1516 :                     format("{} \"{}\" Cooling tower water outlet temperature is below the specified minimum condenser loop temp error continues...",
    6394         758 :                            DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6395         758 :                            this->Name),
    6396         758 :                     this->OutletWaterTempErrorIndex,
    6397         758 :                     this->OutletWaterTemp,
    6398         758 :                     this->OutletWaterTemp);
    6399             :             }
    6400             :         }
    6401             : 
    6402             :         // Check if water mass flow rate is small (e.g. no flow) and warn user
    6403      622974 :         if (this->WaterMassFlowRate > 0.0 && this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) {
    6404           0 :             ++this->SmallWaterMassFlowErrorCount;
    6405           0 :             if (this->SmallWaterMassFlowErrorCount < 2) {
    6406           0 :                 ShowWarningError(state, format("{} \"{}\"", DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)], this->Name));
    6407           0 :                 ShowContinueError(state, "Cooling tower water mass flow rate near zero.");
    6408           0 :                 ShowContinueErrorTimeStamp(state, "");
    6409           0 :                 ShowContinueError(state, format("Actual Mass flow = {:.2T}", this->WaterMassFlowRate));
    6410             :             } else {
    6411           0 :                 ShowRecurringWarningErrorAtEnd(state,
    6412           0 :                                                format("{} \"{}\"  Cooling tower water mass flow rate near zero error continues...",
    6413           0 :                                                       DataPlant::PlantEquipTypeNames[static_cast<int>(this->TowerType)],
    6414           0 :                                                       this->Name),
    6415           0 :                                                this->SmallWaterMassFlowErrorIndex,
    6416           0 :                                                this->WaterMassFlowRate,
    6417           0 :                                                this->WaterMassFlowRate);
    6418             :             }
    6419             :         }
    6420             :     }
    6421             : 
    6422     8767027 :     void CoolingTower::report(EnergyPlusData &state, bool const RunFlag)
    6423             :     {
    6424             : 
    6425             :         // SUBROUTINE INFORMATION:
    6426             :         //       AUTHOR:          Dan Fisher
    6427             :         //       DATE WRITTEN:    October 1998
    6428             : 
    6429             :         // PURPOSE OF THIS SUBROUTINE:
    6430             :         // This subroutine updates the report variables for the tower.
    6431             : 
    6432     8767027 :         Real64 const ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
    6433             : 
    6434     8767027 :         if (!RunFlag) {
    6435     4649770 :             this->InletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    6436     4649770 :             this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    6437     4649770 :             this->Qactual = 0.0;
    6438     4649770 :             this->FanPower = 0.0;
    6439     4649770 :             this->FanEnergy = 0.0;
    6440     4649770 :             this->AirFlowRatio = 0.0;
    6441     4649770 :             this->WaterAmountUsed = 0.0;
    6442     4649770 :             this->BasinHeaterConsumption = this->BasinHeaterPower * ReportingConstant;
    6443     4649770 :             this->FanCyclingRatio = 0.0;
    6444     4649770 :             this->BypassFraction = 0.0; // added for fluid bypass
    6445     4649770 :             this->NumCellOn = 0;
    6446     4649770 :             this->SpeedSelected = 0;
    6447             :         } else {
    6448     4117257 :             this->InletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    6449     4117257 :             this->FanEnergy = this->FanPower * ReportingConstant;
    6450     4117257 :             this->AirFlowRatio = this->airFlowRateRatio;
    6451     4117257 :             this->WaterAmountUsed = this->WaterUsage * ReportingConstant;
    6452     4117257 :             this->BasinHeaterConsumption = this->BasinHeaterPower * ReportingConstant;
    6453             :         }
    6454     8767027 :     }
    6455             : 
    6456     8223922 :     void CoolingTower::checkMassFlowAndLoad(EnergyPlusData &state, Real64 const MyLoad, bool RunFlag, bool &returnFlagSet)
    6457             :     {
    6458     8223922 :         if ((MyLoad > -HVAC::SmallLoad) || !RunFlag) {
    6459             :             // tower doesn't need to do anything
    6460     4601746 :             this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    6461     4601746 :             this->FanPower = 0.0;
    6462     4601746 :             this->airFlowRateRatio = 0.0;
    6463     4601746 :             this->Qactual = 0.0;
    6464     4601746 :             this->WaterMassFlowRate = 0.0;
    6465     4601746 :             PlantUtilities::SetComponentFlowRate(state, this->WaterMassFlowRate, this->WaterInletNodeNum, this->WaterOutletNodeNum, this->plantLoc);
    6466     4601746 :             CalcBasinHeaterPower(
    6467     4601746 :                 state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    6468     4601746 :             returnFlagSet = true;
    6469     3622176 :         } else if (this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) {
    6470             :             // for multiple cells, we assume that it's a common basin
    6471           0 :             CalcBasinHeaterPower(
    6472           0 :                 state, this->BasinHeaterPowerFTempDiff, this->BasinHeaterSchedulePtr, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    6473           0 :             returnFlagSet = true;
    6474             :         }
    6475     8223922 :     }
    6476             : 
    6477             : } // namespace CondenserLoopTowers
    6478             : 
    6479             : } // namespace EnergyPlus

Generated by: LCOV version 1.14