LCOV - code coverage report
Current view: top level - EnergyPlus - FluidCoolers.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 44.3 % 985 436
Test Date: 2025-05-22 16:09:37 Functions: 73.9 % 23 17

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

Generated by: LCOV version 2.0-1