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

Generated by: LCOV version 2.0-1