LCOV - code coverage report
Current view: top level - EnergyPlus - CoolTower.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 254 389 65.3 %
Date: 2023-01-17 19:17:23 Functions: 7 7 100.0 %

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

Generated by: LCOV version 1.13