LCOV - code coverage report
Current view: top level - EnergyPlus - FluidCoolers.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 523 1030 50.8 %
Date: 2024-08-23 23:50:59 Functions: 20 22 90.9 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cmath>
      50             : 
      51             : // ObjexxFCL Headers
      52             : #include <ObjexxFCL/Array.functions.hh>
      53             : #include <ObjexxFCL/Fmath.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <EnergyPlus/Autosizing/Base.hh>
      57             : #include <EnergyPlus/BranchNodeConnections.hh>
      58             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      59             : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      60             : #include <EnergyPlus/DataEnvironment.hh>
      61             : #include <EnergyPlus/DataHVACGlobals.hh>
      62             : #include <EnergyPlus/DataIPShortCuts.hh>
      63             : #include <EnergyPlus/DataLoopNode.hh>
      64             : #include <EnergyPlus/DataSizing.hh>
      65             : #include <EnergyPlus/FluidCoolers.hh>
      66             : #include <EnergyPlus/FluidProperties.hh>
      67             : #include <EnergyPlus/General.hh>
      68             : #include <EnergyPlus/GlobalNames.hh>
      69             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      70             : #include <EnergyPlus/NodeInputManager.hh>
      71             : #include <EnergyPlus/OutAirNodeManager.hh>
      72             : #include <EnergyPlus/OutputProcessor.hh>
      73             : #include <EnergyPlus/OutputReportPredefined.hh>
      74             : #include <EnergyPlus/Plant/DataPlant.hh>
      75             : #include <EnergyPlus/PlantUtilities.hh>
      76             : #include <EnergyPlus/Psychrometrics.hh>
      77             : #include <EnergyPlus/UtilityRoutines.hh>
      78             : 
      79             : namespace EnergyPlus::FluidCoolers {
      80             : 
      81             : // Module containing the routines dealing with the objects FluidCooler:SingleSpeed and
      82             : // FluidCooler:TwoSpeed
      83             : 
      84             : // MODULE INFORMATION:
      85             : //       AUTHOR         Chandan Sharma
      86             : //       DATE WRITTEN   August 2008
      87             : //       MODIFIED       April 2010, Chandan Sharma, FSEC
      88             : 
      89             : // PURPOSE OF THIS MODULE:
      90             : // Model the performance of fluid coolers
      91             : 
      92             : // REFERENCES:
      93             : // Based on cooling tower by Shirey, Raustad: Dec 2000; Shirey, Sept 2002
      94             : 
      95             : // MODULE PARAMETER DEFINITIONS:
      96             : std::string const cFluidCooler_SingleSpeed("FluidCooler:SingleSpeed");
      97             : std::string const cFluidCooler_TwoSpeed("FluidCooler:TwoSpeed");
      98             : 
      99           6 : FluidCoolerspecs *FluidCoolerspecs::factory(EnergyPlusData &state, DataPlant::PlantEquipmentType objectType, std::string const &objectName)
     100             : {
     101           6 :     if (state.dataFluidCoolers->GetFluidCoolerInputFlag) {
     102           6 :         GetFluidCoolerInput(state);
     103           6 :         state.dataFluidCoolers->GetFluidCoolerInputFlag = false;
     104             :     }
     105             :     // Now look for this particular fluid cooler in the list
     106          12 :     auto thisObj = std::find_if(
     107           6 :         state.dataFluidCoolers->SimpleFluidCooler.begin(),
     108           6 :         state.dataFluidCoolers->SimpleFluidCooler.end(),
     109           6 :         [objectType, &objectName](const FluidCoolerspecs &myObj) { return myObj.FluidCoolerType == objectType && myObj.Name == objectName; });
     110           6 :     if (thisObj != state.dataFluidCoolers->SimpleFluidCooler.end()) return thisObj;
     111             : 
     112             :     // If we didn't find it, fatal
     113           0 :     ShowFatalError(state, format("FluidCooler::factory: Error getting inputs for cooler named: {}", objectName));
     114             :     // Shut up the compiler
     115           0 :     return nullptr;
     116             : }
     117             : 
     118      160595 : void FluidCoolerspecs::simulate(EnergyPlusData &state,
     119             :                                 [[maybe_unused]] const PlantLocation &calledFromLocation,
     120             :                                 [[maybe_unused]] bool const FirstHVACIteration,
     121             :                                 [[maybe_unused]] Real64 &CurLoad,
     122             :                                 bool const RunFlag)
     123             : {
     124      160595 :     this->initialize(state);
     125      160595 :     if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_SingleSpd) {
     126       22981 :         this->calcSingleSpeed(state);
     127             :     } else {
     128      137614 :         this->calcTwoSpeed(state);
     129             :     }
     130      160595 :     this->update(state);
     131      160595 :     this->report(state, RunFlag);
     132      160595 : }
     133             : 
     134          30 : void FluidCoolerspecs::onInitLoopEquip(EnergyPlusData &state, [[maybe_unused]] const PlantLocation &calledFromLocation)
     135             : {
     136          30 :     this->initialize(state);
     137          30 :     this->size(state);
     138          30 : }
     139             : 
     140          30 : void FluidCoolerspecs::getDesignCapacities([[maybe_unused]] EnergyPlusData &state,
     141             :                                            [[maybe_unused]] const PlantLocation &calledFromLocation,
     142             :                                            Real64 &MaxLoad,
     143             :                                            Real64 &MinLoad,
     144             :                                            Real64 &OptLoad)
     145             : {
     146          30 :     MaxLoad = this->FluidCoolerNominalCapacity;
     147          30 :     OptLoad = this->FluidCoolerNominalCapacity;
     148          30 :     MinLoad = 0.0;
     149          30 : }
     150             : 
     151           6 : void GetFluidCoolerInput(EnergyPlusData &state)
     152             : {
     153             : 
     154             :     // SUBROUTINE INFORMATION:
     155             :     //       AUTHOR:          Chandan Sharma
     156             :     //       DATE WRITTEN:    August 2008
     157             :     //       MODIFIED         Chandan Sharma, FSEC, April 2010
     158             : 
     159             :     // PURPOSE OF THIS SUBROUTINE:
     160             :     // Obtains input data for fluid coolers and stores it in SimpleFluidCooler data structure.
     161             : 
     162             :     // METHODOLOGY EMPLOYED:
     163             :     // Uses "Get" routines to read in the data.
     164             : 
     165             :     // REFERENCES:
     166             :     // Based on GetTowerInput subroutine from Don Shirey, Jan 2001 and Sept/Oct 2002;
     167             : 
     168             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     169           6 :     int NumAlphas = 0;            // Number of elements in the alpha array
     170           6 :     int NumNums = 0;              // Number of elements in the numeric array
     171           6 :     int IOStat = 0;               // IO Status when calling get input subroutine
     172           6 :     bool ErrorsFound(false);      // Logical flag set .TRUE. if errors found while getting input data
     173           6 :     Array1D<Real64> NumArray(16); // Numeric input data array
     174           6 :     Array1D_string AlphArray(5);  // Character string input data array
     175             : 
     176             :     // Get number of all Fluid Coolers specified in the input data file (idf)
     177           6 :     int const NumSingleSpeedFluidCoolers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "FluidCooler:SingleSpeed");
     178           6 :     int const NumTwoSpeedFluidCoolers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "FluidCooler:TwoSpeed");
     179           6 :     state.dataFluidCoolers->NumSimpleFluidCoolers = NumSingleSpeedFluidCoolers + NumTwoSpeedFluidCoolers;
     180             : 
     181           6 :     if (state.dataFluidCoolers->NumSimpleFluidCoolers <= 0)
     182           0 :         ShowFatalError(state,
     183             :                        "No fluid cooler objects found in input, however, a branch object has specified a fluid cooler. Search the input for "
     184             :                        "fluid cooler to determine the cause for this error.");
     185             : 
     186             :     // See if load distribution manager has already gotten the input
     187           6 :     if (allocated(state.dataFluidCoolers->SimpleFluidCooler)) return;
     188           6 :     state.dataFluidCoolers->GetFluidCoolerInputFlag = false;
     189             : 
     190             :     // Allocate data structures to hold fluid cooler input data, report data and fluid cooler inlet conditions
     191           6 :     state.dataFluidCoolers->SimpleFluidCooler.allocate(state.dataFluidCoolers->NumSimpleFluidCoolers);
     192           6 :     state.dataFluidCoolers->UniqueSimpleFluidCoolerNames.reserve(state.dataFluidCoolers->NumSimpleFluidCoolers);
     193             : 
     194             :     // Load data structures with fluid cooler input data
     195           6 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     196           6 :     cCurrentModuleObject = cFluidCooler_SingleSpeed;
     197           7 :     for (int SingleSpeedFluidCoolerNumber = 1; SingleSpeedFluidCoolerNumber <= NumSingleSpeedFluidCoolers; ++SingleSpeedFluidCoolerNumber) {
     198           1 :         int FluidCoolerNum = SingleSpeedFluidCoolerNumber;
     199           2 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     200             :                                                                  cCurrentModuleObject,
     201             :                                                                  SingleSpeedFluidCoolerNumber,
     202             :                                                                  AlphArray,
     203             :                                                                  NumAlphas,
     204             :                                                                  NumArray,
     205             :                                                                  NumNums,
     206             :                                                                  IOStat,
     207           1 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     208           1 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     209           1 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     210           1 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     211           1 :         GlobalNames::VerifyUniqueInterObjectName(state,
     212           1 :                                                  state.dataFluidCoolers->UniqueSimpleFluidCoolerNames,
     213           1 :                                                  AlphArray(1),
     214             :                                                  cCurrentModuleObject,
     215           1 :                                                  state.dataIPShortCut->cAlphaFieldNames(1),
     216             :                                                  ErrorsFound);
     217             : 
     218           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).Name = AlphArray(1);
     219           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerType = DataPlant::PlantEquipmentType::FluidCooler_SingleSpd;
     220           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).indexInArray = FluidCoolerNum;
     221           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerMassFlowRateMultiplier = 2.5;
     222           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).WaterInletNodeNum =
     223           2 :             NodeInputManager::GetOnlySingleNode(state,
     224           1 :                                                 AlphArray(2),
     225             :                                                 ErrorsFound,
     226             :                                                 DataLoopNode::ConnectionObjectType::FluidCoolerSingleSpeed,
     227           1 :                                                 AlphArray(1),
     228             :                                                 DataLoopNode::NodeFluidType::Water,
     229             :                                                 DataLoopNode::ConnectionType::Inlet,
     230             :                                                 NodeInputManager::CompFluidStream::Primary,
     231             :                                                 DataLoopNode::ObjectIsNotParent);
     232           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).WaterOutletNodeNum =
     233           2 :             NodeInputManager::GetOnlySingleNode(state,
     234           1 :                                                 AlphArray(3),
     235             :                                                 ErrorsFound,
     236             :                                                 DataLoopNode::ConnectionObjectType::FluidCoolerSingleSpeed,
     237           1 :                                                 AlphArray(1),
     238             :                                                 DataLoopNode::NodeFluidType::Water,
     239             :                                                 DataLoopNode::ConnectionType::Outlet,
     240             :                                                 NodeInputManager::CompFluidStream::Primary,
     241             :                                                 DataLoopNode::ObjectIsNotParent);
     242           1 :         BranchNodeConnections::TestCompSet(state, cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Chilled Water Nodes");
     243           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFluidCoolerUA = NumArray(1);
     244           1 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFluidCoolerUA == DataSizing::AutoSize) {
     245           0 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFluidCoolerUAWasAutoSized = true;
     246             :         }
     247           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerNominalCapacity = NumArray(2);
     248           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignEnteringWaterTemp = NumArray(3);
     249           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignEnteringAirTemp = NumArray(4);
     250           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignEnteringAirWetBulbTemp = NumArray(5);
     251           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignWaterFlowRate = NumArray(6);
     252           1 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignWaterFlowRate == DataSizing::AutoSize) {
     253           0 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignWaterFlowRateWasAutoSized = true;
     254             :         }
     255           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedAirFlowRate = NumArray(7);
     256           1 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedAirFlowRate == DataSizing::AutoSize) {
     257           0 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedAirFlowRateWasAutoSized = true;
     258             :         }
     259           1 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFanPower = NumArray(8);
     260           1 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFanPower == DataSizing::AutoSize) {
     261           1 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFanPowerWasAutoSized = true;
     262             :         }
     263             : 
     264             :         //   outdoor air inlet node
     265           1 :         if (AlphArray(5).empty()) {
     266           1 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).OutdoorAirInletNodeNum = 0;
     267             :         } else {
     268           0 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).OutdoorAirInletNodeNum =
     269           0 :                 NodeInputManager::GetOnlySingleNode(state,
     270           0 :                                                     AlphArray(5),
     271             :                                                     ErrorsFound,
     272             :                                                     DataLoopNode::ConnectionObjectType::FluidCoolerSingleSpeed,
     273           0 :                                                     state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).Name,
     274             :                                                     DataLoopNode::NodeFluidType::Air,
     275             :                                                     DataLoopNode::ConnectionType::OutsideAirReference,
     276             :                                                     NodeInputManager::CompFluidStream::Primary,
     277             :                                                     DataLoopNode::ObjectIsNotParent);
     278           0 :             if (!OutAirNodeManager::CheckOutAirNodeNumber(state, state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).OutdoorAirInletNodeNum)) {
     279           0 :                 ShowSevereError(state,
     280           0 :                                 format("{}= \"{}\" {}= \"{}\" not valid.",
     281             :                                        cCurrentModuleObject,
     282           0 :                                        state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).Name,
     283           0 :                                        state.dataIPShortCut->cAlphaFieldNames(5),
     284             :                                        AlphArray(5)));
     285           0 :                 ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
     286           0 :                 ErrorsFound = true;
     287             :             }
     288             :         }
     289             : 
     290           1 :         ErrorsFound |=
     291           1 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum)
     292           1 :                 .validateSingleSpeedInputs(
     293           1 :                     state, cCurrentModuleObject, AlphArray, state.dataIPShortCut->cNumericFieldNames, state.dataIPShortCut->cAlphaFieldNames);
     294             : 
     295             :     } // End Single-Speed fluid cooler Loop
     296             : 
     297           6 :     cCurrentModuleObject = cFluidCooler_TwoSpeed;
     298          11 :     for (int TwoSpeedFluidCoolerNumber = 1; TwoSpeedFluidCoolerNumber <= NumTwoSpeedFluidCoolers; ++TwoSpeedFluidCoolerNumber) {
     299           5 :         int FluidCoolerNum = NumSingleSpeedFluidCoolers + TwoSpeedFluidCoolerNumber;
     300          10 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     301             :                                                                  cCurrentModuleObject,
     302             :                                                                  TwoSpeedFluidCoolerNumber,
     303             :                                                                  AlphArray,
     304             :                                                                  NumAlphas,
     305             :                                                                  NumArray,
     306             :                                                                  NumNums,
     307             :                                                                  IOStat,
     308           5 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     309           5 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     310           5 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     311           5 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     312           5 :         GlobalNames::VerifyUniqueInterObjectName(state,
     313           5 :                                                  state.dataFluidCoolers->UniqueSimpleFluidCoolerNames,
     314           5 :                                                  AlphArray(1),
     315             :                                                  cCurrentModuleObject,
     316           5 :                                                  state.dataIPShortCut->cAlphaFieldNames(1),
     317             :                                                  ErrorsFound);
     318             : 
     319           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).Name = AlphArray(1);
     320           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerType = DataPlant::PlantEquipmentType::FluidCooler_TwoSpd;
     321           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).indexInArray = FluidCoolerNum;
     322           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerMassFlowRateMultiplier = 2.5;
     323           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).WaterInletNodeNum =
     324          10 :             NodeInputManager::GetOnlySingleNode(state,
     325           5 :                                                 AlphArray(2),
     326             :                                                 ErrorsFound,
     327             :                                                 DataLoopNode::ConnectionObjectType::FluidCoolerTwoSpeed,
     328           5 :                                                 AlphArray(1),
     329             :                                                 DataLoopNode::NodeFluidType::Water,
     330             :                                                 DataLoopNode::ConnectionType::Inlet,
     331             :                                                 NodeInputManager::CompFluidStream::Primary,
     332             :                                                 DataLoopNode::ObjectIsNotParent);
     333           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).WaterOutletNodeNum =
     334          10 :             NodeInputManager::GetOnlySingleNode(state,
     335           5 :                                                 AlphArray(3),
     336             :                                                 ErrorsFound,
     337             :                                                 DataLoopNode::ConnectionObjectType::FluidCoolerTwoSpeed,
     338           5 :                                                 AlphArray(1),
     339             :                                                 DataLoopNode::NodeFluidType::Water,
     340             :                                                 DataLoopNode::ConnectionType::Outlet,
     341             :                                                 NodeInputManager::CompFluidStream::Primary,
     342             :                                                 DataLoopNode::ObjectIsNotParent);
     343           5 :         BranchNodeConnections::TestCompSet(state, cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Chilled Water Nodes");
     344             : 
     345           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFluidCoolerUA = NumArray(1);
     346           5 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFluidCoolerUA == DataSizing::AutoSize) {
     347           0 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFluidCoolerUAWasAutoSized = true;
     348             :         }
     349           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedFluidCoolerUA = NumArray(2);
     350           5 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedFluidCoolerUA == DataSizing::AutoSize) {
     351           0 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedFluidCoolerUAWasAutoSized = true;
     352             :         }
     353           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedFluidCoolerUASizingFactor = NumArray(3);
     354           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerNominalCapacity = NumArray(4);
     355           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerLowSpeedNomCap = NumArray(5);
     356           5 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerLowSpeedNomCap == DataSizing::AutoSize) {
     357           0 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerLowSpeedNomCapWasAutoSized = true;
     358             :         }
     359           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).FluidCoolerLowSpeedNomCapSizingFactor = NumArray(6);
     360           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignEnteringWaterTemp = NumArray(7);
     361           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignEnteringAirTemp = NumArray(8);
     362           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignEnteringAirWetBulbTemp = NumArray(9);
     363           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignWaterFlowRate = NumArray(10);
     364           5 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignWaterFlowRate == DataSizing::AutoSize) {
     365           5 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).DesignWaterFlowRateWasAutoSized = true;
     366             :         }
     367           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedAirFlowRate = NumArray(11);
     368           5 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedAirFlowRate == DataSizing::AutoSize) {
     369           5 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedAirFlowRateWasAutoSized = true;
     370             :         }
     371           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFanPower = NumArray(12);
     372           5 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFanPower == DataSizing::AutoSize) {
     373           1 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).HighSpeedFanPowerWasAutoSized = true;
     374             :         }
     375           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedAirFlowRate = NumArray(13);
     376           5 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedAirFlowRate == DataSizing::AutoSize) {
     377           5 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedAirFlowRateWasAutoSized = true;
     378             :         }
     379           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedAirFlowRateSizingFactor = NumArray(14);
     380           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedFanPower = NumArray(15);
     381           5 :         if (state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedFanPower == DataSizing::AutoSize) {
     382           5 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedFanPowerWasAutoSized = true;
     383             :         }
     384           5 :         state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).LowSpeedFanPowerSizingFactor = NumArray(16);
     385             : 
     386             :         //   outdoor air inlet node
     387           5 :         if (AlphArray(5).empty()) {
     388           5 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).OutdoorAirInletNodeNum = 0;
     389             :         } else {
     390           0 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).OutdoorAirInletNodeNum =
     391           0 :                 NodeInputManager::GetOnlySingleNode(state,
     392           0 :                                                     AlphArray(5),
     393             :                                                     ErrorsFound,
     394             :                                                     DataLoopNode::ConnectionObjectType::FluidCoolerTwoSpeed,
     395           0 :                                                     state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).Name,
     396             :                                                     DataLoopNode::NodeFluidType::Air,
     397             :                                                     DataLoopNode::ConnectionType::OutsideAirReference,
     398             :                                                     NodeInputManager::CompFluidStream::Primary,
     399             :                                                     DataLoopNode::ObjectIsNotParent);
     400           0 :             if (!OutAirNodeManager::CheckOutAirNodeNumber(state, state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).OutdoorAirInletNodeNum)) {
     401           0 :                 ShowSevereError(state,
     402           0 :                                 format("{}= \"{}\" {}= \"{}\" not valid.",
     403             :                                        cCurrentModuleObject,
     404           0 :                                        state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).Name,
     405           0 :                                        state.dataIPShortCut->cAlphaFieldNames(5),
     406             :                                        AlphArray(5)));
     407           0 :                 ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
     408           0 :                 ErrorsFound = true;
     409             :             }
     410             :         }
     411             : 
     412           5 :         ErrorsFound |=
     413           5 :             state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum)
     414           5 :                 .validateTwoSpeedInputs(
     415           5 :                     state, cCurrentModuleObject, AlphArray, state.dataIPShortCut->cNumericFieldNames, state.dataIPShortCut->cAlphaFieldNames);
     416             :     }
     417             : 
     418           6 :     if (ErrorsFound) {
     419           0 :         ShowFatalError(state, "Errors found in getting fluid cooler input.");
     420             :     }
     421           6 : }
     422             : 
     423           6 : void FluidCoolerspecs::setupOutputVars(EnergyPlusData &state)
     424             : {
     425             : 
     426          12 :     SetupOutputVariable(state,
     427             :                         "Cooling Tower Inlet Temperature",
     428             :                         Constant::Units::C,
     429           6 :                         this->InletWaterTemp,
     430             :                         OutputProcessor::TimeStepType::System,
     431             :                         OutputProcessor::StoreType::Average,
     432           6 :                         this->Name);
     433          12 :     SetupOutputVariable(state,
     434             :                         "Cooling Tower Outlet Temperature",
     435             :                         Constant::Units::C,
     436           6 :                         this->OutletWaterTemp,
     437             :                         OutputProcessor::TimeStepType::System,
     438             :                         OutputProcessor::StoreType::Average,
     439           6 :                         this->Name);
     440          12 :     SetupOutputVariable(state,
     441             :                         "Cooling Tower Mass Flow Rate",
     442             :                         Constant::Units::kg_s,
     443           6 :                         this->WaterMassFlowRate,
     444             :                         OutputProcessor::TimeStepType::System,
     445             :                         OutputProcessor::StoreType::Average,
     446           6 :                         this->Name);
     447          12 :     SetupOutputVariable(state,
     448             :                         "Cooling Tower Heat Transfer Rate",
     449             :                         Constant::Units::W,
     450           6 :                         this->Qactual,
     451             :                         OutputProcessor::TimeStepType::System,
     452             :                         OutputProcessor::StoreType::Average,
     453           6 :                         this->Name);
     454          12 :     SetupOutputVariable(state,
     455             :                         "Cooling Tower Fan Electricity Rate",
     456             :                         Constant::Units::W,
     457           6 :                         this->FanPower,
     458             :                         OutputProcessor::TimeStepType::System,
     459             :                         OutputProcessor::StoreType::Average,
     460           6 :                         this->Name);
     461          12 :     SetupOutputVariable(state,
     462             :                         "Cooling Tower Fan Electricity Energy",
     463             :                         Constant::Units::J,
     464           6 :                         this->FanEnergy,
     465             :                         OutputProcessor::TimeStepType::System,
     466             :                         OutputProcessor::StoreType::Sum,
     467           6 :                         this->Name,
     468             :                         Constant::eResource::Electricity,
     469             :                         OutputProcessor::Group::Plant,
     470             :                         OutputProcessor::EndUseCat::HeatRejection);
     471           6 : }
     472             : 
     473           1 : bool FluidCoolerspecs::validateSingleSpeedInputs(EnergyPlusData &state,
     474             :                                                  std::string const &cCurrentModuleObject,
     475             :                                                  Array1D<std::string> const &AlphArray,
     476             :                                                  Array1D<std::string> const &cNumericFieldNames,
     477             :                                                  Array1D<std::string> const &cAlphaFieldNames)
     478             : {
     479             :     // FUNCTION INFORMATION:
     480             :     //       AUTHOR:          Chandan Sharma
     481             :     //       DATE WRITTEN:    August 2008
     482             :     //       MODIFIED         Chandan Sharma, FSEC, April 2010
     483             :     //       RE-ENGINEERED    Jason Glazer, GARD Analytics, February 2015, refactor into a separate function
     484             : 
     485             :     // PURPOSE OF THIS FUNCTION:
     486             :     // Separate the testing of inputs related to design so that it could be called from the unit tests
     487             : 
     488             :     // REFERENCES:
     489             :     // Based on GetTowerInput subroutine from Don Shirey, Jan 2001 and Sept/Oct 2002;
     490             : 
     491             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
     492           1 :     bool ErrorsFound = false;
     493             : 
     494             :     //   Design entering water temperature, design entering air temperature and design entering air
     495             :     //   wetbulb temperature must be specified for the both the performance input methods
     496           1 :     if (this->DesignEnteringWaterTemp <= 0.0) {
     497           0 :         ShowSevereError(state,
     498           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 ",
     499             :                                cCurrentModuleObject,
     500             :                                AlphArray(1),
     501             :                                cNumericFieldNames(3)));
     502           0 :         ErrorsFound = true;
     503             :     }
     504           1 :     if (this->DesignEnteringAirTemp <= 0.0) {
     505           0 :         ShowSevereError(state,
     506           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 ",
     507             :                                cCurrentModuleObject,
     508             :                                AlphArray(1),
     509             :                                cNumericFieldNames(4)));
     510           0 :         ErrorsFound = true;
     511             :     }
     512           1 :     if (this->DesignEnteringAirWetBulbTemp <= 0.0) {
     513           0 :         ShowSevereError(state,
     514           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 ",
     515             :                                cCurrentModuleObject,
     516             :                                AlphArray(1),
     517             :                                cNumericFieldNames(5)));
     518           0 :         ErrorsFound = true;
     519             :     }
     520           1 :     if (this->DesignEnteringWaterTemp <= this->DesignEnteringAirTemp) {
     521           0 :         ShowSevereError(
     522             :             state,
     523           0 :             format("{}= \"{}\",{} must be greater than {}.", cCurrentModuleObject, AlphArray(1), cNumericFieldNames(3), cNumericFieldNames(4)));
     524           0 :         ErrorsFound = true;
     525             :     }
     526           1 :     if (this->DesignEnteringAirTemp <= this->DesignEnteringAirWetBulbTemp) {
     527           0 :         ShowSevereError(
     528             :             state,
     529           0 :             format("{}= \"{}\",{} must be greater than {}.", cCurrentModuleObject, AlphArray(1), cNumericFieldNames(4), cNumericFieldNames(5)));
     530           0 :         ErrorsFound = true;
     531             :     }
     532           1 :     if (this->HighSpeedAirFlowRate <= 0.0 && this->HighSpeedAirFlowRate != DataSizing::AutoSize) {
     533           0 :         ShowSevereError(state,
     534           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     535             :                                cCurrentModuleObject,
     536             :                                AlphArray(1),
     537             :                                cNumericFieldNames(7),
     538             :                                cAlphaFieldNames(4),
     539             :                                AlphArray(4)));
     540           0 :         ErrorsFound = true;
     541             :     }
     542           1 :     if (this->DesignWaterFlowRate <= 0.0 && !this->DesignWaterFlowRateWasAutoSized) {
     543           0 :         ShowSevereError(state,
     544           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     545             :                                cCurrentModuleObject,
     546             :                                AlphArray(1),
     547             :                                cNumericFieldNames(6),
     548             :                                cAlphaFieldNames(4),
     549             :                                AlphArray(4)));
     550           0 :         ErrorsFound = true;
     551             :     }
     552           1 :     if (this->HighSpeedFanPower <= 0.0 && this->HighSpeedFanPower != DataSizing::AutoSize) {
     553           0 :         ShowSevereError(state,
     554           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     555             :                                cCurrentModuleObject,
     556             :                                AlphArray(1),
     557             :                                cNumericFieldNames(8),
     558             :                                cAlphaFieldNames(4),
     559             :                                AlphArray(4)));
     560           0 :         ErrorsFound = true;
     561             :     }
     562             : 
     563             :     //   Check various inputs for both the performance input methods
     564           1 :     if (Util::SameString(AlphArray(4), "UFactorTimesAreaAndDesignWaterFlowRate")) {
     565           0 :         this->PerformanceInputMethod_Num = PerfInputMethod::U_FACTOR;
     566           0 :         if (this->HighSpeedFluidCoolerUA <= 0.0 && this->HighSpeedFluidCoolerUA != DataSizing::AutoSize) {
     567           0 :             ShowSevereError(state,
     568           0 :                             format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     569             :                                    cCurrentModuleObject,
     570             :                                    AlphArray(1),
     571             :                                    cNumericFieldNames(1),
     572             :                                    cAlphaFieldNames(4),
     573             :                                    AlphArray(4)));
     574           0 :             ErrorsFound = true;
     575             :         }
     576           1 :     } else if (Util::SameString(AlphArray(4), "NominalCapacity")) {
     577           1 :         this->PerformanceInputMethod_Num = PerfInputMethod::NOMINAL_CAPACITY;
     578           1 :         if (this->FluidCoolerNominalCapacity <= 0.0) {
     579           0 :             ShowSevereError(state,
     580           0 :                             format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     581             :                                    cCurrentModuleObject,
     582             :                                    AlphArray(1),
     583             :                                    cNumericFieldNames(2),
     584             :                                    cAlphaFieldNames(4),
     585             :                                    AlphArray(4)));
     586           0 :             ErrorsFound = true;
     587             :         }
     588           1 :         if (this->HighSpeedFluidCoolerUA != 0.0) {
     589           0 :             if (this->HighSpeedFluidCoolerUA > 0.0) {
     590           0 :                 ShowWarningError(state,
     591           0 :                                  format("{}= \"{}\". Nominal fluid cooler capacity and design fluid cooler UA have been specified.",
     592             :                                         cCurrentModuleObject,
     593           0 :                                         this->Name));
     594             :             } else {
     595           0 :                 ShowWarningError(state,
     596           0 :                                  format("{}= \"{}\". Nominal fluid cooler capacity has been specified and design fluid cooler UA is being autosized.",
     597             :                                         cCurrentModuleObject,
     598           0 :                                         this->Name));
     599             :             }
     600           0 :             ShowContinueError(state,
     601             :                               "Design fluid cooler UA field must be left blank when nominal fluid cooler capacity performance input method is used.");
     602           0 :             ShowContinueError(state, "Design fluid cooler UA value will be reset to zero and the simulation continuous.");
     603           0 :             this->HighSpeedFluidCoolerUA = 0.0;
     604             :         }
     605             :     } else { // Fluid cooler performance input method is not specified as a valid "choice"
     606           0 :         ShowSevereError(state, format("{}= \"{}\", invalid {} = \"{}\".", cCurrentModuleObject, AlphArray(1), cAlphaFieldNames(4), AlphArray(4)));
     607           0 :         ShowContinueError(state, R"(... must be "UFactorTimesAreaAndDesignWaterFlowRate" or "NominalCapacity".)");
     608           0 :         ErrorsFound = true;
     609             :     }
     610           1 :     return ErrorsFound;
     611             : }
     612             : 
     613           5 : bool FluidCoolerspecs::validateTwoSpeedInputs(EnergyPlusData &state,
     614             :                                               std::string const &cCurrentModuleObject,
     615             :                                               Array1D<std::string> const &AlphArray,
     616             :                                               Array1D<std::string> const &cNumericFieldNames,
     617             :                                               Array1D<std::string> const &cAlphaFieldNames)
     618             : {
     619             :     // FUNCTION INFORMATION:
     620             :     //       AUTHOR:          Chandan Sharma
     621             :     //       DATE WRITTEN:    August 2008
     622             :     //       MODIFIED         Chandan Sharma, FSEC, April 2010
     623             :     //       RE-ENGINEERED    Jason Glazer, GARD Analytics, February 2015, refactor into a separate function
     624             : 
     625             :     // PURPOSE OF THIS FUNCTION:
     626             :     // Separate the testing of inputs related to design so that it could be called from the unit tests
     627             : 
     628             :     // REFERENCES:
     629             :     // Based on GetTowerInput subroutine from Don Shirey, Jan 2001 and Sept/Oct 2002;
     630             : 
     631             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
     632           5 :     bool ErrorsFound = false;
     633             : 
     634             :     //   Design entering water temperature, design entering air temperature and design entering air
     635             :     //   wetbulb temperature must be specified for the both the performance input methods
     636           5 :     if (this->DesignEnteringWaterTemp <= 0.0) {
     637           0 :         ShowSevereError(state,
     638           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 ",
     639             :                                cCurrentModuleObject,
     640             :                                AlphArray(1),
     641             :                                cNumericFieldNames(7)));
     642           0 :         ErrorsFound = true;
     643             :     }
     644           5 :     if (this->DesignEnteringAirTemp <= 0.0) {
     645           0 :         ShowSevereError(state,
     646           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 ",
     647             :                                cCurrentModuleObject,
     648             :                                AlphArray(1),
     649             :                                cNumericFieldNames(8)));
     650           0 :         ErrorsFound = true;
     651             :     }
     652           5 :     if (this->DesignEnteringAirWetBulbTemp <= 0.0) {
     653           0 :         ShowSevereError(state,
     654           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 ",
     655             :                                cCurrentModuleObject,
     656             :                                AlphArray(1),
     657             :                                cNumericFieldNames(9)));
     658           0 :         ErrorsFound = true;
     659             :     }
     660           5 :     if (this->DesignEnteringWaterTemp <= this->DesignEnteringAirTemp) {
     661           0 :         ShowSevereError(
     662             :             state,
     663           0 :             format("{} = \"{}\", {} must be greater than {}.", cCurrentModuleObject, AlphArray(1), cNumericFieldNames(7), cNumericFieldNames(8)));
     664           0 :         ErrorsFound = true;
     665             :     }
     666           5 :     if (this->DesignEnteringAirTemp <= this->DesignEnteringAirWetBulbTemp) {
     667           0 :         ShowSevereError(
     668             :             state,
     669           0 :             format("{} = \"{}\", {} must be greater than {}.", cCurrentModuleObject, AlphArray(1), cNumericFieldNames(8), cNumericFieldNames(9)));
     670           0 :         ErrorsFound = true;
     671             :     }
     672             : 
     673             :     //   Check various inputs for both the performance input methods
     674           5 :     if (this->DesignWaterFlowRate <= 0.0 && !this->DesignWaterFlowRateWasAutoSized) {
     675           0 :         ShowSevereError(state,
     676           0 :                         format("{}= \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {}= \"{}\".",
     677             :                                cCurrentModuleObject,
     678             :                                AlphArray(1),
     679             :                                cNumericFieldNames(10),
     680             :                                cAlphaFieldNames(4),
     681             :                                AlphArray(4)));
     682           0 :         ErrorsFound = true;
     683             :     }
     684           5 :     if (this->HighSpeedAirFlowRate <= 0.0 && !this->HighSpeedAirFlowRateWasAutoSized) {
     685           0 :         ShowSevereError(state,
     686           0 :                         format("{}= \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {}= \"{}\".",
     687             :                                cCurrentModuleObject,
     688             :                                AlphArray(1),
     689             :                                cNumericFieldNames(11),
     690             :                                cAlphaFieldNames(4),
     691             :                                AlphArray(4)));
     692           0 :         ErrorsFound = true;
     693             :     }
     694           5 :     if (this->LowSpeedAirFlowRate <= 0.0 && !this->LowSpeedAirFlowRateWasAutoSized) {
     695           0 :         ShowSevereError(state,
     696           0 :                         format("{}= \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {}= \"{}\".",
     697             :                                cCurrentModuleObject,
     698             :                                AlphArray(1),
     699             :                                cNumericFieldNames(13),
     700             :                                cAlphaFieldNames(4),
     701             :                                AlphArray(4)));
     702           0 :         ErrorsFound = true;
     703             :     }
     704             :     //   High speed air flow rate must be greater than low speed air flow rate.
     705             :     //   Can't tell yet if autosized, check later in InitFluidCooler.
     706           5 :     if (this->HighSpeedAirFlowRate <= this->LowSpeedAirFlowRate && !this->HighSpeedAirFlowRateWasAutoSized) {
     707           0 :         ShowSevereError(state,
     708           0 :                         format("{}= \"{}\". Fluid cooler air flow rate at low fan speed must be less than the air flow rate at high fan speed.",
     709             :                                cCurrentModuleObject,
     710           0 :                                this->Name));
     711           0 :         ErrorsFound = true;
     712             :     }
     713           5 :     if (this->HighSpeedFanPower <= 0.0 && !this->HighSpeedFanPowerWasAutoSized) {
     714           0 :         ShowSevereError(state,
     715           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     716             :                                cCurrentModuleObject,
     717             :                                AlphArray(1),
     718             :                                cNumericFieldNames(12),
     719             :                                cAlphaFieldNames(4),
     720             :                                AlphArray(4)));
     721           0 :         ErrorsFound = true;
     722             :     }
     723           5 :     if (this->LowSpeedFanPower <= 0.0 && !this->LowSpeedFanPowerWasAutoSized) {
     724           0 :         ShowSevereError(state,
     725           0 :                         format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     726             :                                cCurrentModuleObject,
     727             :                                AlphArray(1),
     728             :                                cNumericFieldNames(15),
     729             :                                cAlphaFieldNames(4),
     730             :                                AlphArray(4)));
     731           0 :         ErrorsFound = true;
     732             :     }
     733           5 :     if (this->HighSpeedFanPower <= this->LowSpeedFanPower && !this->HighSpeedFanPowerWasAutoSized) {
     734           0 :         ShowSevereError(
     735           0 :             state, format("{}= \"{}\". Fluid cooler low speed fan power must be less than high speed fan power.", cCurrentModuleObject, this->Name));
     736           0 :         ErrorsFound = true;
     737             :     }
     738             : 
     739           5 :     if (Util::SameString(AlphArray(4), "UFactorTimesAreaAndDesignWaterFlowRate")) {
     740           0 :         this->PerformanceInputMethod_Num = PerfInputMethod::U_FACTOR;
     741           0 :         if (this->HighSpeedFluidCoolerUA <= 0.0 && !this->HighSpeedFluidCoolerUAWasAutoSized) {
     742           0 :             ShowSevereError(state,
     743           0 :                             format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     744             :                                    cCurrentModuleObject,
     745             :                                    AlphArray(1),
     746             :                                    cNumericFieldNames(1),
     747             :                                    cAlphaFieldNames(4),
     748             :                                    AlphArray(4)));
     749           0 :             ErrorsFound = true;
     750             :         }
     751           0 :         if (this->LowSpeedFluidCoolerUA <= 0.0 && !this->LowSpeedFluidCoolerUAWasAutoSized) {
     752           0 :             ShowSevereError(state,
     753           0 :                             format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {} = \"{}\".",
     754             :                                    cCurrentModuleObject,
     755             :                                    AlphArray(1),
     756             :                                    cNumericFieldNames(2),
     757             :                                    cAlphaFieldNames(4),
     758             :                                    AlphArray(4)));
     759           0 :             ErrorsFound = true;
     760             :         }
     761           0 :         if (this->HighSpeedFluidCoolerUA <= this->LowSpeedFluidCoolerUA && !this->HighSpeedFluidCoolerUAWasAutoSized) {
     762           0 :             ShowSevereError(state,
     763           0 :                             format("{}= \"{}\". Fluid cooler UA at low fan speed must be less than the fluid cooler UA at high fan speed.",
     764             :                                    cCurrentModuleObject,
     765           0 :                                    this->Name));
     766           0 :             ErrorsFound = true;
     767             :         }
     768           5 :     } else if (Util::SameString(AlphArray(4), "NominalCapacity")) {
     769           5 :         this->PerformanceInputMethod_Num = PerfInputMethod::NOMINAL_CAPACITY;
     770           5 :         if (this->FluidCoolerNominalCapacity <= 0.0) {
     771           0 :             ShowSevereError(state,
     772           0 :                             format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {}= \"{}\".",
     773             :                                    cCurrentModuleObject,
     774             :                                    AlphArray(1),
     775             :                                    cNumericFieldNames(4),
     776             :                                    cAlphaFieldNames(4),
     777             :                                    AlphArray(4)));
     778           0 :             ErrorsFound = true;
     779             :         }
     780           5 :         if (this->FluidCoolerLowSpeedNomCap <= 0.0 && !this->FluidCoolerLowSpeedNomCapWasAutoSized) {
     781           0 :             ShowSevereError(state,
     782           0 :                             format("{} = \"{}\", invalid data for \"{}\", entered value <= 0.0, but must be > 0 for {}= \"{}\".",
     783             :                                    cCurrentModuleObject,
     784             :                                    AlphArray(1),
     785             :                                    cNumericFieldNames(5),
     786             :                                    cAlphaFieldNames(4),
     787             :                                    AlphArray(4)));
     788           0 :             ErrorsFound = true;
     789             :         }
     790           5 :         if (this->HighSpeedFluidCoolerUA != 0.0) {
     791           0 :             if (this->HighSpeedFluidCoolerUA > 0.0) {
     792           0 :                 ShowSevereError(state,
     793           0 :                                 format("{}= \"{}\". Nominal capacity input method and fluid cooler UA at high fan speed have been specified.",
     794             :                                        cCurrentModuleObject,
     795           0 :                                        this->Name));
     796             :             } else {
     797           0 :                 ShowSevereError(
     798             :                     state,
     799           0 :                     format("{}= \"{}\". Nominal capacity input method has been specified and fluid cooler UA at high fan speed is being autosized.",
     800             :                            cCurrentModuleObject,
     801           0 :                            this->Name));
     802             :             }
     803           0 :             ShowContinueError(
     804             :                 state, "Fluid cooler UA at high fan speed must be left blank when nominal fluid cooler capacity performance input method is used.");
     805           0 :             ErrorsFound = true;
     806             :         }
     807           5 :         if (this->LowSpeedFluidCoolerUA != 0.0) {
     808           0 :             if (this->LowSpeedFluidCoolerUA > 0.0) {
     809           0 :                 ShowSevereError(state,
     810           0 :                                 format("{}= \"{}\". Nominal capacity input method and fluid cooler UA at low fan speed have been specified.",
     811             :                                        cCurrentModuleObject,
     812           0 :                                        this->Name));
     813             :             } else {
     814           0 :                 ShowSevereError(
     815             :                     state,
     816           0 :                     format("{}= \"{}\". Nominal capacity input method has been specified and fluid cooler UA at low fan speed is being autosized.",
     817             :                            cCurrentModuleObject,
     818           0 :                            this->Name));
     819             :             }
     820           0 :             ShowContinueError(
     821             :                 state, "Fluid cooler UA at low fan speed must be left blank when nominal fluid cooler capacity performance input method is used.");
     822           0 :             ErrorsFound = true;
     823             :         }
     824           5 :         if (this->FluidCoolerLowSpeedNomCap >= this->FluidCoolerNominalCapacity) {
     825           0 :             ShowSevereError(state,
     826           0 :                             format("{} = \"{}\". Low-speed nominal capacity must be less than the high-speed nominal capacity.",
     827             :                                    cCurrentModuleObject,
     828           0 :                                    this->Name));
     829           0 :             ErrorsFound = true;
     830             :         }
     831             :     } else { // Fluid cooler performance input method is not specified as a valid "choice"
     832           0 :         ShowSevereError(state, format("{}= \"{}\", invalid {}= \"{}\".", cCurrentModuleObject, AlphArray(1), cAlphaFieldNames(4), AlphArray(4)));
     833           0 :         ShowContinueError(state, R"(... must be "UFactorTimesAreaAndDesignWaterFlowRate" or "NominalCapacity".)");
     834           0 :         ErrorsFound = true;
     835             :     }
     836           5 :     return ErrorsFound;
     837             : }
     838             : 
     839           6 : void FluidCoolerspecs::oneTimeInit_new(EnergyPlusData &state)
     840             : {
     841           6 :     this->setupOutputVars(state);
     842           6 :     bool ErrorsFound = false;
     843             :     // Locate the tower on the plant loops for later usage
     844           6 :     PlantUtilities::ScanPlantLoopsForObject(state, this->Name, this->FluidCoolerType, this->plantLoc, ErrorsFound, _, _, _, _, _);
     845             : 
     846           6 :     if (ErrorsFound) {
     847           0 :         ShowFatalError(state, "InitFluidCooler: Program terminated due to previous condition(s).");
     848             :     }
     849           6 : }
     850             : 
     851          40 : void FluidCoolerspecs::initEachEnvironment(EnergyPlusData &state)
     852             : {
     853             :     static constexpr std::string_view RoutineName("FluidCoolerspecs::initEachEnvironment");
     854          40 :     Real64 const rho = FluidProperties::GetDensityGlycol(state,
     855          40 :                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
     856             :                                                          Constant::InitConvTemp,
     857          40 :                                                          state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
     858             :                                                          RoutineName);
     859          40 :     this->DesWaterMassFlowRate = this->DesignWaterFlowRate * rho;
     860          40 :     PlantUtilities::InitComponentNodes(state, 0.0, this->DesWaterMassFlowRate, this->WaterInletNodeNum, this->WaterOutletNodeNum);
     861          40 : }
     862             : 
     863      160625 : void FluidCoolerspecs::initialize(EnergyPlusData &state)
     864             : {
     865             : 
     866             :     // SUBROUTINE INFORMATION:
     867             :     //       AUTHOR         Chandan Sharma
     868             :     //       DATE WRITTEN   August 2008
     869             : 
     870             :     // PURPOSE OF THIS SUBROUTINE:
     871             :     // This subroutine is for initializations of the fluid cooler components and for
     872             :     // final checking of fluid cooler inputs (post autosizing)
     873             : 
     874             :     // METHODOLOGY EMPLOYED:
     875             :     // Uses the status flags to trigger initializations.
     876             : 
     877             :     // REFERENCES:
     878             :     // Based on InitTower subroutine by Don Shirey Sept/Oct 2002, F Buhl Oct 2002
     879             : 
     880             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     881             : 
     882             :     // Begin environment initializations
     883      160625 :     if (this->beginEnvrnInit && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
     884          40 :         this->initEachEnvironment(state);
     885          40 :         this->beginEnvrnInit = false;
     886             :     }
     887             : 
     888      160625 :     if (!state.dataGlobal->BeginEnvrnFlag) {
     889      159936 :         this->beginEnvrnInit = true;
     890             :     }
     891             : 
     892             :     // Each time initializations
     893      160625 :     this->WaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
     894             : 
     895      160625 :     if (this->OutdoorAirInletNodeNum != 0) {
     896           0 :         this->AirTemp = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).Temp;
     897           0 :         this->AirHumRat = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).HumRat;
     898           0 :         this->AirPress = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).Press;
     899           0 :         this->AirWetBulb = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).OutAirWetBulb;
     900             :     } else {
     901      160625 :         this->AirTemp = state.dataEnvrn->OutDryBulbTemp;
     902      160625 :         this->AirHumRat = state.dataEnvrn->OutHumRat;
     903      160625 :         this->AirPress = state.dataEnvrn->OutBaroPress;
     904      160625 :         this->AirWetBulb = state.dataEnvrn->OutWetBulbTemp;
     905             :     }
     906             : 
     907      160625 :     this->WaterMassFlowRate =
     908      160625 :         PlantUtilities::RegulateCondenserCompFlowReqOp(state, this->plantLoc, this->DesWaterMassFlowRate * this->FluidCoolerMassFlowRateMultiplier);
     909             : 
     910      160625 :     PlantUtilities::SetComponentFlowRate(state, this->WaterMassFlowRate, this->WaterInletNodeNum, this->WaterOutletNodeNum, this->plantLoc);
     911      160625 : }
     912             : 
     913          30 : void FluidCoolerspecs::size(EnergyPlusData &state)
     914             : {
     915             : 
     916             :     // SUBROUTINE INFORMATION:
     917             :     //       AUTHOR         Chandan Sharma
     918             :     //       DATE WRITTEN   August 2008
     919             :     //       MODIFIED       April 2010, Chandan Sharma, FSEC
     920             : 
     921             :     // PURPOSE OF THIS SUBROUTINE:
     922             :     // This subroutine is for sizing fluid cooler Components for which capacities and flow rates
     923             :     // have not been specified in the input. This subroutine also calculates fluid cooler UA if the user
     924             :     // has specified fluid cooler performance via the "Nominal Capacity" method.
     925             : 
     926             :     // METHODOLOGY EMPLOYED:
     927             :     // Obtains condenser flow rate from the plant sizing array. If fluid cooler performance is specified
     928             :     // via the "Nominal Capacity" method, the water flow rate is directly proportional to capacity.
     929             : 
     930             :     // REFERENCES:
     931             :     // Based on SizeTower by Don Shirey, Sept/Oct 2002; Richard Raustad, Feb 2005
     932             : 
     933             :     // SUBROUTINE PARAMETER DEFINITIONS:
     934          30 :     constexpr int MaxIte(500);    // Maximum number of iterations
     935          30 :     constexpr Real64 Acc(0.0001); // Accuracy of result
     936             :     static constexpr std::string_view CalledFrom("SizeFluidCooler");
     937             : 
     938             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     939             :     int SolFla;                           // Flag of solver
     940          30 :     Real64 DesFluidCoolerLoad(0.0);       // Design fluid cooler load [W]
     941             :     Real64 UA0;                           // Lower bound for UA [W/C]
     942             :     Real64 UA1;                           // Upper bound for UA [W/C]
     943             :     Real64 UA;                            // Calculated UA value
     944             :     Real64 OutWaterTempAtUA0;             // Water outlet temperature at UA0
     945             :     Real64 OutWaterTempAtUA1;             // Water outlet temperature at UA1
     946             :     Real64 Cp;                            // local specific heat for fluid
     947             :     Real64 rho;                           // local density for fluid
     948             :     Real64 tmpHighSpeedFanPower;          // local temporary for high speed fan power
     949             :     Real64 tmpHighSpeedEvapFluidCoolerUA; // local temporary for high speed cooler UA
     950             :     bool ErrorsFound;
     951             : 
     952          30 :     Real64 tmpDesignWaterFlowRate = this->DesignWaterFlowRate;
     953          30 :     Real64 tmpHighSpeedAirFlowRate = this->HighSpeedAirFlowRate;
     954             :     // Find the appropriate Plant Sizing object
     955          30 :     int PltSizCondNum = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).PlantSizNum;
     956             : 
     957          30 :     if (this->DesignWaterFlowRateWasAutoSized) {
     958          25 :         if (PltSizCondNum > 0) {
     959          25 :             if (state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
     960          20 :                 tmpDesignWaterFlowRate = state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate;
     961          20 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
     962             :             } else {
     963           5 :                 tmpDesignWaterFlowRate = 0.0;
     964           5 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
     965             :             }
     966          25 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     967           5 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     968          10 :                     BaseSizer::reportSizerOutput(state,
     969           5 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
     970             :                                                  this->Name,
     971             :                                                  "Design Water Flow Rate [m3/s]",
     972             :                                                  this->DesignWaterFlowRate);
     973             :                 }
     974           5 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
     975           0 :                     BaseSizer::reportSizerOutput(state,
     976           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
     977             :                                                  this->Name,
     978             :                                                  "Initial Design Water Flow Rate [m3/s]",
     979             :                                                  this->DesignWaterFlowRate);
     980             :                 }
     981             :             }
     982          25 :             this->DesignLeavingWaterTemp = state.dataSize->PlantSizData(PltSizCondNum).ExitTemp;
     983             :         } else {
     984           0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     985           0 :                 ShowSevereError(state, format("Autosizing error for fluid cooler object = {}", this->Name));
     986           0 :                 ShowFatalError(state, "Autosizing of fluid cooler condenser flow rate requires a loop Sizing:Plant object.");
     987             :             }
     988             :         }
     989             :         // This conditional statement is to trap when the user specified Condenser/Fluid Cooler water design setpoint
     990             :         // temperature is less than design inlet air dry bulb temperature
     991          25 :         if (state.dataSize->PlantSizData(PltSizCondNum).ExitTemp <= this->DesignEnteringAirTemp && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     992           0 :             ShowSevereError(state, format("Error when autosizing the UA value for fluid cooler = {}.", this->Name));
     993           0 :             ShowContinueError(state,
     994           0 :                               format("Design Loop Exit Temperature ({:.2R} C) must be greater than design entering air dry-bulb temperature "
     995             :                                      "({:.2R} C) when autosizing the fluid cooler UA.",
     996           0 :                                      state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
     997           0 :                                      this->DesignEnteringAirTemp));
     998           0 :             ShowContinueError(state,
     999             :                               "It is recommended that the Design Loop Exit Temperature = design inlet air dry-bulb temp plus the Fluid Cooler "
    1000             :                               "design approach temperature (e.g., 4 C).");
    1001           0 :             ShowContinueError(state,
    1002             :                               "If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design Setpoint must be "
    1003             :                               "> design inlet air dry-bulb temp if autosizing the Fluid Cooler.");
    1004           0 :             ShowFatalError(state, "Review and revise design input values as appropriate.");
    1005             :         }
    1006             :     }
    1007             : 
    1008          30 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->WaterInletNodeNum, tmpDesignWaterFlowRate);
    1009             : 
    1010          30 :     if (this->PerformanceInputMethod_Num == PerfInputMethod::U_FACTOR && this->HighSpeedFluidCoolerUAWasAutoSized) {
    1011           0 :         if (PltSizCondNum > 0) {
    1012           0 :             rho = FluidProperties::GetDensityGlycol(state,
    1013           0 :                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1014             :                                                     Constant::InitConvTemp,
    1015           0 :                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1016             :                                                     CalledFrom);
    1017           0 :             Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1018           0 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1019           0 :                                                         state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
    1020           0 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1021             :                                                         CalledFrom);
    1022           0 :             DesFluidCoolerLoad = rho * Cp * tmpDesignWaterFlowRate * state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
    1023           0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->FluidCoolerNominalCapacity = DesFluidCoolerLoad;
    1024             :         } else {
    1025           0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->FluidCoolerNominalCapacity = 0.0;
    1026             :         }
    1027             :     }
    1028             : 
    1029          30 :     if (this->HighSpeedFanPowerWasAutoSized) {
    1030             :         // We assume the nominal fan power is 0.0105 times the design load
    1031          10 :         if (this->PerformanceInputMethod_Num == PerfInputMethod::NOMINAL_CAPACITY) {
    1032          10 :             tmpHighSpeedFanPower = 0.0105 * this->FluidCoolerNominalCapacity;
    1033          10 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
    1034             :         } else {
    1035           0 :             if (DesFluidCoolerLoad > 0.0) {
    1036           0 :                 tmpHighSpeedFanPower = 0.0105 * DesFluidCoolerLoad;
    1037           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
    1038           0 :             } else if (PltSizCondNum > 0) {
    1039           0 :                 if (state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1040             :                     // This conditional statement is to trap when the user specified Condenser/Fluid Cooler water design setpoint
    1041             :                     // temperature is less than design inlet air dry bulb temperature
    1042           0 :                     if (state.dataSize->PlantSizData(PltSizCondNum).ExitTemp <= this->DesignEnteringAirTemp &&
    1043           0 :                         state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1044           0 :                         ShowSevereError(state, format("Error when autosizing the UA value for fluid cooler = {}.", this->Name));
    1045           0 :                         ShowContinueError(state,
    1046           0 :                                           format("Design Loop Exit Temperature ({:.2R} C) must be greater than design entering air dry-bulb "
    1047             :                                                  "temperature ({:.2R} C) when autosizing the fluid cooler UA.",
    1048           0 :                                                  state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
    1049           0 :                                                  this->DesignEnteringAirTemp));
    1050           0 :                         ShowContinueError(state,
    1051             :                                           "It is recommended that the Design Loop Exit Temperature = design inlet air dry-bulb temp plus the "
    1052             :                                           "Fluid Cooler design approach temperature (e.g., 4 C).");
    1053           0 :                         ShowContinueError(state,
    1054             :                                           "If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design "
    1055             :                                           "Setpoint must be > design inlet air dry-bulb temp if autosizing the Fluid Cooler.");
    1056           0 :                         ShowFatalError(state, "Review and revise design input values as appropriate.");
    1057             :                     }
    1058           0 :                     rho = FluidProperties::GetDensityGlycol(state,
    1059           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1060             :                                                             Constant::InitConvTemp,
    1061           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1062             :                                                             CalledFrom);
    1063           0 :                     Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1064           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1065           0 :                                                                 state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
    1066           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1067             :                                                                 CalledFrom);
    1068           0 :                     DesFluidCoolerLoad = rho * Cp * tmpDesignWaterFlowRate * state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
    1069           0 :                     tmpHighSpeedFanPower = 0.0105 * DesFluidCoolerLoad;
    1070           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
    1071             :                 } else {
    1072           0 :                     tmpHighSpeedFanPower = 0.0;
    1073           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
    1074             :                 }
    1075             :             } else {
    1076           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1077           0 :                     ShowSevereError(state, "Autosizing of fluid cooler fan power requires a loop Sizing:Plant object.");
    1078           0 :                     ShowFatalError(state, format(" Occurs in fluid cooler object = {}", this->Name));
    1079             :                 }
    1080             :             }
    1081             :         }
    1082          10 :         if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_SingleSpd) {
    1083           5 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1084           1 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1085           2 :                     BaseSizer::reportSizerOutput(state,
    1086           1 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1087             :                                                  this->Name,
    1088             :                                                  "Fan Power at Design Air Flow Rate [W]",
    1089             :                                                  this->HighSpeedFanPower);
    1090             :                 }
    1091           1 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1092           0 :                     BaseSizer::reportSizerOutput(state,
    1093           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1094             :                                                  this->Name,
    1095             :                                                  "Initial Fan Power at Design Air Flow Rate [W]",
    1096             :                                                  this->HighSpeedFanPower);
    1097             :                 }
    1098             :             }
    1099           5 :         } else if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_TwoSpd) {
    1100           5 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1101           1 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1102           2 :                     BaseSizer::reportSizerOutput(state,
    1103           1 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1104             :                                                  this->Name,
    1105             :                                                  "Fan Power at High Fan Speed [W]",
    1106             :                                                  this->HighSpeedFanPower);
    1107             :                 }
    1108           1 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1109           0 :                     BaseSizer::reportSizerOutput(state,
    1110           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1111             :                                                  this->Name,
    1112             :                                                  "Initial Fan Power at High Fan Speed [W]",
    1113             :                                                  this->HighSpeedFanPower);
    1114             :                 }
    1115             :             }
    1116             :         }
    1117             :     }
    1118             : 
    1119          30 :     if (this->HighSpeedAirFlowRateWasAutoSized) {
    1120          25 :         if (this->PerformanceInputMethod_Num == PerfInputMethod::NOMINAL_CAPACITY) {
    1121          25 :             tmpHighSpeedAirFlowRate = this->FluidCoolerNominalCapacity / (this->DesignEnteringWaterTemp - this->DesignEnteringAirTemp) * 4.0;
    1122          25 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedAirFlowRate = tmpHighSpeedAirFlowRate;
    1123             :         } else {
    1124           0 :             if (DesFluidCoolerLoad > 0.0) {
    1125           0 :                 tmpHighSpeedAirFlowRate = DesFluidCoolerLoad / (this->DesignEnteringWaterTemp - this->DesignEnteringAirTemp) * 4.0;
    1126           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedAirFlowRate = tmpHighSpeedAirFlowRate;
    1127           0 :             } else if (PltSizCondNum > 0) {
    1128           0 :                 if (state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1129             :                     // This conditional statement is to trap when the user specified Condenser/Fluid Cooler water design setpoint
    1130             :                     // temperature is less than design inlet air dry bulb temperature
    1131           0 :                     if (state.dataSize->PlantSizData(PltSizCondNum).ExitTemp <= this->DesignEnteringAirTemp &&
    1132           0 :                         state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1133           0 :                         ShowSevereError(state, format("Error when autosizing the UA value for fluid cooler = {}.", this->Name));
    1134           0 :                         ShowContinueError(state,
    1135           0 :                                           format("Design Loop Exit Temperature ({:.2R} C) must be greater than design entering air dry-bulb "
    1136             :                                                  "temperature ({:.2R} C) when autosizing the fluid cooler UA.",
    1137           0 :                                                  state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
    1138           0 :                                                  this->DesignEnteringAirTemp));
    1139           0 :                         ShowContinueError(state,
    1140             :                                           "It is recommended that the Design Loop Exit Temperature = design inlet air dry-bulb temp plus the "
    1141             :                                           "Fluid Cooler design approach temperature (e.g., 4 C).");
    1142           0 :                         ShowContinueError(state,
    1143             :                                           "If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design "
    1144             :                                           "Setpoint must be > design inlet air dry-bulb temp if autosizing the Fluid Cooler.");
    1145           0 :                         ShowFatalError(state, "Review and revise design input values as appropriate.");
    1146             :                     }
    1147           0 :                     rho = FluidProperties::GetDensityGlycol(state,
    1148           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1149             :                                                             Constant::InitConvTemp,
    1150           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1151             :                                                             CalledFrom);
    1152           0 :                     Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1153           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1154           0 :                                                                 state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
    1155           0 :                                                                 state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1156             :                                                                 CalledFrom);
    1157           0 :                     DesFluidCoolerLoad = rho * Cp * tmpDesignWaterFlowRate * state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
    1158           0 :                     tmpHighSpeedAirFlowRate = DesFluidCoolerLoad / (this->DesignEnteringWaterTemp - this->DesignEnteringAirTemp) * 4.0;
    1159           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedAirFlowRate = tmpHighSpeedAirFlowRate;
    1160             :                 } else {
    1161           0 :                     tmpHighSpeedAirFlowRate = 0.0;
    1162           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedAirFlowRate = tmpHighSpeedAirFlowRate;
    1163             :                 }
    1164             :             } else {
    1165           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1166           0 :                     ShowSevereError(state, "Autosizing of fluid cooler air flow rate requires a loop Sizing:Plant object");
    1167           0 :                     ShowFatalError(state, format(" Occurs in fluid cooler object = {}", this->Name));
    1168             :                 }
    1169             :             }
    1170             :         }
    1171          25 :         if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_SingleSpd) {
    1172           0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1173           0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1174           0 :                     BaseSizer::reportSizerOutput(state,
    1175           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1176             :                                                  this->Name,
    1177             :                                                  "Design Air Flow Rate [m3/s]",
    1178             :                                                  this->HighSpeedAirFlowRate);
    1179             :                 }
    1180           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1181           0 :                     BaseSizer::reportSizerOutput(state,
    1182           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1183             :                                                  this->Name,
    1184             :                                                  "Initial Design Air Flow Rate [m3/s]",
    1185             :                                                  this->HighSpeedAirFlowRate);
    1186             :                 }
    1187             :             }
    1188          25 :         } else if (DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)] == "FluidCooler:TwoSpeed") {
    1189          25 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1190           5 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1191          10 :                     BaseSizer::reportSizerOutput(state,
    1192           5 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1193             :                                                  this->Name,
    1194             :                                                  "Air Flow Rate at High Fan Speed [m3/s]",
    1195             :                                                  this->HighSpeedAirFlowRate);
    1196             :                 }
    1197           5 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1198           0 :                     BaseSizer::reportSizerOutput(state,
    1199           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1200             :                                                  this->Name,
    1201             :                                                  "Initial Air Flow Rate at High Fan Speed [m3/s]",
    1202             :                                                  this->HighSpeedAirFlowRate);
    1203             :                 }
    1204             :             }
    1205             :         }
    1206             :     }
    1207             : 
    1208          30 :     if (this->HighSpeedFluidCoolerUAWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1209           0 :         if (PltSizCondNum > 0) {
    1210           0 :             if (state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1211             :                 // This conditional statement is to trap when the user specified Condenser/Fluid Cooler water design setpoint
    1212             :                 // temperature is less than design inlet air dry bulb temperature
    1213           0 :                 if (state.dataSize->PlantSizData(PltSizCondNum).ExitTemp <= this->DesignEnteringAirTemp &&
    1214           0 :                     state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1215           0 :                     ShowSevereError(state, format("Error when autosizing the UA value for fluid cooler = {}.", this->Name));
    1216           0 :                     ShowContinueError(state,
    1217           0 :                                       format("Design Loop Exit Temperature ({:.2R} C) must be greater than design entering air dry-bulb "
    1218             :                                              "temperature ({:.2R} C) when autosizing the fluid cooler UA.",
    1219           0 :                                              state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
    1220           0 :                                              this->DesignEnteringAirTemp));
    1221           0 :                     ShowContinueError(state,
    1222             :                                       "It is recommended that the Design Loop Exit Temperature = design inlet air dry-bulb temp plus the Fluid "
    1223             :                                       "Cooler design approach temperature (e.g., 4 C).");
    1224           0 :                     ShowContinueError(state,
    1225             :                                       "If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design Setpoint "
    1226             :                                       "must be > design inlet air dry-bulb temp if autosizing the Fluid Cooler.");
    1227           0 :                     ShowFatalError(state, "Review and revise design input values as appropriate.");
    1228             :                 }
    1229           0 :                 rho = FluidProperties::GetDensityGlycol(state,
    1230           0 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1231             :                                                         Constant::InitConvTemp,
    1232           0 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1233             :                                                         CalledFrom);
    1234           0 :                 Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1235           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1236           0 :                                                             state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
    1237           0 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1238             :                                                             CalledFrom);
    1239           0 :                 DesFluidCoolerLoad = rho * Cp * tmpDesignWaterFlowRate * state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
    1240           0 :                 UA0 = 0.0001 * DesFluidCoolerLoad; // Assume deltaT = 10000K (limit)
    1241           0 :                 UA1 = DesFluidCoolerLoad;          // Assume deltaT = 1K
    1242           0 :                 this->WaterTemp = state.dataSize->PlantSizData(PltSizCondNum).ExitTemp + state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
    1243           0 :                 this->AirTemp = this->DesignEnteringAirTemp;
    1244           0 :                 this->AirWetBulb = this->DesignEnteringAirWetBulbTemp;
    1245           0 :                 this->AirPress = state.dataEnvrn->StdBaroPress;
    1246           0 :                 this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress, CalledFrom);
    1247           0 :                 auto f = [&state, this, DesFluidCoolerLoad, rho, tmpDesignWaterFlowRate, tmpHighSpeedAirFlowRate, Cp](Real64 const UA) {
    1248           0 :                     Real64 OutWaterTemp = 0.0; // outlet water temperature [C]
    1249           0 :                     CalcFluidCoolerOutlet(state, this->indexInArray, rho * tmpDesignWaterFlowRate, tmpHighSpeedAirFlowRate, UA, OutWaterTemp);
    1250             :                     Real64 const Output =
    1251           0 :                         Cp * rho * tmpDesignWaterFlowRate * (state.dataFluidCoolers->SimpleFluidCooler(this->indexInArray).WaterTemp - OutWaterTemp);
    1252           0 :                     return (DesFluidCoolerLoad - Output) / DesFluidCoolerLoad;
    1253           0 :                 };
    1254           0 :                 General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    1255           0 :                 if (SolFla == -1) {
    1256           0 :                     ShowWarningError(state, "Iteration limit exceeded in calculating fluid cooler UA.");
    1257           0 :                     ShowContinueError(state, format("Autosizing of fluid cooler UA failed for fluid cooler = {}", this->Name));
    1258           0 :                     ShowContinueError(state, format("The final UA value ={:.2R} W/K, and the simulation continues...", UA));
    1259           0 :                 } else if (SolFla == -2) {
    1260           0 :                     CalcFluidCoolerOutlet(state, this->indexInArray, rho * tmpDesignWaterFlowRate, tmpHighSpeedAirFlowRate, UA0, OutWaterTempAtUA0);
    1261           0 :                     CalcFluidCoolerOutlet(state, this->indexInArray, rho * tmpDesignWaterFlowRate, tmpHighSpeedAirFlowRate, UA1, OutWaterTempAtUA1);
    1262           0 :                     ShowSevereError(state, format("{}: The combination of design input values did not allow the calculation of a ", CalledFrom));
    1263           0 :                     ShowContinueError(state, "reasonable UA value. Review and revise design input values as appropriate. Specifying hard");
    1264           0 :                     ShowContinueError(state, R"(sizes for some "autosizable" fields while autosizing other "autosizable" fields may be )");
    1265           0 :                     ShowContinueError(state, "contributing to this problem.");
    1266           0 :                     ShowContinueError(state, "This model iterates on UA to find the heat transfer required to provide the design outlet ");
    1267           0 :                     ShowContinueError(state, "water temperature. Initially, the outlet water temperatures at high and low UA values are ");
    1268           0 :                     ShowContinueError(state, "calculated. The Design Exit Water Temperature should be between the outlet water ");
    1269           0 :                     ShowContinueError(state, "temperatures calculated at high and low UA values. If the Design Exit Water Temperature is ");
    1270           0 :                     ShowContinueError(state, "out of this range, the solution will not converge and UA will not be calculated. ");
    1271           0 :                     ShowContinueError(state, "The possible solutions could be to manually input adjusted water and/or air flow rates based ");
    1272           0 :                     ShowContinueError(state, "on the autosized values shown below or to adjust design fluid cooler air inlet dry-bulb temperature.");
    1273           0 :                     ShowContinueError(state, "Plant:Sizing object inputs also influence these results (e.g. DeltaT and ExitTemp).");
    1274           0 :                     ShowContinueError(state, "Inputs to the fluid cooler object:");
    1275           0 :                     ShowContinueError(state, format("Design Fluid Cooler Load [W]                       = {:.2R}", DesFluidCoolerLoad));
    1276           0 :                     ShowContinueError(state, format("Design Fluid Cooler Water Volume Flow Rate [m3/s]  = {:.6R}", this->DesignWaterFlowRate));
    1277           0 :                     ShowContinueError(state, format("Design Fluid Cooler Air Volume Flow Rate [m3/s]    = {:.2R}", tmpHighSpeedAirFlowRate));
    1278           0 :                     ShowContinueError(state, format("Design Fluid Cooler Air Inlet Dry-bulb Temp [C]    = {:.2R}", this->AirTemp));
    1279           0 :                     ShowContinueError(state, "Inputs to the plant sizing object:");
    1280           0 :                     ShowContinueError(
    1281             :                         state,
    1282           0 :                         format("Design Exit Water Temp [C]                         = {:.2R}", state.dataSize->PlantSizData(PltSizCondNum).ExitTemp));
    1283           0 :                     ShowContinueError(
    1284             :                         state,
    1285           0 :                         format("Loop Design Temperature Difference [C]             = {:.2R}", state.dataSize->PlantSizData(PltSizCondNum).DeltaT));
    1286           0 :                     ShowContinueError(state, format("Design Fluid Cooler Water Inlet Temp [C]           = {:.2R}", this->WaterTemp));
    1287           0 :                     ShowContinueError(state, format("Calculated water outlet temp at low UA [C] (UA = {:.2R} W/K) = {:.2R}", UA0, OutWaterTempAtUA0));
    1288           0 :                     ShowContinueError(state, format("Calculated water outlet temp at high UA [C](UA = {:.2R} W/K) = {:.2R}", UA1, OutWaterTempAtUA1));
    1289           0 :                     ShowFatalError(state, format("Autosizing of Fluid Cooler UA failed for fluid cooler = {}", this->Name));
    1290             :                 }
    1291           0 :                 tmpHighSpeedEvapFluidCoolerUA = UA;
    1292           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFluidCoolerUA = tmpHighSpeedEvapFluidCoolerUA;
    1293           0 :                 this->FluidCoolerNominalCapacity = DesFluidCoolerLoad;
    1294             :             } else {
    1295           0 :                 tmpHighSpeedEvapFluidCoolerUA = 0.0;
    1296           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFluidCoolerUA = tmpHighSpeedEvapFluidCoolerUA;
    1297             :             }
    1298           0 :             if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_SingleSpd) {
    1299           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1300           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1301           0 :                         BaseSizer::reportSizerOutput(state,
    1302           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1303             :                                                      this->Name,
    1304             :                                                      "U-factor Times Area Value at Design Air Flow Rate [W/K]",
    1305             :                                                      this->HighSpeedFluidCoolerUA);
    1306             :                     }
    1307           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1308           0 :                         BaseSizer::reportSizerOutput(state,
    1309           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1310             :                                                      this->Name,
    1311             :                                                      "Initial U-factor Times Area Value at Design Air Flow Rate [W/K]",
    1312             :                                                      this->HighSpeedFluidCoolerUA);
    1313             :                     }
    1314             :                 }
    1315           0 :             } else if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_TwoSpd) {
    1316           0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1317           0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1318           0 :                         BaseSizer::reportSizerOutput(state,
    1319           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1320             :                                                      this->Name,
    1321             :                                                      "U-factor Times Area Value at High Fan Speed [W/K]",
    1322             :                                                      this->HighSpeedFluidCoolerUA);
    1323             :                     }
    1324           0 :                     if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1325           0 :                         BaseSizer::reportSizerOutput(state,
    1326           0 :                                                      DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1327             :                                                      this->Name,
    1328             :                                                      "Initial U-factor Times Area Value at High Fan Speed [W/K]",
    1329             :                                                      this->HighSpeedFluidCoolerUA);
    1330             :                     }
    1331             :                 }
    1332             :             }
    1333             :         } else {
    1334           0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1335           0 :                 ShowSevereError(state, format("Autosizing error for fluid cooler object = {}", this->Name));
    1336           0 :                 ShowFatalError(state, "Autosizing of fluid cooler UA requires a loop Sizing:Plant object.");
    1337             :             }
    1338             :         }
    1339             :     }
    1340             : 
    1341          30 :     if (this->PerformanceInputMethod_Num == PerfInputMethod::NOMINAL_CAPACITY) {
    1342          30 :         if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow) {
    1343          10 :             rho = FluidProperties::GetDensityGlycol(state,
    1344          10 :                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1345             :                                                     Constant::InitConvTemp,
    1346          10 :                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1347             :                                                     CalledFrom);
    1348          10 :             Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1349          10 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1350             :                                                         this->DesignEnteringWaterTemp,
    1351          10 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1352             :                                                         CalledFrom);
    1353          10 :             DesFluidCoolerLoad = this->FluidCoolerNominalCapacity;
    1354          10 :             Real64 par2_WaterFlow = rho * tmpDesignWaterFlowRate;
    1355          10 :             UA0 = 0.0001 * DesFluidCoolerLoad;                     // Assume deltaT = 10000K (limit)
    1356          10 :             UA1 = DesFluidCoolerLoad;                              // Assume deltaT = 1K
    1357          10 :             this->WaterTemp = this->DesignEnteringWaterTemp;       // design inlet water temperature
    1358          10 :             this->AirTemp = this->DesignEnteringAirTemp;           // design inlet air dry-bulb temp
    1359          10 :             this->AirWetBulb = this->DesignEnteringAirWetBulbTemp; // design inlet air wet-bulb temp
    1360          10 :             this->AirPress = state.dataEnvrn->StdBaroPress;
    1361          10 :             this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress);
    1362         768 :             auto f = [&state, this, DesFluidCoolerLoad, par2_WaterFlow, tmpHighSpeedAirFlowRate, Cp](Real64 const UA) {
    1363         192 :                 Real64 OutWaterTemp = 0.0; // outlet water temperature [C]
    1364         192 :                 CalcFluidCoolerOutlet(state, this->indexInArray, par2_WaterFlow, tmpHighSpeedAirFlowRate, UA, OutWaterTemp);
    1365         192 :                 Real64 const Output = Cp * par2_WaterFlow * (state.dataFluidCoolers->SimpleFluidCooler(this->indexInArray).WaterTemp - OutWaterTemp);
    1366         192 :                 return (DesFluidCoolerLoad - Output) / DesFluidCoolerLoad;
    1367          10 :             };
    1368          10 :             General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    1369          10 :             if (SolFla == -1) {
    1370           0 :                 ShowWarningError(state, "Iteration limit exceeded in calculating fluid cooler UA.");
    1371           0 :                 if (PltSizCondNum > 0) {
    1372           0 :                     ShowContinueError(state, format("Autosizing of fluid cooler UA failed for fluid cooler = {}", this->Name));
    1373             :                 }
    1374           0 :                 ShowContinueError(state, format("The final UA value ={:.2R} W/K, and the simulation continues...", UA));
    1375          10 :             } else if (SolFla == -2) {
    1376           0 :                 CalcFluidCoolerOutlet(state, this->indexInArray, rho * tmpDesignWaterFlowRate, tmpHighSpeedAirFlowRate, UA0, OutWaterTempAtUA0);
    1377           0 :                 CalcFluidCoolerOutlet(state, this->indexInArray, rho * tmpDesignWaterFlowRate, tmpHighSpeedAirFlowRate, UA1, OutWaterTempAtUA1);
    1378           0 :                 ShowSevereError(state, format("{}: The combination of design input values did not allow the calculation of a ", CalledFrom));
    1379           0 :                 ShowContinueError(state, "reasonable UA value. Review and revise design input values as appropriate. Specifying hard");
    1380           0 :                 ShowContinueError(state, R"(sizes for some "autosizable" fields while autosizing other "autosizable" fields may be )");
    1381           0 :                 ShowContinueError(state, "contributing to this problem.");
    1382           0 :                 ShowContinueError(state, "This model iterates on UA to find the heat transfer required to provide the design outlet ");
    1383           0 :                 ShowContinueError(state, "water temperature. Initially, the outlet water temperatures at high and low UA values are ");
    1384           0 :                 ShowContinueError(state, "calculated. The Design Exit Water Temperature should be between the outlet water ");
    1385           0 :                 ShowContinueError(state, "temperatures calculated at high and low UA values. If the Design Exit Water Temperature is ");
    1386           0 :                 ShowContinueError(state, "out of this range, the solution will not converge and UA will not be calculated. ");
    1387           0 :                 ShowContinueError(state, "The possible solutions could be to manually input adjusted water and/or air flow rates based ");
    1388           0 :                 ShowContinueError(state, "on the autosized values shown below or to adjust design fluid cooler air inlet dry-bulb temperature.");
    1389           0 :                 ShowContinueError(state, "Plant:Sizing object inputs also influence these results (e.g. DeltaT and ExitTemp).");
    1390           0 :                 ShowContinueError(state, "Inputs to the fluid cooler object:");
    1391           0 :                 ShowContinueError(state, format("Design Fluid Cooler Load [W]                       = {:.2R}", DesFluidCoolerLoad));
    1392           0 :                 ShowContinueError(state, format("Design Fluid Cooler Water Volume Flow Rate [m3/s]  = {:.6R}", this->DesignWaterFlowRate));
    1393           0 :                 ShowContinueError(state, format("Design Fluid Cooler Air Volume Flow Rate [m3/s]    = {:.2R}", tmpHighSpeedAirFlowRate));
    1394           0 :                 ShowContinueError(state, format("Design Fluid Cooler Air Inlet Dry-bulb Temp [C]    = {:.2R}", this->AirTemp));
    1395           0 :                 if (PltSizCondNum > 0) {
    1396           0 :                     ShowContinueError(state, "Inputs to the plant sizing object:");
    1397           0 :                     ShowContinueError(
    1398             :                         state,
    1399           0 :                         format("Design Exit Water Temp [C]                         = {:.2R}", state.dataSize->PlantSizData(PltSizCondNum).ExitTemp));
    1400           0 :                     ShowContinueError(
    1401             :                         state,
    1402           0 :                         format("Loop Design Temperature Difference [C]             = {:.2R}", state.dataSize->PlantSizData(PltSizCondNum).DeltaT));
    1403             :                 }
    1404           0 :                 ShowContinueError(state, format("Design Fluid Cooler Water Inlet Temp [C]           = {:.2R}", this->WaterTemp));
    1405           0 :                 ShowContinueError(state, format("Calculated water outlet temp at low UA [C] (UA = {:.2R} W/K) = {:.2R}", UA0, OutWaterTempAtUA0));
    1406           0 :                 ShowContinueError(state, format("Calculated water outlet temp at high UA [C] (UA = {:.2R} W/K) = {:.2R}", UA1, OutWaterTempAtUA1));
    1407           0 :                 if (PltSizCondNum > 0) {
    1408           0 :                     ShowFatalError(state, format("Autosizing of Fluid Cooler UA failed for fluid cooler = {}", this->Name));
    1409             :                 }
    1410             :             }
    1411          10 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFluidCoolerUA = UA;
    1412             :         } else {
    1413          20 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFluidCoolerUA = 0.0;
    1414             :         }
    1415          30 :         if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_SingleSpd) {
    1416           5 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1417           1 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1418           2 :                     BaseSizer::reportSizerOutput(state,
    1419           1 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1420             :                                                  this->Name,
    1421             :                                                  "Fluid cooler UA value at design air flow rate based on nominal capacity input [W/K]",
    1422             :                                                  this->HighSpeedFluidCoolerUA);
    1423             :                 }
    1424           1 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1425           0 :                     BaseSizer::reportSizerOutput(state,
    1426           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1427             :                                                  this->Name,
    1428             :                                                  "Initial Fluid cooler UA value at design air flow rate based on nominal capacity input [W/K]",
    1429             :                                                  this->HighSpeedFluidCoolerUA);
    1430             :                 }
    1431             :             }
    1432          25 :         } else if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_TwoSpd) {
    1433          25 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1434           5 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1435          10 :                     BaseSizer::reportSizerOutput(state,
    1436           5 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1437             :                                                  this->Name,
    1438             :                                                  "Fluid cooler UA value at high fan speed based on nominal capacity input [W/K]",
    1439             :                                                  this->HighSpeedFluidCoolerUA);
    1440             :                 }
    1441           5 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1442           0 :                     BaseSizer::reportSizerOutput(state,
    1443           0 :                                                  DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1444             :                                                  this->Name,
    1445             :                                                  "Initial Fluid cooler UA value at high fan speed based on nominal capacity input [W/K]",
    1446             :                                                  this->HighSpeedFluidCoolerUA);
    1447             :                 }
    1448             :             }
    1449             :         }
    1450             :     }
    1451             : 
    1452          30 :     if (this->LowSpeedAirFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1453           5 :         this->LowSpeedAirFlowRate = this->LowSpeedAirFlowRateSizingFactor * this->HighSpeedAirFlowRate;
    1454           5 :         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1455          10 :             BaseSizer::reportSizerOutput(state,
    1456           5 :                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1457             :                                          this->Name,
    1458             :                                          "Air Flow Rate at Low Fan Speed [m3/s]",
    1459             :                                          this->LowSpeedAirFlowRate);
    1460             :         }
    1461           5 :         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1462           0 :             BaseSizer::reportSizerOutput(state,
    1463           0 :                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1464             :                                          this->Name,
    1465             :                                          "Initial Air Flow Rate at Low Fan Speed [m3/s]",
    1466             :                                          this->LowSpeedAirFlowRate);
    1467             :         }
    1468             :     }
    1469             : 
    1470          30 :     if (this->LowSpeedFanPowerWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1471           5 :         this->LowSpeedFanPower = this->LowSpeedFanPowerSizingFactor * this->HighSpeedFanPower;
    1472           5 :         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1473          10 :             BaseSizer::reportSizerOutput(state,
    1474           5 :                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1475             :                                          this->Name,
    1476             :                                          "Fan Power at Low Fan Speed [W]",
    1477             :                                          this->LowSpeedFanPower);
    1478             :         }
    1479           5 :         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1480           0 :             BaseSizer::reportSizerOutput(state,
    1481           0 :                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1482             :                                          this->Name,
    1483             :                                          "Initial Fan Power at Low Fan Speed [W]",
    1484             :                                          this->LowSpeedFanPower);
    1485             :         }
    1486             :     }
    1487             : 
    1488          30 :     if (this->LowSpeedFluidCoolerUAWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1489           0 :         this->LowSpeedFluidCoolerUA = this->LowSpeedFluidCoolerUASizingFactor * this->HighSpeedFluidCoolerUA;
    1490           0 :         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1491           0 :             BaseSizer::reportSizerOutput(state,
    1492           0 :                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1493             :                                          this->Name,
    1494             :                                          "U-factor Times Area Value at Low Fan Speed [W/K]",
    1495             :                                          this->LowSpeedFluidCoolerUA);
    1496             :         }
    1497           0 :         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1498           0 :             BaseSizer::reportSizerOutput(state,
    1499           0 :                                          DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1500             :                                          this->Name,
    1501             :                                          "Initial U-factor Times Area Value at Low Fan Speed [W/K]",
    1502             :                                          this->LowSpeedFluidCoolerUA);
    1503             :         }
    1504             :     }
    1505             : 
    1506          30 :     if (this->PerformanceInputMethod_Num == PerfInputMethod::NOMINAL_CAPACITY &&
    1507          30 :         this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_TwoSpd) {
    1508          25 :         if (this->FluidCoolerLowSpeedNomCapWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1509           0 :             this->FluidCoolerLowSpeedNomCap = this->FluidCoolerLowSpeedNomCapSizingFactor * this->FluidCoolerNominalCapacity;
    1510           0 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1511           0 :                 BaseSizer::reportSizerOutput(state,
    1512           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1513             :                                              this->Name,
    1514             :                                              "Low Fan Speed Nominal Capacity [W]",
    1515             :                                              this->FluidCoolerLowSpeedNomCap);
    1516             :             }
    1517           0 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1518           0 :                 BaseSizer::reportSizerOutput(state,
    1519           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1520             :                                              this->Name,
    1521             :                                              "Initial Low Fan Speed Nominal Capacity [W]",
    1522             :                                              this->FluidCoolerLowSpeedNomCap);
    1523             :             }
    1524             :         }
    1525             : 
    1526          25 :         if (this->DesignWaterFlowRate >= HVAC::SmallWaterVolFlow && this->FluidCoolerLowSpeedNomCap > 0.0) {
    1527           5 :             rho = FluidProperties::GetDensityGlycol(state,
    1528           5 :                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1529             :                                                     Constant::InitConvTemp,
    1530           5 :                                                     state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1531             :                                                     CalledFrom);
    1532           5 :             Cp = FluidProperties::GetSpecificHeatGlycol(state,
    1533           5 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1534             :                                                         this->DesignEnteringWaterTemp,
    1535           5 :                                                         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1536             :                                                         CalledFrom);
    1537           5 :             DesFluidCoolerLoad = this->FluidCoolerLowSpeedNomCap;
    1538           5 :             UA0 = 0.0001 * DesFluidCoolerLoad;                     // Assume deltaT = 10000K (limit)
    1539           5 :             UA1 = DesFluidCoolerLoad;                              // Assume deltaT = 1K
    1540           5 :             this->WaterTemp = this->DesignEnteringWaterTemp;       // design inlet water temperature
    1541           5 :             this->AirTemp = this->DesignEnteringAirTemp;           // design inlet air dry-bulb temp
    1542           5 :             this->AirWetBulb = this->DesignEnteringAirWetBulbTemp; // design inlet air wet-bulb temp
    1543           5 :             this->AirPress = state.dataEnvrn->StdBaroPress;
    1544           5 :             this->AirHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, this->AirTemp, this->AirWetBulb, this->AirPress, CalledFrom);
    1545         184 :             auto f = [&state, this, DesFluidCoolerLoad, rho, tmpDesignWaterFlowRate, Cp](Real64 const UA) {
    1546          46 :                 Real64 OutWaterTemp = 0.0; // outlet water temperature [C]
    1547          46 :                 CalcFluidCoolerOutlet(state, this->indexInArray, rho * tmpDesignWaterFlowRate, this->LowSpeedAirFlowRate, UA, OutWaterTemp);
    1548             :                 Real64 const Output =
    1549          46 :                     Cp * rho * tmpDesignWaterFlowRate * (state.dataFluidCoolers->SimpleFluidCooler(this->indexInArray).WaterTemp - OutWaterTemp);
    1550          46 :                 return (DesFluidCoolerLoad - Output) / DesFluidCoolerLoad;
    1551           5 :             };
    1552           5 :             General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
    1553           5 :             if (SolFla == -1) {
    1554           0 :                 ShowWarningError(state, "Iteration limit exceeded in calculating fluid cooler UA.");
    1555           0 :                 ShowContinueError(state, format("Autosizing of fluid cooler UA failed for fluid cooler = {}", this->Name));
    1556           0 :                 ShowContinueError(state, format("The final UA value at low fan speed ={:.2R} W/C, and the simulation continues...", UA));
    1557           5 :             } else if (SolFla == -2) {
    1558           0 :                 CalcFluidCoolerOutlet(state, this->indexInArray, rho * tmpDesignWaterFlowRate, this->LowSpeedAirFlowRate, UA0, OutWaterTempAtUA0);
    1559           0 :                 CalcFluidCoolerOutlet(state, this->indexInArray, rho * tmpDesignWaterFlowRate, this->LowSpeedAirFlowRate, UA1, OutWaterTempAtUA1);
    1560           0 :                 ShowSevereError(state, format("{}: The combination of design input values did not allow the calculation of a ", CalledFrom));
    1561           0 :                 ShowContinueError(state, "reasonable low-speed UA value. Review and revise design input values as appropriate. ");
    1562           0 :                 ShowContinueError(state, R"(Specifying hard sizes for some "autosizable" fields while autosizing other "autosizable" )");
    1563           0 :                 ShowContinueError(state, "fields may be contributing to this problem.");
    1564           0 :                 ShowContinueError(state, "This model iterates on UA to find the heat transfer required to provide the design outlet ");
    1565           0 :                 ShowContinueError(state, "water temperature. Initially, the outlet water temperatures at high and low UA values are ");
    1566           0 :                 ShowContinueError(state, "calculated. The Design Exit Water Temperature should be between the outlet water ");
    1567           0 :                 ShowContinueError(state, "temperatures calculated at high and low UA values. If the Design Exit Water Temperature is ");
    1568           0 :                 ShowContinueError(state, "out of this range, the solution will not converge and UA will not be calculated. ");
    1569           0 :                 ShowContinueError(state, "The possible solutions could be to manually input adjusted water and/or air flow rates based ");
    1570           0 :                 ShowContinueError(state, "on the autosized values shown below or to adjust design fluid cooler air inlet dry-bulb temperature.");
    1571           0 :                 ShowContinueError(state, "Plant:Sizing object inputs also influence these results (e.g. DeltaT and ExitTemp).");
    1572           0 :                 ShowContinueError(state, "Inputs to the fluid cooler object:");
    1573           0 :                 ShowContinueError(state, format("Design Fluid Cooler Load [W]                         = {:.2R}", DesFluidCoolerLoad));
    1574           0 :                 ShowContinueError(state, format("Design Fluid Cooler Water Volume Flow Rate [m3/s]    = {:.6R}", this->DesignWaterFlowRate));
    1575           0 :                 ShowContinueError(state, format("Design Fluid Cooler Air Volume Flow Rate [m3/s]      = {:.2R}", this->LowSpeedAirFlowRate));
    1576           0 :                 ShowContinueError(state, format("Design Fluid Cooler Air Inlet Dry-bulb Temp [C]      = {:.2R}", this->AirTemp));
    1577           0 :                 ShowContinueError(state, "Inputs to the plant sizing object:");
    1578           0 :                 ShowContinueError(
    1579             :                     state,
    1580           0 :                     format("Design Exit Water Temp [C]                           = {:.2R}", state.dataSize->PlantSizData(PltSizCondNum).ExitTemp));
    1581           0 :                 ShowContinueError(
    1582             :                     state,
    1583           0 :                     format("Loop Design Temperature Difference [C]               = {:.2R}", state.dataSize->PlantSizData(PltSizCondNum).DeltaT));
    1584           0 :                 ShowContinueError(state, format("Design Fluid Cooler Water Inlet Temp [C]             = {:.2R}", this->WaterTemp));
    1585           0 :                 ShowContinueError(state, format("Calculated water outlet temp at low UA [C](UA = {:.2R} W/C) = {:.2R}", UA0, OutWaterTempAtUA0));
    1586           0 :                 ShowContinueError(state, format("Calculated water outlet temp at high UA [C](UA = {:.2R} W/C) = {:.2R}", UA1, OutWaterTempAtUA1));
    1587           0 :                 ShowFatalError(state, format("Autosizing of Fluid Cooler UA failed for fluid cooler = {}", this->Name));
    1588             :             }
    1589           5 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->LowSpeedFluidCoolerUA = UA;
    1590           5 :         } else {
    1591          20 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->LowSpeedFluidCoolerUA = 0.0;
    1592             :         }
    1593          25 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1594           5 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1595          10 :                 BaseSizer::reportSizerOutput(state,
    1596           5 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1597             :                                              this->Name,
    1598             :                                              "U-factor Times Area Value at Low Fan Speed [W/C]",
    1599             :                                              this->LowSpeedFluidCoolerUA);
    1600             :             }
    1601           5 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1602           0 :                 BaseSizer::reportSizerOutput(state,
    1603           0 :                                              DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1604             :                                              this->Name,
    1605             :                                              "Initial U-factor Times Area Value at Low Fan Speed [W/C]",
    1606             :                                              this->LowSpeedFluidCoolerUA);
    1607             :             }
    1608             :         }
    1609             :     }
    1610             : 
    1611          30 :     ErrorsFound = false;
    1612             : 
    1613          30 :     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1614             :         // create predefined report
    1615          12 :         OutputReportPredefined::PreDefTableEntry(
    1616          12 :             state, state.dataOutRptPredefined->pdchMechType, this->Name, DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)]);
    1617           6 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, this->Name, this->FluidCoolerNominalCapacity);
    1618             : 
    1619             :         // create std 229 new table for cooling towers and fluid coolers
    1620          12 :         OutputReportPredefined::PreDefTableEntry(
    1621          12 :             state, state.dataOutRptPredefined->pdchCTFCType, this->Name, DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)]);
    1622          12 :         OutputReportPredefined::PreDefTableEntry(state,
    1623           6 :                                                  state.dataOutRptPredefined->pdchCTFCCondLoopName,
    1624             :                                                  this->Name,
    1625          12 :                                                  this->plantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(this->plantLoc.loopNum).Name : "N/A");
    1626          12 :         OutputReportPredefined::PreDefTableEntry(
    1627             :             state,
    1628           6 :             state.dataOutRptPredefined->pdchCTFCCondLoopBranchName,
    1629             :             this->Name,
    1630          12 :             this->plantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(plantLoc.loopNum).LoopSide(plantLoc.loopSideNum).Branch(plantLoc.branchNum).Name
    1631             :                                        : "N/A");
    1632          12 :         OutputReportPredefined::PreDefTableEntry(
    1633             :             state,
    1634           6 :             state.dataOutRptPredefined->pdchCTFCFluidType,
    1635             :             this->Name,
    1636           6 :             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName); // Fluid Name more reasonable than FluidType
    1637          12 :         OutputReportPredefined::PreDefTableEntry(
    1638           6 :             state, state.dataOutRptPredefined->pdchCTFCRange, this->Name, this->DesignEnteringWaterTemp - this->DesignLeavingWaterTemp);
    1639          12 :         OutputReportPredefined::PreDefTableEntry(
    1640           6 :             state, state.dataOutRptPredefined->pdchCTFCApproach, this->Name, this->DesignLeavingWaterTemp - this->DesignEnteringAirWetBulbTemp);
    1641          12 :         OutputReportPredefined::PreDefTableEntry(
    1642           6 :             state, state.dataOutRptPredefined->pdchCTFCDesFanPwr, this->Name, this->HighSpeedFanPower); // eqival to Design Fan Power?
    1643          12 :         OutputReportPredefined::PreDefTableEntry(
    1644           6 :             state, state.dataOutRptPredefined->pdchCTFCDesInletAirWBT, this->Name, this->DesignEnteringAirWetBulbTemp);
    1645           6 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCTFCDesWaterFlowRate, this->Name, this->DesignWaterFlowRate);
    1646           6 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCTFCLevWaterSPTemp, this->Name, this->DesignLeavingWaterTemp);
    1647             :     }
    1648             : 
    1649          30 :     if (this->FluidCoolerType == DataPlant::PlantEquipmentType::FluidCooler_TwoSpd && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1650           5 :         if (this->DesignWaterFlowRate > 0.0) {
    1651           5 :             if (this->HighSpeedAirFlowRate <= this->LowSpeedAirFlowRate) {
    1652           0 :                 ShowSevereError(
    1653           0 :                     state, format("FluidCooler:TwoSpeed  \"{}\". Low speed air flow rate must be less than high speed air flow rate.", this->Name));
    1654           0 :                 ErrorsFound = true;
    1655             :             }
    1656           5 :             if (this->HighSpeedFluidCoolerUA <= this->LowSpeedFluidCoolerUA) {
    1657           0 :                 ShowSevereError(
    1658             :                     state,
    1659           0 :                     format("FluidCooler:TwoSpeed  \"{}\". Fluid cooler UA at low fan speed must be less than the fluid cooler UA at high fan speed.",
    1660           0 :                            this->Name));
    1661           0 :                 ErrorsFound = true;
    1662             :             }
    1663             :         }
    1664             :     }
    1665             : 
    1666          30 :     if (ErrorsFound) {
    1667           0 :         ShowFatalError(state, "SizeFluidCooler: Program terminated due to previous condition(s).");
    1668             :     }
    1669          30 : }
    1670             : 
    1671       22981 : void FluidCoolerspecs::calcSingleSpeed(EnergyPlusData &state)
    1672             : {
    1673             : 
    1674             :     // SUBROUTINE INFORMATION:
    1675             :     //       AUTHOR         Chandan Sharma
    1676             :     //       DATE WRITTEN   August 2008
    1677             :     //       MODIFIED       Dec. 2008. BG. added RunFlag logic per original methodology
    1678             : 
    1679             :     // PURPOSE OF THIS SUBROUTINE:
    1680             :     // To simulate the operation of a single-speed fan fluid cooler.
    1681             : 
    1682             :     // METHODOLOGY EMPLOYED:
    1683             :     // The fluid cooler is modeled using effectiveness-NTU relationships for
    1684             :     // cross flow heat exchangers (both stream unmixed)based on cooling tower model.
    1685             :     // The subroutine calculates the period of time required to meet a
    1686             :     // leaving water temperature setpoint. It assumes that part-load
    1687             :     // operation represents a linear interpolation of two steady-state regimes.
    1688             :     // Cyclic losses are neglected. The period of time required to meet the
    1689             :     // leaving water temperature setpoint is used to determine the required
    1690             :     // fan power and energy.
    1691             :     // A RunFlag is passed by the upper level manager to indicate the ON/OFF status,
    1692             :     // or schedule, of the fluid cooler. If the fluid cooler is OFF, outlet water
    1693             :     // temperature and flow rate are passed through the model from inlet node to
    1694             :     // outlet node without intervention. Reports are also updated with fan power
    1695             :     // and energy being zero.
    1696             :     // When the RunFlag indicates an ON condition for thefluid cooler, the
    1697             :     // mass flow rate and water temperature are read from the inlet node of the
    1698             :     // fluid cooler (water-side). The outdoor air dry-bulb temperature is used
    1699             :     // as the entering condition to thefluid cooler (air-side).Thefluid cooler
    1700             :     // fan is turned on and design parameters are used to calculate the leaving
    1701             :     // water temperature.If the calculated leaving water temperature is below the setpoint,
    1702             :     // a fan run-time fraction is calculated and used to determine fan power. The leaving
    1703             :     // water temperature setpoint is placed on the outlet node. If the calculated
    1704             :     // leaving water temperature is at or above the setpoint, the calculated
    1705             :     // leaving water temperature is placed on the outlet node and the fan runs at
    1706             :     // full power. Water mass flow rate is passed from inlet node to outlet node
    1707             :     // with no intervention.
    1708             : 
    1709             :     // REFERENCES:
    1710             :     // ASHRAE HVAC1KIT: A Toolkit for Primary HVAC System Energy Calculation. 1999.
    1711             :     // Based on SingleSpeedTower subroutine by Dan Fisher ,Sept 1998.
    1712             : 
    1713             :     // SUBROUTINE PARAMETER DEFINITIONS:
    1714             :     static constexpr std::string_view RoutineName("SingleSpeedFluidCooler");
    1715             : 
    1716             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1717       22981 :     Real64 TempSetPoint = 0.0;
    1718             : 
    1719             :     // set inlet and outlet nodes
    1720       22981 :     this->Qactual = 0.0;
    1721       22981 :     this->FanPower = 0.0;
    1722       22981 :     this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    1723       22981 :     switch (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopDemandCalcScheme) {
    1724       22981 :     case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1725       22981 :         TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPoint;
    1726       22981 :     } break;
    1727           0 :     case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1728           0 :         TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPointHi;
    1729           0 :     } break;
    1730           0 :     default:
    1731           0 :         break;
    1732             :     }
    1733             : 
    1734             :     //   MassFlowTol is a parameter to indicate a no flow condition
    1735       22981 :     if (this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) return;
    1736             : 
    1737        4960 :     if (this->OutletWaterTemp < TempSetPoint) { // already there don't need to run the cooler
    1738           0 :         return;
    1739             :     }
    1740             : 
    1741             :     //   Initialize local variables
    1742        4960 :     Real64 OutletWaterTempOFF = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    1743        4960 :     this->OutletWaterTemp = OutletWaterTempOFF;
    1744             : 
    1745        4960 :     Real64 UAdesign = this->HighSpeedFluidCoolerUA;
    1746        4960 :     Real64 AirFlowRate = this->HighSpeedAirFlowRate;
    1747        4960 :     Real64 FanPowerOn = this->HighSpeedFanPower;
    1748             : 
    1749        4960 :     CalcFluidCoolerOutlet(state, this->indexInArray, this->WaterMassFlowRate, AirFlowRate, UAdesign, this->OutletWaterTemp);
    1750             : 
    1751        4960 :     if (this->OutletWaterTemp <= TempSetPoint) {
    1752             :         //   Setpoint was met with pump ON and fan ON, calculate run-time fraction or just wasn't needed at all
    1753           0 :         Real64 FanModeFrac = 0.0;
    1754           0 :         if (this->OutletWaterTemp != OutletWaterTempOFF) { // don't divide by zero
    1755           0 :             FanModeFrac = (TempSetPoint - OutletWaterTempOFF) / (this->OutletWaterTemp - OutletWaterTempOFF);
    1756             :         }
    1757           0 :         this->FanPower = max(FanModeFrac * FanPowerOn, 0.0); // BG change
    1758           0 :         this->OutletWaterTemp = TempSetPoint;
    1759             :     } else {
    1760             :         //    Setpoint was not met, fluid cooler ran at full capacity
    1761        4960 :         this->FanPower = FanPowerOn;
    1762             :     }
    1763        4960 :     Real64 CpWater = FluidProperties::GetSpecificHeatGlycol(state,
    1764        4960 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1765        4960 :                                                             state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp,
    1766        4960 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1767             :                                                             RoutineName);
    1768        4960 :     this->Qactual = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    1769             : }
    1770             : 
    1771      137614 : void FluidCoolerspecs::calcTwoSpeed(EnergyPlusData &state)
    1772             : {
    1773             : 
    1774             :     // SUBROUTINE INFORMATION:
    1775             :     //       AUTHOR         Chandan Sharma
    1776             :     //       DATE WRITTEN   August 2008
    1777             :     //       MODIFIED       Dec. 2008. BG. added RunFlag logic per original methodology
    1778             : 
    1779             :     // PURPOSE OF THIS SUBROUTINE:
    1780             :     // To simulate the operation of a fluid cooler with a two-speed fan.
    1781             : 
    1782             :     // METHODOLOGY EMPLOYED:
    1783             :     // The fluid cooler is modeled using effectiveness-NTU relationships for
    1784             :     // cross flow heat exchangers (both stream unmixed)based on cooling tower model.
    1785             :     // The subroutine calculates the period of time required to meet a
    1786             :     // leaving water temperature setpoint. It assumes that part-load
    1787             :     // operation represents a linear interpolation of two steady-state regimes
    1788             :     // (high-speed fan operation and low-speed fan operation).
    1789             :     // Cyclic losses are neglected. The period of time required to meet the
    1790             :     // leaving water temperature setpoint is used to determine the required
    1791             :     // fan power and energy.
    1792             :     // A RunFlag is passed by the upper level manager to indicate the ON/OFF status,
    1793             :     // or schedule, of the fluid cooler. If the fluid cooler is OFF, outlet water
    1794             :     // temperature and flow rate are passed through the model from inlet node to
    1795             :     // outlet node without intervention.Reports are also updated with fan power
    1796             :     // and fan energy being zero.
    1797             :     // When the RunFlag indicates an ON condition for the fluid cooler, the
    1798             :     // mass flow rate and water temperature are read from the inlet node of the
    1799             :     // fluid cooler (water-side). The outdoor air dry-bulb temperature is used
    1800             :     // as the entering condition to the fluid cooler (air-side). Input deck
    1801             :     // parameters are read for the low fan speed and a leaving water temperature
    1802             :     // is calculated.
    1803             :     // If the calculated leaving water temperature is below the setpoint,
    1804             :     // a fan run-time fraction (FanModeFrac) is calculated and used to determine fan power.
    1805             :     // The leaving water temperature setpoint is placed on the outlet node.
    1806             :     // If the calculated leaving water temperature is at or above
    1807             :     // the setpoint, the fluid cooler fan is turned on 'high speed' and the routine is
    1808             :     // repeated. If the calculated leaving water temperature is below the setpoint,
    1809             :     // a fan run-time fraction is calculated for the second stage fan and fan power
    1810             :     // is calculated as FanModeFrac*HighSpeedFanPower+(1-FanModeFrac)*LowSpeedFanPower.
    1811             :     // If the calculated leaving water temperature is above the leaving water temp.
    1812             :     // setpoint, the calculated leaving water temperature is placed on the outlet
    1813             :     // node and the fan runs at full power (High Speed Fan Power). Water mass flow
    1814             :     // rate is passed from inlet node to outlet node with no intervention.
    1815             : 
    1816             :     // REFERENCES:
    1817             :     // ASHRAE HVAC1KIT: A Toolkit for Primary HVAC System Energy Calculation. 1999.
    1818             :     // Based on TwoSpeedTower by Dan Fisher ,Sept. 1998.
    1819             : 
    1820             :     // SUBROUTINE PARAMETER DEFINITIONS:
    1821             :     static constexpr std::string_view RoutineName("TwoSpeedFluidCooler");
    1822             : 
    1823             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1824      137614 :     Real64 TempSetPoint = 0.0;
    1825             : 
    1826      137614 :     this->Qactual = 0.0;
    1827      137614 :     this->FanPower = 0.0;
    1828      137614 :     this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    1829      137614 :     switch (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopDemandCalcScheme) {
    1830       22982 :     case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1831       22982 :         TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPoint;
    1832       22982 :     } break;
    1833      114632 :     case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1834      114632 :         TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPointHi;
    1835      114632 :     } break;
    1836           0 :     default:
    1837           0 :         break;
    1838             :     }
    1839             : 
    1840             :     // MassFlowTol is a parameter to indicate a no flow condition
    1841      256878 :     if (this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance ||
    1842      119264 :         state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked)
    1843       77982 :         return;
    1844             : 
    1845             :     // set local variable for fluid cooler
    1846       59632 :     this->WaterMassFlowRate = state.dataLoopNodes->Node(this->WaterInletNodeNum).MassFlowRate;
    1847       59632 :     Real64 OutletWaterTempOFF = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    1848       59632 :     Real64 OutletWaterTemp1stStage = OutletWaterTempOFF;
    1849       59632 :     Real64 OutletWaterTemp2ndStage = OutletWaterTempOFF;
    1850       59632 :     Real64 FanModeFrac = 0.0;
    1851             : 
    1852       59632 :     if (OutletWaterTempOFF < TempSetPoint) { // already there don't need to run the cooler
    1853           0 :         return;
    1854             :     }
    1855             : 
    1856       59632 :     Real64 UAdesign = this->LowSpeedFluidCoolerUA;
    1857       59632 :     Real64 AirFlowRate = this->LowSpeedAirFlowRate;
    1858       59632 :     Real64 FanPowerLow = this->LowSpeedFanPower;
    1859             : 
    1860       59632 :     CalcFluidCoolerOutlet(state, this->indexInArray, this->WaterMassFlowRate, AirFlowRate, UAdesign, OutletWaterTemp1stStage);
    1861             : 
    1862       59632 :     if (OutletWaterTemp1stStage <= TempSetPoint) {
    1863             :         // Setpoint was met with pump ON and fan ON 1st stage, calculate fan mode fraction
    1864       33904 :         if (OutletWaterTemp1stStage != OutletWaterTempOFF) { // don't divide by zero
    1865       33904 :             FanModeFrac = (TempSetPoint - OutletWaterTempOFF) / (OutletWaterTemp1stStage - OutletWaterTempOFF);
    1866             :         }
    1867       33904 :         this->FanPower = FanModeFrac * FanPowerLow;
    1868       33904 :         this->OutletWaterTemp = TempSetPoint;
    1869       33904 :         this->Qactual *= FanModeFrac;
    1870             :     } else {
    1871             :         // Setpoint was not met, turn on fluid cooler 2nd stage fan
    1872       25728 :         UAdesign = this->HighSpeedFluidCoolerUA;
    1873       25728 :         AirFlowRate = this->HighSpeedAirFlowRate;
    1874       25728 :         Real64 FanPowerHigh = this->HighSpeedFanPower;
    1875             : 
    1876       25728 :         CalcFluidCoolerOutlet(state, this->indexInArray, this->WaterMassFlowRate, AirFlowRate, UAdesign, OutletWaterTemp2ndStage);
    1877             : 
    1878       25728 :         if ((OutletWaterTemp2ndStage <= TempSetPoint) && UAdesign > 0.0) {
    1879             :             // Setpoint was met with pump ON and fan ON 2nd stage, calculate fan mode fraction
    1880          52 :             FanModeFrac = (TempSetPoint - OutletWaterTemp1stStage) / (OutletWaterTemp2ndStage - OutletWaterTemp1stStage);
    1881          52 :             this->FanPower = max((FanModeFrac * FanPowerHigh) + (1.0 - FanModeFrac) * FanPowerLow, 0.0);
    1882          52 :             this->OutletWaterTemp = TempSetPoint;
    1883             :         } else {
    1884             :             // Setpoint was not met, fluid cooler ran at full capacity
    1885       25676 :             this->OutletWaterTemp = OutletWaterTemp2ndStage;
    1886       25676 :             this->FanPower = FanPowerHigh;
    1887             :         }
    1888             :     }
    1889       59632 :     Real64 CpWater = FluidProperties::GetSpecificHeatGlycol(state,
    1890       59632 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
    1891       59632 :                                                             state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp,
    1892       59632 :                                                             state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
    1893             :                                                             RoutineName);
    1894       59632 :     this->Qactual = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp - this->OutletWaterTemp);
    1895             : }
    1896             : 
    1897       90558 : void CalcFluidCoolerOutlet(
    1898             :     EnergyPlusData &state, int FluidCoolerNum, Real64 _WaterMassFlowRate, Real64 AirFlowRate, Real64 UAdesign, Real64 &_OutletWaterTemp)
    1899             : {
    1900             : 
    1901             :     // SUBROUTINE INFORMATION:
    1902             :     //       AUTHOR         Chandan Sharma
    1903             :     //       DATE WRITTEN   August 2008
    1904             :     //       MODIFIED       April 2010, Chandan Sharma, FSEC
    1905             : 
    1906             :     // PURPOSE OF THIS SUBROUTINE:
    1907             :     // See purpose for Single Speed or Two Speed Fluid Cooler model
    1908             : 
    1909             :     // METHODOLOGY EMPLOYED:
    1910             :     // See methodology for Single Speed or Two Speed Fluid Cooler model
    1911             : 
    1912             :     // Locals
    1913             :     Real64 _Qactual; // Actual heat transfer rate between fluid cooler water and air [W]
    1914             : 
    1915             :     // SUBROUTINE PARAMETER DEFINITIONS:
    1916             :     static constexpr std::string_view RoutineName("CalcFluidCoolerOutlet");
    1917             : 
    1918       90558 :     if (UAdesign == 0.0) return;
    1919             : 
    1920             :     // set local fluid cooler inlet and outlet temperature variables
    1921       90558 :     Real64 _InletWaterTemp = state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).WaterTemp;
    1922       90558 :     _OutletWaterTemp = _InletWaterTemp;
    1923       90558 :     Real64 InletAirTemp = state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).AirTemp;
    1924             : 
    1925             :     // set water and air properties
    1926       90558 :     Real64 AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state,
    1927       90558 :                                                           state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).AirPress,
    1928             :                                                           InletAirTemp,
    1929       90558 :                                                           state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).AirHumRat);
    1930       90558 :     Real64 AirMassFlowRate = AirFlowRate * AirDensity;
    1931       90558 :     Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).AirHumRat);
    1932       90558 :     Real64 CpWater = FluidProperties::GetSpecificHeatGlycol(
    1933             :         state,
    1934       90558 :         state.dataPlnt->PlantLoop(state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).plantLoc.loopNum).FluidName,
    1935             :         _InletWaterTemp,
    1936       90558 :         state.dataPlnt->PlantLoop(state.dataFluidCoolers->SimpleFluidCooler(FluidCoolerNum).plantLoc.loopNum).FluidIndex,
    1937             :         RoutineName);
    1938             : 
    1939             :     // Calculate mass flow rates
    1940       90558 :     Real64 MdotCpWater = _WaterMassFlowRate * CpWater;
    1941       90558 :     Real64 AirCapacity = AirMassFlowRate * CpAir;
    1942             : 
    1943             :     // calculate the minimum to maximum capacity ratios of airside and waterside
    1944       90558 :     Real64 CapacityRatioMin = min(AirCapacity, MdotCpWater);
    1945       90558 :     Real64 CapacityRatioMax = max(AirCapacity, MdotCpWater);
    1946       90558 :     Real64 CapacityRatio = CapacityRatioMin / CapacityRatioMax;
    1947             : 
    1948             :     // Calculate number of transfer units (NTU)
    1949       90558 :     Real64 NumTransferUnits = UAdesign / CapacityRatioMin;
    1950       90558 :     Real64 ETA = std::pow(NumTransferUnits, 0.22);
    1951       90558 :     Real64 A = CapacityRatio * NumTransferUnits / ETA;
    1952       90558 :     Real64 effectiveness = 1.0 - std::exp((std::exp(-A) - 1.0) / (CapacityRatio / ETA));
    1953             : 
    1954             :     // calculate water to air heat transfer
    1955       90558 :     _Qactual = effectiveness * CapacityRatioMin * (_InletWaterTemp - InletAirTemp);
    1956             : 
    1957       90558 :     if (_Qactual >= 0.0) {
    1958       90558 :         _OutletWaterTemp = _InletWaterTemp - _Qactual / MdotCpWater;
    1959             :     } else {
    1960           0 :         _OutletWaterTemp = _InletWaterTemp;
    1961             :     }
    1962             : }
    1963             : 
    1964      160595 : void FluidCoolerspecs::update(EnergyPlusData &state)
    1965             : {
    1966             : 
    1967             :     // SUBROUTINE INFORMATION:
    1968             :     //       AUTHOR:          Chandan Sharma
    1969             :     //       DATE WRITTEN:    August 2008
    1970             : 
    1971             :     // PURPOSE OF THIS SUBROUTINE:
    1972             :     // This subroutine is for passing results to the outlet water node.
    1973             : 
    1974      160595 :     int waterOutletNode = this->WaterOutletNodeNum;
    1975      160595 :     state.dataLoopNodes->Node(waterOutletNode).Temp = this->OutletWaterTemp;
    1976             : 
    1977      240875 :     if (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked ||
    1978       80280 :         state.dataGlobal->WarmupFlag)
    1979      151203 :         return;
    1980             : 
    1981             :     // Check flow rate through fluid cooler and compare to design flow rate, show warning if greater than Design * Mulitplier
    1982        9392 :     if (state.dataLoopNodes->Node(waterOutletNode).MassFlowRate > this->DesWaterMassFlowRate * this->FluidCoolerMassFlowRateMultiplier) {
    1983           0 :         ++this->HighMassFlowErrorCount;
    1984           0 :         if (this->HighMassFlowErrorCount < 2) {
    1985           0 :             ShowWarningError(state, format("{} \"{}\"", DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)], this->Name));
    1986           0 :             ShowContinueError(state, " Condenser Loop Mass Flow Rate is much greater than the fluid coolers design mass flow rate.");
    1987           0 :             ShowContinueError(state, format(" Condenser Loop Mass Flow Rate = {:.6T}", state.dataLoopNodes->Node(waterOutletNode).MassFlowRate));
    1988           0 :             ShowContinueError(state, format(" Fluid Cooler Design Mass Flow Rate   = {:.6T}", this->DesWaterMassFlowRate));
    1989           0 :             ShowContinueErrorTimeStamp(state, "");
    1990             :         } else {
    1991           0 :             ShowRecurringWarningErrorAtEnd(
    1992             :                 state,
    1993           0 :                 format("{} \"{}\"  Condenser Loop Mass Flow Rate is much greater than the fluid coolers design mass flow rate. Error continues...",
    1994           0 :                        DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    1995           0 :                        this->Name),
    1996           0 :                 this->HighMassFlowErrorIndex,
    1997           0 :                 state.dataLoopNodes->Node(waterOutletNode).MassFlowRate,
    1998           0 :                 state.dataLoopNodes->Node(waterOutletNode).MassFlowRate);
    1999             :         }
    2000             :     }
    2001             : 
    2002             :     // Check if OutletWaterTemp is below the minimum condenser loop temp and warn user
    2003        9392 :     Real64 LoopMinTemp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MinTemp;
    2004        9392 :     if ((this->OutletWaterTemp < LoopMinTemp) && (this->WaterMassFlowRate > 0.0)) {
    2005           0 :         ++this->OutletWaterTempErrorCount;
    2006             : 
    2007           0 :         if (this->OutletWaterTempErrorCount < 2) {
    2008           0 :             ShowWarningError(state, format("{} \"{}\"", DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)], this->Name));
    2009           0 :             ShowContinueError(state,
    2010           0 :                               format(" Fluid cooler water outlet temperature ({.2F} C) is below the specified minimum condenser loop temp of {.2F} C",
    2011           0 :                                      this->OutletWaterTemp,
    2012             :                                      LoopMinTemp));
    2013           0 :             ShowContinueErrorTimeStamp(state, "");
    2014             :         } else {
    2015           0 :             ShowRecurringWarningErrorAtEnd(
    2016             :                 state,
    2017           0 :                 format("{} \"{}\"  Fluid cooler water outlet temperature is below the specified minimum condenser loop temp. Error continues...",
    2018           0 :                        DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    2019           0 :                        this->Name),
    2020           0 :                 this->OutletWaterTempErrorIndex,
    2021           0 :                 this->OutletWaterTemp,
    2022           0 :                 this->OutletWaterTemp);
    2023             :         }
    2024             :     }
    2025             : 
    2026             :     // Check if water mass flow rate is small (e.g. no flow) and warn user
    2027        9392 :     if (this->WaterMassFlowRate > 0.0 && this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) {
    2028           0 :         ++this->SmallWaterMassFlowErrorCount;
    2029           0 :         if (this->SmallWaterMassFlowErrorCount < 2) {
    2030           0 :             ShowWarningError(state, format("{} \"{}\"", DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)], this->Name));
    2031           0 :             ShowContinueError(state, " Fluid cooler water mass flow rate near zero.");
    2032           0 :             ShowContinueErrorTimeStamp(state, "");
    2033           0 :             ShowContinueError(state, format("Actual Mass flow = {:.2T}", this->WaterMassFlowRate));
    2034             :         } else {
    2035           0 :             ShowRecurringWarningErrorAtEnd(state,
    2036           0 :                                            format("{} \"{}\"  Fluid cooler water mass flow rate is near zero. Error continues...",
    2037           0 :                                                   DataPlant::PlantEquipTypeNames[static_cast<int>(this->FluidCoolerType)],
    2038           0 :                                                   this->Name),
    2039           0 :                                            this->SmallWaterMassFlowErrorIndex,
    2040           0 :                                            this->WaterMassFlowRate,
    2041           0 :                                            this->WaterMassFlowRate);
    2042             :         }
    2043             :     }
    2044             : }
    2045             : 
    2046      160595 : void FluidCoolerspecs::report(EnergyPlusData &state, bool const RunFlag)
    2047             : {
    2048             : 
    2049             :     // SUBROUTINE INFORMATION:
    2050             :     //       AUTHOR:          Chandan Sharma
    2051             :     //       DATE WRITTEN:    August 2008
    2052             : 
    2053             :     // PURPOSE OF THIS SUBROUTINE:
    2054             :     // This subroutine updates the report variables for the fluid cooler.
    2055             : 
    2056      160595 :     Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
    2057      160595 :     if (!RunFlag) {
    2058       36371 :         this->InletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    2059       36371 :         this->OutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    2060       36371 :         this->Qactual = 0.0;
    2061       36371 :         this->FanPower = 0.0;
    2062       36371 :         this->FanEnergy = 0.0;
    2063             :     } else {
    2064      124224 :         this->InletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNodeNum).Temp;
    2065      124224 :         this->FanEnergy = this->FanPower * ReportingConstant;
    2066             :     }
    2067      160595 : }
    2068           0 : void FluidCoolerspecs::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
    2069             : {
    2070           0 : }
    2071             : 
    2072             : } // namespace EnergyPlus::FluidCoolers

Generated by: LCOV version 1.14