LCOV - code coverage report
Current view: top level - EnergyPlus - CoolTower.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 69.6 % 375 261
Test Date: 2025-06-02 07:23:51 Functions: 100.0 % 5 5

            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/Fmath.hh>
      53              : 
      54              : // EnergyPlus Headers
      55              : #include <EnergyPlus/CoolTower.hh>
      56              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      57              : #include <EnergyPlus/DataEnvironment.hh>
      58              : #include <EnergyPlus/DataHVACGlobals.hh>
      59              : #include <EnergyPlus/DataHeatBalance.hh>
      60              : #include <EnergyPlus/DataIPShortCuts.hh>
      61              : #include <EnergyPlus/DataWater.hh>
      62              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      63              : #include <EnergyPlus/OutputProcessor.hh>
      64              : #include <EnergyPlus/Psychrometrics.hh>
      65              : #include <EnergyPlus/ScheduleManager.hh>
      66              : #include <EnergyPlus/UtilityRoutines.hh>
      67              : #include <EnergyPlus/WaterManager.hh>
      68              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      69              : 
      70              : namespace EnergyPlus {
      71              : 
      72              : namespace CoolTower {
      73              :     // Module containing the data for cooltower system
      74              : 
      75              :     // MODULE INFORMATION:
      76              :     //       AUTHOR         Daeho Kang
      77              :     //       DATE WRITTEN   Aug 2008
      78              :     //       MODIFIED       na
      79              :     //       RE-ENGINEERED  na
      80              : 
      81              :     // PURPOSE OF THIS MODULE:
      82              :     // To encapsulate the data and algorithms required to manage the cooltower component.
      83              : 
      84              :     // REFERENCES:
      85              :     // Baruch Givoni. 1994. Passive and Low Energy Cooling of Buildings. Chapter 5: Evaporative Cooling Systems.
      86              :     //     John Wiley & Sons, Inc.
      87              :     // OTHER NOTES: none
      88              : 
      89              :     // Using/Aliasing
      90              :     using namespace DataHeatBalance;
      91              : 
      92              :     constexpr std::array<std::string_view, static_cast<int>(FlowCtrl::Num)> FlowCtrlNamesUC{"WATERFLOWSCHEDULE", "WINDDRIVENFLOW"};
      93              : 
      94      3757673 :     void ManageCoolTower(EnergyPlusData &state)
      95              :     {
      96              : 
      97              :         // SUBROUTINE INFORMATION:
      98              :         //       AUTHOR         Daeho Kang
      99              :         //       DATE WRITTEN   Aug 2008
     100              : 
     101              :         // PURPOSE OF THIS SUBROUTINE:
     102              :         // This subroutine manages the simulation of Cooltower component.
     103              :         // This driver manages the calls to all of the other drivers and simulation algorithms.
     104              : 
     105              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     106              : 
     107              :         // Obtains and allocates heat balance related parameters from input
     108      3757673 :         if (state.dataCoolTower->GetInputFlag) {
     109          768 :             GetCoolTower(state);
     110          768 :             state.dataCoolTower->GetInputFlag = false;
     111              :         }
     112              : 
     113      3757673 :         if ((int)state.dataCoolTower->CoolTowerSys.size() == 0) {
     114      3754093 :             return;
     115              :         }
     116              : 
     117         3580 :         CalcCoolTower(state);
     118              : 
     119         3580 :         UpdateCoolTower(state);
     120              : 
     121         3580 :         ReportCoolTower(state);
     122              :     }
     123              : 
     124          768 :     void GetCoolTower(EnergyPlusData &state)
     125              :     {
     126              : 
     127              :         // SUBROUTINE INFORMATION:
     128              :         //       AUTHOR         Daeho Kang
     129              :         //       DATE WRITTEN   Aug 2008
     130              : 
     131              :         // PURPOSE OF THIS SUBROUTINE:
     132              :         // This subroutine gets input data for cooltower components
     133              :         // and stores it in the Cooltower data structure.
     134              : 
     135              :         // SUBROUTINE PARAMETER DEFINITIONS:
     136              :         static constexpr std::string_view routineName = "GetCoolTower";
     137              : 
     138         2304 :         static std::string const CurrentModuleObject("ZoneCoolTower:Shower");
     139          768 :         Real64 constexpr MaximumWaterFlowRate(0.016667); // Maximum limit of water flow rate in m3/s (1000 l/min)
     140          768 :         Real64 constexpr MinimumWaterFlowRate(0.0);      // Minimum limit of water flow rate
     141          768 :         Real64 constexpr MaxHeight(30.0);                // Maximum effective tower height in m
     142          768 :         Real64 constexpr MinHeight(1.0);                 // Minimum effective tower height in m
     143          768 :         Real64 constexpr MaxValue(100.0);                // Maximum limit of outlet area, airflow, and temperature
     144          768 :         Real64 constexpr MinValue(0.0);                  // Minimum limit of outlet area, airflow, and temperature
     145          768 :         Real64 constexpr MaxFrac(1.0);                   // Maximum fraction
     146          768 :         Real64 constexpr MinFrac(0.0);                   // Minimum fraction
     147              : 
     148              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     149          768 :         bool ErrorsFound(false); // If errors detected in input
     150              :         int NumAlphas;           // Number of Alphas for each GetobjectItem call
     151              :         int NumNumbers;          // Number of Numbers for each GetobjectItem call
     152              :         int NumArgs;
     153              :         int IOStat;
     154          768 :         Array1D_string cAlphaArgs;     // Alpha input items for object
     155          768 :         Array1D_string cAlphaFields;   // Alpha field names
     156          768 :         Array1D_string cNumericFields; // Numeric field names
     157          768 :         Array1D<Real64> rNumericArgs;  // Numeric input items for object
     158          768 :         Array1D_bool lAlphaBlanks;     // Logical array, alpha field input BLANK = .TRUE.
     159          768 :         Array1D_bool lNumericBlanks;   // Logical array, numeric field input BLANK = .TRUE.
     160              : 
     161              :         // Initializations and allocations
     162          768 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumArgs, NumAlphas, NumNumbers);
     163          768 :         cAlphaArgs.allocate(NumAlphas);
     164          768 :         cAlphaFields.allocate(NumAlphas);
     165          768 :         cNumericFields.allocate(NumNumbers);
     166          768 :         rNumericArgs.dimension(NumNumbers, 0.0);
     167          768 :         lAlphaBlanks.dimension(NumAlphas, true);
     168          768 :         lNumericBlanks.dimension(NumNumbers, true);
     169              : 
     170          768 :         auto &Zone(state.dataHeatBal->Zone);
     171              : 
     172          768 :         auto &s_ipsc = state.dataIPShortCut;
     173              : 
     174          768 :         int NumCoolTowers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     175              : 
     176          768 :         state.dataCoolTower->CoolTowerSys.allocate(NumCoolTowers);
     177              : 
     178              :         // Obtain inputs
     179          773 :         for (int CoolTowerNum = 1; CoolTowerNum <= NumCoolTowers; ++CoolTowerNum) {
     180              : 
     181           10 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     182              :                                                                      CurrentModuleObject,
     183              :                                                                      CoolTowerNum,
     184            5 :                                                                      s_ipsc->cAlphaArgs,
     185              :                                                                      NumAlphas,
     186            5 :                                                                      s_ipsc->rNumericArgs,
     187              :                                                                      NumNumbers,
     188              :                                                                      IOStat,
     189              :                                                                      lNumericBlanks,
     190              :                                                                      lAlphaBlanks,
     191              :                                                                      cAlphaFields,
     192              :                                                                      cNumericFields);
     193              : 
     194            5 :             ErrorObjectHeader eoh{routineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)};
     195              : 
     196            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).Name = s_ipsc->cAlphaArgs(1); // Name of cooltower
     197            5 :             if (lAlphaBlanks(2)) {
     198            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).availSched = Sched::GetScheduleAlwaysOn(state);
     199            5 :             } else if ((state.dataCoolTower->CoolTowerSys(CoolTowerNum).availSched = Sched::GetSchedule(state, s_ipsc->cAlphaArgs(2))) == nullptr) {
     200            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), s_ipsc->cAlphaArgs(2));
     201            0 :                 ErrorsFound = true;
     202              :             }
     203              : 
     204            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr = Util::FindItemInList(s_ipsc->cAlphaArgs(3), Zone);
     205            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr = Util::FindItemInList(s_ipsc->cAlphaArgs(3), state.dataHeatBal->space);
     206            5 :             if ((state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr == 0) && (state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr == 0)) {
     207            0 :                 if (lAlphaBlanks(3)) {
     208            0 :                     ShowSevereError(
     209              :                         state,
     210            0 :                         format("{}=\"{}\" invalid {} is required but input is blank.", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cAlphaFields(3)));
     211              :                 } else {
     212            0 :                     ShowSevereError(state,
     213            0 :                                     format("{}=\"{}\" invalid {}=\"{}\" not found.",
     214              :                                            CurrentModuleObject,
     215            0 :                                            s_ipsc->cAlphaArgs(1),
     216              :                                            cAlphaFields(3),
     217            0 :                                            s_ipsc->cAlphaArgs(3)));
     218              :                 }
     219            0 :                 ErrorsFound = true;
     220            5 :             } else if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr == 0) {
     221            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr =
     222            0 :                     state.dataHeatBal->space(state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr).zoneNum;
     223              :             }
     224              : 
     225            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyName = s_ipsc->cAlphaArgs(4); // Name of water storage tank
     226            5 :             if (lAlphaBlanks(4)) {
     227            5 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode = WaterSupplyMode::FromMains;
     228            0 :             } else if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromTank) {
     229            0 :                 WaterManager::SetupTankDemandComponent(state,
     230            0 :                                                        state.dataCoolTower->CoolTowerSys(CoolTowerNum).Name,
     231              :                                                        CurrentModuleObject,
     232            0 :                                                        state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyName,
     233              :                                                        ErrorsFound,
     234            0 :                                                        state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupTankID,
     235            0 :                                                        state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterTankDemandARRID);
     236              :             }
     237              : 
     238              :             {
     239            5 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).FlowCtrlType =
     240            5 :                     static_cast<FlowCtrl>(getEnumValue(FlowCtrlNamesUC, s_ipsc->cAlphaArgs(5))); // Type of flow control
     241            5 :                 if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FlowCtrlType == FlowCtrl::Invalid) {
     242            0 :                     ShowSevereError(
     243              :                         state,
     244            0 :                         format("{}=\"{}\" invalid {}=\"{}\".", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cAlphaFields(5), s_ipsc->cAlphaArgs(5)));
     245            0 :                     ErrorsFound = true;
     246              :                 }
     247              :             }
     248              : 
     249            5 :             if ((state.dataCoolTower->CoolTowerSys(CoolTowerNum).pumpSched = Sched::GetSchedule(state, s_ipsc->cAlphaArgs(6))) == nullptr) {
     250            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(6), s_ipsc->cAlphaArgs(6));
     251            0 :                 ErrorsFound = true;
     252              :             }
     253              : 
     254            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate = s_ipsc->rNumericArgs(1); // Maximum limit of water supply
     255            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate > MaximumWaterFlowRate) {
     256            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate = MaximumWaterFlowRate;
     257            0 :                 ShowWarningError(
     258              :                     state,
     259            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(1), s_ipsc->rNumericArgs(1)));
     260            0 :                 ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaximumWaterFlowRate));
     261              :             }
     262            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate < MinimumWaterFlowRate) {
     263            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate = MinimumWaterFlowRate;
     264            0 :                 ShowWarningError(
     265              :                     state,
     266            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(1), s_ipsc->rNumericArgs(1)));
     267            0 :                 ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinimumWaterFlowRate));
     268              :             }
     269              : 
     270            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight = s_ipsc->rNumericArgs(2); // Get effctive tower height
     271            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight > MaxHeight) {
     272            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight = MaxHeight;
     273            0 :                 ShowWarningError(
     274              :                     state,
     275            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(2), s_ipsc->rNumericArgs(2)));
     276            0 :                 ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxHeight));
     277              :             }
     278            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight < MinHeight) {
     279            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight = MinHeight;
     280            0 :                 ShowWarningError(
     281              :                     state,
     282            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(2), s_ipsc->rNumericArgs(2)));
     283            0 :                 ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinHeight));
     284              :             }
     285              : 
     286            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea = s_ipsc->rNumericArgs(3); // Get outlet area
     287            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea > MaxValue) {
     288            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea = MaxValue;
     289            0 :                 ShowWarningError(
     290              :                     state,
     291            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(3), s_ipsc->rNumericArgs(3)));
     292            0 :                 ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxValue));
     293              :             }
     294            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea < MinValue) {
     295            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea = MinValue;
     296            0 :                 ShowWarningError(
     297              :                     state,
     298            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(3), s_ipsc->rNumericArgs(3)));
     299            0 :                 ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinValue));
     300              :             }
     301              : 
     302            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate = s_ipsc->rNumericArgs(4); // Maximum limit of air flow to the space
     303            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate > MaxValue) {
     304            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate = MaxValue;
     305            0 :                 ShowWarningError(
     306              :                     state,
     307            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(4), s_ipsc->rNumericArgs(4)));
     308            0 :                 ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxValue));
     309              :             }
     310            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate < MinValue) {
     311            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate = MinValue;
     312            0 :                 ShowWarningError(
     313              :                     state,
     314            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(4), s_ipsc->rNumericArgs(4)));
     315            0 :                 ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinValue));
     316              :             }
     317              : 
     318            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp =
     319            5 :                 s_ipsc->rNumericArgs(5); // Get minimum temp limit which gets this cooltower off
     320            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp > MaxValue) {
     321            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp = MaxValue;
     322            0 :                 ShowWarningError(
     323              :                     state,
     324            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(5), s_ipsc->rNumericArgs(5)));
     325            0 :                 ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxValue));
     326              :             }
     327            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp < MinValue) {
     328            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp = MinValue;
     329            0 :                 ShowWarningError(
     330              :                     state,
     331            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(5), s_ipsc->rNumericArgs(5)));
     332            0 :                 ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinValue));
     333              :             }
     334              : 
     335            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss = s_ipsc->rNumericArgs(6); // Fraction of water loss
     336            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss > MaxFrac) {
     337            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss = MaxFrac;
     338            0 :                 ShowWarningError(
     339              :                     state,
     340            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(6), s_ipsc->rNumericArgs(6)));
     341            0 :                 ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxFrac));
     342              :             }
     343            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss < MinFrac) {
     344            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss = MinFrac;
     345            0 :                 ShowWarningError(
     346              :                     state,
     347            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(6), s_ipsc->rNumericArgs(6)));
     348            0 :                 ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinFrac));
     349              :             }
     350              : 
     351            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched = s_ipsc->rNumericArgs(7); // Fraction of loss of air flow
     352            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched > MaxFrac) {
     353            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched = MaxFrac;
     354            0 :                 ShowWarningError(
     355              :                     state,
     356            0 :                     format("{}=\"{}\" invalid {}=[{:.2R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(7), s_ipsc->rNumericArgs(7)));
     357            0 :                 ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxFrac));
     358              :             }
     359            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched < MinFrac) {
     360            0 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched = MinFrac;
     361            0 :                 ShowWarningError(
     362              :                     state,
     363            0 :                     format("{}=\"{}\" invalid {}=[{:.5R}].", CurrentModuleObject, s_ipsc->cAlphaArgs(1), cNumericFields(7), s_ipsc->rNumericArgs(7)));
     364            0 :                 ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinFrac));
     365              :             }
     366              : 
     367            5 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).RatedPumpPower = s_ipsc->rNumericArgs(8); // Get rated pump power
     368              :         }
     369              : 
     370          768 :         cAlphaArgs.deallocate();
     371          768 :         cAlphaFields.deallocate();
     372          768 :         cNumericFields.deallocate();
     373          768 :         rNumericArgs.deallocate();
     374          768 :         lAlphaBlanks.deallocate();
     375          768 :         lNumericBlanks.deallocate();
     376              : 
     377          768 :         if (ErrorsFound) {
     378            0 :             ShowFatalError(state, format("{} errors occurred in input.  Program terminates.", CurrentModuleObject));
     379              :         }
     380              : 
     381          773 :         for (int CoolTowerNum = 1; CoolTowerNum <= NumCoolTowers; ++CoolTowerNum) {
     382           10 :             SetupOutputVariable(state,
     383              :                                 "Zone Cooltower Sensible Heat Loss Energy",
     384              :                                 Constant::Units::J,
     385            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatLoss,
     386              :                                 OutputProcessor::TimeStepType::System,
     387              :                                 OutputProcessor::StoreType::Sum,
     388            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     389           10 :             SetupOutputVariable(state,
     390              :                                 "Zone Cooltower Sensible Heat Loss Rate",
     391              :                                 Constant::Units::W,
     392            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower,
     393              :                                 OutputProcessor::TimeStepType::System,
     394              :                                 OutputProcessor::StoreType::Average,
     395            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     396           10 :             SetupOutputVariable(state,
     397              :                                 "Zone Cooltower Latent Heat Loss Energy",
     398              :                                 Constant::Units::J,
     399            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatLoss,
     400              :                                 OutputProcessor::TimeStepType::System,
     401              :                                 OutputProcessor::StoreType::Sum,
     402            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     403           10 :             SetupOutputVariable(state,
     404              :                                 "Zone Cooltower Latent Heat Loss Rate",
     405              :                                 Constant::Units::W,
     406            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower,
     407              :                                 OutputProcessor::TimeStepType::System,
     408              :                                 OutputProcessor::StoreType::Average,
     409            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     410           10 :             SetupOutputVariable(state,
     411              :                                 "Zone Cooltower Air Volume",
     412              :                                 Constant::Units::m3,
     413            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTAirVol,
     414              :                                 OutputProcessor::TimeStepType::System,
     415              :                                 OutputProcessor::StoreType::Sum,
     416            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     417           10 :             SetupOutputVariable(state,
     418              :                                 "Zone Cooltower Current Density Air Volume Flow Rate",
     419              :                                 Constant::Units::m3_s,
     420            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate,
     421              :                                 OutputProcessor::TimeStepType::System,
     422              :                                 OutputProcessor::StoreType::Average,
     423            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     424           10 :             SetupOutputVariable(state,
     425              :                                 "Zone Cooltower Standard Density Air Volume Flow Rate",
     426              :                                 Constant::Units::m3_s,
     427            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd,
     428              :                                 OutputProcessor::TimeStepType::System,
     429              :                                 OutputProcessor::StoreType::Average,
     430            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     431           10 :             SetupOutputVariable(state,
     432              :                                 "Zone Cooltower Air Mass",
     433              :                                 Constant::Units::kg,
     434            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTAirMass,
     435              :                                 OutputProcessor::TimeStepType::System,
     436              :                                 OutputProcessor::StoreType::Sum,
     437            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     438           10 :             SetupOutputVariable(state,
     439              :                                 "Zone Cooltower Air Mass Flow Rate",
     440              :                                 Constant::Units::kg_s,
     441            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate,
     442              :                                 OutputProcessor::TimeStepType::System,
     443              :                                 OutputProcessor::StoreType::Average,
     444            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     445           10 :             SetupOutputVariable(state,
     446              :                                 "Zone Cooltower Air Inlet Temperature",
     447              :                                 Constant::Units::C,
     448            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletDBTemp,
     449              :                                 OutputProcessor::TimeStepType::System,
     450              :                                 OutputProcessor::StoreType::Average,
     451            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     452           10 :             SetupOutputVariable(state,
     453              :                                 "Zone Cooltower Air Inlet Humidity Ratio",
     454              :                                 Constant::Units::kgWater_kgDryAir,
     455            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletHumRat,
     456              :                                 OutputProcessor::TimeStepType::System,
     457              :                                 OutputProcessor::StoreType::Average,
     458            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     459           10 :             SetupOutputVariable(state,
     460              :                                 "Zone Cooltower Air Outlet Temperature",
     461              :                                 Constant::Units::C,
     462            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletTemp,
     463              :                                 OutputProcessor::TimeStepType::System,
     464              :                                 OutputProcessor::StoreType::Average,
     465            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     466           10 :             SetupOutputVariable(state,
     467              :                                 "Zone Cooltower Air Outlet Humidity Ratio",
     468              :                                 Constant::Units::kgWater_kgDryAir,
     469            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletHumRat,
     470              :                                 OutputProcessor::TimeStepType::System,
     471              :                                 OutputProcessor::StoreType::Average,
     472            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     473           10 :             SetupOutputVariable(state,
     474              :                                 "Zone Cooltower Pump Electricity Rate",
     475              :                                 Constant::Units::W,
     476            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower,
     477              :                                 OutputProcessor::TimeStepType::System,
     478              :                                 OutputProcessor::StoreType::Average,
     479            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     480           10 :             SetupOutputVariable(state,
     481              :                                 "Zone Cooltower Pump Electricity Energy",
     482              :                                 Constant::Units::J,
     483            5 :                                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecConsump,
     484              :                                 OutputProcessor::TimeStepType::System,
     485              :                                 OutputProcessor::StoreType::Sum,
     486            5 :                                 Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name,
     487              :                                 Constant::eResource::Electricity,
     488              :                                 OutputProcessor::Group::HVAC, // System
     489              :                                 OutputProcessor::EndUseCat::Cooling);
     490            5 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromMains) {
     491           10 :                 SetupOutputVariable(state,
     492              :                                     "Zone Cooltower Water Volume",
     493              :                                     Constant::Units::m3,
     494            5 :                                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump,
     495              :                                     OutputProcessor::TimeStepType::System,
     496              :                                     OutputProcessor::StoreType::Sum,
     497            5 :                                     Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     498           10 :                 SetupOutputVariable(state,
     499              :                                     "Zone Cooltower Mains Water Volume",
     500              :                                     Constant::Units::m3,
     501            5 :                                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump,
     502              :                                     OutputProcessor::TimeStepType::System,
     503              :                                     OutputProcessor::StoreType::Sum,
     504            5 :                                     Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name,
     505              :                                     Constant::eResource::MainsWater,
     506              :                                     OutputProcessor::Group::HVAC, // System
     507              :                                     OutputProcessor::EndUseCat::Cooling);
     508            0 :             } else if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromTank) {
     509            0 :                 SetupOutputVariable(state,
     510              :                                     "Zone Cooltower Water Volume",
     511              :                                     Constant::Units::m3,
     512            0 :                                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump,
     513              :                                     OutputProcessor::TimeStepType::System,
     514              :                                     OutputProcessor::StoreType::Sum,
     515            0 :                                     Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     516            0 :                 SetupOutputVariable(state,
     517              :                                     "Zone Cooltower Storage Tank Water Volume",
     518              :                                     Constant::Units::m3,
     519            0 :                                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump,
     520              :                                     OutputProcessor::TimeStepType::System,
     521              :                                     OutputProcessor::StoreType::Sum,
     522            0 :                                     Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
     523            0 :                 SetupOutputVariable(state,
     524              :                                     "Zone Cooltower Starved Mains Water Volume",
     525              :                                     Constant::Units::m3,
     526            0 :                                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeup,
     527              :                                     OutputProcessor::TimeStepType::System,
     528              :                                     OutputProcessor::StoreType::Sum,
     529            0 :                                     Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name,
     530              :                                     Constant::eResource::MainsWater,
     531              :                                     OutputProcessor::Group::HVAC, // System
     532              :                                     OutputProcessor::EndUseCat::Cooling);
     533              :             }
     534              :         }
     535          768 :     }
     536              : 
     537         3580 :     void CalcCoolTower(EnergyPlusData &state)
     538              :     {
     539              : 
     540              :         // SUBROUTINE INFORMATION:
     541              :         //       AUTHOR         Daeho Kang
     542              :         //       DATE WRITTEN   Aug 2008
     543              : 
     544              :         // REFERENCES:
     545              :         // Baruch Givoni. 1994. Passive and Low Energy Cooling of Buildings. Chapter 5: Evaporative Cooling Systems.
     546              :         //     John Wiley & Sons, Inc.
     547              : 
     548              :         // SUBROUTINE PARAMETER DEFINITIONS:
     549         3580 :         Real64 constexpr MinWindSpeed(0.1);  // Minimum limit of outdoor air wind speed in m/s
     550         3580 :         Real64 constexpr MaxWindSpeed(30.0); // Maximum limit of outdoor air wind speed in m/s
     551         3580 :         Real64 constexpr UCFactor(60000.0);  // Unit conversion factor m3/s to l/min
     552              : 
     553              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     554              :         Real64 CVF_ZoneNum;          // Design flow rate in m3/s
     555              :         Real64 AirMassFlowRate;      // Actual air mass flow rate in kg/s
     556              :         Real64 AirSpecHeat;          // Specific heat of air
     557              :         Real64 AirDensity;           // Density of air
     558              :         Real64 RhoWater;             // Density of water
     559              :         Real64 PumpPartLoadRat;      // Pump part load ratio (based on user schedule, or 1.0 for no schedule)
     560         3580 :         Real64 WaterFlowRate = 0.0;  // Calculated water flow rate in m3/s
     561         3580 :         Real64 AirVolFlowRate = 0.0; // Calculated air volume flow rate in m3/s
     562              :         Real64 InletHumRat;          // Humidity ratio of outdoor air
     563              :         Real64 OutletHumRat;         // Humidity ratio of air at the cooltower outlet
     564         3580 :         Real64 OutletTemp = 0.0;     // Dry bulb temperature of air at the cooltower outlet
     565              :         Real64 IntHumRat;            // Humidity ratio of initialized air
     566              : 
     567         3580 :         auto &Zone(state.dataHeatBal->Zone);
     568              : 
     569        12501 :         for (int CoolTowerNum = 1; CoolTowerNum <= (int)state.dataCoolTower->CoolTowerSys.size(); ++CoolTowerNum) {
     570         8921 :             int const ZoneNum = state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr;
     571         8921 :             auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     572         8921 :             thisZoneHB.MCPTC = 0.0;
     573         8921 :             thisZoneHB.MCPC = 0.0;
     574         8921 :             thisZoneHB.CTMFL = 0.0;
     575         8921 :             if ((state.dataHeatBal->doSpaceHeatBalance) && (state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr > 0)) {
     576            0 :                 auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr);
     577            0 :                 thisSpaceHB.MCPTC = 0.0;
     578            0 :                 thisSpaceHB.MCPC = 0.0;
     579            0 :                 thisSpaceHB.CTMFL = 0.0;
     580              :             }
     581              : 
     582         8921 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).availSched->getCurrentVal() > 0.0) {
     583              :                 // check component operation
     584         6365 :                 if (state.dataEnvrn->WindSpeed < MinWindSpeed || state.dataEnvrn->WindSpeed > MaxWindSpeed) {
     585            0 :                     continue;
     586              :                 }
     587         6365 :                 if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT <
     588         6365 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp) {
     589         2920 :                     continue;
     590              :                 }
     591              : 
     592              :                 // Unit is on and simulate this component
     593              :                 // Determine the temperature and air flow rate at the cooltower outlet
     594         3445 :                 if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FlowCtrlType == FlowCtrl::WindDriven) {
     595         2785 :                     Real64 const height_sqrt(std::sqrt(state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight));
     596         2785 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletVelocity = 0.7 * height_sqrt + 0.47 * (state.dataEnvrn->WindSpeed - 1.0);
     597         2785 :                     AirVolFlowRate =
     598         2785 :                         state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea * state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletVelocity;
     599         2785 :                     AirVolFlowRate = min(AirVolFlowRate, state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate);
     600         2785 :                     WaterFlowRate = (AirVolFlowRate / (0.0125 * height_sqrt));
     601         2785 :                     if (WaterFlowRate > state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate * UCFactor) {
     602         2049 :                         WaterFlowRate = state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate * UCFactor;
     603         2049 :                         AirVolFlowRate = 0.0125 * WaterFlowRate * height_sqrt;
     604         2049 :                         AirVolFlowRate = min(AirVolFlowRate, state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate);
     605              :                     }
     606         2785 :                     WaterFlowRate = min(WaterFlowRate, (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate * UCFactor));
     607         2785 :                     OutletTemp =
     608         2785 :                         state.dataEnvrn->OutDryBulbTemp - (state.dataEnvrn->OutDryBulbTemp - state.dataEnvrn->OutWetBulbTemp) *
     609         2785 :                                                               (1.0 - std::exp(-0.8 * state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight)) *
     610         2785 :                                                               (1.0 - std::exp(-0.15 * WaterFlowRate));
     611          660 :                 } else if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FlowCtrlType == FlowCtrl::FlowSchedule) {
     612          660 :                     WaterFlowRate = state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate * UCFactor;
     613          660 :                     AirVolFlowRate = 0.0125 * WaterFlowRate * std::sqrt(state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight);
     614          660 :                     AirVolFlowRate = min(AirVolFlowRate, state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate);
     615          660 :                     OutletTemp =
     616          660 :                         state.dataEnvrn->OutDryBulbTemp - (state.dataEnvrn->OutDryBulbTemp - state.dataEnvrn->OutWetBulbTemp) *
     617          660 :                                                               (1.0 - std::exp(-0.8 * state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight)) *
     618          660 :                                                               (1.0 - std::exp(-0.15 * WaterFlowRate));
     619              :                 }
     620              : 
     621         3445 :                 if (OutletTemp < state.dataEnvrn->OutWetBulbTemp) {
     622            0 :                     ShowSevereError(state, "Cooltower outlet temperature exceed the outdoor wet bulb temperature reset to input values");
     623            0 :                     ShowContinueError(state, format("Occurs in Cooltower ={}", state.dataCoolTower->CoolTowerSys(CoolTowerNum).Name));
     624              :                 }
     625              : 
     626         3445 :                 WaterFlowRate /= UCFactor;
     627              :                 // Determine actual water flow rate
     628         3445 :                 if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss > 0.0) {
     629         2782 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualWaterFlowRate =
     630         2782 :                         WaterFlowRate * (1.0 + state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss);
     631              :                 } else {
     632          663 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualWaterFlowRate = WaterFlowRate;
     633              :                 }
     634              : 
     635              :                 // Determine actual air flow rate
     636         3445 :                 if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched > 0.0) {
     637         2782 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate =
     638         2782 :                         AirVolFlowRate * (1.0 - state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched);
     639              :                 } else {
     640          663 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate = AirVolFlowRate;
     641              :                 }
     642              : 
     643              :                 // Determine pump power
     644         3445 :                 if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).pumpSched->getCurrentVal() > 0) {
     645         3445 :                     PumpPartLoadRat = state.dataCoolTower->CoolTowerSys(CoolTowerNum).pumpSched->getCurrentVal();
     646              :                 } else {
     647            0 :                     PumpPartLoadRat = 1.0;
     648              :                 }
     649              : 
     650              :                 // Determine air mass flow rate and volume flow rate
     651         6890 :                 InletHumRat = Psychrometrics::PsyWFnTdbTwbPb(
     652         3445 :                     state, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutWetBulbTemp, state.dataEnvrn->OutBaroPress);
     653              :                 // Assume no pressure drops and no changes in enthalpy between inlet and outlet air
     654         3445 :                 IntHumRat = Psychrometrics::PsyWFnTdbH(state, OutletTemp, state.dataEnvrn->OutEnthalpy); // Initialized humidity ratio
     655         3445 :                 AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, OutletTemp, IntHumRat);
     656         3445 :                 AirMassFlowRate = AirDensity * state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate;
     657              :                 // From the mass balance W_in*(m_air + m_water) = W_out*m_air
     658         3445 :                 RhoWater = Psychrometrics::RhoH2O(OutletTemp); // Assume T_water = T_outlet
     659         3445 :                 OutletHumRat = (InletHumRat * (AirMassFlowRate + (state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualWaterFlowRate * RhoWater))) /
     660              :                                AirMassFlowRate;
     661         3445 :                 AirSpecHeat = Psychrometrics::PsyCpAirFnW(OutletHumRat);
     662         3445 :                 AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, OutletTemp, OutletHumRat); // Outlet air density
     663         3445 :                 CVF_ZoneNum = state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate *
     664         3445 :                               state.dataCoolTower->CoolTowerSys(CoolTowerNum).availSched->getCurrentVal();
     665         3445 :                 Real64 thisMCPC = CVF_ZoneNum * AirDensity * AirSpecHeat;
     666         3445 :                 Real64 thisMCPTC = thisMCPC * OutletTemp;
     667         3445 :                 Real64 thisCTMFL = thisMCPC / AirSpecHeat;
     668         3445 :                 Real64 thisZT = thisZoneHB.ZT;
     669         3445 :                 Real64 thisAirHumRat = thisZoneHB.airHumRat;
     670         3445 :                 thisZoneHB.MCPC = thisMCPC;
     671         3445 :                 thisZoneHB.MCPTC = thisMCPTC;
     672         3445 :                 thisZoneHB.CTMFL = thisCTMFL;
     673         3445 :                 if ((state.dataHeatBal->doSpaceHeatBalance) && (state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr > 0)) {
     674              :                     auto &thisSpaceHB =
     675            0 :                         state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataCoolTower->CoolTowerSys(CoolTowerNum).spacePtr);
     676            0 :                     thisSpaceHB.MCPC = thisMCPC;
     677            0 :                     thisSpaceHB.MCPTC = thisMCPTC;
     678            0 :                     thisSpaceHB.CTMFL = thisCTMFL;
     679            0 :                     thisZT = thisSpaceHB.ZT;
     680            0 :                     thisAirHumRat = thisSpaceHB.airHumRat;
     681              :                 }
     682              : 
     683         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower = thisMCPC * std::abs(thisZT - OutletTemp);
     684         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower = CVF_ZoneNum * std::abs(thisAirHumRat - OutletHumRat);
     685         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletTemp = OutletTemp;
     686         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletHumRat = OutletHumRat;
     687         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate = CVF_ZoneNum;
     688         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate = thisCTMFL;
     689         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd = thisCTMFL / state.dataEnvrn->StdRhoAir;
     690         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletDBTemp = Zone(ZoneNum).OutDryBulbTemp;
     691         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletWBTemp = Zone(ZoneNum).OutWetBulbTemp;
     692         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletHumRat = state.dataEnvrn->OutHumRat;
     693         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate = (std::abs(InletHumRat - OutletHumRat) * thisCTMFL) / RhoWater;
     694         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate = 0.0; // initialize -- calc in update
     695         3445 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower =
     696         3445 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).RatedPumpPower * PumpPartLoadRat;
     697              :             } else { // Unit is off
     698         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower = 0.0;
     699         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower = 0.0;
     700         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletTemp = 0.0;
     701         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletHumRat = 0.0;
     702         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate = 0.0;
     703         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate = 0.0;
     704         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd = 0.0;
     705         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletDBTemp = 0.0;
     706         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletHumRat = 0.0;
     707         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower = 0.0;
     708         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate = 0.0;
     709         2556 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate = 0.0;
     710              :             }
     711              :         }
     712         3580 :     }
     713              : 
     714         3580 :     void UpdateCoolTower(EnergyPlusData &state)
     715              :     {
     716              : 
     717              :         // SUBROUTINE INFORMATION:
     718              :         //       AUTHOR         Richard J. Liesen
     719              :         //       DATE WRITTEN   October 2000
     720              :         //       MODIFIED       Aug 2008 Daeho Kang
     721              : 
     722        12501 :         for (int CoolTowerNum = 1; CoolTowerNum <= (int)state.dataCoolTower->CoolTowerSys.size(); ++CoolTowerNum) {
     723              : 
     724              :             // Set the demand request for supply water from water storage tank (if needed)
     725         8921 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromTank) {
     726            0 :                 state.dataWaterData->WaterStorage(state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupTankID)
     727            0 :                     .VdotRequestDemand(state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterTankDemandARRID) =
     728            0 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate;
     729              :             }
     730              : 
     731              :             // check if should be starved by restricted flow from tank
     732         8921 :             if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromTank) {
     733            0 :                 Real64 AvailWaterRate = state.dataWaterData->WaterStorage(state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupTankID)
     734            0 :                                             .VdotAvailDemand(state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterTankDemandARRID);
     735            0 :                 if (AvailWaterRate < state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate) {
     736            0 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate =
     737            0 :                         state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate - AvailWaterRate;
     738            0 :                     state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate = AvailWaterRate;
     739              :                 }
     740              :             }
     741              :         }
     742         3580 :     }
     743              : 
     744         3580 :     void ReportCoolTower(EnergyPlusData &state)
     745              :     {
     746              : 
     747              :         // SUBROUTINE INFORMATION:
     748              :         //       AUTHOR         Daeho Kang
     749              :         //       DATE WRITTEN   Aut 2008
     750              : 
     751         3580 :         Real64 const TSMult = state.dataHVACGlobal->TimeStepSysSec;
     752              : 
     753        12501 :         for (int CoolTowerNum = 1; CoolTowerNum <= (int)state.dataCoolTower->CoolTowerSys.size(); ++CoolTowerNum) {
     754              : 
     755         8921 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTAirVol = state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate * TSMult;
     756         8921 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTAirMass = state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate * TSMult;
     757         8921 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatLoss = state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower * TSMult;
     758         8921 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatLoss = state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower * TSMult;
     759         8921 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecConsump = state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower * TSMult;
     760         8921 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump =
     761         8921 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate * TSMult;
     762         8921 :             state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeup =
     763         8921 :                 state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate * TSMult;
     764              :         }
     765         3580 :     }
     766              : 
     767              : } // namespace CoolTower
     768              : 
     769              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1