LCOV - code coverage report
Current view: top level - EnergyPlus - EvaporativeCoolers.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1702 2210 77.0 %
Date: 2023-01-17 19:17:23 Functions: 32 36 88.9 %

          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 <cassert>
      50             : #include <cmath>
      51             : 
      52             : // ObjexxFCL Headers
      53             : #include <ObjexxFCL/Array.functions.hh>
      54             : #include <ObjexxFCL/Fmath.hh>
      55             : 
      56             : // EnergyPlus Headers
      57             : #include <EnergyPlus/Autosizing/CoolingAirFlowSizing.hh>
      58             : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
      59             : #include <EnergyPlus/BranchNodeConnections.hh>
      60             : #include <EnergyPlus/CurveManager.hh>
      61             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      62             : #include <EnergyPlus/DataContaminantBalance.hh>
      63             : #include <EnergyPlus/DataEnvironment.hh>
      64             : #include <EnergyPlus/DataGlobalConstants.hh>
      65             : #include <EnergyPlus/DataHVACGlobals.hh>
      66             : #include <EnergyPlus/DataHeatBalFanSys.hh>
      67             : #include <EnergyPlus/DataHeatBalance.hh>
      68             : #include <EnergyPlus/DataIPShortCuts.hh>
      69             : #include <EnergyPlus/DataLoopNode.hh>
      70             : #include <EnergyPlus/DataSizing.hh>
      71             : #include <EnergyPlus/DataWater.hh>
      72             : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      73             : #include <EnergyPlus/EMSManager.hh>
      74             : #include <EnergyPlus/EvaporativeCoolers.hh>
      75             : #include <EnergyPlus/Fans.hh>
      76             : #include <EnergyPlus/FaultsManager.hh>
      77             : #include <EnergyPlus/General.hh>
      78             : #include <EnergyPlus/GeneralRoutines.hh>
      79             : #include <EnergyPlus/GlobalNames.hh>
      80             : #include <EnergyPlus/HVACFan.hh>
      81             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      82             : #include <EnergyPlus/NodeInputManager.hh>
      83             : #include <EnergyPlus/OutAirNodeManager.hh>
      84             : #include <EnergyPlus/OutputProcessor.hh>
      85             : #include <EnergyPlus/Psychrometrics.hh>
      86             : #include <EnergyPlus/ScheduleManager.hh>
      87             : #include <EnergyPlus/UtilityRoutines.hh>
      88             : #include <EnergyPlus/WaterManager.hh>
      89             : 
      90             : namespace EnergyPlus::EvaporativeCoolers {
      91             : // Module containing the EvaporativeCoolers simulation routines
      92             : 
      93             : // MODULE INFORMATION:
      94             : //       AUTHOR         Richard J. Liesen
      95             : //       DATE WRITTEN   Oct 2000
      96             : //       MODIFIED       BG July 2003 ResearchSpecial Indirect
      97             : //                      BG Febraury 2007 outside air nodes
      98             : //                      BG March 2009 ResearchSpecial Direct
      99             : //       RE-ENGINEERED  na
     100             : 
     101             : // PURPOSE OF THIS MODULE:
     102             : // To encapsulate the data and algorithms required for
     103             : // Evaporative Coolers Components for use in mechanical air systems
     104             : 
     105             : // provide models for evaporative coolers as zone forced air units.
     106             : 
     107             : // METHODOLOGY EMPLOYED:
     108             : // various evaporative component models in this module
     109             : //   different models share common module level data structure.
     110             : 
     111             : constexpr std::array<std::string_view, static_cast<int>(EvapCoolerType::Num)> evapCoolerTypeNamesUC = {"EVAPORATIVECOOLER:DIRECT:CELDEKPAD",
     112             :                                                                                                        "EVAPORATIVECOOLER:INDIRECT:CELDEKPAD",
     113             :                                                                                                        "EVAPORATIVECOOLER:INDIRECT:WETCOIL",
     114             :                                                                                                        "EVAPORATIVECOOLER:INDIRECT:RESEARCHSPECIAL",
     115             :                                                                                                        "EVAPORATIVECOOLER:DIRECT:RESEARCHSPECIAL"};
     116             : constexpr std::array<std::string_view, static_cast<int>(EvapCoolerType::Num)> evapCoolerTypeNames = {"EvaporativeCooler:Direct:CelDekPad",
     117             :                                                                                                      "EvaporativeCooler:Indirect:CelDekPad",
     118             :                                                                                                      "EvaporativeCooler:Indirect:WetCoil",
     119             :                                                                                                      "EvaporativeCooler:Indirect:ResearchSpecial",
     120             :                                                                                                      "EvaporativeCooler:Direct:ResearchSpecial"};
     121             : 
     122     2882159 : void SimEvapCooler(EnergyPlusData &state, std::string_view CompName, int &CompIndex, Real64 const ZoneEvapCoolerPLR)
     123             : {
     124             : 
     125             :     // SUBROUTINE INFORMATION:
     126             :     //       AUTHOR         Richard Liesen
     127             :     //       DATE WRITTEN   October 2000
     128             :     //       MODIFIED       na
     129             :     //       RE-ENGINEERED  na
     130             : 
     131             :     // PURPOSE OF THIS SUBROUTINE:
     132             :     // This subroutine manages EvapCooler component simulation.
     133             :     // It is called from the SimAirLoopComponent
     134             :     // at the system time step.
     135             : 
     136             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     137             :     int EvapCoolNum; // The EvapCooler that you are currently loading input into
     138             : 
     139     2882159 :     auto &EvapCond(state.dataEvapCoolers->EvapCond);
     140             : 
     141             :     // Obtains and Allocates EvapCooler related parameters from input file
     142     2882159 :     if (state.dataEvapCoolers->GetInputEvapComponentsFlag) { // First time subroutine has been entered
     143          13 :         GetEvapInput(state);
     144          13 :         state.dataEvapCoolers->GetInputEvapComponentsFlag = false;
     145             :     }
     146             : 
     147             :     // Find the correct EvapCoolNumber
     148     2882159 :     if (CompIndex == 0) {
     149          51 :         EvapCoolNum = UtilityRoutines::FindItemInList(CompName, EvapCond, &EvapConditions::Name);
     150          51 :         if (EvapCoolNum == 0) {
     151           0 :             ShowFatalError(state, "SimEvapCooler: Unit not found=" + std::string{CompName});
     152             :         }
     153          51 :         CompIndex = EvapCoolNum;
     154             :     } else {
     155     2882108 :         EvapCoolNum = CompIndex;
     156     2882108 :         if (EvapCoolNum > state.dataEvapCoolers->NumEvapCool || EvapCoolNum < 1) {
     157           0 :             ShowFatalError(state,
     158           0 :                            format("SimEvapCooler:  Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
     159             :                                   EvapCoolNum,
     160           0 :                                   state.dataEvapCoolers->NumEvapCool,
     161           0 :                                   CompName));
     162             :         }
     163     2882108 :         if (state.dataEvapCoolers->CheckEquipName(EvapCoolNum)) {
     164          90 :             if (CompName != EvapCond(EvapCoolNum).Name) {
     165           0 :                 ShowFatalError(state,
     166           0 :                                format("SimEvapCooler: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
     167             :                                       EvapCoolNum,
     168             :                                       CompName,
     169           0 :                                       EvapCond(EvapCoolNum).Name));
     170             :             }
     171          90 :             state.dataEvapCoolers->CheckEquipName(EvapCoolNum) = false;
     172             :         }
     173             :     }
     174             : 
     175             :     // With the correct EvapCoolNum Initialize
     176     2882159 :     InitEvapCooler(state, EvapCoolNum); // Initialize all related parameters
     177             : 
     178     2882159 :     switch (EvapCond(EvapCoolNum).evapCoolerType) {
     179      251504 :     case EvapCoolerType::DirectCELDEKPAD: {
     180      251504 :         CalcDirectEvapCooler(state, EvapCoolNum, ZoneEvapCoolerPLR);
     181      251504 :     } break;
     182       34981 :     case EvapCoolerType::IndirectCELDEKPAD: {
     183       34981 :         CalcDryIndirectEvapCooler(state, EvapCoolNum, ZoneEvapCoolerPLR);
     184       34981 :     } break;
     185       68343 :     case EvapCoolerType::IndirectWETCOIL: {
     186       68343 :         CalcWetIndirectEvapCooler(state, EvapCoolNum, ZoneEvapCoolerPLR);
     187       68343 :     } break;
     188     1135644 :     case EvapCoolerType::IndirectRDDSpecial: {
     189     1135644 :         CalcResearchSpecialPartLoad(state, EvapCoolNum);
     190     1135644 :         CalcIndirectResearchSpecialEvapCooler(state, EvapCoolNum, ZoneEvapCoolerPLR);
     191     1135644 :     } break;
     192     1391687 :     case EvapCoolerType::DirectResearchSpecial: {
     193     1391687 :         CalcResearchSpecialPartLoad(state, EvapCoolNum);
     194     1391687 :         CalcDirectResearchSpecialEvapCooler(state, EvapCoolNum, ZoneEvapCoolerPLR);
     195     1391687 :     } break;
     196           0 :     default:
     197           0 :         break;
     198             :     }
     199             :     // Update the current Evap Cooler to the outlet nodes
     200     2882159 :     UpdateEvapCooler(state, EvapCoolNum);
     201             : 
     202             :     // Report the current Evap Cooler
     203     2882159 :     ReportEvapCooler(state, EvapCoolNum);
     204     2882159 : }
     205             : 
     206          16 : void GetEvapInput(EnergyPlusData &state)
     207             : {
     208             : 
     209             :     // SUBROUTINE INFORMATION:
     210             :     //       AUTHOR         Richard J. Liesen
     211             :     //       DATE WRITTEN   Oct 2000
     212             :     //       MODIFIED       BTG,  adding in EVAPCOOLER:INDIRECT:RDDSPECIAL
     213             :     //       RE-ENGINEERED  na
     214             : 
     215             :     // PURPOSE OF THIS SUBROUTINE:
     216             :     // This subroutine is the main routine to call other input routines and Get routines
     217             : 
     218             :     // METHODOLOGY EMPLOYED:
     219             :     // Uses the status flags to trigger events.
     220             : 
     221             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     222             :     int NumDirectEvapCool;                // The number of Direct CelDek EvapCooler in this simulation
     223             :     int NumDryInDirectEvapCool;           // The number of dry indirect evap coolers
     224             :     int NumWetInDirectEvapCool;           // The number of wet indirect evap coolers
     225             :     int NumRDDEvapCool;                   // the number of special research indirect evap coolers
     226             :     int NumDirectResearchSpecialEvapCool; // the number of special research direct evap coolers
     227             : 
     228             :     int NumAlphas;
     229             :     int NumNums;
     230             :     int IOStat;
     231          16 :     bool ErrorsFound(false);
     232             : 
     233          16 :     auto &EvapCond(state.dataEvapCoolers->EvapCond);
     234          16 :     auto &UniqueEvapCondNames(state.dataEvapCoolers->UniqueEvapCondNames);
     235             : 
     236          16 :     state.dataEvapCoolers->GetInputEvapComponentsFlag = false;
     237             :     // Start getting the input data
     238          16 :     NumDirectEvapCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "EvaporativeCooler:Direct:CelDekPad");
     239          16 :     NumDryInDirectEvapCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "EvaporativeCooler:Indirect:CelDekPad");
     240          16 :     NumWetInDirectEvapCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "EvaporativeCooler:Indirect:WetCoil");
     241          16 :     NumRDDEvapCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "EvaporativeCooler:Indirect:ResearchSpecial");
     242          16 :     NumDirectResearchSpecialEvapCool =
     243          32 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "EvaporativeCooler:Direct:ResearchSpecial");
     244             : 
     245             :     // Sum up all of the Evap Cooler Types
     246          16 :     state.dataEvapCoolers->NumEvapCool =
     247          16 :         NumDirectEvapCool + NumDryInDirectEvapCool + NumWetInDirectEvapCool + NumRDDEvapCool + NumDirectResearchSpecialEvapCool;
     248             : 
     249          16 :     if (state.dataEvapCoolers->NumEvapCool > 0) {
     250          16 :         EvapCond.allocate(state.dataEvapCoolers->NumEvapCool);
     251          16 :         UniqueEvapCondNames.reserve(state.dataEvapCoolers->NumEvapCool);
     252             :     }
     253          16 :     state.dataEvapCoolers->CheckEquipName.dimension(state.dataEvapCoolers->NumEvapCool, true);
     254          16 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     255          16 :     cCurrentModuleObject = "EvaporativeCooler:Direct:CelDekPad";
     256             : 
     257          38 :     for (int EvapCoolNum = 1; EvapCoolNum <= NumDirectEvapCool; ++EvapCoolNum) {
     258          22 :         auto &thisEvapCooler = EvapCond(EvapCoolNum);
     259         132 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     260             :                                                                  cCurrentModuleObject,
     261             :                                                                  EvapCoolNum,
     262          22 :                                                                  state.dataIPShortCut->cAlphaArgs,
     263             :                                                                  NumAlphas,
     264          22 :                                                                  state.dataIPShortCut->rNumericArgs,
     265             :                                                                  NumNums,
     266             :                                                                  IOStat,
     267             :                                                                  _,
     268          22 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     269          22 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     270          22 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     271          44 :         GlobalNames::VerifyUniqueInterObjectName(state,
     272             :                                                  UniqueEvapCondNames,
     273          22 :                                                  state.dataIPShortCut->cAlphaArgs(1),
     274             :                                                  cCurrentModuleObject,
     275          22 :                                                  state.dataIPShortCut->cAlphaFieldNames(1),
     276             :                                                  ErrorsFound);
     277          22 :         thisEvapCooler.Name = state.dataIPShortCut->cAlphaArgs(1);
     278          22 :         thisEvapCooler.evapCoolerType = EvapCoolerType::DirectCELDEKPAD;
     279             : 
     280          22 :         thisEvapCooler.Schedule = state.dataIPShortCut->cAlphaArgs(2);
     281          22 :         if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     282           0 :             thisEvapCooler.SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     283             :         } else {
     284          22 :             thisEvapCooler.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     285          22 :             if (thisEvapCooler.SchedPtr == 0) {
     286           0 :                 ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(2) + '=' + state.dataIPShortCut->cAlphaArgs(2));
     287           0 :                 ShowContinueError(state, "Entered in " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
     288           0 :                 ErrorsFound = true;
     289             :             }
     290             :         }
     291             : 
     292          22 :         thisEvapCooler.InletNode = GetOnlySingleNode(state,
     293          22 :                                                      state.dataIPShortCut->cAlphaArgs(3),
     294             :                                                      ErrorsFound,
     295             :                                                      DataLoopNode::ConnectionObjectType::EvaporativeCoolerDirectCelDekPad,
     296          22 :                                                      state.dataIPShortCut->cAlphaArgs(1),
     297             :                                                      DataLoopNode::NodeFluidType::Air,
     298             :                                                      DataLoopNode::ConnectionType::Inlet,
     299             :                                                      NodeInputManager::CompFluidStream::Primary,
     300          22 :                                                      DataLoopNode::ObjectIsNotParent);
     301             : 
     302          22 :         thisEvapCooler.OutletNode = GetOnlySingleNode(state,
     303          22 :                                                       state.dataIPShortCut->cAlphaArgs(4),
     304             :                                                       ErrorsFound,
     305             :                                                       DataLoopNode::ConnectionObjectType::EvaporativeCoolerDirectCelDekPad,
     306          22 :                                                       state.dataIPShortCut->cAlphaArgs(1),
     307             :                                                       DataLoopNode::NodeFluidType::Air,
     308             :                                                       DataLoopNode::ConnectionType::Outlet,
     309             :                                                       NodeInputManager::CompFluidStream::Primary,
     310          22 :                                                       DataLoopNode::ObjectIsNotParent);
     311             : 
     312          44 :         BranchNodeConnections::TestCompSet(state,
     313             :                                            cCurrentModuleObject,
     314          22 :                                            state.dataIPShortCut->cAlphaArgs(1),
     315          22 :                                            state.dataIPShortCut->cAlphaArgs(3),
     316          22 :                                            state.dataIPShortCut->cAlphaArgs(4),
     317             :                                            "Evap Air Nodes");
     318             : 
     319          22 :         thisEvapCooler.EvapControlType = state.dataIPShortCut->cAlphaArgs(5);
     320             : 
     321             :         // input the numerical data
     322          22 :         thisEvapCooler.PadArea = state.dataIPShortCut->rNumericArgs(1);
     323          22 :         thisEvapCooler.PadDepth = state.dataIPShortCut->rNumericArgs(2);
     324          22 :         thisEvapCooler.RecircPumpPower = state.dataIPShortCut->rNumericArgs(3);
     325             : 
     326          44 :         SetupOutputVariable(state,
     327             :                             "Evaporative Cooler Wet Bulb Effectiveness",
     328             :                             OutputProcessor::Unit::None,
     329             :                             thisEvapCooler.SatEff,
     330             :                             OutputProcessor::SOVTimeStepType::System,
     331             :                             OutputProcessor::SOVStoreType::Average,
     332          22 :                             thisEvapCooler.Name);
     333             : 
     334             :         // A6 ; \Field Name of Water Supply Storage Tank
     335          22 :         thisEvapCooler.EvapWaterSupplyName = state.dataIPShortCut->cAlphaArgs(6);
     336          22 :         if (state.dataIPShortCut->lAlphaFieldBlanks(6)) {
     337          22 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromMains;
     338             :         } else {
     339           0 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromTank;
     340           0 :             WaterManager::SetupTankDemandComponent(state,
     341             :                                                    thisEvapCooler.Name,
     342             :                                                    cCurrentModuleObject,
     343             :                                                    thisEvapCooler.EvapWaterSupplyName,
     344             :                                                    ErrorsFound,
     345             :                                                    thisEvapCooler.EvapWaterSupTankID,
     346             :                                                    thisEvapCooler.EvapWaterTankDemandARRID);
     347             :         }
     348             : 
     349             :     } // end Number of EvapCooler Loop
     350             : 
     351             :     //**************************************************************
     352             :     // This is the start of the Dry Indirect Evap Cooler Loop
     353          16 :     cCurrentModuleObject = "EvaporativeCooler:Indirect:CelDekPad";
     354             : 
     355          20 :     for (int IndEvapCoolNum = 1; IndEvapCoolNum <= NumDryInDirectEvapCool; ++IndEvapCoolNum) {
     356           4 :         int EvapCoolNum = NumDirectEvapCool + IndEvapCoolNum;
     357           4 :         auto &thisEvapCooler = EvapCond(EvapCoolNum);
     358          24 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     359             :                                                                  cCurrentModuleObject,
     360             :                                                                  IndEvapCoolNum,
     361           4 :                                                                  state.dataIPShortCut->cAlphaArgs,
     362             :                                                                  NumAlphas,
     363           4 :                                                                  state.dataIPShortCut->rNumericArgs,
     364             :                                                                  NumNums,
     365             :                                                                  IOStat,
     366             :                                                                  _,
     367           4 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     368           4 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     369           4 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     370           8 :         GlobalNames::VerifyUniqueInterObjectName(state,
     371             :                                                  UniqueEvapCondNames,
     372           4 :                                                  state.dataIPShortCut->cAlphaArgs(1),
     373             :                                                  cCurrentModuleObject,
     374           4 :                                                  state.dataIPShortCut->cAlphaFieldNames(1),
     375             :                                                  ErrorsFound);
     376           4 :         thisEvapCooler.Name = state.dataIPShortCut->cAlphaArgs(1);
     377           4 :         thisEvapCooler.evapCoolerType = EvapCoolerType::IndirectCELDEKPAD; //'EvaporativeCooler:Indirect:CelDekPad'
     378             : 
     379           4 :         thisEvapCooler.Schedule = state.dataIPShortCut->cAlphaArgs(2);
     380           4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     381           0 :             thisEvapCooler.SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     382             :         } else {
     383           4 :             thisEvapCooler.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     384           4 :             if (thisEvapCooler.SchedPtr == 0) {
     385           0 :                 ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(2) + '=' + state.dataIPShortCut->cAlphaArgs(2));
     386           0 :                 ShowContinueError(state, "Entered in " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
     387           0 :                 ErrorsFound = true;
     388             :             }
     389             :         }
     390             : 
     391           4 :         thisEvapCooler.InletNode = GetOnlySingleNode(state,
     392           4 :                                                      state.dataIPShortCut->cAlphaArgs(3),
     393             :                                                      ErrorsFound,
     394             :                                                      DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectCelDekPad,
     395           4 :                                                      state.dataIPShortCut->cAlphaArgs(1),
     396             :                                                      DataLoopNode::NodeFluidType::Air,
     397             :                                                      DataLoopNode::ConnectionType::Inlet,
     398             :                                                      NodeInputManager::CompFluidStream::Primary,
     399           4 :                                                      DataLoopNode::ObjectIsNotParent);
     400             : 
     401           4 :         thisEvapCooler.OutletNode = GetOnlySingleNode(state,
     402           4 :                                                       state.dataIPShortCut->cAlphaArgs(4),
     403             :                                                       ErrorsFound,
     404             :                                                       DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectCelDekPad,
     405           4 :                                                       state.dataIPShortCut->cAlphaArgs(1),
     406             :                                                       DataLoopNode::NodeFluidType::Air,
     407             :                                                       DataLoopNode::ConnectionType::Outlet,
     408             :                                                       NodeInputManager::CompFluidStream::Primary,
     409           4 :                                                       DataLoopNode::ObjectIsNotParent);
     410             : 
     411           8 :         BranchNodeConnections::TestCompSet(state,
     412             :                                            cCurrentModuleObject,
     413           4 :                                            state.dataIPShortCut->cAlphaArgs(1),
     414           4 :                                            state.dataIPShortCut->cAlphaArgs(3),
     415           4 :                                            state.dataIPShortCut->cAlphaArgs(4),
     416             :                                            "Evap Air Nodes");
     417             : 
     418           4 :         thisEvapCooler.EvapControlType = state.dataIPShortCut->cAlphaArgs(5);
     419             : 
     420             :         // input the numerical data
     421           4 :         thisEvapCooler.IndirectPadArea = state.dataIPShortCut->rNumericArgs(1);
     422           4 :         thisEvapCooler.IndirectPadDepth = state.dataIPShortCut->rNumericArgs(2);
     423           4 :         thisEvapCooler.IndirectRecircPumpPower = state.dataIPShortCut->rNumericArgs(3);
     424           4 :         thisEvapCooler.IndirectVolFlowRate = state.dataIPShortCut->rNumericArgs(4);
     425           4 :         thisEvapCooler.IndirectFanEff = state.dataIPShortCut->rNumericArgs(5);
     426           4 :         thisEvapCooler.IndirectFanDeltaPress = state.dataIPShortCut->rNumericArgs(6);
     427           4 :         thisEvapCooler.IndirectHXEffectiveness = state.dataIPShortCut->rNumericArgs(7);
     428             : 
     429           8 :         SetupOutputVariable(state,
     430             :                             "Evaporative Cooler Wetbulb Effectiveness",
     431             :                             OutputProcessor::Unit::None,
     432             :                             thisEvapCooler.SatEff,
     433             :                             OutputProcessor::SOVTimeStepType::System,
     434             :                             OutputProcessor::SOVStoreType::Average,
     435           4 :                             thisEvapCooler.Name);
     436           8 :         SetupOutputVariable(state,
     437             :                             "Evaporative Cooler Total Stage Effectiveness",
     438             :                             OutputProcessor::Unit::None,
     439             :                             thisEvapCooler.StageEff,
     440             :                             OutputProcessor::SOVTimeStepType::System,
     441             :                             OutputProcessor::SOVStoreType::Average,
     442           4 :                             thisEvapCooler.Name);
     443             : 
     444             :         // A6 ; \Field Name of Water Supply Storage Tank
     445           4 :         thisEvapCooler.EvapWaterSupplyName = state.dataIPShortCut->cAlphaArgs(6);
     446           4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(6)) {
     447           4 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromMains;
     448             :         } else {
     449           0 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromTank;
     450           0 :             WaterManager::SetupTankDemandComponent(state,
     451             :                                                    thisEvapCooler.Name,
     452             :                                                    cCurrentModuleObject,
     453             :                                                    thisEvapCooler.EvapWaterSupplyName,
     454             :                                                    ErrorsFound,
     455             :                                                    thisEvapCooler.EvapWaterSupTankID,
     456             :                                                    thisEvapCooler.EvapWaterTankDemandARRID);
     457             :         }
     458             : 
     459             :         // A7 ; \field Secondary Outside Air Inlet node.
     460           4 :         if (state.dataIPShortCut->lAlphaFieldBlanks(7)) {
     461           0 :             thisEvapCooler.SecondaryInletNode = 0;
     462             :         } else {
     463           4 :             thisEvapCooler.SecondaryInletNode = GetOnlySingleNode(state,
     464           4 :                                                                   state.dataIPShortCut->cAlphaArgs(7),
     465             :                                                                   ErrorsFound,
     466             :                                                                   DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectCelDekPad,
     467           4 :                                                                   state.dataIPShortCut->cAlphaArgs(1),
     468             :                                                                   DataLoopNode::NodeFluidType::Air,
     469             :                                                                   DataLoopNode::ConnectionType::OutsideAirReference,
     470             :                                                                   NodeInputManager::CompFluidStream::Primary,
     471           4 :                                                                   DataLoopNode::ObjectIsNotParent);
     472           4 :             if (!OutAirNodeManager::CheckOutAirNodeNumber(state, thisEvapCooler.SecondaryInletNode)) {
     473           0 :                 ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(7) + '=' + state.dataIPShortCut->cAlphaArgs(7));
     474           0 :                 ShowContinueError(state, "Entered in " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
     475             :                 // TODO rename point
     476           0 :                 ShowContinueError(state, "Node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
     477           0 :                 ErrorsFound = true;
     478             :             }
     479             :         }
     480             : 
     481             :     } // end Number of Dry Indirect EvapCooler Loop
     482             : 
     483             :     //**************************************************************
     484             :     // This is the start of the WetIndirect Evap Cooler Loop
     485          16 :     cCurrentModuleObject = "EvaporativeCooler:Indirect:WetCoil";
     486          23 :     for (int IndEvapCoolNum = 1; IndEvapCoolNum <= NumWetInDirectEvapCool; ++IndEvapCoolNum) {
     487           7 :         int EvapCoolNum = NumDirectEvapCool + NumDryInDirectEvapCool + IndEvapCoolNum;
     488           7 :         auto &thisEvapCooler = EvapCond(EvapCoolNum);
     489          42 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     490             :                                                                  cCurrentModuleObject,
     491             :                                                                  IndEvapCoolNum,
     492           7 :                                                                  state.dataIPShortCut->cAlphaArgs,
     493             :                                                                  NumAlphas,
     494           7 :                                                                  state.dataIPShortCut->rNumericArgs,
     495             :                                                                  NumNums,
     496             :                                                                  IOStat,
     497             :                                                                  _,
     498           7 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     499           7 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     500           7 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     501          14 :         GlobalNames::VerifyUniqueInterObjectName(state,
     502             :                                                  UniqueEvapCondNames,
     503           7 :                                                  state.dataIPShortCut->cAlphaArgs(1),
     504             :                                                  cCurrentModuleObject,
     505           7 :                                                  state.dataIPShortCut->cAlphaFieldNames(1),
     506             :                                                  ErrorsFound);
     507           7 :         thisEvapCooler.Name = state.dataIPShortCut->cAlphaArgs(1);
     508           7 :         thisEvapCooler.evapCoolerType = EvapCoolerType::IndirectWETCOIL; //'EvaporativeCooler:Indirect:WetCoil'
     509             : 
     510           7 :         thisEvapCooler.Schedule = state.dataIPShortCut->cAlphaArgs(2);
     511           7 :         if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     512           0 :             thisEvapCooler.SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     513             :         } else {
     514           7 :             thisEvapCooler.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     515           7 :             if (thisEvapCooler.SchedPtr == 0) {
     516           0 :                 ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(2) + '=' + state.dataIPShortCut->cAlphaArgs(2));
     517           0 :                 ShowContinueError(state, "Entered in " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
     518           0 :                 ErrorsFound = true;
     519             :             }
     520             :         }
     521             : 
     522           7 :         thisEvapCooler.InletNode = GetOnlySingleNode(state,
     523           7 :                                                      state.dataIPShortCut->cAlphaArgs(3),
     524             :                                                      ErrorsFound,
     525             :                                                      DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectWetCoil,
     526           7 :                                                      state.dataIPShortCut->cAlphaArgs(1),
     527             :                                                      DataLoopNode::NodeFluidType::Air,
     528             :                                                      DataLoopNode::ConnectionType::Inlet,
     529             :                                                      NodeInputManager::CompFluidStream::Primary,
     530           7 :                                                      DataLoopNode::ObjectIsNotParent);
     531             : 
     532           7 :         thisEvapCooler.OutletNode = GetOnlySingleNode(state,
     533           7 :                                                       state.dataIPShortCut->cAlphaArgs(4),
     534             :                                                       ErrorsFound,
     535             :                                                       DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectWetCoil,
     536           7 :                                                       state.dataIPShortCut->cAlphaArgs(1),
     537             :                                                       DataLoopNode::NodeFluidType::Air,
     538             :                                                       DataLoopNode::ConnectionType::Outlet,
     539             :                                                       NodeInputManager::CompFluidStream::Primary,
     540           7 :                                                       DataLoopNode::ObjectIsNotParent);
     541             : 
     542          14 :         BranchNodeConnections::TestCompSet(state,
     543             :                                            cCurrentModuleObject,
     544           7 :                                            state.dataIPShortCut->cAlphaArgs(1),
     545           7 :                                            state.dataIPShortCut->cAlphaArgs(3),
     546           7 :                                            state.dataIPShortCut->cAlphaArgs(4),
     547             :                                            "Evap Air Nodes");
     548             : 
     549           7 :         thisEvapCooler.EvapControlType = state.dataIPShortCut->cAlphaArgs(5);
     550             : 
     551             :         // input the numerical data
     552           7 :         thisEvapCooler.WetCoilMaxEfficiency = state.dataIPShortCut->rNumericArgs(1);
     553           7 :         thisEvapCooler.WetCoilFlowRatio = state.dataIPShortCut->rNumericArgs(2);
     554           7 :         thisEvapCooler.IndirectRecircPumpPower = state.dataIPShortCut->rNumericArgs(3);
     555           7 :         thisEvapCooler.IndirectVolFlowRate = state.dataIPShortCut->rNumericArgs(4);
     556           7 :         thisEvapCooler.IndirectFanEff = state.dataIPShortCut->rNumericArgs(5);
     557           7 :         thisEvapCooler.IndirectFanDeltaPress = state.dataIPShortCut->rNumericArgs(6);
     558             : 
     559          14 :         SetupOutputVariable(state,
     560             :                             "Evaporative Cooler Total Stage Effectiveness",
     561             :                             OutputProcessor::Unit::None,
     562             :                             thisEvapCooler.StageEff,
     563             :                             OutputProcessor::SOVTimeStepType::System,
     564             :                             OutputProcessor::SOVStoreType::Average,
     565           7 :                             thisEvapCooler.Name);
     566             : 
     567             :         //  A6 ; \Field Name of Water Supply Storage Tank
     568           7 :         thisEvapCooler.EvapWaterSupplyName = state.dataIPShortCut->cAlphaArgs(6);
     569           7 :         if (state.dataIPShortCut->lAlphaFieldBlanks(6)) {
     570           7 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromMains;
     571             :         } else {
     572           0 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromTank;
     573           0 :             WaterManager::SetupTankDemandComponent(state,
     574             :                                                    thisEvapCooler.Name,
     575             :                                                    cCurrentModuleObject,
     576             :                                                    thisEvapCooler.EvapWaterSupplyName,
     577             :                                                    ErrorsFound,
     578             :                                                    thisEvapCooler.EvapWaterSupTankID,
     579             :                                                    thisEvapCooler.EvapWaterTankDemandARRID);
     580             :         }
     581             : 
     582             :         // A7 ; \field Secondary Outside Air Inlet node.
     583           7 :         if (state.dataIPShortCut->lAlphaFieldBlanks(7)) {
     584           0 :             thisEvapCooler.SecondaryInletNode = 0;
     585             :         } else {
     586           7 :             thisEvapCooler.SecondaryInletNode = GetOnlySingleNode(state,
     587           7 :                                                                   state.dataIPShortCut->cAlphaArgs(7),
     588             :                                                                   ErrorsFound,
     589             :                                                                   DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectWetCoil,
     590           7 :                                                                   state.dataIPShortCut->cAlphaArgs(1),
     591             :                                                                   DataLoopNode::NodeFluidType::Air,
     592             :                                                                   DataLoopNode::ConnectionType::OutsideAirReference,
     593             :                                                                   NodeInputManager::CompFluidStream::Primary,
     594           7 :                                                                   DataLoopNode::ObjectIsNotParent);
     595           7 :             if (!OutAirNodeManager::CheckOutAirNodeNumber(state, thisEvapCooler.SecondaryInletNode)) {
     596           0 :                 ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(7) + '=' + state.dataIPShortCut->cAlphaArgs(7));
     597           0 :                 ShowContinueError(state, "Entered in " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
     598             :                 // TODO rename point
     599           0 :                 ShowContinueError(state, "Node does not appear in an OutdoorAir:NodeList or as an OutdoorAir:Node.");
     600           0 :                 ErrorsFound = true;
     601             :             }
     602             :         }
     603             : 
     604             :     } // end Number of Wet Coil Indirect EvapCooler Loop
     605             :     //**************************************************************
     606             :     // This is the start of the Indirect Research Special Evap Cooler
     607          16 :     cCurrentModuleObject = "EvaporativeCooler:Indirect:ResearchSpecial";
     608          52 :     for (int IndEvapCoolNum = 1; IndEvapCoolNum <= NumRDDEvapCool; ++IndEvapCoolNum) {
     609          36 :         int EvapCoolNum = NumDirectEvapCool + NumDryInDirectEvapCool + NumWetInDirectEvapCool + IndEvapCoolNum;
     610          36 :         auto &thisEvapCooler = EvapCond(EvapCoolNum);
     611         252 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     612             :                                                                  cCurrentModuleObject,
     613             :                                                                  IndEvapCoolNum,
     614          36 :                                                                  state.dataIPShortCut->cAlphaArgs,
     615             :                                                                  NumAlphas,
     616          36 :                                                                  state.dataIPShortCut->rNumericArgs,
     617             :                                                                  NumNums,
     618             :                                                                  IOStat,
     619          36 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     620          36 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     621          36 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     622          36 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     623          72 :         GlobalNames::VerifyUniqueInterObjectName(state,
     624             :                                                  UniqueEvapCondNames,
     625          36 :                                                  state.dataIPShortCut->cAlphaArgs(1),
     626             :                                                  cCurrentModuleObject,
     627          36 :                                                  state.dataIPShortCut->cAlphaFieldNames(1),
     628             :                                                  ErrorsFound);
     629          36 :         thisEvapCooler.Name = state.dataIPShortCut->cAlphaArgs(1);
     630          36 :         thisEvapCooler.evapCoolerType = EvapCoolerType::IndirectRDDSpecial; //'EvaporativeCooler:Indirect:ResearchSpecial'
     631             : 
     632          36 :         thisEvapCooler.Schedule = state.dataIPShortCut->cAlphaArgs(2);
     633          36 :         if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     634           0 :             thisEvapCooler.SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     635             :         } else {
     636          36 :             thisEvapCooler.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     637          36 :             if (thisEvapCooler.SchedPtr == 0) {
     638           0 :                 ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(2) + '=' + state.dataIPShortCut->cAlphaArgs(2));
     639           0 :                 ShowContinueError(state, "Entered in " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
     640           0 :                 ErrorsFound = true;
     641             :             }
     642             :         }
     643             : 
     644          36 :         thisEvapCooler.InletNode = GetOnlySingleNode(state,
     645          36 :                                                      state.dataIPShortCut->cAlphaArgs(7),
     646             :                                                      ErrorsFound,
     647             :                                                      DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectResearchSpecial,
     648          36 :                                                      state.dataIPShortCut->cAlphaArgs(1),
     649             :                                                      DataLoopNode::NodeFluidType::Air,
     650             :                                                      DataLoopNode::ConnectionType::Inlet,
     651             :                                                      NodeInputManager::CompFluidStream::Primary,
     652          36 :                                                      DataLoopNode::ObjectIsNotParent);
     653             : 
     654          36 :         thisEvapCooler.OutletNode = GetOnlySingleNode(state,
     655          36 :                                                       state.dataIPShortCut->cAlphaArgs(8),
     656             :                                                       ErrorsFound,
     657             :                                                       DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectResearchSpecial,
     658          36 :                                                       state.dataIPShortCut->cAlphaArgs(1),
     659             :                                                       DataLoopNode::NodeFluidType::Air,
     660             :                                                       DataLoopNode::ConnectionType::Outlet,
     661             :                                                       NodeInputManager::CompFluidStream::Primary,
     662          36 :                                                       DataLoopNode::ObjectIsNotParent);
     663             : 
     664          72 :         BranchNodeConnections::TestCompSet(state,
     665             :                                            cCurrentModuleObject,
     666          36 :                                            state.dataIPShortCut->cAlphaArgs(1),
     667          36 :                                            state.dataIPShortCut->cAlphaArgs(7),
     668          36 :                                            state.dataIPShortCut->cAlphaArgs(8),
     669             :                                            "Evap Air Nodes");
     670             : 
     671          36 :         if (state.dataIPShortCut->lAlphaFieldBlanks(9)) {
     672           0 :             thisEvapCooler.SecondaryInletNode = 0;
     673             :         } else {
     674          36 :             thisEvapCooler.SecondaryInletNode = GetOnlySingleNode(state,
     675          36 :                                                                   state.dataIPShortCut->cAlphaArgs(9),
     676             :                                                                   ErrorsFound,
     677             :                                                                   DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectResearchSpecial,
     678          36 :                                                                   state.dataIPShortCut->cAlphaArgs(1),
     679             :                                                                   DataLoopNode::NodeFluidType::Air,
     680             :                                                                   DataLoopNode::ConnectionType::Inlet,
     681             :                                                                   NodeInputManager::CompFluidStream::Secondary,
     682          36 :                                                                   DataLoopNode::ObjectIsNotParent);
     683             :         }
     684             : 
     685          36 :         if (state.dataIPShortCut->lAlphaFieldBlanks(10)) {
     686           0 :             thisEvapCooler.SecondaryOutletNode = 0;
     687             :         } else {
     688          36 :             thisEvapCooler.SecondaryOutletNode = GetOnlySingleNode(state,
     689          36 :                                                                    state.dataIPShortCut->cAlphaArgs(10),
     690             :                                                                    ErrorsFound,
     691             :                                                                    DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectResearchSpecial,
     692          36 :                                                                    state.dataIPShortCut->cAlphaArgs(1),
     693             :                                                                    DataLoopNode::NodeFluidType::Air,
     694             :                                                                    DataLoopNode::ConnectionType::Outlet,
     695             :                                                                    NodeInputManager::CompFluidStream::Secondary,
     696          36 :                                                                    DataLoopNode::ObjectIsNotParent);
     697             :         }
     698             : 
     699          36 :         thisEvapCooler.EvapControlNodeNum = GetOnlySingleNode(state,
     700          36 :                                                               state.dataIPShortCut->cAlphaArgs(11),
     701             :                                                               ErrorsFound,
     702             :                                                               DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectResearchSpecial,
     703          36 :                                                               state.dataIPShortCut->cAlphaArgs(1),
     704             :                                                               DataLoopNode::NodeFluidType::Air,
     705             :                                                               DataLoopNode::ConnectionType::Sensor,
     706             :                                                               NodeInputManager::CompFluidStream::Primary,
     707          36 :                                                               DataLoopNode::ObjectIsNotParent);
     708             : 
     709          36 :         thisEvapCooler.TertiaryInletNode = GetOnlySingleNode(state,
     710          36 :                                                              state.dataIPShortCut->cAlphaArgs(12),
     711             :                                                              ErrorsFound,
     712             :                                                              DataLoopNode::ConnectionObjectType::EvaporativeCoolerIndirectResearchSpecial,
     713          36 :                                                              state.dataIPShortCut->cAlphaArgs(1),
     714             :                                                              DataLoopNode::NodeFluidType::Air,
     715             :                                                              DataLoopNode::ConnectionType::Inlet,
     716             :                                                              NodeInputManager::CompFluidStream::Tertiary,
     717          36 :                                                              DataLoopNode::ObjectIsNotParent);
     718             : 
     719          36 :         thisEvapCooler.EvapWaterSupplyName = state.dataIPShortCut->cAlphaArgs(13);
     720          36 :         if (state.dataIPShortCut->lAlphaFieldBlanks(13)) {
     721          36 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromMains;
     722             :         } else {
     723           0 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromTank;
     724           0 :             WaterManager::SetupTankDemandComponent(state,
     725             :                                                    thisEvapCooler.Name,
     726             :                                                    cCurrentModuleObject,
     727             :                                                    thisEvapCooler.EvapWaterSupplyName,
     728             :                                                    ErrorsFound,
     729             :                                                    thisEvapCooler.EvapWaterSupTankID,
     730             :                                                    thisEvapCooler.EvapWaterTankDemandARRID);
     731             :         }
     732             : 
     733             :         // input the numerical data
     734          36 :         thisEvapCooler.WetCoilMaxEfficiency = state.dataIPShortCut->rNumericArgs(1);
     735          36 :         if (state.dataIPShortCut->lNumericFieldBlanks(2)) {
     736          32 :             thisEvapCooler.DryCoilMaxEfficiency = 0.0;
     737             :         } else {
     738           4 :             thisEvapCooler.DryCoilMaxEfficiency = state.dataIPShortCut->rNumericArgs(2);
     739             :         }
     740          36 :         thisEvapCooler.IndirectRecircPumpPower = state.dataIPShortCut->rNumericArgs(3);
     741          36 :         thisEvapCooler.RecircPumpSizingFactor = state.dataIPShortCut->rNumericArgs(4);
     742          36 :         thisEvapCooler.IndirectVolFlowRate = state.dataIPShortCut->rNumericArgs(5);
     743          36 :         thisEvapCooler.IndirectVolFlowScalingFactor = state.dataIPShortCut->rNumericArgs(6);
     744          36 :         thisEvapCooler.IndirectFanPower = state.dataIPShortCut->rNumericArgs(7);
     745          36 :         thisEvapCooler.FanSizingSpecificPower = state.dataIPShortCut->rNumericArgs(8);
     746          36 :         thisEvapCooler.DesVolFlowRate = state.dataIPShortCut->rNumericArgs(9);
     747          36 :         thisEvapCooler.DPBoundFactor = state.dataIPShortCut->rNumericArgs(10);
     748          36 :         if (state.dataIPShortCut->lNumericFieldBlanks(11)) {
     749          24 :             thisEvapCooler.DriftFraction = 0.0;
     750             :         } else {
     751          12 :             thisEvapCooler.DriftFraction = state.dataIPShortCut->rNumericArgs(11);
     752             :         }
     753          36 :         if (state.dataIPShortCut->lNumericFieldBlanks(12)) {
     754          28 :             thisEvapCooler.BlowDownRatio = 0.0;
     755             :         } else {
     756           8 :             thisEvapCooler.BlowDownRatio = state.dataIPShortCut->rNumericArgs(12);
     757             :         }
     758          80 :         if (state.dataIPShortCut->lNumericFieldBlanks(2) || state.dataIPShortCut->lNumericFieldBlanks(13) ||
     759          44 :             state.dataIPShortCut->lNumericFieldBlanks(14) || state.dataIPShortCut->lNumericFieldBlanks(15)) {
     760          32 :             thisEvapCooler.EvapCoolerOperationControlFlag = false;
     761             :         } else {
     762          16 :             if (!state.dataIPShortCut->lNumericFieldBlanks(2) && !state.dataIPShortCut->lNumericFieldBlanks(13) &&
     763          12 :                 !state.dataIPShortCut->lNumericFieldBlanks(14) && !state.dataIPShortCut->lNumericFieldBlanks(15)) {
     764           4 :                 thisEvapCooler.EvapCoolerOperationControlFlag = true;
     765           4 :                 thisEvapCooler.MinOATDBEvapCooler = state.dataIPShortCut->rNumericArgs(13);
     766           4 :                 thisEvapCooler.MaxOATWBEvapCooler = state.dataIPShortCut->rNumericArgs(14);
     767           4 :                 thisEvapCooler.MaxOATDBEvapCooler = state.dataIPShortCut->rNumericArgs(15);
     768             :             } else {
     769           0 :                 thisEvapCooler.EvapCoolerOperationControlFlag = false;
     770             :             }
     771             :         }
     772          36 :         thisEvapCooler.WetbulbEffecCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(3));
     773          36 :         thisEvapCooler.DrybulbEffecCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(4));
     774          36 :         thisEvapCooler.PumpPowerModifierCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(5));
     775          36 :         thisEvapCooler.FanPowerModifierCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(6));
     776             : 
     777          72 :         SetupOutputVariable(state,
     778             :                             "Evaporative Cooler Total Stage Effectiveness",
     779             :                             OutputProcessor::Unit::None,
     780             :                             thisEvapCooler.StageEff,
     781             :                             OutputProcessor::SOVTimeStepType::System,
     782             :                             OutputProcessor::SOVStoreType::Average,
     783          36 :                             thisEvapCooler.Name);
     784          72 :         SetupOutputVariable(state,
     785             :                             "Evaporative Cooler Part Load Ratio",
     786             :                             OutputProcessor::Unit::None,
     787             :                             thisEvapCooler.PartLoadFract,
     788             :                             OutputProcessor::SOVTimeStepType::System,
     789             :                             OutputProcessor::SOVStoreType::Average,
     790          36 :                             thisEvapCooler.Name);
     791             : 
     792          72 :         SetupOutputVariable(state,
     793             :                             "Evaporative Cooler Dewpoint Bound Status",
     794             :                             OutputProcessor::Unit::None,
     795             :                             thisEvapCooler.DewPointBoundFlag,
     796             :                             OutputProcessor::SOVTimeStepType::System,
     797             :                             OutputProcessor::SOVStoreType::Average,
     798          36 :                             thisEvapCooler.Name);
     799          72 :         SetupOutputVariable(state,
     800             :                             "Evaporative Cooler Operating Mode Status",
     801             :                             OutputProcessor::Unit::None,
     802             :                             thisEvapCooler.IECOperatingStatus,
     803             :                             OutputProcessor::SOVTimeStepType::System,
     804             :                             OutputProcessor::SOVStoreType::Average,
     805          36 :                             thisEvapCooler.Name);
     806             : 
     807             :     } // end of Indirect Research Special cooler input loop
     808             : 
     809          16 :     cCurrentModuleObject = "EvaporativeCooler:Direct:ResearchSpecial";
     810          37 :     for (int DirectEvapCoolNum = 1; DirectEvapCoolNum <= NumDirectResearchSpecialEvapCool; ++DirectEvapCoolNum) {
     811          21 :         int EvapCoolNum = NumDirectEvapCool + NumDryInDirectEvapCool + NumWetInDirectEvapCool + NumRDDEvapCool + DirectEvapCoolNum;
     812          21 :         auto &thisEvapCooler = EvapCond(EvapCoolNum);
     813         147 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     814             :                                                                  cCurrentModuleObject,
     815             :                                                                  DirectEvapCoolNum,
     816          21 :                                                                  state.dataIPShortCut->cAlphaArgs,
     817             :                                                                  NumAlphas,
     818          21 :                                                                  state.dataIPShortCut->rNumericArgs,
     819             :                                                                  NumNums,
     820             :                                                                  IOStat,
     821          21 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     822          21 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     823          21 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     824          21 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     825          42 :         GlobalNames::VerifyUniqueInterObjectName(state,
     826             :                                                  UniqueEvapCondNames,
     827          21 :                                                  state.dataIPShortCut->cAlphaArgs(1),
     828             :                                                  cCurrentModuleObject,
     829          21 :                                                  state.dataIPShortCut->cAlphaFieldNames(1),
     830             :                                                  ErrorsFound);
     831          21 :         thisEvapCooler.Name = state.dataIPShortCut->cAlphaArgs(1);
     832          21 :         thisEvapCooler.evapCoolerType = EvapCoolerType::DirectResearchSpecial;
     833             : 
     834          21 :         thisEvapCooler.Schedule = state.dataIPShortCut->cAlphaArgs(2);
     835          21 :         if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     836           0 :             thisEvapCooler.SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     837             :         } else {
     838          21 :             thisEvapCooler.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     839          21 :             if (thisEvapCooler.SchedPtr == 0) {
     840           0 :                 ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(2) + '=' + state.dataIPShortCut->cAlphaArgs(2));
     841           0 :                 ShowContinueError(state, "Entered in " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
     842           0 :                 ErrorsFound = true;
     843             :             }
     844             :         }
     845             : 
     846          21 :         thisEvapCooler.InletNode = GetOnlySingleNode(state,
     847          21 :                                                      state.dataIPShortCut->cAlphaArgs(5),
     848             :                                                      ErrorsFound,
     849             :                                                      DataLoopNode::ConnectionObjectType::EvaporativeCoolerDirectResearchSpecial,
     850          21 :                                                      state.dataIPShortCut->cAlphaArgs(1),
     851             :                                                      DataLoopNode::NodeFluidType::Air,
     852             :                                                      DataLoopNode::ConnectionType::Inlet,
     853             :                                                      NodeInputManager::CompFluidStream::Primary,
     854          21 :                                                      DataLoopNode::ObjectIsNotParent);
     855             : 
     856          21 :         thisEvapCooler.OutletNode = GetOnlySingleNode(state,
     857          21 :                                                       state.dataIPShortCut->cAlphaArgs(6),
     858             :                                                       ErrorsFound,
     859             :                                                       DataLoopNode::ConnectionObjectType::EvaporativeCoolerDirectResearchSpecial,
     860          21 :                                                       state.dataIPShortCut->cAlphaArgs(1),
     861             :                                                       DataLoopNode::NodeFluidType::Air,
     862             :                                                       DataLoopNode::ConnectionType::Outlet,
     863             :                                                       NodeInputManager::CompFluidStream::Primary,
     864          21 :                                                       DataLoopNode::ObjectIsNotParent);
     865             : 
     866          42 :         BranchNodeConnections::TestCompSet(state,
     867             :                                            cCurrentModuleObject,
     868          21 :                                            state.dataIPShortCut->cAlphaArgs(1),
     869          21 :                                            state.dataIPShortCut->cAlphaArgs(5),
     870          21 :                                            state.dataIPShortCut->cAlphaArgs(6),
     871             :                                            "Evap Air Nodes");
     872             : 
     873          21 :         thisEvapCooler.EvapControlNodeNum = GetOnlySingleNode(state,
     874          21 :                                                               state.dataIPShortCut->cAlphaArgs(7),
     875             :                                                               ErrorsFound,
     876             :                                                               DataLoopNode::ConnectionObjectType::EvaporativeCoolerDirectResearchSpecial,
     877          21 :                                                               state.dataIPShortCut->cAlphaArgs(1),
     878             :                                                               DataLoopNode::NodeFluidType::Air,
     879             :                                                               DataLoopNode::ConnectionType::Sensor,
     880             :                                                               NodeInputManager::CompFluidStream::Primary,
     881          21 :                                                               DataLoopNode::ObjectIsNotParent);
     882             : 
     883          21 :         thisEvapCooler.EvapWaterSupplyName = state.dataIPShortCut->cAlphaArgs(8);
     884             : 
     885          21 :         if (state.dataIPShortCut->lAlphaFieldBlanks(8)) {
     886          21 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromMains;
     887             :         } else {
     888           0 :             thisEvapCooler.EvapWaterSupplyMode = WaterSupply::FromTank;
     889           0 :             WaterManager::SetupTankDemandComponent(state,
     890             :                                                    thisEvapCooler.Name,
     891             :                                                    cCurrentModuleObject,
     892             :                                                    thisEvapCooler.EvapWaterSupplyName,
     893             :                                                    ErrorsFound,
     894             :                                                    thisEvapCooler.EvapWaterSupTankID,
     895             :                                                    thisEvapCooler.EvapWaterTankDemandARRID);
     896             :         }
     897          21 :         thisEvapCooler.DirectEffectiveness = state.dataIPShortCut->rNumericArgs(1);
     898             : 
     899          21 :         thisEvapCooler.DesVolFlowRate = state.dataIPShortCut->rNumericArgs(2);
     900          21 :         thisEvapCooler.RecircPumpPower = state.dataIPShortCut->rNumericArgs(3);
     901          21 :         thisEvapCooler.RecircPumpSizingFactor = state.dataIPShortCut->rNumericArgs(4);
     902          21 :         if (state.dataIPShortCut->lNumericFieldBlanks(5)) {
     903           0 :             thisEvapCooler.DriftFraction = 0.0;
     904             :         } else {
     905          21 :             thisEvapCooler.DriftFraction = state.dataIPShortCut->rNumericArgs(5);
     906             :         }
     907          21 :         if (state.dataIPShortCut->lNumericFieldBlanks(6)) {
     908           0 :             thisEvapCooler.BlowDownRatio = 0.0;
     909             :         } else {
     910          21 :             thisEvapCooler.BlowDownRatio = state.dataIPShortCut->rNumericArgs(6);
     911             :         }
     912          25 :         if (state.dataIPShortCut->lNumericFieldBlanks(7) || state.dataIPShortCut->lNumericFieldBlanks(8) ||
     913           4 :             state.dataIPShortCut->lNumericFieldBlanks(9)) {
     914          17 :             thisEvapCooler.EvapCoolerOperationControlFlag = false;
     915             :         } else {
     916           8 :             if (!state.dataIPShortCut->lNumericFieldBlanks(7) && !state.dataIPShortCut->lNumericFieldBlanks(8) &&
     917           4 :                 !state.dataIPShortCut->lNumericFieldBlanks(9)) {
     918           4 :                 thisEvapCooler.EvapCoolerOperationControlFlag = true;
     919           4 :                 thisEvapCooler.MinOATDBEvapCooler = state.dataIPShortCut->rNumericArgs(7);
     920           4 :                 thisEvapCooler.MaxOATWBEvapCooler = state.dataIPShortCut->rNumericArgs(8);
     921           4 :                 thisEvapCooler.MaxOATDBEvapCooler = state.dataIPShortCut->rNumericArgs(9);
     922             :             } else {
     923           0 :                 thisEvapCooler.EvapCoolerOperationControlFlag = false;
     924             :             }
     925             :         }
     926          21 :         thisEvapCooler.WetbulbEffecCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(3));
     927          21 :         thisEvapCooler.PumpPowerModifierCurveIndex = Curve::GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(4));
     928             : 
     929          42 :         SetupOutputVariable(state,
     930             :                             "Evaporative Cooler Stage Effectiveness",
     931             :                             OutputProcessor::Unit::None,
     932             :                             thisEvapCooler.StageEff,
     933             :                             OutputProcessor::SOVTimeStepType::System,
     934             :                             OutputProcessor::SOVStoreType::Average,
     935          21 :                             thisEvapCooler.Name);
     936             :     }
     937             : 
     938          16 :     if (ErrorsFound) {
     939           0 :         ShowFatalError(state, "Errors found in processing input for evaporative coolers");
     940             :     }
     941             : 
     942         106 :     for (int EvapCoolNum = 1; EvapCoolNum <= state.dataEvapCoolers->NumEvapCool; ++EvapCoolNum) {
     943          90 :         auto &thisEvapCooler = EvapCond(EvapCoolNum);
     944             :         // Setup Report variables for the Evap Coolers
     945         180 :         SetupOutputVariable(state,
     946             :                             "Evaporative Cooler Electricity Energy",
     947             :                             OutputProcessor::Unit::J,
     948             :                             thisEvapCooler.EvapCoolerEnergy,
     949             :                             OutputProcessor::SOVTimeStepType::System,
     950             :                             OutputProcessor::SOVStoreType::Summed,
     951             :                             thisEvapCooler.Name,
     952             :                             _,
     953             :                             "Electricity",
     954             :                             "Cooling",
     955             :                             _,
     956          90 :                             "System");
     957         180 :         SetupOutputVariable(state,
     958             :                             "Evaporative Cooler Electricity Rate",
     959             :                             OutputProcessor::Unit::W,
     960             :                             thisEvapCooler.EvapCoolerPower,
     961             :                             OutputProcessor::SOVTimeStepType::System,
     962             :                             OutputProcessor::SOVStoreType::Average,
     963          90 :                             thisEvapCooler.Name);
     964             :         // this next report variable is setup differently depending on how the water should be metered here.
     965          90 :         if (thisEvapCooler.EvapWaterSupplyMode == WaterSupply::FromMains) {
     966         180 :             SetupOutputVariable(state,
     967             :                                 "Evaporative Cooler Water Volume",
     968             :                                 OutputProcessor::Unit::m3,
     969             :                                 thisEvapCooler.EvapWaterConsump,
     970             :                                 OutputProcessor::SOVTimeStepType::System,
     971             :                                 OutputProcessor::SOVStoreType::Summed,
     972             :                                 thisEvapCooler.Name,
     973             :                                 _,
     974             :                                 "Water",
     975             :                                 "Cooling",
     976             :                                 _,
     977          90 :                                 "System");
     978         180 :             SetupOutputVariable(state,
     979             :                                 "Evaporative Cooler Mains Water Volume",
     980             :                                 OutputProcessor::Unit::m3,
     981             :                                 thisEvapCooler.EvapWaterConsump,
     982             :                                 OutputProcessor::SOVTimeStepType::System,
     983             :                                 OutputProcessor::SOVStoreType::Summed,
     984             :                                 thisEvapCooler.Name,
     985             :                                 _,
     986             :                                 "MainsWater",
     987             :                                 "Cooling",
     988             :                                 _,
     989          90 :                                 "System");
     990             : 
     991           0 :         } else if (thisEvapCooler.EvapWaterSupplyMode == WaterSupply::FromTank) {
     992           0 :             SetupOutputVariable(state,
     993             :                                 "Evaporative Cooler Storage Tank Water Volume",
     994             :                                 OutputProcessor::Unit::m3,
     995             :                                 thisEvapCooler.EvapWaterConsump,
     996             :                                 OutputProcessor::SOVTimeStepType::System,
     997             :                                 OutputProcessor::SOVStoreType::Summed,
     998             :                                 thisEvapCooler.Name,
     999             :                                 _,
    1000             :                                 "Water",
    1001             :                                 "Cooling",
    1002             :                                 _,
    1003           0 :                                 "System");
    1004           0 :             SetupOutputVariable(state,
    1005             :                                 "Evaporative Cooler Starved Water Volume",
    1006             :                                 OutputProcessor::Unit::m3,
    1007             :                                 thisEvapCooler.EvapWaterStarvMakup,
    1008             :                                 OutputProcessor::SOVTimeStepType::System,
    1009             :                                 OutputProcessor::SOVStoreType::Summed,
    1010             :                                 thisEvapCooler.Name,
    1011             :                                 _,
    1012             :                                 "Water",
    1013             :                                 "Cooling",
    1014             :                                 _,
    1015           0 :                                 "System");
    1016           0 :             SetupOutputVariable(state,
    1017             :                                 "Evaporative Cooler Starved Mains Water Volume",
    1018             :                                 OutputProcessor::Unit::m3,
    1019             :                                 thisEvapCooler.EvapWaterStarvMakup,
    1020             :                                 OutputProcessor::SOVTimeStepType::System,
    1021             :                                 OutputProcessor::SOVStoreType::Summed,
    1022             :                                 thisEvapCooler.Name,
    1023             :                                 _,
    1024             :                                 "MainsWater",
    1025             :                                 "Cooling",
    1026             :                                 _,
    1027           0 :                                 "System");
    1028             :         }
    1029             :     }
    1030          16 : }
    1031             : 
    1032     5196305 : void InitEvapCooler(EnergyPlusData &state, int const EvapCoolNum)
    1033             : {
    1034             : 
    1035             :     // SUBROUTINE INFORMATION:
    1036             :     //       AUTHOR         Richard J. Liesen
    1037             :     //       DATE WRITTEN   October 2000
    1038             :     //       MODIFIED       B. Griffith, May 2009, added EMS setpoint check
    1039             :     //       RE-ENGINEERED  na
    1040             : 
    1041             :     // PURPOSE OF THIS SUBROUTINE:
    1042             :     // This subroutine is for  initializations of the EvapCooler Components.
    1043             : 
    1044             :     // METHODOLOGY EMPLOYED:
    1045             :     // Uses the status flags to trigger events.
    1046             : 
    1047             :     // Using/Aliasing
    1048     5196305 :     auto &DoSetPointTest = state.dataHVACGlobal->DoSetPointTest;
    1049             : 
    1050             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1051     5196305 :     bool localSetPointCheck(false);
    1052             : 
    1053     5196305 :     auto &EvapCond(state.dataEvapCoolers->EvapCond);
    1054             : 
    1055             :     // Check that setpoint is active
    1056     5196305 :     if (!state.dataGlobal->SysSizingCalc && state.dataEvapCoolers->MySetPointCheckFlag && DoSetPointTest) {
    1057         106 :         for (int EvapUnitNum = 1; EvapUnitNum <= state.dataEvapCoolers->NumEvapCool; ++EvapUnitNum) {
    1058             : 
    1059             :             // only check evap coolers that are supposed to have a control node
    1060         146 :             if ((EvapCond(EvapCoolNum).evapCoolerType != EvapCoolerType::IndirectRDDSpecial) &&
    1061          56 :                 (EvapCond(EvapCoolNum).evapCoolerType != EvapCoolerType::DirectResearchSpecial))
    1062          48 :                 continue;
    1063             : 
    1064          42 :             int ControlNode = EvapCond(EvapUnitNum).EvapControlNodeNum;
    1065          42 :             if (ControlNode > 0) {
    1066          42 :                 if (state.dataLoopNodes->Node(ControlNode).TempSetPoint == DataLoopNode::SensedNodeFlagValue) {
    1067           0 :                     if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1068           0 :                         ShowSevereError(state, "Missing temperature setpoint for Evap Cooler unit " + EvapCond(EvapCoolNum).Name);
    1069           0 :                         ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the unit control node.");
    1070             :                     } else {
    1071           0 :                         localSetPointCheck = false;
    1072           0 :                         CheckIfNodeSetPointManagedByEMS(state, ControlNode, EMSManager::SPControlType::TemperatureSetPoint, localSetPointCheck);
    1073           0 :                         state.dataLoopNodes->NodeSetpointCheck(ControlNode).needsSetpointChecking = false;
    1074             :                         // Let it slide apparently
    1075           0 :                         if (localSetPointCheck) {
    1076           0 :                             ShowSevereError(state, "Missing temperature setpoint for Evap Cooler unit " + EvapCond(EvapCoolNum).Name);
    1077           0 :                             ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the unit control node.");
    1078           0 :                             ShowContinueError(state, " or use an EMS actuator to establish a setpoint at the unit control node.");
    1079             :                         }
    1080             :                     }
    1081             :                 }
    1082             :             }
    1083             :         }
    1084          16 :         state.dataEvapCoolers->MySetPointCheckFlag = false;
    1085             :     }
    1086             : 
    1087     5196305 :     auto &thisEvapCond = EvapCond(EvapCoolNum);
    1088     5196305 :     if (!state.dataGlobal->SysSizingCalc && thisEvapCond.MySizeFlag) {
    1089             :         // for each cooler, do the sizing once.
    1090          90 :         SizeEvapCooler(state, EvapCoolNum);
    1091             : 
    1092          90 :         thisEvapCond.MySizeFlag = false;
    1093             :     }
    1094             : 
    1095             :     // Do the following initializations (every time step): This should be the info from
    1096             :     // the previous components outlets or the node data in this section.
    1097             : 
    1098             :     // Transfer the node data to EvapCond data structure
    1099     5196305 :     auto &thisInletNode = state.dataLoopNodes->Node(thisEvapCond.InletNode);
    1100             : 
    1101     5196305 :     Real64 const RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisInletNode.Temp, thisInletNode.HumRat);
    1102             : 
    1103             :     // set the volume flow rates from the input mass flow rates
    1104     5196305 :     thisEvapCond.VolFlowRate = thisInletNode.MassFlowRate / RhoAir;
    1105             : 
    1106             :     // Calculate the entering wet bulb temperature for inlet conditions
    1107     5196305 :     thisEvapCond.InletWetBulbTemp = Psychrometrics::PsyTwbFnTdbWPb(state, thisInletNode.Temp, thisInletNode.HumRat, state.dataEnvrn->OutBaroPress);
    1108             : 
    1109             :     // Set all of the inlet mass flow variables from the nodes
    1110     5196305 :     thisEvapCond.InletMassFlowRate = thisInletNode.MassFlowRate;
    1111     5196305 :     thisEvapCond.InletMassFlowRateMaxAvail = thisInletNode.MassFlowRateMaxAvail;
    1112     5196305 :     thisEvapCond.InletMassFlowRateMinAvail = thisInletNode.MassFlowRateMinAvail;
    1113             :     // Set all of the inlet state variables from the inlet nodes
    1114     5196305 :     thisEvapCond.InletTemp = thisInletNode.Temp;
    1115     5196305 :     thisEvapCond.InletHumRat = thisInletNode.HumRat;
    1116     5196305 :     thisEvapCond.InletEnthalpy = thisInletNode.Enthalpy;
    1117     5196305 :     thisEvapCond.InletPressure = thisInletNode.Press;
    1118             :     // Set default outlet state to inlet states(?)
    1119     5196305 :     thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    1120     5196305 :     thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    1121     5196305 :     thisEvapCond.OutletEnthalpy = thisEvapCond.InletEnthalpy;
    1122     5196305 :     thisEvapCond.OutletPressure = thisEvapCond.InletPressure;
    1123             : 
    1124     5196305 :     thisEvapCond.OutletMassFlowRate = thisEvapCond.InletMassFlowRate;
    1125     5196305 :     thisEvapCond.OutletMassFlowRateMaxAvail = thisEvapCond.InletMassFlowRateMaxAvail;
    1126     5196305 :     thisEvapCond.OutletMassFlowRateMinAvail = thisEvapCond.InletMassFlowRateMinAvail;
    1127             : 
    1128             :     // Set all of the secondary inlet mass flow variables from the nodes
    1129     5196305 :     if (thisEvapCond.SecondaryInletNode != 0) {
    1130     2259992 :         auto &thisSecInletNode = state.dataLoopNodes->Node(thisEvapCond.SecondaryInletNode);
    1131     2259992 :         thisEvapCond.SecInletMassFlowRate = thisSecInletNode.MassFlowRate;
    1132     2259992 :         thisEvapCond.SecInletMassFlowRateMaxAvail = thisSecInletNode.MassFlowRateMaxAvail;
    1133     2259992 :         thisEvapCond.SecInletMassFlowRateMinAvail = thisSecInletNode.MassFlowRateMinAvail;
    1134     2259992 :         thisEvapCond.SecInletTemp = thisSecInletNode.Temp;
    1135     2259992 :         thisEvapCond.SecInletHumRat = thisSecInletNode.HumRat;
    1136     2259992 :         thisEvapCond.SecInletEnthalpy = thisSecInletNode.Enthalpy;
    1137     2259992 :         thisEvapCond.SecInletPressure = thisSecInletNode.Press;
    1138             :     } else {
    1139     2936313 :         thisEvapCond.SecInletMassFlowRate = thisEvapCond.IndirectVolFlowRate * state.dataEnvrn->OutAirDensity;
    1140     2936313 :         thisEvapCond.SecInletMassFlowRateMaxAvail = thisEvapCond.IndirectVolFlowRate * state.dataEnvrn->OutAirDensity;
    1141     2936313 :         thisEvapCond.SecInletMassFlowRateMinAvail = 0.0;
    1142     2936313 :         thisEvapCond.SecInletTemp = state.dataEnvrn->OutDryBulbTemp;
    1143     2936313 :         thisEvapCond.SecInletHumRat =
    1144     5872626 :             Psychrometrics::PsyWFnTdbTwbPb(state, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutWetBulbTemp, state.dataEnvrn->OutBaroPress);
    1145     2936313 :         thisEvapCond.SecInletEnthalpy = state.dataEnvrn->OutEnthalpy;
    1146     2936313 :         thisEvapCond.SecInletPressure = state.dataEnvrn->OutBaroPress;
    1147             :     }
    1148             :     // Set the energy consumption to zero each time through for reporting
    1149     5196305 :     thisEvapCond.EvapCoolerEnergy = 0.0;
    1150     5196305 :     thisEvapCond.EvapCoolerPower = 0.0;
    1151     5196305 :     thisEvapCond.DewPointBoundFlag = 0;
    1152             :     // Set the water consumption to zero each time through for reporting
    1153     5196305 :     thisEvapCond.EvapWaterConsumpRate = 0.0;
    1154     5196305 :     thisEvapCond.EvapWaterConsump = 0.0;
    1155     5196305 :     thisEvapCond.EvapWaterStarvMakup = 0.0;
    1156             : 
    1157             :     // Set the Saturation and Stage Efficiency to zero each time through for reporting
    1158     5196305 :     thisEvapCond.StageEff = 0.0;
    1159     5196305 :     thisEvapCond.SatEff = 0.0;
    1160             : 
    1161             :     // These initializations are done every iteration
    1162     5196305 :     int OutNode = thisEvapCond.OutletNode;
    1163     5196305 :     int ControlNode = thisEvapCond.EvapControlNodeNum;
    1164     5196305 :     thisEvapCond.IECOperatingStatus = 0;
    1165             : 
    1166     5196305 :     if (ControlNode == 0) {
    1167      354828 :         thisEvapCond.DesiredOutletTemp = 0.0;
    1168     4841477 :     } else if (ControlNode == OutNode) {
    1169     2757375 :         thisEvapCond.DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint;
    1170             :     } else {
    1171     4168204 :         thisEvapCond.DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint -
    1172     2084102 :                                          (state.dataLoopNodes->Node(ControlNode).Temp - state.dataLoopNodes->Node(OutNode).Temp);
    1173             :     }
    1174     5196305 : }
    1175             : 
    1176          90 : void SizeEvapCooler(EnergyPlusData &state, int const EvapCoolNum)
    1177             : {
    1178             : 
    1179             :     // SUBROUTINE INFORMATION:
    1180             :     //       AUTHOR         B. Griffith
    1181             :     //       DATE WRITTEN   March 2009
    1182             :     //       MODIFIED       March 2014 Daeho Kang, Add sizing additional fields
    1183             :     //       RE-ENGINEERED  na
    1184             : 
    1185             :     // PURPOSE OF THIS SUBROUTINE:
    1186             :     // Size calculations for Evap coolers
    1187             :     //  currently just for secondary side of Research Special Indirect evap cooler
    1188             : 
    1189             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1190          90 :     bool CoolerOnOApath(false);
    1191          90 :     bool CoolerOnMainAirLoop(false);
    1192          90 :     int AirSysBranchLoop(0);
    1193          90 :     int BranchComp(0);
    1194             :     bool HardSizeNoDesRun;          // Indicator to a hard-sized field with no design sizing data
    1195             :     bool IsAutoSize;                // Indicator to autosize
    1196             :     Real64 IndirectVolFlowRateDes;  // Autosized volume flow rate for reporting
    1197             :     Real64 IndirectVolFlowRateUser; // Hardsized volume flow rate for reporting
    1198             :     bool SizingDesRunThisAirSys;    // true if a particular air system had a Sizing:System object and system sizing done
    1199             :     bool SizingDesRunThisZone;      // true if a particular zone had a Sizing:Zone object and zone sizing was done
    1200             :     Real64 PadAreaDes;              // Autosized celdek pad area for reporting
    1201             :     Real64 PadAreaUser;             // Hardsized celdek pad area for reporting
    1202             :     Real64 PadDepthDes;             // Autosized celdek pad depth for reporting
    1203             :     Real64 PadDepthUser;            // Hardsized celdek pad depth for reporting
    1204             : 
    1205             :     Real64 volFlowRateDes; // Autosized volume flow rate for reporting
    1206         180 :     std::string CompType;  // for ease in getting objects
    1207             : 
    1208             :     // inits
    1209          90 :     CoolerOnOApath = false;
    1210          90 :     CoolerOnMainAirLoop = false;
    1211          90 :     IndirectVolFlowRateDes = 0.0;
    1212          90 :     IndirectVolFlowRateUser = 0.0;
    1213          90 :     PadAreaDes = 0.0;
    1214          90 :     PadAreaUser = 0.0;
    1215          90 :     PadDepthDes = 0.0;
    1216          90 :     PadDepthUser = 0.0;
    1217             : 
    1218          90 :     auto &CurSysNum(state.dataSize->CurSysNum);
    1219          90 :     auto &CurZoneEqNum(state.dataSize->CurZoneEqNum);
    1220          90 :     auto &FinalSysSizing(state.dataSize->FinalSysSizing);
    1221          90 :     auto &EvapCond(state.dataEvapCoolers->EvapCond);
    1222          90 :     auto &thisEvapCond(EvapCond(EvapCoolNum));
    1223             : 
    1224          90 :     HardSizeNoDesRun = !((state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone));
    1225             : 
    1226          90 :     if (CurSysNum > 0) {
    1227          51 :         CheckThisAirSystemForSizing(state, CurSysNum, SizingDesRunThisAirSys);
    1228             :     } else {
    1229          39 :         SizingDesRunThisAirSys = false;
    1230             :     }
    1231          90 :     if (CurZoneEqNum > 0) {
    1232          39 :         CheckThisZoneForSizing(state, CurZoneEqNum, SizingDesRunThisZone);
    1233             :     } else {
    1234          51 :         SizingDesRunThisZone = false;
    1235             :     }
    1236          90 :     if (SizingDesRunThisAirSys) {
    1237          42 :         HardSizeNoDesRun = false; // Check if design infomation is available
    1238             :     }
    1239             : 
    1240          90 :     CompType = evapCoolerTypeNames[static_cast<int>(thisEvapCond.evapCoolerType)];
    1241             : 
    1242             :     // Search once for the object on an air system
    1243          90 :     if (CurSysNum > 0) { // central system
    1244             :         // where is this cooler located, is it on OA system or main loop?
    1245             :         // search for this component in Air loop branches.
    1246         102 :         for (AirSysBranchLoop = 1; AirSysBranchLoop <= state.dataAirSystemsData->PrimaryAirSystems(CurSysNum).NumBranches; ++AirSysBranchLoop) {
    1247         258 :             for (BranchComp = 1; BranchComp <= state.dataAirSystemsData->PrimaryAirSystems(CurSysNum).Branch(AirSysBranchLoop).TotalComponents;
    1248             :                  ++BranchComp) {
    1249             : 
    1250         207 :                 if (UtilityRoutines::SameString(state.dataAirSystemsData->PrimaryAirSystems(CurSysNum).Branch(AirSysBranchLoop).Comp(BranchComp).Name,
    1251             :                                                 thisEvapCond.Name)) {
    1252          37 :                     CoolerOnMainAirLoop = true;
    1253             :                 }
    1254             :             }
    1255             :         }
    1256          51 :         if (!CoolerOnMainAirLoop) CoolerOnOApath = true;
    1257             :     }
    1258             : 
    1259             :     // Start with the indirect volume flow rate
    1260          90 :     IsAutoSize = false;
    1261          90 :     if (thisEvapCond.IndirectVolFlowRate == DataSizing::AutoSize) {
    1262          10 :         IsAutoSize = true;
    1263             :     }
    1264          90 :     if (CurSysNum > 0 && !IsAutoSize && !SizingDesRunThisAirSys) {
    1265           9 :         HardSizeNoDesRun = true;
    1266             :     }
    1267          90 :     if (CurSysNum > 0) { // central system
    1268          51 :         if (!IsAutoSize && !SizingDesRunThisAirSys) {
    1269          18 :             if (thisEvapCond.IndirectVolFlowRate > 0.0) {
    1270           3 :                 if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectCELDEKPAD ||
    1271           1 :                     thisEvapCond.evapCoolerType == EvapCoolerType::IndirectWETCOIL ||
    1272           0 :                     thisEvapCond.evapCoolerType == EvapCoolerType::IndirectRDDSpecial) {
    1273           4 :                     BaseSizer::reportSizerOutput(
    1274           2 :                         state, CompType, thisEvapCond.Name, "User-Specified Secondary Fan Flow Rate [m3/s]", thisEvapCond.IndirectVolFlowRate);
    1275             :                 }
    1276             :             }
    1277             :         } else { // Autosize or hardsize with design data
    1278          42 :             CheckSysSizing(state, CompType, thisEvapCond.Name);
    1279          42 :             if (CoolerOnMainAirLoop) {
    1280          28 :                 IndirectVolFlowRateDes = FinalSysSizing(CurSysNum).DesMainVolFlow;
    1281          14 :             } else if (CoolerOnOApath) {
    1282          14 :                 IndirectVolFlowRateDes = max(FinalSysSizing(CurSysNum).DesOutAirVolFlow, 0.5 * FinalSysSizing(CurSysNum).DesMainVolFlow);
    1283             :             }
    1284             :             // apply scaling factor the secondary air fan flow rate
    1285          42 :             if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectRDDSpecial) {
    1286          30 :                 IndirectVolFlowRateDes = IndirectVolFlowRateDes * thisEvapCond.IndirectVolFlowScalingFactor;
    1287             :             }
    1288             :         }
    1289          39 :     } else if (CurZoneEqNum > 0) { // zone equipment
    1290          39 :         if (!IsAutoSize && !SizingDesRunThisAirSys) {
    1291          78 :             if (thisEvapCond.IndirectVolFlowRate > 0.0) {
    1292             :                 // report for the indirect evap cooler types only
    1293          27 :                 if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectCELDEKPAD ||
    1294          18 :                     thisEvapCond.evapCoolerType == EvapCoolerType::IndirectWETCOIL ||
    1295           6 :                     thisEvapCond.evapCoolerType == EvapCoolerType::IndirectRDDSpecial) {
    1296          30 :                     BaseSizer::reportSizerOutput(
    1297          15 :                         state, CompType, thisEvapCond.Name, "User-Specified Secondary Fan Flow Rate [m3/s]", thisEvapCond.IndirectVolFlowRate);
    1298             :                 }
    1299             :             }
    1300             :         } else { // Autosize or hardsize with design data
    1301             :             // zone equip evap coolers
    1302           0 :             IndirectVolFlowRateDes = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    1303             :             // apply scaling factor the secondary air fan flow rate
    1304           0 :             if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectRDDSpecial) {
    1305           0 :                 IndirectVolFlowRateDes = IndirectVolFlowRateDes * thisEvapCond.IndirectVolFlowScalingFactor;
    1306             :             }
    1307             :         }
    1308             : 
    1309             :     } else {
    1310             :     }
    1311          90 :     if (!HardSizeNoDesRun) {
    1312          81 :         if (IsAutoSize) {
    1313          10 :             thisEvapCond.IndirectVolFlowRate = IndirectVolFlowRateDes;
    1314          20 :             if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectCELDEKPAD || thisEvapCond.evapCoolerType == EvapCoolerType::IndirectWETCOIL ||
    1315          10 :                 thisEvapCond.evapCoolerType == EvapCoolerType::IndirectRDDSpecial) {
    1316          20 :                 BaseSizer::reportSizerOutput(
    1317          10 :                     state, CompType, thisEvapCond.Name, "Design Size Secondary Fan Flow Rate [m3/s]", thisEvapCond.IndirectVolFlowRate);
    1318             :             }
    1319             :         } else {
    1320          71 :             if (thisEvapCond.IndirectVolFlowRate > 0.0 && IndirectVolFlowRateDes > 0.0) {
    1321          20 :                 IndirectVolFlowRateUser = thisEvapCond.IndirectVolFlowRate;
    1322          60 :                 BaseSizer::reportSizerOutput(state,
    1323             :                                              "EvaporativeCooler:Indirect:ResearchSpecial",
    1324             :                                              thisEvapCond.Name,
    1325             :                                              "Design Size Secondary Fan Flow Rate [m3/s]",
    1326             :                                              IndirectVolFlowRateDes,
    1327             :                                              "User-Specified Secondary Fan Flow Rate [m3/s]",
    1328          40 :                                              IndirectVolFlowRateUser);
    1329          20 :                 if (state.dataGlobal->DisplayExtraWarnings) {
    1330           0 :                     if ((std::abs(IndirectVolFlowRateDes - IndirectVolFlowRateUser) / IndirectVolFlowRateUser) >
    1331           0 :                         state.dataSize->AutoVsHardSizingThreshold) {
    1332           0 :                         ShowMessage(state,
    1333           0 :                                     "SizeEvaporativeCooler:Indirect:ResearchSpecial: Potential issue with equipment sizing for " + thisEvapCond.Name);
    1334           0 :                         ShowContinueError(state, format("User-Specified Secondary Fan Flow Rate of {:.5R} [m3/s]", IndirectVolFlowRateUser));
    1335           0 :                         ShowContinueError(state, format("differs from Design Size Secondary Fan Flow Rate of {:.5R} [m3/s]", IndirectVolFlowRateDes));
    1336           0 :                         ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1337           0 :                         ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1338             :                     }
    1339             :                 }
    1340             :             }
    1341             :         }
    1342             :     }
    1343             : 
    1344             :     // Next up the other volume flow rate
    1345          90 :     IsAutoSize = false;
    1346          90 :     if (thisEvapCond.DesVolFlowRate == DataSizing::AutoSize) {
    1347          57 :         IsAutoSize = true;
    1348             :     }
    1349          90 :     if (CurSysNum > 0 && !IsAutoSize && !SizingDesRunThisAirSys) {
    1350           9 :         HardSizeNoDesRun = true;
    1351             :     }
    1352          90 :     if (CurSysNum > 0) { // central system
    1353          51 :         if (!IsAutoSize && !SizingDesRunThisAirSys) {
    1354             :             // the .VolFlowRate variable wasn't reported to the eio in develop, so not doing it here
    1355             :             // if ( EvapCond( EvapCoolNum ).VolFlowRate > 0.0 ) {
    1356             :             // BaseSizer::reportSizerOutput( CompType, EvapCond( EvapCoolNum ).Name,
    1357             :             //"User-Specified Secondary Fan Flow Rate [m3/s]", EvapCond( EvapCoolNum ).VolFlowRate );
    1358             :             //}
    1359             :         } else { // Autosize or hardsize with design data
    1360          42 :             CheckSysSizing(state, CompType, thisEvapCond.Name);
    1361          42 :             if (CoolerOnMainAirLoop) {
    1362          28 :                 volFlowRateDes = FinalSysSizing(CurSysNum).DesMainVolFlow;
    1363          14 :             } else if (CoolerOnOApath) {
    1364          14 :                 volFlowRateDes = max(FinalSysSizing(CurSysNum).DesOutAirVolFlow, 0.5 * FinalSysSizing(CurSysNum).DesMainVolFlow);
    1365             :             }
    1366             :             // no scaling factor on the volFlowRate in develop, so not doing it here
    1367             :         }
    1368          39 :     } else if (CurZoneEqNum > 0) { // zone equipment
    1369             :         // zone equip evap coolers
    1370             : 
    1371          39 :         if (!IsAutoSize && !SizingDesRunThisAirSys) {
    1372             :             // the .VolFlowRate variable wasn't reported to the eio in develop, so not doing it here
    1373             :             // if ( EvapCond( EvapCoolNum ).VolFlowRate > 0.0 ) {
    1374             :             // BaseSizer::reportSizerOutput( "EvaporativeCooler:Indirect:ResearchSpecial", EvapCond( EvapCoolNum ).Name,
    1375             :             //"User-Specified Secondary Fan Flow Rate [m3/s]", EvapCond( EvapCoolNum ).VolFlowRate );
    1376             :             //}
    1377             :         } else { // Autosize or hardsize with design data
    1378          15 :             volFlowRateDes = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    1379             :         }
    1380             : 
    1381             :     } else { // zone equipment
    1382             :              // can't do zone equip evap coolers yet
    1383             :     }
    1384          90 :     if (!HardSizeNoDesRun) {
    1385          81 :         if (IsAutoSize) {
    1386          57 :             thisEvapCond.DesVolFlowRate = volFlowRateDes;
    1387             :             // only these two evap coolers has primary air design flow rate
    1388          57 :             if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectRDDSpecial) {
    1389         108 :                 BaseSizer::reportSizerOutput(state,
    1390             :                                              "EvaporativeCooler:Indirect:ResearchSpecial",
    1391             :                                              thisEvapCond.Name,
    1392             :                                              "Primary Air Design Flow Rate [m3/s]",
    1393          72 :                                              thisEvapCond.DesVolFlowRate);
    1394         108 :                 BaseSizer::reportSizerOutput(state,
    1395             :                                              "EvaporativeCooler:Indirect:ResearchSpecial",
    1396             :                                              thisEvapCond.Name,
    1397             :                                              "Secondary Air Design Flow Rate [m3/s]",
    1398          72 :                                              thisEvapCond.IndirectVolFlowRate);
    1399          21 :             } else if (thisEvapCond.evapCoolerType == EvapCoolerType::DirectResearchSpecial) {
    1400          63 :                 BaseSizer::reportSizerOutput(state,
    1401             :                                              "EvaporativeCooler:Direct:ResearchSpecial",
    1402             :                                              thisEvapCond.Name,
    1403             :                                              "Primary Air Design Flow Rate [m3/s]",
    1404          42 :                                              thisEvapCond.DesVolFlowRate);
    1405             :             }
    1406             :         } else {
    1407             :             // the .VolFlowRate variable wasn't reported to the eio in develop, so not doing it here
    1408             :             // if ( EvapCond( EvapCoolNum ).IndirectVolFlowRate > 0.0 && IndirectVolFlowRateDes > 0.0 ) {
    1409             :             // IndirectVolFlowRateUser = EvapCond( EvapCoolNum ).IndirectVolFlowRate;
    1410             :             // BaseSizer::reportSizerOutput( "EvaporativeCooler:Indirect:ResearchSpecial", EvapCond( EvapCoolNum ).Name,
    1411             :             //"Design Size Secondary Fan Flow Rate [m3/s]", IndirectVolFlowRateDes,
    1412             :             //"User-Specified Secondary Fan Flow Rate [m3/s]", IndirectVolFlowRateUser );
    1413             :             // if ( DisplayExtraWarnings ) {
    1414             :             // if ( ( std::abs( IndirectVolFlowRateDes - IndirectVolFlowRateUser ) / IndirectVolFlowRateUser ) > AutoVsHardSizingThreshold ) {
    1415             :             // ShowMessage(state,  "SizeEvaporativeCooler:Indirect:ResearchSpecial: \nPotential issue with equipment sizing for " + EvapCond(
    1416             :             // EvapCoolNum
    1417             :             // ).Name );  ShowContinueError(state,  "User-Specified Secondary Fan Flow Rate of " +  RoundSigDigits(
    1418             :             // IndirectVolFlowRateUser, 5 ) + " [m3/s]" ); ShowContinueError(state,  format("differs from Design Size Secondary Fan Flow Rate of
    1419             :             // {:.5R}", IndirectVolFlowRateDes) + " [m3/s]" ); ShowContinueError(state,  "This may, or may not, indicate mismatched component
    1420             :             // sizes." ); ShowContinueError(state,  "Verify that the value entered is intended and is consistent with other components." );
    1421             :             //}
    1422             :             //}
    1423             :             //}
    1424             :         }
    1425             :     }
    1426             : 
    1427          90 :     if (thisEvapCond.evapCoolerType == EvapCoolerType::DirectCELDEKPAD) {
    1428          22 :         IsAutoSize = false;
    1429          22 :         if (thisEvapCond.PadArea == DataSizing::AutoSize) {
    1430           1 :             IsAutoSize = true;
    1431             :         }
    1432          22 :         if (CurSysNum > 0 && !IsAutoSize && !SizingDesRunThisAirSys) {
    1433           7 :             HardSizeNoDesRun = true;
    1434             :         }
    1435          22 :         if (SizingDesRunThisAirSys) HardSizeNoDesRun = false; // Check if design infomation is available
    1436             :         // Design air flow rate
    1437          22 :         if (CurSysNum > 0) { // central system
    1438           7 :             if (!IsAutoSize && !SizingDesRunThisAirSys) {
    1439           7 :                 HardSizeNoDesRun = true;
    1440          14 :                 if (thisEvapCond.PadArea > 0.0) {
    1441          21 :                     BaseSizer::reportSizerOutput(
    1442          14 :                         state, "EvaporativeCooler:Direct:CelDekPad", thisEvapCond.Name, "User-Specified Celdek Pad Area [m2]", thisEvapCond.PadArea);
    1443             :                 }
    1444             :             } else { // Autosize or hardsize with design data
    1445           0 :                 CheckSysSizing(state, CompType, thisEvapCond.Name);
    1446           0 :                 if (CoolerOnMainAirLoop) {
    1447           0 :                     IndirectVolFlowRateDes = FinalSysSizing(CurSysNum).DesMainVolFlow;
    1448           0 :                 } else if (CoolerOnOApath) {
    1449           0 :                     IndirectVolFlowRateDes = std::max(FinalSysSizing(CurSysNum).DesOutAirVolFlow, 0.50 * FinalSysSizing(CurSysNum).DesMainVolFlow);
    1450             :                 }
    1451             :                 // Face air velocity of 3m/s is assumed
    1452           0 :                 PadAreaDes = IndirectVolFlowRateDes / 3.0;
    1453             :             }
    1454          15 :         } else if (CurZoneEqNum > 0) { // zone equipment
    1455             :             // zone equip evap coolers
    1456          15 :             if (!IsAutoSize && !SizingDesRunThisAirSys) {
    1457          14 :                 HardSizeNoDesRun = true;
    1458          28 :                 if (thisEvapCond.PadArea > 0.0) {
    1459             :                     // report for the indirect evap cooler types only
    1460          14 :                     if (thisEvapCond.PadArea > 0.0) {
    1461          42 :                         BaseSizer::reportSizerOutput(state,
    1462             :                                                      "EvaporativeCooler:Direct:CelDekPad",
    1463             :                                                      thisEvapCond.Name,
    1464             :                                                      "User-Specified Celdek Pad Area [m2]",
    1465          28 :                                                      thisEvapCond.PadArea);
    1466             :                     }
    1467             :                 }
    1468             :             } else { // Autosize or hardsize with design data
    1469             :                 // zone equip evap coolers
    1470           1 :                 IndirectVolFlowRateDes = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    1471             :                 // Face air velocity of 3m/s is assumed
    1472           1 :                 PadAreaDes = IndirectVolFlowRateDes / 3.0;
    1473             :             }
    1474             :         } else {
    1475             :         }
    1476             : 
    1477          22 :         if (!HardSizeNoDesRun) {
    1478           1 :             if (IsAutoSize) {
    1479           1 :                 thisEvapCond.PadArea = PadAreaDes;
    1480           3 :                 BaseSizer::reportSizerOutput(
    1481           2 :                     state, "EvaporativeCooler:Direct:CelDekPad", thisEvapCond.Name, "Design Size Celdek Pad Area [m2]", PadAreaDes);
    1482             :             } else {
    1483           0 :                 if (thisEvapCond.PadArea > 0.0 && PadAreaDes > 0.0) {
    1484           0 :                     PadAreaUser = thisEvapCond.PadArea;
    1485           0 :                     BaseSizer::reportSizerOutput(state,
    1486             :                                                  "EvaporativeCooler:Direct:CelDekPad",
    1487             :                                                  thisEvapCond.Name,
    1488             :                                                  "Design Size Celdek Pad Area [m2]",
    1489             :                                                  PadAreaDes,
    1490             :                                                  "User-Specified Celdek Pad Area [m2]",
    1491           0 :                                                  PadAreaUser);
    1492           0 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    1493           0 :                         if ((std::abs(PadAreaDes - PadAreaUser) / PadAreaUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1494           0 :                             ShowMessage(state,
    1495           0 :                                         "SizeEvaporativeCooler:Direct:CelDekPad: Potential issue with equipment sizing for " + thisEvapCond.Name);
    1496           0 :                             ShowContinueError(state, format("User-Specified Celdek Pad Area of{:.2R} [m2]", PadAreaUser));
    1497           0 :                             ShowContinueError(state, format("differs from Design Size Celdek Pad Area of {:.2R} [m2]", PadAreaDes));
    1498           0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1499           0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1500             :                         }
    1501             :                     }
    1502             :                 }
    1503             :             }
    1504             :         }
    1505             : 
    1506          22 :         IsAutoSize = false;
    1507          22 :         if (thisEvapCond.PadDepth == DataSizing::AutoSize) {
    1508           1 :             IsAutoSize = true;
    1509             :         }
    1510          22 :         if (CurSysNum > 0 && !IsAutoSize && !SizingDesRunThisAirSys) {
    1511           7 :             HardSizeNoDesRun = true;
    1512             :         }
    1513             :         // The following regression equation is used to determine pad depth,
    1514             :         // assuming saturation effectiveness of 70% and face air velocity of 3m/s:
    1515             :         // Effectiveness = 0.792714 + 0.958569D - 0.25193V - 1.03215D^2 + 0.0262659V^2 + 0.914869DV -
    1516             :         // 1.48241VD^2 - 0.018992V^3D + 1.13137D^3V + 0.0327622V^3D^2 - 0.145384D^3V^2
    1517          22 :         PadDepthDes = 0.17382;
    1518          22 :         if (IsAutoSize) {
    1519           1 :             thisEvapCond.PadDepth = PadDepthDes;
    1520           3 :             BaseSizer::reportSizerOutput(
    1521           2 :                 state, "EvaporativeCooler:Direct:CelDekPad", thisEvapCond.Name, "Design Size Celdek Pad Depth [m]", PadDepthDes);
    1522             :         } else {
    1523          21 :             if (thisEvapCond.PadDepth > 0.0 && PadDepthDes > 0.0) {
    1524          21 :                 PadDepthUser = thisEvapCond.PadDepth;
    1525          63 :                 BaseSizer::reportSizerOutput(state,
    1526             :                                              "EvaporativeCooler:Direct:CelDekPad",
    1527             :                                              thisEvapCond.Name,
    1528             :                                              "Design Size Celdek Pad Depth [m]",
    1529             :                                              PadDepthDes,
    1530             :                                              "User-Specified Celdek Pad Depth [m]",
    1531          42 :                                              PadDepthUser);
    1532          21 :                 if (state.dataGlobal->DisplayExtraWarnings) {
    1533           0 :                     if ((std::abs(PadDepthDes - PadDepthUser) / PadDepthUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1534           0 :                         ShowMessage(state, "SizeEvaporativeCooler:Direct:CelDekPad: Potential issue with equipment sizing for " + thisEvapCond.Name);
    1535           0 :                         ShowContinueError(state, format("User-Specified Celdek Pad Depth of {:.2R} [m]", PadDepthUser));
    1536           0 :                         ShowContinueError(state, format("differs from Design Size Celdek Pad Depth of {:.2R} [m]", PadDepthDes));
    1537           0 :                         ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1538           0 :                         ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1539             :                     }
    1540             :                 }
    1541             :             }
    1542             :         }
    1543             :     }
    1544             : 
    1545          90 :     if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectCELDEKPAD) {
    1546           4 :         IsAutoSize = false;
    1547             : 
    1548           4 :         if (thisEvapCond.IndirectPadArea == DataSizing::AutoSize) {
    1549           1 :             IsAutoSize = true;
    1550             :         }
    1551           4 :         if (SizingDesRunThisAirSys) {
    1552           0 :             HardSizeNoDesRun = false; // Check if design infomation is available
    1553             :         }
    1554             :         // Design air flow rate
    1555           4 :         if (CurSysNum > 0) { // central system
    1556             :             // where is this cooler located, is it on OA system or main loop?
    1557             :             // search for this component in Air loop branches.
    1558           2 :             for (AirSysBranchLoop = 1; AirSysBranchLoop <= state.dataAirSystemsData->PrimaryAirSystems(CurSysNum).NumBranches; ++AirSysBranchLoop) {
    1559           5 :                 for (BranchComp = 1; BranchComp <= state.dataAirSystemsData->PrimaryAirSystems(CurSysNum).Branch(AirSysBranchLoop).TotalComponents;
    1560             :                      ++BranchComp) {
    1561           8 :                     if (UtilityRoutines::SameString(
    1562           4 :                             state.dataAirSystemsData->PrimaryAirSystems(CurSysNum).Branch(AirSysBranchLoop).Comp(BranchComp).Name,
    1563             :                             thisEvapCond.Name)) {
    1564           1 :                         CoolerOnMainAirLoop = true;
    1565             :                     }
    1566             :                 }
    1567             :             }
    1568           1 :             if (!IsAutoSize && !SizingDesRunThisAirSys) {
    1569           1 :                 HardSizeNoDesRun = true;
    1570           2 :                 if (thisEvapCond.IndirectPadArea > 0.0) {
    1571           3 :                     BaseSizer::reportSizerOutput(state,
    1572             :                                                  "EvaporativeCooler:Indirect:CelDekPad",
    1573             :                                                  thisEvapCond.Name,
    1574             :                                                  "User-Specified Celdek Pad Area [m2]",
    1575           2 :                                                  thisEvapCond.IndirectPadArea);
    1576             :                 }
    1577             :             } else { // Autosize or hardsize with design data
    1578           0 :                 CheckSysSizing(state, CompType, thisEvapCond.Name);
    1579           0 :                 if (!CoolerOnMainAirLoop) {
    1580           0 :                     CoolerOnOApath = true;
    1581             :                 }
    1582           0 :                 if (CoolerOnMainAirLoop) {
    1583           0 :                     IndirectVolFlowRateDes = FinalSysSizing(CurSysNum).DesMainVolFlow;
    1584           0 :                 } else if (CoolerOnOApath) {
    1585           0 :                     IndirectVolFlowRateDes = std::max(FinalSysSizing(CurSysNum).DesOutAirVolFlow, 0.5 * FinalSysSizing(CurSysNum).DesMainVolFlow);
    1586             :                 }
    1587             :                 // Face air velocity of 3m/s is assumed
    1588           0 :                 PadAreaDes = IndirectVolFlowRateDes / 3.0;
    1589             :             }
    1590           3 :         } else if (CurZoneEqNum > 0) { // zone equipment
    1591             :             // zone equip evap coolers
    1592           3 :             if (!IsAutoSize && !SizingDesRunThisAirSys) {
    1593           2 :                 HardSizeNoDesRun = true;
    1594           4 :                 if (thisEvapCond.IndirectPadArea > 0.0) {
    1595             :                     // report for the indirect evap cooler types only
    1596           2 :                     if (thisEvapCond.PadArea > 0.0) {
    1597           0 :                         BaseSizer::reportSizerOutput(state,
    1598             :                                                      "EvaporativeCooler:Indirect:CelDekPad",
    1599             :                                                      thisEvapCond.Name,
    1600             :                                                      "User-Specified Celdek Pad Area [m2]",
    1601           0 :                                                      thisEvapCond.IndirectPadArea);
    1602             :                     }
    1603             :                 }
    1604             :             } else { // Autosize or hardsize with design data
    1605             :                 // zone equip evap coolers
    1606           1 :                 IndirectVolFlowRateDes = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    1607             :                 // Face air velocity of 3m/s is assumed
    1608           1 :                 PadAreaDes = IndirectVolFlowRateDes / 3.0;
    1609             :             }
    1610             :         } else {
    1611             :         }
    1612             : 
    1613           4 :         if (!HardSizeNoDesRun) {
    1614           1 :             if (IsAutoSize) {
    1615           1 :                 thisEvapCond.IndirectPadArea = PadAreaDes;
    1616           3 :                 BaseSizer::reportSizerOutput(
    1617           2 :                     state, "EvaporativeCooler:Indirect:CelDekPad", thisEvapCond.Name, "Design Size Celdek Pad Area [m2]", PadAreaDes);
    1618             :             } else {
    1619           0 :                 if (thisEvapCond.IndirectPadArea > 0.0 && PadAreaDes > 0.0) {
    1620           0 :                     PadAreaUser = thisEvapCond.IndirectPadArea;
    1621           0 :                     BaseSizer::reportSizerOutput(state,
    1622             :                                                  "EvaporativeCooler:Indirect:CelDekPad",
    1623             :                                                  thisEvapCond.Name,
    1624             :                                                  "Design Size Celdek Pad Area [m2]",
    1625             :                                                  PadAreaDes,
    1626             :                                                  "User-Specified Celdek Pad Area [m2]",
    1627           0 :                                                  PadAreaUser);
    1628           0 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    1629           0 :                         if ((std::abs(PadAreaDes - PadAreaUser) / PadAreaUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1630           0 :                             ShowMessage(state,
    1631           0 :                                         "SizeEvaporativeCooler:Indirect:CelDekPad: Potential issue with equipment sizing for " + thisEvapCond.Name);
    1632           0 :                             ShowContinueError(state, format("User-Specified Celdek Pad Area {:.2R} [m2]", PadAreaUser));
    1633           0 :                             ShowContinueError(state, format("differs from Design Size Celdek Pad Area of {:.2R} [m2]", PadAreaDes));
    1634           0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1635           0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1636             :                         }
    1637             :                     }
    1638             :                 }
    1639             :             }
    1640             :         }
    1641             : 
    1642           4 :         IsAutoSize = thisEvapCond.IndirectPadDepth == DataSizing::AutoSize;
    1643             :         // The following regression equation is used to determine pad depth,
    1644             :         // assuming saturation effectiveness of 70% and face air velocity of 3m/s:
    1645             :         // Effectiveness = 0.792714 + 0.958569D - 0.25193V - 1.03215D^2 + 0.0262659V^2 + 0.914869DV -
    1646             :         // 1.48241VD^2 - 0.018992V^3D + 1.13137D^3V + 0.0327622V^3D^2 - 0.145384D^3V^2
    1647             : 
    1648           4 :         PadDepthDes = 0.17382;
    1649           4 :         if (IsAutoSize) {
    1650           1 :             thisEvapCond.IndirectPadDepth = PadDepthDes;
    1651           3 :             BaseSizer::reportSizerOutput(
    1652           2 :                 state, "EvaporativeCooler:Indirect:CelDekPad", thisEvapCond.Name, "Design Size Celdek Pad Depth [m]", PadDepthDes);
    1653             :         } else {
    1654           3 :             if (thisEvapCond.IndirectPadDepth > 0.0 && PadDepthDes > 0.0) {
    1655           3 :                 PadDepthUser = thisEvapCond.IndirectPadDepth;
    1656           9 :                 BaseSizer::reportSizerOutput(state,
    1657             :                                              "EvaporativeCooler:Indirect:CelDekPad",
    1658             :                                              thisEvapCond.Name,
    1659             :                                              "Design Size Celdek Pad Depth [m]",
    1660             :                                              PadDepthDes,
    1661             :                                              "User-Specified Celdek Pad Depth [m]",
    1662           6 :                                              PadDepthUser);
    1663           3 :                 if (state.dataGlobal->DisplayExtraWarnings) {
    1664           0 :                     if ((std::abs(PadDepthDes - PadDepthUser) / PadDepthUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1665           0 :                         ShowMessage(state,
    1666           0 :                                     "SizeEvaporativeCooler:Indirect:CelDekPad: Potential issue with equipment sizing for " + thisEvapCond.Name);
    1667           0 :                         ShowContinueError(state, format("User-Specified Celdek Pad Depth of {:.2R} [m]", PadDepthUser));
    1668           0 :                         ShowContinueError(state, format("differs from Design Size Celdek Pad Depth of {:.2R} [m]", PadDepthDes));
    1669           0 :                         ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1670           0 :                         ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1671             :                     }
    1672             :                 }
    1673             :             }
    1674             :         }
    1675             :     }
    1676             : 
    1677          90 :     if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectRDDSpecial) {
    1678             :         // secondary air fan sizing: Secondary flow Rate (m3/s) * Fan Flow Sizing Factor (W/(m3/s)
    1679          36 :         if (thisEvapCond.IndirectFanPower == DataSizing::AutoSize) {
    1680          36 :             thisEvapCond.IndirectFanPower = thisEvapCond.IndirectVolFlowRate * thisEvapCond.FanSizingSpecificPower;
    1681         108 :             BaseSizer::reportSizerOutput(
    1682          72 :                 state, "EvaporativeCooler:Indirect:ResearchSpecial", thisEvapCond.Name, "Secondary Fan Power [W]", thisEvapCond.IndirectFanPower);
    1683             :         }
    1684             :         // recirculating water pump sizing: Secondary flow Rate (m3/s) * Pump Sizing Factor (W/(m3/s)
    1685          36 :         if (thisEvapCond.IndirectRecircPumpPower == DataSizing::AutoSize) {
    1686           4 :             thisEvapCond.IndirectRecircPumpPower = thisEvapCond.IndirectVolFlowRate * thisEvapCond.RecircPumpSizingFactor;
    1687          12 :             BaseSizer::reportSizerOutput(state,
    1688             :                                          "EvaporativeCooler:Indirect:ResearchSpecial",
    1689             :                                          thisEvapCond.Name,
    1690             :                                          "Recirculating Pump Power [W]",
    1691           8 :                                          thisEvapCond.IndirectRecircPumpPower);
    1692             :         }
    1693             :     }
    1694             : 
    1695          90 :     if (thisEvapCond.evapCoolerType == EvapCoolerType::DirectResearchSpecial) {
    1696             :         // recirculating water pump sizing: Primary Air Design flow Rate (m3/s) * Pump Sizing Factor (W/(m3/s)
    1697          21 :         if (thisEvapCond.RecircPumpPower == DataSizing::AutoSize) {
    1698           0 :             thisEvapCond.RecircPumpPower = thisEvapCond.DesVolFlowRate * thisEvapCond.RecircPumpSizingFactor;
    1699           0 :             BaseSizer::reportSizerOutput(
    1700           0 :                 state, "EvaporativeCooler:Direct:ResearchSpecial", thisEvapCond.Name, "Recirculating Pump Power [W]", thisEvapCond.RecircPumpPower);
    1701             :         }
    1702             :     }
    1703          90 : }
    1704             : 
    1705      251504 : void CalcDirectEvapCooler(EnergyPlusData &state, int EvapCoolNum, Real64 const PartLoadRatio)
    1706             : {
    1707             : 
    1708             :     // SUBROUTINE INFORMATION:
    1709             :     //       AUTHOR         Richard J. Liesen
    1710             :     //       DATE WRITTEN   October 2000
    1711             :     //       MODIFIED       na
    1712             :     //       RE-ENGINEERED  na
    1713             : 
    1714             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1715             :     Real64 PadDepth; // EvapCooler Pad Depth in Meters as input by the User
    1716             :     Real64 SatEff;   // Saturation Efficiency of the CelDek Pad
    1717             :     Real64 AirVel;   // The Calculated Air Velocity through the Pad
    1718             :     Real64 TEDB;     // Entering Dry Bulb Temperature
    1719             :     Real64 TEWB;     // Entering Wet Bulb Temperature
    1720             :     Real64 RhoWater;
    1721             : 
    1722      251504 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    1723             : 
    1724             :     // If the Evaporative Cooler  is operating there should be some mass flow rate
    1725             :     //  Also the evap cooler has to be scheduled to be available
    1726      251504 :     if ((thisEvapCond.InletMassFlowRate > 0.0) && (ScheduleManager::GetCurrentScheduleValue(state, thisEvapCond.SchedPtr) > 0.0)) {
    1727             : 
    1728      103098 :         PadDepth = thisEvapCond.PadDepth;
    1729             :         //******************************************************************************
    1730             :         //   THIS SUBROUTINE WILL CACULATE THE TEMPERATURE OF THE LEAVING AIR DRY BULB
    1731             :         //   FOR A DIRECT EVAPORATIVE AIR COOLER SUPPLIED WITH CFMAir,DIRPAD,TEWB,TEDB,
    1732             :         //   AND PB (ATM. PRESS.) FOR AIR DENSITY CALCULATIONS.
    1733             :         //******************************************************************************
    1734             : 
    1735      103098 :         AirVel = thisEvapCond.VolFlowRate / thisEvapCond.PadArea;
    1736             : 
    1737             :         //******************************************************************************
    1738             :         //   SAT EFF IS FOR DIFFERENT THICKNESS CELDEK PAD (CURVE FIT FROM DATA)
    1739             :         //******************************************************************************
    1740      309294 :         SatEff = 0.792714 + 0.958569 * PadDepth - 0.25193 * AirVel - 1.03215 * pow_2(PadDepth) + 2.62659e-2 * pow_2(AirVel) +
    1741      309294 :                  0.914869 * PadDepth * AirVel - 1.48241 * AirVel * pow_2(PadDepth) - 1.89919e-2 * pow_3(AirVel) * PadDepth +
    1742      206196 :                  1.13137 * pow_3(PadDepth) * AirVel + 3.27622e-2 * pow_3(AirVel) * pow_2(PadDepth) - 0.145384 * pow_3(PadDepth) * pow_2(AirVel);
    1743             : 
    1744      103098 :         if (SatEff >= 1.0) SatEff = 1.0;
    1745      103098 :         if (SatEff < 0.0) { // we have a serious problem.  Pad Area and/or depth not suitable for system air flow rates
    1746           0 :             ShowSevereError(state, "EVAPCOOLER:DIRECT:CELDEKPAD: " + thisEvapCond.Name + " has a problem");
    1747           0 :             ShowContinueError(state, "Check size of Pad Area and/or Pad Depth in input");
    1748           0 :             ShowContinueError(state, format("Cooler Effectiveness calculated as: {:.2R}", SatEff));
    1749           0 :             ShowContinueError(state, format("Air velocity (m/s) through pads calculated as: {:.2R}", AirVel));
    1750           0 :             ShowFatalError(state, "Program Terminates due to previous error condition");
    1751             :         }
    1752      103098 :         thisEvapCond.SatEff = SatEff;
    1753             :         //***************************************************************************
    1754             :         //   TEMP LEAVING DRY BULB IS CALCULATED FROM SATURATION EFFICIENCY AS THE
    1755             :         //   DRY BULB TEMP APPROACHES THE WET BULB TEMP. WET BULB TEMP IS CONSTANT
    1756             :         //   ACROSS A DIRECT EVAPORATION COOLER.
    1757      103098 :         TEWB = thisEvapCond.InletWetBulbTemp;
    1758      103098 :         TEDB = thisEvapCond.InletTemp;
    1759             : 
    1760      103098 :         thisEvapCond.OutletTemp = TEDB - ((TEDB - TEWB) * SatEff);
    1761             : 
    1762      103098 :         thisEvapCond.OuletWetBulbTemp = thisEvapCond.InletWetBulbTemp;
    1763             : 
    1764      103098 :         thisEvapCond.OutletHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, thisEvapCond.OutletTemp, TEWB, state.dataEnvrn->OutBaroPress);
    1765             : 
    1766      103098 :         thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    1767             : 
    1768             :         //***************************************************************************
    1769             :         //                  ENERGY CONSUMED BY THE RECIRCULATING PUMP
    1770             :         // Add the pump energy to the total Evap Cooler energy comsumption
    1771      103098 :         thisEvapCond.EvapCoolerPower += PartLoadRatio * thisEvapCond.RecircPumpPower;
    1772             :         //******************
    1773             :         //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
    1774             :         //             H2O [m3/s] = Delta W[kgWater/kDryAir]*Mass Flow Air[kgDryAir/s]
    1775             :         //                                /RhoWater [kgWater/m3]
    1776             :         //******************
    1777      103098 :         RhoWater = Psychrometrics::RhoH2O(thisEvapCond.OutletTemp);
    1778      103098 :         thisEvapCond.EvapWaterConsumpRate = (thisEvapCond.OutletHumRat - thisEvapCond.InletHumRat) * thisEvapCond.InletMassFlowRate / RhoWater;
    1779             :         // A numerical check to keep from having very tiny negative water consumption values being reported
    1780      103098 :         if (thisEvapCond.EvapWaterConsumpRate < 0.0) thisEvapCond.EvapWaterConsumpRate = 0.0;
    1781             : 
    1782             :     } else {
    1783             :         // The evap cooler is not running and does not change conditions from inlet to outlet
    1784      148406 :         thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    1785             : 
    1786      148406 :         thisEvapCond.OuletWetBulbTemp = thisEvapCond.InletWetBulbTemp;
    1787             : 
    1788      148406 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    1789             : 
    1790      148406 :         thisEvapCond.OutletEnthalpy = thisEvapCond.InletEnthalpy;
    1791             : 
    1792      148406 :         thisEvapCond.EvapCoolerEnergy = 0.0;
    1793             : 
    1794      148406 :         thisEvapCond.EvapWaterConsumpRate = 0.0;
    1795             :     }
    1796             :     // all of the mass flowrates are not changed across the evap cooler
    1797      251504 :     thisEvapCond.OutletMassFlowRate = thisEvapCond.InletMassFlowRate;
    1798      251504 :     thisEvapCond.OutletMassFlowRateMaxAvail = thisEvapCond.InletMassFlowRateMaxAvail;
    1799      251504 :     thisEvapCond.OutletMassFlowRateMinAvail = thisEvapCond.InletMassFlowRateMinAvail;
    1800             : 
    1801             :     // the pressure is not changed across the evap cooler
    1802      251504 :     thisEvapCond.OutletPressure = thisEvapCond.InletPressure;
    1803      251504 : }
    1804             : 
    1805       34981 : void CalcDryIndirectEvapCooler(EnergyPlusData &state, int EvapCoolNum, Real64 const PartLoadRatio)
    1806             : {
    1807             : 
    1808             :     // SUBROUTINE INFORMATION:
    1809             :     //       AUTHOR         Richard J. Liesen
    1810             :     //       DATE WRITTEN   October 2000
    1811             :     //       MODIFIED       BG Feb. 2007 secondary air inlet node
    1812             :     //       RE-ENGINEERED  na
    1813             : 
    1814             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1815             :     Real64 PadDepth;  // EvapCooler Pad Depth in Meters as input by the User
    1816             :     Real64 SatEff;    // Saturation Efficiency of the CelDek Pad
    1817             :     Real64 AirVel;    // The Calculated Air Velocity through the Pad
    1818             :     Real64 TDBSec;    // Secondary leaving dry bulb
    1819             :     Real64 TWBSec;    // Secondary Leaving Wet Bulb
    1820             :     Real64 HumRatSec; // Secondary leaving Humidity Ratio
    1821             :     Real64 EffHX;     // Effectiveness of Secondary Heat Exchanger
    1822             :     Real64 QHX;       // Q Across Sec HX
    1823             :     Real64 RhoWater;
    1824             :     Real64 RhoAir; // Density of the primary side air
    1825             :     Real64 CpAir;  // Cp of the primary side air
    1826             :     Real64 CFMAir;
    1827             :     Real64 CFMSec;
    1828             : 
    1829       34981 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    1830             : 
    1831             :     // If the Evaporative Cooler  is operating there should be some mass flow rate
    1832             :     //  Also the evap cooler has to be scheduled to be available
    1833       34981 :     if ((thisEvapCond.InletMassFlowRate > 0.0) && (ScheduleManager::GetCurrentScheduleValue(state, thisEvapCond.SchedPtr) > 0.0)) {
    1834             : 
    1835       18472 :         PadDepth = thisEvapCond.IndirectPadDepth;
    1836             :         //******************************************************************************
    1837             :         //   THIS SUBROUTINE WILL CACULATE THE TEMPERATURE OF THE LEAVING AIR DRY BULB
    1838             :         //   FOR A DIRECT EVAPORATIVE AIR COOLER SUPPLIED WITH CFMAir,DIRPAD,TEWB,TEDB,
    1839             :         //   AND PB (ATM. PRESS.) FOR AIR DENSITY CALCULATIONS.
    1840             :         //******************************************************************************
    1841             : 
    1842       18472 :         AirVel = thisEvapCond.IndirectVolFlowRate / thisEvapCond.IndirectPadArea;
    1843             : 
    1844             :         //******************************************************************************
    1845             :         //   SAT EFF IS FOR DIFFERENT THICKNESS CELDEK PAD (CURVE FIT FROM DATA)
    1846             :         //******************************************************************************
    1847       55416 :         SatEff = 0.792714 + 0.958569 * PadDepth - 0.25193 * AirVel - 1.03215 * pow_2(PadDepth) + 2.62659e-2 * pow_2(AirVel) +
    1848       55416 :                  0.914869 * PadDepth * AirVel - 1.48241 * AirVel * pow_2(PadDepth) - 1.89919e-2 * pow_3(AirVel) * PadDepth +
    1849       36944 :                  1.13137 * pow_3(PadDepth) * AirVel + 3.27622e-2 * pow_3(AirVel) * pow_2(PadDepth) - 0.145384 * pow_3(PadDepth) * pow_2(AirVel);
    1850             : 
    1851       18472 :         if (SatEff >= 1.0) SatEff = 1.0;
    1852       18472 :         thisEvapCond.SatEff = SatEff;
    1853             :         //***************************************************************************
    1854             :         //   TEMP LEAVING DRY BULB IS CALCULATED FROM SATURATION EFFICIENCY AS THE
    1855             :         //   DRY BULB TEMP APPROACHES THE WET BULB TEMP ACROSS THE PAD BEFORE THE HX.
    1856             :         //***************************************************************************
    1857             :         //***** FIRST CHECK IF THIS TEWB IS A FEASIBLE POINT ON PSYCH CHART**********
    1858             : 
    1859             :         // BG Feb 2007 mods for oa node (eg. height-dependent outside air model)
    1860       18472 :         TWBSec = Psychrometrics::PsyTwbFnTdbWPb(state,
    1861             :                                                 thisEvapCond.SecInletTemp,
    1862             :                                                 thisEvapCond.SecInletHumRat,
    1863       18472 :                                                 thisEvapCond.SecInletPressure); //  OutWetBulbTemp
    1864       18472 :         TDBSec = thisEvapCond.SecInletTemp - ((thisEvapCond.SecInletTemp - TWBSec) * SatEff);
    1865             : 
    1866       18472 :         HumRatSec = Psychrometrics::PsyWFnTdbTwbPb(state, TDBSec, TWBSec, thisEvapCond.SecInletPressure);
    1867             : 
    1868             :         //***************************************************************************
    1869             :         //                  CALCULATE THE TLDB FROM HX EQUATIONS GIVEN AN EFFICIENCY
    1870             :         //***************************************************************************
    1871       18472 :         EffHX = thisEvapCond.IndirectHXEffectiveness;
    1872       18472 :         CpAir = Psychrometrics::PsyCpAirFnW(thisEvapCond.InletHumRat);
    1873       18472 :         RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisEvapCond.InletTemp, thisEvapCond.InletHumRat);
    1874       18472 :         CFMAir = thisEvapCond.VolFlowRate;         // Volume Flow Rate Primary Side
    1875       18472 :         CFMSec = thisEvapCond.IndirectVolFlowRate; // Volume Flolw Rate Secondary Side
    1876             : 
    1877       18472 :         QHX = EffHX * min(CFMSec, CFMAir) * RhoAir * CpAir * (thisEvapCond.InletTemp - TDBSec);
    1878       18472 :         thisEvapCond.OutletTemp = thisEvapCond.InletTemp - QHX / (RhoAir * CFMAir * CpAir);
    1879             :         // This is a rough approximation of the Total Indirect Stage Efficiency for the Dry stage which
    1880             :         //   is a 2 step process the first being teh pad efficiency and then the HX Effectiveness.  I think that
    1881             :         //   this would mainly be used for evap sizing purposes.
    1882       18472 :         thisEvapCond.StageEff = SatEff * EffHX;
    1883             :         //***************************************************************************
    1884             :         //                  CALCULATE THE WET BULB TEMP in the primary system air USING PSYCH ROUTINES
    1885             :         // There is a constant humidity ratio across the primary side but a reduction in the dry bulb temp
    1886       18472 :         thisEvapCond.OuletWetBulbTemp =
    1887       36944 :             Psychrometrics::PsyTwbFnTdbWPb(state, thisEvapCond.OutletTemp, thisEvapCond.InletHumRat, state.dataEnvrn->OutBaroPress);
    1888             :         //***************************************************************************
    1889             :         //   TEMP LEAVING DRY BULB IS CALCULATED FROM SATURATION EFFICIENCY AS THE
    1890             :         //   DRY BULB TEMP APPROACHES THE WET BULB TEMP. WET BULB TEMP IS CONSTANT
    1891             :         //   ACROSS A DIRECT EVAPORATION COOLER.
    1892             : 
    1893       18472 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    1894             : 
    1895       18472 :         thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    1896             : 
    1897             :         //***************************************************************************
    1898             :         //                  POWER OF THE SECONDARY AIR FAN
    1899       18472 :         if (thisEvapCond.IndirectFanEff > 0.0) {
    1900       36944 :             thisEvapCond.EvapCoolerPower +=
    1901       18472 :                 PartLoadRatio * thisEvapCond.IndirectFanDeltaPress * thisEvapCond.IndirectVolFlowRate / thisEvapCond.IndirectFanEff;
    1902             :         }
    1903             : 
    1904             :         //                  ENERGY CONSUMED BY THE RECIRCULATING PUMP
    1905             :         //                  ENERGY CONSUMED BY THE RECIRCULATING PUMP
    1906             :         // Add the pump energy to the total Evap Cooler energy comsumption
    1907       18472 :         thisEvapCond.EvapCoolerPower += PartLoadRatio * thisEvapCond.IndirectRecircPumpPower;
    1908             : 
    1909             :         //******************
    1910             :         //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
    1911             :         //             H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir/s]
    1912             :         //                                /RhoWater [kgWater/m3]
    1913             :         //******************
    1914       18472 :         RhoWater = Psychrometrics::RhoH2O(TDBSec);
    1915       55416 :         RhoAir = (Psychrometrics::PsyRhoAirFnPbTdbW(state, thisEvapCond.SecInletPressure, thisEvapCond.SecInletTemp, thisEvapCond.SecInletHumRat) +
    1916       36944 :                   Psychrometrics::PsyRhoAirFnPbTdbW(state, thisEvapCond.SecInletPressure, TDBSec, HumRatSec)) /
    1917             :                  2.0;
    1918       18472 :         thisEvapCond.EvapWaterConsumpRate =
    1919       18472 :             PartLoadRatio * (HumRatSec - thisEvapCond.SecInletHumRat) * thisEvapCond.IndirectVolFlowRate * RhoAir / RhoWater;
    1920             :         // A numerical check to keep from having very tiny negative water consumption values being reported
    1921       18472 :         if (thisEvapCond.EvapWaterConsumpRate < 0.0) thisEvapCond.EvapWaterConsumpRate = 0.0;
    1922             : 
    1923             :     } else {
    1924             :         // The evap cooler is not running and does not change conditions from inlet to outlet
    1925       16509 :         thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    1926             : 
    1927       16509 :         thisEvapCond.OuletWetBulbTemp = thisEvapCond.InletWetBulbTemp;
    1928             : 
    1929       16509 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    1930             : 
    1931       16509 :         thisEvapCond.OutletEnthalpy = thisEvapCond.InletEnthalpy;
    1932             : 
    1933       16509 :         thisEvapCond.EvapCoolerEnergy = 0.0;
    1934             : 
    1935       16509 :         thisEvapCond.EvapWaterConsumpRate = 0.0;
    1936             :     }
    1937             :     // all of the mass flowrates are not changed across the evap cooler
    1938       34981 :     thisEvapCond.OutletMassFlowRate = thisEvapCond.InletMassFlowRate;
    1939       34981 :     thisEvapCond.OutletMassFlowRateMaxAvail = thisEvapCond.InletMassFlowRateMaxAvail;
    1940       34981 :     thisEvapCond.OutletMassFlowRateMinAvail = thisEvapCond.InletMassFlowRateMinAvail;
    1941             : 
    1942             :     // the pressure is not changed across the evap cooler
    1943       34981 :     thisEvapCond.OutletPressure = thisEvapCond.InletPressure;
    1944       34981 : }
    1945             : 
    1946       68343 : void CalcWetIndirectEvapCooler(EnergyPlusData &state, int EvapCoolNum, Real64 const PartLoadRatio)
    1947             : {
    1948             : 
    1949             :     // SUBROUTINE INFORMATION:
    1950             :     //       AUTHOR         Richard J. Liesen
    1951             :     //       DATE WRITTEN   October 2000
    1952             :     //       MODIFIED       na
    1953             :     //       RE-ENGINEERED  Jan. 2017, Rongpeng Zhang, added fouling fault for evaporative coolers
    1954             : 
    1955             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1956             :     Real64 StageEff; // Stage Efficiency of the Heat Exchanger
    1957             :     Real64 TEDB;     // Entering Dry Bulb Temperature
    1958             :     Real64 TEWB;     // Entering Wet Bulb Temperature
    1959             :     Real64 QHX;      // Q Across Sec HX in Watts or J/sec
    1960             :     Real64 RhoWater;
    1961             :     Real64 RhoAir; // Density of the primary side air
    1962             :     Real64 CFMAir;
    1963             :     Real64 CFMSec;
    1964             :     Real64 TWBSec; // wet bulb of secondary air
    1965             : 
    1966       68343 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    1967             : 
    1968             :     // If the Evaporative Cooler  is operating there should be some mass flow rate
    1969             :     //  Also the evap cooler has to be scheduled to be available
    1970       68343 :     if ((thisEvapCond.InletMassFlowRate > 0.0) && (ScheduleManager::GetCurrentScheduleValue(state, thisEvapCond.SchedPtr) > 0.0)) {
    1971             : 
    1972             :         //******************************************************************************
    1973             :         //   THIS SUBROUTINE WILL CACULATE THE TEMPERATURE OF THE LEAVING AIR DRY BULB
    1974             :         //   FOR A WET COIL EVAPORATIVE COOLER
    1975             :         //******************************************************************************
    1976             :         //  INDIRECT STAGE EFFICIENCY FOR WET COIL INDIRECT EVAP COOLERS
    1977       39888 :         CFMAir = thisEvapCond.VolFlowRate;         // Volume Flow Rate Primary Side
    1978       39888 :         CFMSec = thisEvapCond.IndirectVolFlowRate; // Volume Flolw Rate Secondary Side
    1979             : 
    1980       39888 :         StageEff = thisEvapCond.WetCoilMaxEfficiency - min(thisEvapCond.WetCoilFlowRatio * CFMAir / CFMSec, thisEvapCond.WetCoilMaxEfficiency);
    1981             : 
    1982       39888 :         if (StageEff >= 1.0) StageEff = 1.0;
    1983             :         // This is a rough approximation of the Total Indirect Stage Efficiency.  I think that
    1984             :         //   this would mainly be used for evap sizing purposes.
    1985             : 
    1986             :         // If there is a fault of fouling
    1987       41410 :         if (thisEvapCond.FaultyEvapCoolerFoulingFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    1988        1522 :             (!state.dataGlobal->KickOffSimulation)) {
    1989        1522 :             int FaultIndex = thisEvapCond.FaultyEvapCoolerFoulingIndex;
    1990        1522 :             Real64 StageEff_ff = StageEff;
    1991             : 
    1992             :             // calculate the Faulty Evaporative Cooler Fouling Factor using fault information
    1993        1522 :             thisEvapCond.FaultyEvapCoolerFoulingFactor = state.dataFaultsMgr->FaultsEvapCoolerFouling(FaultIndex).CalFoulingFactor(state);
    1994             : 
    1995             :             // update the StageEff at faulty cases
    1996        1522 :             StageEff = StageEff_ff * thisEvapCond.FaultyEvapCoolerFoulingFactor;
    1997             :         }
    1998             : 
    1999       39888 :         thisEvapCond.StageEff = StageEff;
    2000             :         //***************************************************************************
    2001             :         //   TEMP LEAVING DRY BULB IS CALCULATED FROM A SIMPLE WET BULB APPROACH
    2002             :         //   MODEL GIVEN THE INDIRECT STAGE EFFICIENCY.
    2003             :         //   DRY BULB TEMP APPROACHES THE WET BULB TEMP ACROSS THE INDIRECT STAGE.
    2004             :         //***************************************************************************
    2005             :         //                  CALCULATE THE TLDB
    2006       39888 :         TEWB = thisEvapCond.InletWetBulbTemp;
    2007       39888 :         TEDB = thisEvapCond.InletTemp;
    2008       39888 :         TWBSec = Psychrometrics::PsyTwbFnTdbWPb(state, thisEvapCond.SecInletTemp, thisEvapCond.SecInletHumRat, thisEvapCond.SecInletPressure);
    2009       39888 :         thisEvapCond.OutletTemp = TEDB - StageEff * (TEDB - TWBSec);
    2010             : 
    2011             :         //***************************************************************************
    2012             :         //                  CALCULATE THE WET BULB TEMP in the primary system air using PSYCH ROUTINES
    2013             :         // There is a constant humidity ratio across the primary side but a reduction in the dry bulb temp
    2014       39888 :         thisEvapCond.OuletWetBulbTemp =
    2015       79776 :             Psychrometrics::PsyTwbFnTdbWPb(state, thisEvapCond.OutletTemp, thisEvapCond.InletHumRat, state.dataEnvrn->OutBaroPress);
    2016             :         //***************************************************************************
    2017             :         //                  CALCULATE other outlet properties using PSYCH ROUTINES
    2018       39888 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    2019             : 
    2020       39888 :         thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    2021             : 
    2022             :         //***************************************************************************
    2023             :         // Real64 FlowFraction = 1.0;
    2024             :         // Real64 MassFlowRateMax = Node(thisEvapCond.InletNode).MassFlowRateMax;
    2025             :         // if (MassFlowRateMax > 0) {
    2026             :         //    FlowFraction = thisEvapCond.InletMassFlowRate / MassFlowRateMax;
    2027             :         //}
    2028             :         //                  POWER OF THE SECONDARY AIR FAN
    2029       39888 :         if (thisEvapCond.IndirectFanEff > 0.0) {
    2030       79776 :             thisEvapCond.EvapCoolerPower +=
    2031       39888 :                 PartLoadRatio * thisEvapCond.IndirectFanDeltaPress * thisEvapCond.IndirectVolFlowRate / thisEvapCond.IndirectFanEff;
    2032             :         }
    2033             : 
    2034             :         //                  ENERGY CONSUMED BY THE RECIRCULATING PUMP
    2035             :         //                  ENERGY CONSUMED BY THE RECIRCULATING PUMP
    2036             :         // Add the pump energy to the total Evap Cooler energy comsumption
    2037       39888 :         thisEvapCond.EvapCoolerPower += PartLoadRatio * thisEvapCond.IndirectRecircPumpPower;
    2038             : 
    2039             :         //******************
    2040             :         //             WATER CONSUMPTION IN m3 OF WATER FOR Wet InDIRECT
    2041             :         //             H2O [m3/s] = (QHX [J/s])/(2,500,000 [J/kgWater] * RhoWater [kgWater/m3])
    2042             :         //******************
    2043             :         //***** FIRST calculate the heat exchange on the primary air side**********
    2044       39888 :         RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisEvapCond.InletTemp, thisEvapCond.InletHumRat);
    2045       39888 :         QHX = PartLoadRatio * CFMAir * RhoAir * (thisEvapCond.InletEnthalpy - thisEvapCond.OutletEnthalpy);
    2046             : 
    2047       39888 :         RhoWater = Psychrometrics::RhoH2O(thisEvapCond.SecInletTemp);
    2048       39888 :         thisEvapCond.EvapWaterConsumpRate = (QHX / StageEff) / (2500000.0 * RhoWater);
    2049             :         // A numerical check to keep from having very tiny negative water consumption values being reported
    2050       39888 :         if (thisEvapCond.EvapWaterConsumpRate < 0.0) thisEvapCond.EvapWaterConsumpRate = 0.0;
    2051             : 
    2052             :     } else {
    2053             :         // The evap cooler is not running and does not change conditions from inlet to outlet
    2054       28455 :         thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    2055             : 
    2056       28455 :         thisEvapCond.OuletWetBulbTemp = thisEvapCond.InletWetBulbTemp;
    2057             : 
    2058       28455 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    2059             : 
    2060       28455 :         thisEvapCond.OutletEnthalpy = thisEvapCond.InletEnthalpy;
    2061             : 
    2062       28455 :         thisEvapCond.EvapCoolerEnergy = 0.0;
    2063             : 
    2064       28455 :         thisEvapCond.EvapWaterConsumpRate = 0.0;
    2065             :     }
    2066             :     // all of the mass flowrates are not changed across the evap cooler
    2067       68343 :     thisEvapCond.OutletMassFlowRate = thisEvapCond.InletMassFlowRate;
    2068       68343 :     thisEvapCond.OutletMassFlowRateMaxAvail = thisEvapCond.InletMassFlowRateMaxAvail;
    2069       68343 :     thisEvapCond.OutletMassFlowRateMinAvail = thisEvapCond.InletMassFlowRateMinAvail;
    2070             : 
    2071             :     // the pressure is not changed across the evap cooler
    2072       68343 :     thisEvapCond.OutletPressure = thisEvapCond.InletPressure;
    2073       68343 : }
    2074             : 
    2075     2527331 : void CalcResearchSpecialPartLoad(EnergyPlusData &state, int EvapCoolNum)
    2076             : {
    2077             :     // SUBROUTINE INFORMATION:
    2078             :     //       AUTHOR         B. Griffith
    2079             :     //       DATE WRITTEN   July 2003
    2080             :     //       MODIFIED       na
    2081             :     //       RE-ENGINEERED  na
    2082             : 
    2083             :     // REFERENCES:
    2084             :     // copied CalcWetIndirectEvapCooler as template for new cooler
    2085             : 
    2086     2527331 :     Real64 constexpr MinAirMassFlow(0.001);
    2087             : 
    2088             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2089     2527331 :     Real64 FullOutput(0.0);
    2090     2527331 :     Real64 ReqOutput(0.0);
    2091             :     int InletNode;
    2092             :     int OutletNode;
    2093             :     int ControlNode;
    2094             :     Real64 PartLoadFrac;
    2095             :     Real64 DesOutTemp;
    2096             :     // Set local variables
    2097             : 
    2098     2527331 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2099     2527331 :     auto &Node(state.dataLoopNodes->Node);
    2100             : 
    2101             :     // Retrieve the load on the controlled zone
    2102     2527331 :     OutletNode = thisEvapCond.OutletNode;
    2103     2527331 :     InletNode = thisEvapCond.InletNode;
    2104     2527331 :     ControlNode = thisEvapCond.EvapControlNodeNum;
    2105     2527331 :     DesOutTemp = thisEvapCond.DesiredOutletTemp;
    2106     2527331 :     PartLoadFrac = 0.0;
    2107             : 
    2108             :     // If Evap Cooler runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
    2109    10020442 :     if ((ScheduleManager::GetCurrentScheduleValue(state, thisEvapCond.SchedPtr) > 0.0) && (Node(InletNode).MassFlowRate > MinAirMassFlow) &&
    2110     7322681 :         (Node(InletNode).Temp > Node(ControlNode).TempSetPoint) && (std::abs(Node(InletNode).Temp - DesOutTemp) > DataHVACGlobals::TempControlTol)) {
    2111             : 
    2112             :         // Get full load result, depending on model
    2113     2314146 :         thisEvapCond.PartLoadFract = 1.0;
    2114     2314146 :         switch (thisEvapCond.evapCoolerType) {
    2115     1021024 :         case EvapCoolerType::IndirectRDDSpecial: {
    2116     1021024 :             CalcIndirectResearchSpecialEvapCooler(state, EvapCoolNum);
    2117     1021024 :             UpdateEvapCooler(state, EvapCoolNum);
    2118     2042048 :             FullOutput = Node(InletNode).MassFlowRate * (Psychrometrics::PsyHFnTdbW(Node(OutletNode).Temp, Node(InletNode).HumRat) -
    2119     1021024 :                                                          Psychrometrics::PsyHFnTdbW(Node(InletNode).Temp, Node(InletNode).HumRat));
    2120             : 
    2121     2042048 :             ReqOutput = Node(InletNode).MassFlowRate * (Psychrometrics::PsyHFnTdbW(thisEvapCond.DesiredOutletTemp, Node(InletNode).HumRat) -
    2122     1021024 :                                                         Psychrometrics::PsyHFnTdbW(Node(InletNode).Temp, Node(InletNode).HumRat));
    2123             : 
    2124             :             // now reinit after test call
    2125     1021024 :             InitEvapCooler(state, EvapCoolNum);
    2126             : 
    2127     1021024 :         } break;
    2128     1293122 :         case EvapCoolerType::DirectResearchSpecial: {
    2129     1293122 :             CalcDirectResearchSpecialEvapCooler(state, EvapCoolNum);
    2130     1293122 :             UpdateEvapCooler(state, EvapCoolNum);
    2131     1293122 :             FullOutput = Node(OutletNode).Temp - Node(InletNode).Temp;
    2132     1293122 :             ReqOutput = thisEvapCond.DesiredOutletTemp - Node(InletNode).Temp;
    2133             : 
    2134             :             // now reinit after test call
    2135     1293122 :             InitEvapCooler(state, EvapCoolNum);
    2136             : 
    2137     1293122 :         } break;
    2138           0 :         default: {
    2139           0 :             assert(false);
    2140             :         } break;
    2141             :         }
    2142             : 
    2143             :         // Since we are cooling, we expect FullOutput to be < 0 and FullOutput < NoCoolOutput
    2144             :         // Check that this is the case; if not set PartLoadFrac = 0.0 (off) and return
    2145             :         // Calculate the part load fraction
    2146     2314146 :         if (FullOutput == 0.0) {
    2147        8992 :             FullOutput = 0.00001;
    2148             :         }
    2149     2314146 :         PartLoadFrac = ReqOutput / FullOutput;
    2150     2314146 :         if (PartLoadFrac > 1.0) {
    2151     2264314 :             PartLoadFrac = 1.0;
    2152       49832 :         } else if (PartLoadFrac < 0.0) {
    2153        8994 :             PartLoadFrac = 0.0;
    2154             :         }
    2155             : 
    2156             :     } else { // No cooling
    2157      213185 :         PartLoadFrac = 0.0;
    2158             : 
    2159             :     } // End of the cooler running If block
    2160             :     // Set the final results
    2161     2527331 :     thisEvapCond.PartLoadFract = PartLoadFrac;
    2162     2527331 : }
    2163             : 
    2164     2156668 : void CalcIndirectResearchSpecialEvapCooler(EnergyPlusData &state, int const EvapCoolNum, Real64 const FanPLR)
    2165             : {
    2166             : 
    2167             :     // SUBROUTINE INFORMATION:
    2168             :     //       AUTHOR         B. Griffith
    2169             :     //       DATE WRITTEN   July 2003
    2170             :     //       MODIFIED       na
    2171             :     //       RE-ENGINEERED  October 2014, B Nigusse, added dry and wet operating modes
    2172             :     //                      and secondary air flow control
    2173             : 
    2174             :     // PURPOSE OF THIS SUBROUTINE:
    2175             :     // Subroutine models a "special" cooler that allows high effectiveness and controls
    2176             : 
    2177             :     // REFERENCES:
    2178             :     // copied CalcWetIndirectEvapCooler as template for new cooler
    2179             : 
    2180             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2181             :     Real64 SecondaryInletDryBulbTemp;  // entering drybulb for secondary/purge side
    2182             :     Real64 SecondaryInletWetBulbTemp;  // entering wet bulb for secondary/purge side
    2183             :     Real64 SecondaryInletDewPointTemp; // entering dewpoint for secondary/purge side
    2184             :     Real64 SecondaryInletHumRatio;     // entering humidity ratio for secondary/purge side
    2185             :     Real64 StageEff;                   // Stage Efficiency of the Heat Exchanger
    2186             :     Real64 TEDB;                       // Entering Dry Bulb Temperature
    2187             :     Real64 TEWB;                       // Entering Wet Bulb Temperature
    2188             :     Real64 QHX;                        // Q Across Sec HX in Watts or J/sec
    2189             :     Real64 RhoWater;
    2190             :     Real64 RhoAir; // Density of the primary side air
    2191             :     Real64 CFMAir;
    2192             :     int TertNode;     // inlet node for relief (from bulding) to mix for purge
    2193             :     Real64 BoundTemp; // temperature limit for outlet
    2194             :     Real64 PartLoad;
    2195             :     Real64 TotalVolFlow;
    2196             :     Real64 TertMdot;
    2197             :     Real64 TertHumRate;
    2198             :     Real64 TertTemp;
    2199             :     Real64 TertRho;
    2200             :     Real64 TertVdot;
    2201             :     Real64 SecVdot;
    2202             :     Real64 SecRho;
    2203             :     Real64 SecMdot;
    2204             :     Real64 PurgeMdot;
    2205             :     Real64 PurgeHumRat;
    2206             :     Real64 PurgeEnthalpy;
    2207             :     Real64 PurgeTemp;
    2208     2156668 :     Real64 BlowDownVdot(0.0);
    2209     2156668 :     Real64 DriftVdot(0.0);
    2210     2156668 :     Real64 EvapVdot(0.0);
    2211             : 
    2212     2156668 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2213             : 
    2214             :     // If the Evaporative Cooler  is operating there should be some mass flow rate
    2215             :     //  Also the evap cooler has to be scheduled to be available
    2216     2156668 :     if ((thisEvapCond.InletMassFlowRate > 0.0) && (ScheduleManager::GetCurrentScheduleValue(state, thisEvapCond.SchedPtr) > 0.0)) {
    2217             : 
    2218             :         //******************************************************************************
    2219             :         //   THIS SUBROUTINE WILL CACULATE THE TEMPERATURE OF THE LEAVING AIR DRY BULB
    2220             :         //   FOR A WET COIL EVAPORATIVE COOLER
    2221             :         //******************************************************************************
    2222             :         //  INDIRECT STAGE EFFICIENCY FOR WET COIL INDIRECT EVAP COOLERS
    2223     2117266 :         CFMAir = thisEvapCond.VolFlowRate; // Volume Flow Rate Primary Side
    2224     2117266 :         StageEff = thisEvapCond.WetCoilMaxEfficiency;
    2225             : 
    2226             :         // This is model is for special indirect cooler with efficiency greater than 1.0
    2227     2117266 :         if (StageEff >= 1.5) StageEff = 1.5;
    2228             : 
    2229     2117266 :         thisEvapCond.StageEff = StageEff;
    2230             : 
    2231             :         //***********************************************
    2232             :         //  Unit is allowed to mix relief air that would otherwise be exhausted outdoors for ventilation
    2233             :         //  If tertiary node is set >0 then it assumed that this node is the exhaust out of the building
    2234             :         //  and the remainder will be made up with outside air from the secondary node
    2235             :         //*********************************************
    2236             : 
    2237     2117266 :         TertNode = thisEvapCond.TertiaryInletNode;
    2238     2117266 :         if (TertNode == 0) {
    2239     2059967 :             SecondaryInletDryBulbTemp = thisEvapCond.SecInletTemp;
    2240     2059967 :             SecondaryInletWetBulbTemp =
    2241     4119934 :                 Psychrometrics::PsyTwbFnTdbWPb(state, thisEvapCond.SecInletTemp, thisEvapCond.SecInletHumRat, state.dataEnvrn->OutBaroPress);
    2242     2059967 :             SecondaryInletDewPointTemp =
    2243     4119934 :                 Psychrometrics::PsyTdpFnTdbTwbPb(state, thisEvapCond.SecInletTemp, SecondaryInletWetBulbTemp, state.dataEnvrn->OutBaroPress);
    2244     2059967 :             SecondaryInletHumRatio = thisEvapCond.SecInletHumRat;
    2245             : 
    2246             :         } else {
    2247             : 
    2248       57299 :             TotalVolFlow = thisEvapCond.IndirectVolFlowRate;
    2249       57299 :             TertMdot = state.dataLoopNodes->Node(TertNode).MassFlowRate;
    2250       57299 :             TertHumRate = state.dataLoopNodes->Node(TertNode).HumRat;
    2251       57299 :             TertTemp = state.dataLoopNodes->Node(TertNode).Temp;
    2252             :             // is Node pressure available or better? using outdoor pressure for now
    2253       57299 :             TertRho = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TertTemp, TertHumRate);
    2254       57299 :             TertVdot = TertMdot / TertRho;
    2255             : 
    2256       57299 :             SecVdot = TotalVolFlow - TertVdot;
    2257             : 
    2258       57299 :             if (SecVdot < 0.0) { // all tertiary/releif air e.g. econonizer wide open
    2259           0 :                 SecVdot = 0.0;
    2260           0 :                 SecondaryInletDryBulbTemp = TertTemp;
    2261           0 :                 SecondaryInletWetBulbTemp = Psychrometrics::PsyTwbFnTdbWPb(state, TertTemp, TertHumRate, state.dataEnvrn->OutBaroPress);
    2262           0 :                 SecondaryInletDewPointTemp =
    2263           0 :                     Psychrometrics::PsyTdpFnTdbTwbPb(state, TertTemp, SecondaryInletWetBulbTemp, state.dataEnvrn->OutBaroPress);
    2264           0 :                 SecondaryInletHumRatio = TertHumRate;
    2265             :             } else {
    2266             : 
    2267             :                 // First determine mass flow of OA,  in secondary
    2268       57299 :                 SecRho =
    2269      114598 :                     Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisEvapCond.SecInletTemp, thisEvapCond.SecInletHumRat);
    2270       57299 :                 SecMdot = SecRho * SecVdot;
    2271             :                 // Mass balance on moisture to get outlet air humidity ratio
    2272             :                 // this mixing takes place before wet media.
    2273       57299 :                 PurgeMdot = SecMdot + TertMdot;
    2274       57299 :                 PurgeHumRat = (SecMdot * thisEvapCond.SecInletHumRat + TertMdot * TertHumRate) / PurgeMdot;
    2275             : 
    2276             :                 // Energy balance to get outlet air enthalpy
    2277             : 
    2278      114598 :                 PurgeEnthalpy = (SecMdot * Psychrometrics::PsyHFnTdbW(thisEvapCond.SecInletTemp, thisEvapCond.SecInletHumRat) +
    2279       57299 :                                  TertMdot * Psychrometrics::PsyHFnTdbW(TertTemp, TertHumRate)) /
    2280             :                                 PurgeMdot;
    2281             : 
    2282             :                 // Use Enthalpy and humidity ratio to get outlet temperature from psych chart
    2283             : 
    2284       57299 :                 PurgeTemp = Psychrometrics::PsyTdbFnHW(PurgeEnthalpy, PurgeHumRat);
    2285       57299 :                 SecondaryInletDryBulbTemp = PurgeTemp;
    2286       57299 :                 SecondaryInletWetBulbTemp = Psychrometrics::PsyTwbFnTdbWPb(state, PurgeTemp, PurgeHumRat, state.dataEnvrn->OutBaroPress);
    2287       57299 :                 SecondaryInletDewPointTemp =
    2288      114598 :                     Psychrometrics::PsyTdpFnTdbTwbPb(state, PurgeTemp, SecondaryInletWetBulbTemp, state.dataEnvrn->OutBaroPress);
    2289       57299 :                 SecondaryInletHumRatio = PurgeHumRat;
    2290             :             }
    2291             :         }
    2292     2117266 :         if (thisEvapCond.EvapCoolerOperationControlFlag) {
    2293             :             // addvanced mode: runs either in dry or wet depending on the entering conditions
    2294       34744 :             CalcIndirectResearchSpecialEvapCoolerAdvanced(
    2295             :                 state, EvapCoolNum, SecondaryInletDryBulbTemp, SecondaryInletWetBulbTemp, SecondaryInletDewPointTemp, SecondaryInletHumRatio);
    2296             : 
    2297             :         } else {
    2298             : 
    2299     2082522 :             TEWB = thisEvapCond.InletWetBulbTemp;
    2300     2082522 :             TEDB = thisEvapCond.InletTemp;
    2301     2082522 :             PartLoad = thisEvapCond.PartLoadFract;
    2302             : 
    2303             :             //***************************************************************************
    2304             :             //   TEMP LEAVING DRY BULB IS CALCULATED FROM A SIMPLE WET BULB APPROACH
    2305             :             //   MODEL GIVEN THE INDIRECT STAGE EFFICIENCY.
    2306             :             //   DRY BULB TEMP APPROACHES THE WET BULB TEMP ACROSS THE INDIRECT STAGE.
    2307             :             //***************************************************************************
    2308     2082522 :             if (PartLoad == 1.0) {
    2309             :                 //                                 Tout = Tin -  (   0.7    (Tin  - Tpurge,wb,in)
    2310     1987995 :                 thisEvapCond.OutletTemp = TEDB - StageEff * (TEDB - SecondaryInletWetBulbTemp);
    2311             :                 //  now bound with secondary dewpoint.
    2312             :                 // unless the resulting Tout<=Tpurge,dp,in ; in which case Tout = Tin - 0.9(Tin-Tpurge,dp,in)
    2313             : 
    2314     1987995 :                 BoundTemp = TEDB - thisEvapCond.DPBoundFactor * (TEDB - SecondaryInletDewPointTemp);
    2315     1987995 :                 if (thisEvapCond.OutletTemp < BoundTemp) {
    2316        1327 :                     thisEvapCond.OutletTemp = BoundTemp;
    2317        1327 :                     thisEvapCond.DewPointBoundFlag = 1;
    2318             :                 }
    2319       94527 :             } else if ((PartLoad < 1.0) && (PartLoad > 0.0)) {
    2320             :                 // assume perfect control Use PLF for energy consumption
    2321       72326 :                 if (thisEvapCond.DesiredOutletTemp < TEDB) {
    2322       36161 :                     thisEvapCond.OutletTemp = thisEvapCond.DesiredOutletTemp;
    2323             :                 }
    2324             :             } else {
    2325             :                 // part load set to zero so no cooling
    2326       58364 :                 thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    2327             :             }
    2328             : 
    2329             :             //***************************************************************************
    2330             :             //                  POWER OF THE SECONDARY AIR FAN with part load factor applied (assumes const efficiency)
    2331     2082522 :             thisEvapCond.EvapCoolerPower += thisEvapCond.IndirectVolFlowRate * thisEvapCond.FanSizingSpecificPower * PartLoad * FanPLR;
    2332             : 
    2333             :             //                  ENERGY CONSUMED BY THE RECIRCULATING PUMP
    2334             :             //                  ENERGY CONSUMED BY THE RECIRCULATING PUMP
    2335             :             // Add the pump energy to the total Evap Cooler energy comsumption
    2336     2082522 :             thisEvapCond.EvapCoolerPower += thisEvapCond.IndirectRecircPumpPower * PartLoad * FanPLR;
    2337             : 
    2338             :             //***************************************************************************
    2339             :             //                  CALCULATE THE WET BULB TEMP in the primary system air using PSYCH ROUTINES
    2340             :             // There is a constant humidity ratio across the primary side but a reduction in the dry bulb temp
    2341     2082522 :             thisEvapCond.OuletWetBulbTemp =
    2342     4165044 :                 Psychrometrics::PsyTwbFnTdbWPb(state, thisEvapCond.OutletTemp, thisEvapCond.InletHumRat, state.dataEnvrn->OutBaroPress);
    2343             :             //***************************************************************************
    2344             :             //                  CALCULATE other outlet propertiesusing PSYCH ROUTINES
    2345     2082522 :             thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    2346             : 
    2347     2082522 :             thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    2348             :             //******************
    2349             :             //             WATER CONSUMPTION IN m3 OF WATER FOR Wet InDIRECT
    2350             :             //             H2O [m3/s] = (QHX [J/s])/(2,500,000 [J/kgWater] * RhoWater [kgWater/m3])
    2351             :             //******************
    2352             :             //***** FIRST calculate the heat exchange on the primary air side**********
    2353     2082522 :             RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisEvapCond.InletTemp, thisEvapCond.InletHumRat);
    2354     2082522 :             QHX = CFMAir * RhoAir * (thisEvapCond.InletEnthalpy - thisEvapCond.OutletEnthalpy);
    2355             : 
    2356     2082522 :             RhoWater = Psychrometrics::RhoH2O(state.dataEnvrn->OutDryBulbTemp);
    2357     2082522 :             EvapVdot = (QHX) / (2500000.0 * RhoWater);
    2358     2082522 :             DriftVdot = EvapVdot * thisEvapCond.DriftFraction;
    2359     2082522 :             if (thisEvapCond.BlowDownRatio > 0.0) {
    2360      696884 :                 BlowDownVdot = EvapVdot / (thisEvapCond.BlowDownRatio - 1) - DriftVdot;
    2361      696884 :                 if (BlowDownVdot < 0.0) BlowDownVdot = 0.0;
    2362             :             } else {
    2363     1385638 :                 BlowDownVdot = 0.0;
    2364             :             }
    2365     2082522 :             thisEvapCond.EvapWaterConsumpRate = EvapVdot + DriftVdot + BlowDownVdot;
    2366             :             // A numerical check to keep from having very tiny negative water consumption values being reported
    2367     2082522 :             if (thisEvapCond.EvapWaterConsumpRate < 0.0) thisEvapCond.EvapWaterConsumpRate = 0.0;
    2368             :         }
    2369             : 
    2370             :     } else {
    2371             :         // The evap cooler is not running and does not change conditions from inlet to outlet
    2372       39402 :         thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    2373       39402 :         thisEvapCond.OuletWetBulbTemp = thisEvapCond.InletWetBulbTemp;
    2374       39402 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    2375       39402 :         thisEvapCond.OutletEnthalpy = thisEvapCond.InletEnthalpy;
    2376       39402 :         thisEvapCond.EvapCoolerEnergy = 0.0;
    2377       39402 :         thisEvapCond.EvapCoolerPower = 0.0;
    2378       39402 :         thisEvapCond.EvapWaterConsumpRate = 0.0;
    2379       39402 :         thisEvapCond.SecInletMassFlowRate = 0.0;
    2380             :     }
    2381             : 
    2382             :     // all of the mass flowrates are not changed across the evap cooler
    2383     2156668 :     thisEvapCond.OutletMassFlowRate = thisEvapCond.InletMassFlowRate;
    2384     2156668 :     thisEvapCond.OutletMassFlowRateMaxAvail = thisEvapCond.InletMassFlowRateMaxAvail;
    2385     2156668 :     thisEvapCond.OutletMassFlowRateMinAvail = thisEvapCond.InletMassFlowRateMinAvail;
    2386             :     // set secondary air side inlet mass flow rate to the outlet node
    2387     2156668 :     thisEvapCond.SecOutletMassFlowRate = thisEvapCond.SecInletMassFlowRate;
    2388     2156668 :     state.dataLoopNodes->Node(thisEvapCond.SecondaryInletNode).MassFlowRate = thisEvapCond.SecInletMassFlowRate;
    2389             : 
    2390             :     // the pressure is not changed across the evap cooler
    2391     2156668 :     thisEvapCond.OutletPressure = thisEvapCond.InletPressure;
    2392     2156668 : }
    2393             : 
    2394       34744 : void CalcIndirectResearchSpecialEvapCoolerAdvanced(EnergyPlusData &state,
    2395             :                                                    int const EvapCoolNum,
    2396             :                                                    Real64 const InletDryBulbTempSec,
    2397             :                                                    Real64 const InletWetBulbTempSec,
    2398             :                                                    Real64 const InletDewPointTempSec,
    2399             :                                                    Real64 const InletHumRatioSec)
    2400             : {
    2401             : 
    2402             :     // SUBROUTINE INFORMATION:
    2403             :     //       AUTHOR         B. Bigusse
    2404             :     //       DATE WRITTEN   October 2014
    2405             :     //       MODIFIED       na
    2406             :     //       RE-ENGINEERED  na
    2407             : 
    2408             :     // PURPOSE OF THIS SUBROUTINE:
    2409             :     // Subroutine models indirect evaporative cooler with variable effectiveness for wet and dry
    2410             :     // operating modes depending on entering conditions
    2411             : 
    2412             :     // SUBROUTINE PARAMETER DEFINITIONS:
    2413       34744 :     int constexpr MaxIte(500);      // Maximum number of iterations for solver
    2414       34744 :     Real64 constexpr TempTol(0.01); // convergence tollerance
    2415             : 
    2416             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2417             :     Real64 TEDB;      // Entering Dry Bulb Temperature
    2418             :     Real64 TEWB;      // Entering Wet Bulb Temperature
    2419             :     Real64 BoundTemp; // temperature limit for outlet
    2420             :     Real64 PartLoad;
    2421             :     Real64 SecRho;
    2422             :     Real64 TdbOutSysWetMin;                 // system( primary ) air drybulb outlet temperature minimum based on wet coil
    2423             :     Real64 TdbOutSysDryMin;                 // system (primary) air drybulb outlet temperature minimum based on dry coil
    2424             :     Real64 SysTempSetPoint;                 // evaporative cooler outlet setpoint temperature, drybulb
    2425             :     Real64 MassFlowRateSecMax;              // Design secondary air mass flow rate
    2426             :     Real64 AirMassFlowSec;                  // current secondary air mass flow rate
    2427             :     Real64 AirMassFlowSecDry;               // current secondary air mass flow rate in dry mode
    2428             :     Real64 AirMassFlowSecWet;               // current secondary air mass flow rate in wet mode
    2429             :     Real64 FlowRatioSec;                    // secondary air flow ratio in dry and wet mode
    2430             :     Real64 FlowRatioSecDry;                 // current secondary air mass flow ratio in dry mode
    2431             :     Real64 FlowRatioSecWet;                 // current secondary air mass flow ratio in wet mode
    2432             :     Real64 EvapCoolerTotalElectricPowerDry; // evaporative cooler current total electric power drawn
    2433             :     Real64 EvapCoolerTotalElectricPowerWet; // evaporative cooler current total electric power drawn
    2434             :     int SolFla;                             // Flag of solver
    2435             :     Real64 QHXLatent;                       // evaporative cooler latent heat transfer rate
    2436             :     Real64 hfg;                             // latent heat of vaporization of water at the secondary air inlet condition
    2437             : 
    2438             :     Real64 QHX; // Q Across Sec HX in Watts or J/sec
    2439             :     Real64 RhoWater;
    2440             :     Real64 RhoAir; // Density of the primary side air
    2441             :     Real64 MassFlowRateSecMin;
    2442       34744 :     Real64 BlowDownVdot(0.0);
    2443       34744 :     Real64 DriftVdot(0.0);
    2444       34744 :     Real64 EvapVdot(0.0);
    2445             : 
    2446       34744 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2447             : 
    2448       34744 :     FlowRatioSecDry = 0.0;
    2449       34744 :     FlowRatioSecWet = 0.0;
    2450       34744 :     thisEvapCond.EvapCoolerRDDOperatingMode = OperatingMode::None;
    2451       34744 :     TEDB = thisEvapCond.InletTemp;
    2452       34744 :     TEWB = thisEvapCond.InletWetBulbTemp;
    2453       34744 :     SysTempSetPoint = thisEvapCond.DesiredOutletTemp;
    2454       34744 :     SecRho = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, InletDryBulbTempSec, InletHumRatioSec);
    2455       34744 :     MassFlowRateSecMax = SecRho * thisEvapCond.IndirectVolFlowRate;
    2456       34744 :     CalcIndirectRDDEvapCoolerOutletTemp(
    2457             :         state, EvapCoolNum, OperatingMode::WetFull, MassFlowRateSecMax, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2458       34744 :     TdbOutSysWetMin = thisEvapCond.OutletTemp;
    2459       34744 :     CalcIndirectRDDEvapCoolerOutletTemp(
    2460             :         state, EvapCoolNum, OperatingMode::DryFull, MassFlowRateSecMax, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2461       34744 :     TdbOutSysDryMin = thisEvapCond.OutletTemp;
    2462             : 
    2463             :     // get current operating modes of indirect evaporative cooler research special
    2464       34744 :     thisEvapCond.EvapCoolerRDDOperatingMode = IndirectResearchSpecialEvapCoolerOperatingMode(
    2465             :         state, EvapCoolNum, InletDryBulbTempSec, InletWetBulbTempSec, TdbOutSysWetMin, TdbOutSysDryMin);
    2466             : 
    2467       34744 :     MassFlowRateSecMin = 0.0;
    2468       34744 :     AirMassFlowSec = MassFlowRateSecMax;
    2469       34744 :     PartLoad = thisEvapCond.PartLoadFract;
    2470             :     {
    2471       34744 :         if (thisEvapCond.EvapCoolerRDDOperatingMode == OperatingMode::DryModulated) {
    2472      191208 :             auto f = [&state, EvapCoolNum, SysTempSetPoint, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec](Real64 AirMassFlowSec) {
    2473       95604 :                 auto &EvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2474       47802 :                 EvapCond.SecInletMassFlowRate = AirMassFlowSec;
    2475       47802 :                 CalcIndirectRDDEvapCoolerOutletTemp(
    2476             :                     state, EvapCoolNum, OperatingMode::DryModulated, AirMassFlowSec, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2477       47802 :                 Real64 const OutletAirTemp = EvapCond.OutletTemp; // evap Coler outlet air temperature
    2478       47802 :                 return SysTempSetPoint - OutletAirTemp;
    2479       13540 :             };
    2480       13540 :             General::SolveRoot(state, TempTol, MaxIte, SolFla, AirMassFlowSec, f, MassFlowRateSecMin, MassFlowRateSecMax);
    2481             :             // if the numerical inversion failed, issue error messages.
    2482       13540 :             if (SolFla == -1) {
    2483           0 :                 if (!state.dataGlobal->WarmupFlag) {
    2484           0 :                     if (thisEvapCond.IterationLimit == 0) {
    2485           0 :                         ShowSevereError(state,
    2486             :                                         "CalcIndirectResearchSpecialEvapCooler: calculate secondary air mass flow failed for Indirect "
    2487           0 :                                         "Evaporative Cooler Research Special = " +
    2488             :                                             thisEvapCond.Name);
    2489           0 :                         ShowContinueErrorTimeStamp(state, "");
    2490           0 :                         ShowContinueError(state, format("  Iteration limit [{}] exceeded in calculating secondary air mass flow rate", MaxIte));
    2491           0 :                         ShowContinueError(state, "  Simulation continues");
    2492             :                     }
    2493           0 :                     ShowRecurringWarningErrorAtEnd(
    2494             :                         state,
    2495           0 :                         "Secondary air mass flow Iteration limit exceeded in Indirect Evaporative Cooler Research Special = " + thisEvapCond.Name,
    2496             :                         thisEvapCond.IterationLimit);
    2497             :                 }
    2498       13540 :             } else if (SolFla == -2) {
    2499           0 :                 if (!state.dataGlobal->WarmupFlag) {
    2500           0 :                     if (thisEvapCond.IterationFailed == 0) {
    2501           0 :                         ShowSevereError(state,
    2502             :                                         "CalcIndirectResearchSpecialEvapCooler: calculate secondary air mass flow failed for Indirect "
    2503           0 :                                         "Evaporative Cooler Research Special = " +
    2504             :                                             thisEvapCond.Name);
    2505           0 :                         ShowContinueErrorTimeStamp(state, "");
    2506           0 :                         ShowContinueError(state, "...Bad secondary air mass flow rate limits");
    2507           0 :                         ShowContinueError(state, format("...Given minimum secondary air mass flow rate={:.3R} kg/s", MassFlowRateSecMin));
    2508           0 :                         ShowContinueError(state, format("...Given maximum secondary air mass flow rate={:.3R} kg/s", MassFlowRateSecMax));
    2509           0 :                         ShowContinueError(state, " Simulation continues");
    2510             :                     }
    2511           0 :                     ShowRecurringWarningErrorAtEnd(state,
    2512           0 :                                                    "Secondary air mass flow control failed in Indirect Evaporative Cooler Research Special = " +
    2513             :                                                        thisEvapCond.Name,
    2514             :                                                    thisEvapCond.IterationFailed);
    2515             :                 }
    2516             :             }
    2517       13540 :             thisEvapCond.SecInletMassFlowRate = AirMassFlowSec;
    2518       13540 :             if (AirMassFlowSec > 0.0) {
    2519       13540 :                 if (MassFlowRateSecMax > 0.0) {
    2520       13540 :                     FlowRatioSec = AirMassFlowSec / MassFlowRateSecMax;
    2521             :                 } else {
    2522           0 :                     FlowRatioSec = 0.0;
    2523             :                 }
    2524             :             } else {
    2525           0 :                 FlowRatioSec = 0.0;
    2526             :             }
    2527       13540 :             thisEvapCond.EvapCoolerPower = IndEvapCoolerPower(state, EvapCoolNum, OperatingMode::DryModulated, FlowRatioSec);
    2528       13540 :             thisEvapCond.IECOperatingStatus = 1;
    2529       21204 :         } else if (thisEvapCond.EvapCoolerRDDOperatingMode == OperatingMode::DryFull) {
    2530           8 :             CalcIndirectRDDEvapCoolerOutletTemp(
    2531             :                 state, EvapCoolNum, OperatingMode::DryFull, MassFlowRateSecMax, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2532           8 :             thisEvapCond.SecInletMassFlowRate = MassFlowRateSecMax;
    2533           8 :             FlowRatioSec = 1.0;
    2534           8 :             thisEvapCond.EvapCoolerPower = IndEvapCoolerPower(state, EvapCoolNum, OperatingMode::DryFull, FlowRatioSec);
    2535           8 :             thisEvapCond.IECOperatingStatus = 1;
    2536       21196 :         } else if (thisEvapCond.EvapCoolerRDDOperatingMode == OperatingMode::DryWetModulated) {
    2537           0 :             auto f = [&state, EvapCoolNum, SysTempSetPoint, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec](Real64 AirMassFlowSec) {
    2538           0 :                 auto &EvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2539           0 :                 EvapCond.SecInletMassFlowRate = AirMassFlowSec;
    2540           0 :                 CalcIndirectRDDEvapCoolerOutletTemp(
    2541             :                     state, EvapCoolNum, OperatingMode::DryModulated, AirMassFlowSec, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2542           0 :                 Real64 const OutletAirTemp = EvapCond.OutletTemp; // evap Coler outlet air temperature
    2543           0 :                 return SysTempSetPoint - OutletAirTemp;
    2544           0 :             };
    2545           0 :             General::SolveRoot(state, TempTol, MaxIte, SolFla, AirMassFlowSec, f, MassFlowRateSecMin, MassFlowRateSecMax);
    2546             :             // if the numerical inversion failed, issue error messages.
    2547           0 :             if (SolFla == -1) {
    2548           0 :                 if (!state.dataGlobal->WarmupFlag) {
    2549           0 :                     if (thisEvapCond.IterationLimit == 0) {
    2550           0 :                         ShowSevereError(state,
    2551             :                                         "CalcIndirectResearchSpecialEvapCooler: calculate secondary air mass flow failed for Indirect "
    2552           0 :                                         "Evaporative Cooler Research Special = " +
    2553             :                                             thisEvapCond.Name);
    2554           0 :                         ShowContinueErrorTimeStamp(state, "");
    2555           0 :                         ShowContinueError(state, format("  Iteration limit [{}] exceeded in calculating secondary air mass flow rate", MaxIte));
    2556           0 :                         ShowContinueError(state, "  Simulation continues");
    2557             :                     }
    2558           0 :                     ShowRecurringWarningErrorAtEnd(
    2559             :                         state,
    2560           0 :                         "Secondary air mass flow Iteration limit exceeded in Indirect Evaporative Cooler Research Special = " + thisEvapCond.Name,
    2561             :                         thisEvapCond.IterationLimit);
    2562             :                 }
    2563           0 :             } else if (SolFla == -2) {
    2564           0 :                 if (!state.dataGlobal->WarmupFlag) {
    2565           0 :                     if (thisEvapCond.IterationFailed == 0) {
    2566           0 :                         ShowSevereError(state,
    2567             :                                         "CalcIndirectResearchSpecialEvapCooler: calculate secondary air mass flow failed for Indirect "
    2568           0 :                                         "Evaporative Cooler Research Special = " +
    2569             :                                             thisEvapCond.Name);
    2570           0 :                         ShowContinueErrorTimeStamp(state, "");
    2571           0 :                         ShowContinueError(state, "...Bad secondary air mass flow rate limits");
    2572           0 :                         ShowContinueError(state, format("...Given minimum secondary air mass flow rate={:.3R} kg/s", MassFlowRateSecMin));
    2573           0 :                         ShowContinueError(state, format("...Given maximum secondary air mass flow rate={:.3R} kg/s", MassFlowRateSecMax));
    2574           0 :                         ShowContinueError(state, " Simulation continues");
    2575             :                     }
    2576           0 :                     ShowRecurringWarningErrorAtEnd(state,
    2577           0 :                                                    "Secondary air mass flow control failed in Indirect Evaporative Cooler Research Special = " +
    2578             :                                                        thisEvapCond.Name,
    2579             :                                                    thisEvapCond.IterationFailed);
    2580             :                 }
    2581             :             }
    2582           0 :             if (AirMassFlowSec > 0.0) {
    2583           0 :                 if (MassFlowRateSecMax > 0.0) {
    2584           0 :                     FlowRatioSec = AirMassFlowSec / MassFlowRateSecMax;
    2585             :                 } else {
    2586           0 :                     FlowRatioSec = 0.0;
    2587             :                 }
    2588             :             } else {
    2589           0 :                 FlowRatioSec = 0.0;
    2590             :             }
    2591           0 :             FlowRatioSecDry = FlowRatioSec;
    2592           0 :             AirMassFlowSecDry = AirMassFlowSec;
    2593           0 :             EvapCoolerTotalElectricPowerDry = IndEvapCoolerPower(state, EvapCoolNum, OperatingMode::DryModulated, FlowRatioSecDry);
    2594             :             // get wet operation performance
    2595           0 :             auto f2 = [&state, EvapCoolNum, SysTempSetPoint, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec](Real64 AirMassFlowSec) {
    2596           0 :                 auto &EvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2597           0 :                 EvapCond.SecInletMassFlowRate = AirMassFlowSec;
    2598           0 :                 CalcIndirectRDDEvapCoolerOutletTemp(
    2599             :                     state, EvapCoolNum, OperatingMode::WetModulated, AirMassFlowSec, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2600           0 :                 Real64 const OutletAirTemp = EvapCond.OutletTemp; // evap Coler outlet air temperature
    2601           0 :                 return SysTempSetPoint - OutletAirTemp;
    2602           0 :             };
    2603           0 :             General::SolveRoot(state, TempTol, MaxIte, SolFla, AirMassFlowSec, f2, MassFlowRateSecMin, MassFlowRateSecMax);
    2604             :             // if the numerical inversion failed, issue error messages.
    2605           0 :             if (SolFla == -1) {
    2606           0 :                 if (!state.dataGlobal->WarmupFlag) {
    2607           0 :                     if (thisEvapCond.IterationLimit == 0) {
    2608           0 :                         ShowSevereError(state,
    2609             :                                         "CalcIndirectResearchSpecialEvapCooler: calculate secondary air mass flow failed for Indirect "
    2610           0 :                                         "Evaporative Cooler Research Special = " +
    2611             :                                             thisEvapCond.Name);
    2612           0 :                         ShowContinueErrorTimeStamp(state, "");
    2613           0 :                         ShowContinueError(state, format("  Iteration limit [{}] exceeded in calculating secondary air mass flow rate", MaxIte));
    2614           0 :                         ShowContinueError(state, "  Simulation continues");
    2615             :                     }
    2616           0 :                     ShowRecurringWarningErrorAtEnd(
    2617             :                         state,
    2618           0 :                         "Secondary air mass flow Iteration limit exceeded in Indirect Evaporative Cooler Research Special = " + thisEvapCond.Name,
    2619             :                         thisEvapCond.IterationLimit);
    2620             :                 }
    2621           0 :             } else if (SolFla == -2) {
    2622           0 :                 if (!state.dataGlobal->WarmupFlag) {
    2623           0 :                     if (thisEvapCond.IterationFailed == 0) {
    2624           0 :                         ShowSevereError(state,
    2625             :                                         "CalcIndirectResearchSpecialEvapCooler: calculate secondary air mass flow failed for Indirect "
    2626           0 :                                         "Evaporative Cooler Research Special = " +
    2627             :                                             thisEvapCond.Name);
    2628           0 :                         ShowContinueErrorTimeStamp(state, "");
    2629           0 :                         ShowContinueError(state, "...Bad secondary air mass flow rate limits");
    2630           0 :                         ShowContinueError(state, format("...Given minimum secondary air mass flow rate={:.3R} kg/s", MassFlowRateSecMin));
    2631           0 :                         ShowContinueError(state, format("...Given maximum secondary air mass flow rate={:.3R} kg/s", MassFlowRateSecMax));
    2632           0 :                         ShowContinueError(state, " Simulation continues");
    2633             :                     }
    2634           0 :                     ShowRecurringWarningErrorAtEnd(state,
    2635           0 :                                                    "Secondary air mass flow control failed in Indirect Evaporative Cooler Research Special = " +
    2636             :                                                        thisEvapCond.Name,
    2637             :                                                    thisEvapCond.IterationFailed);
    2638             :                 }
    2639             :             }
    2640           0 :             if (AirMassFlowSec > 0.0) {
    2641           0 :                 if (MassFlowRateSecMax > 0.0) {
    2642           0 :                     FlowRatioSec = AirMassFlowSec / MassFlowRateSecMax;
    2643             :                 } else {
    2644           0 :                     FlowRatioSec = 0.0;
    2645             :                 }
    2646             :             } else {
    2647           0 :                 FlowRatioSec = 0.0;
    2648             :             }
    2649           0 :             FlowRatioSecWet = FlowRatioSec;
    2650           0 :             AirMassFlowSecWet = AirMassFlowSec;
    2651           0 :             EvapCoolerTotalElectricPowerWet = IndEvapCoolerPower(state, EvapCoolNum, OperatingMode::WetModulated, FlowRatioSecWet);
    2652             :             // compare the dry and wet operation total electric power
    2653           0 :             if (EvapCoolerTotalElectricPowerDry < EvapCoolerTotalElectricPowerWet) {
    2654           0 :                 thisEvapCond.EvapCoolerRDDOperatingMode = OperatingMode::DryModulated;
    2655           0 :                 FlowRatioSec = FlowRatioSecDry;
    2656           0 :                 thisEvapCond.SecInletMassFlowRate = AirMassFlowSecDry;
    2657           0 :                 CalcIndirectRDDEvapCoolerOutletTemp(
    2658             :                     state, EvapCoolNum, OperatingMode::DryModulated, AirMassFlowSecDry, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2659           0 :                 thisEvapCond.EvapCoolerPower = IndEvapCoolerPower(state, EvapCoolNum, OperatingMode::DryModulated, FlowRatioSec);
    2660           0 :                 thisEvapCond.IECOperatingStatus = 1;
    2661             :             } else {
    2662           0 :                 thisEvapCond.EvapCoolerRDDOperatingMode = OperatingMode::WetModulated;
    2663           0 :                 FlowRatioSec = FlowRatioSecWet;
    2664           0 :                 thisEvapCond.SecInletMassFlowRate = AirMassFlowSecWet;
    2665           0 :                 CalcIndirectRDDEvapCoolerOutletTemp(
    2666             :                     state, EvapCoolNum, OperatingMode::WetModulated, AirMassFlowSecWet, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2667           0 :                 thisEvapCond.EvapCoolerPower = IndEvapCoolerPower(state, EvapCoolNum, OperatingMode::WetModulated, FlowRatioSec);
    2668           0 :                 thisEvapCond.IECOperatingStatus = 2;
    2669             :             }
    2670       21196 :         } else if (thisEvapCond.EvapCoolerRDDOperatingMode == OperatingMode::WetModulated) {
    2671      212288 :             auto f = [&state, EvapCoolNum, SysTempSetPoint, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec](Real64 AirMassFlowSec) {
    2672      106144 :                 auto &EvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2673       53072 :                 EvapCond.SecInletMassFlowRate = AirMassFlowSec;
    2674       53072 :                 CalcIndirectRDDEvapCoolerOutletTemp(
    2675             :                     state, EvapCoolNum, OperatingMode::WetModulated, AirMassFlowSec, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2676       53072 :                 Real64 const OutletAirTemp = EvapCond.OutletTemp; // evap Coler outlet air temperature
    2677       53072 :                 return SysTempSetPoint - OutletAirTemp;
    2678        4508 :             };
    2679        4508 :             General::SolveRoot(state, TempTol, MaxIte, SolFla, AirMassFlowSec, f, MassFlowRateSecMin, MassFlowRateSecMax);
    2680             :             // if the numerical inversion failed, issue error messages.
    2681        4508 :             if (SolFla == -1) {
    2682           0 :                 if (!state.dataGlobal->WarmupFlag) {
    2683           0 :                     if (thisEvapCond.IterationLimit == 0) {
    2684           0 :                         ShowSevereError(state,
    2685             :                                         "CalcIndirectResearchSpecialEvapCooler: calculate secondary air mass flow failed for Indirect "
    2686           0 :                                         "Evaporative Cooler Research Special = " +
    2687             :                                             thisEvapCond.Name);
    2688           0 :                         ShowContinueErrorTimeStamp(state, "");
    2689           0 :                         ShowContinueError(state, format("  Iteration limit [{}] exceeded in calculating secondary air mass flow rate", MaxIte));
    2690           0 :                         ShowContinueError(state, "  Simulation continues");
    2691             :                     }
    2692           0 :                     ShowRecurringWarningErrorAtEnd(
    2693             :                         state,
    2694           0 :                         "Secondary air mass flow Iteration limit exceeded in Indirect Evaporative Cooler Research Special = " + thisEvapCond.Name,
    2695             :                         thisEvapCond.IterationLimit);
    2696             :                 }
    2697        4508 :             } else if (SolFla == -2) {
    2698           0 :                 if (!state.dataGlobal->WarmupFlag) {
    2699           0 :                     if (thisEvapCond.IterationFailed == 0) {
    2700           0 :                         ShowSevereError(state,
    2701             :                                         "CalcIndirectResearchSpecialEvapCooler: calculate secondary air mass flow failed for Indirect "
    2702           0 :                                         "Evaporative Cooler Research Special = " +
    2703             :                                             thisEvapCond.Name);
    2704           0 :                         ShowContinueErrorTimeStamp(state, "");
    2705           0 :                         ShowContinueError(state, "...Bad secondary air mass flow rate limits");
    2706           0 :                         ShowContinueError(state, format("...Given minimum secondary air mass flow rate={:.3R} kg/s", MassFlowRateSecMin));
    2707           0 :                         ShowContinueError(state, format("...Given maximum secondary air mass flow rate={:.3R} kg/s", MassFlowRateSecMax));
    2708           0 :                         ShowContinueError(state, " Simulation continues");
    2709             :                     }
    2710           0 :                     ShowRecurringWarningErrorAtEnd(state,
    2711           0 :                                                    "Secondary air mass flow control failed in Indirect Evaporative Cooler Research Special = " +
    2712             :                                                        thisEvapCond.Name,
    2713             :                                                    thisEvapCond.IterationFailed);
    2714             :                 }
    2715             :             }
    2716        4508 :             thisEvapCond.SecInletMassFlowRate = AirMassFlowSec;
    2717        4508 :             if (AirMassFlowSec > 0.0) {
    2718        4508 :                 if (MassFlowRateSecMax > 0.0) {
    2719        4508 :                     FlowRatioSec = AirMassFlowSec / MassFlowRateSecMax;
    2720             :                 } else {
    2721           0 :                     FlowRatioSec = 0.0;
    2722             :                 }
    2723             :             } else {
    2724           0 :                 FlowRatioSec = 0.0;
    2725             :             }
    2726        4508 :             thisEvapCond.EvapCoolerPower = IndEvapCoolerPower(state, EvapCoolNum, OperatingMode::WetModulated, FlowRatioSec);
    2727        4508 :             thisEvapCond.IECOperatingStatus = 2;
    2728       16688 :         } else if (thisEvapCond.EvapCoolerRDDOperatingMode == OperatingMode::WetFull) {
    2729         236 :             CalcIndirectRDDEvapCoolerOutletTemp(
    2730             :                 state, EvapCoolNum, OperatingMode::WetFull, MassFlowRateSecMax, InletDryBulbTempSec, InletWetBulbTempSec, InletHumRatioSec);
    2731         236 :             thisEvapCond.SecInletMassFlowRate = MassFlowRateSecMax;
    2732         236 :             FlowRatioSec = 1.0;
    2733         236 :             thisEvapCond.EvapCoolerPower = IndEvapCoolerPower(state, EvapCoolNum, OperatingMode::WetFull, FlowRatioSec);
    2734         236 :             thisEvapCond.IECOperatingStatus = 2;
    2735             :         }
    2736             :     }
    2737       34744 :     if (PartLoad == 1.0) {
    2738       15994 :         if (thisEvapCond.EvapCoolerRDDOperatingMode == OperatingMode::WetModulated ||
    2739        6824 :             thisEvapCond.EvapCoolerRDDOperatingMode == OperatingMode::WetFull) {
    2740        2582 :             BoundTemp = TEDB - thisEvapCond.DPBoundFactor * (TEDB - InletDewPointTempSec);
    2741        2582 :             if (thisEvapCond.OutletTemp < BoundTemp) {
    2742           0 :                 thisEvapCond.OutletTemp = BoundTemp;
    2743           0 :                 thisEvapCond.DewPointBoundFlag = 1;
    2744             :             }
    2745             :         }
    2746       25574 :     } else if ((PartLoad < 1.0) && (PartLoad > 0.0)) {
    2747             :         // assume perfect control Use PLF for energy consumption
    2748        5820 :         if (thisEvapCond.DesiredOutletTemp < TEDB) {
    2749        2910 :             thisEvapCond.OutletTemp = thisEvapCond.DesiredOutletTemp;
    2750             :         }
    2751             :     } else {
    2752             :         // part load set to zero so no cooling
    2753       22664 :         thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    2754             :     }
    2755       34744 :     if (thisEvapCond.EvapCoolerRDDOperatingMode != OperatingMode::None) {
    2756             :         // There is a constant humidity ratio across the primary side but a reduction in the dry bulb temp
    2757       18292 :         thisEvapCond.OuletWetBulbTemp =
    2758       36584 :             Psychrometrics::PsyTwbFnTdbWPb(state, thisEvapCond.OutletTemp, thisEvapCond.InletHumRat, state.dataEnvrn->OutBaroPress);
    2759       18292 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    2760       18292 :         thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    2761       18292 :         RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisEvapCond.InletTemp, thisEvapCond.InletHumRat);
    2762       18292 :         QHX = thisEvapCond.VolFlowRate * RhoAir * (thisEvapCond.InletEnthalpy - thisEvapCond.OutletEnthalpy);
    2763       18292 :         if (QHX > DataHVACGlobals::SmallLoad) {
    2764             :             // get secondary air outlet condition
    2765        6272 :             CalcSecondaryAirOutletCondition(state,
    2766             :                                             EvapCoolNum,
    2767             :                                             thisEvapCond.EvapCoolerRDDOperatingMode,
    2768             :                                             thisEvapCond.SecInletMassFlowRate,
    2769             :                                             InletDryBulbTempSec,
    2770             :                                             InletWetBulbTempSec,
    2771             :                                             InletHumRatioSec,
    2772             :                                             QHX,
    2773             :                                             QHXLatent);
    2774        6272 :             RhoWater = Psychrometrics::RhoH2O(state.dataEnvrn->OutDryBulbTemp); // this if it is at the outside air inlet node condition
    2775        6272 :             hfg = Psychrometrics::PsyHfgAirFnWTdb(InletHumRatioSec, InletDryBulbTempSec);
    2776        6272 :             EvapVdot = (QHXLatent) / (hfg * RhoWater);
    2777        6272 :             DriftVdot = EvapVdot * thisEvapCond.DriftFraction;
    2778        6272 :             if (thisEvapCond.BlowDownRatio > 0.0) {
    2779           0 :                 BlowDownVdot = EvapVdot / (thisEvapCond.BlowDownRatio - 1) - DriftVdot;
    2780           0 :                 if (BlowDownVdot < 0.0) BlowDownVdot = 0.0;
    2781             :             } else {
    2782        6272 :                 BlowDownVdot = 0.0;
    2783             :             }
    2784        6272 :             thisEvapCond.EvapWaterConsumpRate = EvapVdot + DriftVdot + BlowDownVdot;
    2785             :             // A numerical check to keep from having very tiny negative water consumption values being reported
    2786        6272 :             if (thisEvapCond.EvapWaterConsumpRate < 0.0) thisEvapCond.EvapWaterConsumpRate = 0.0;
    2787             :         } else {
    2788       12020 :             thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    2789       12020 :             thisEvapCond.OuletWetBulbTemp = thisEvapCond.InletWetBulbTemp;
    2790       12020 :             thisEvapCond.OutletEnthalpy = thisEvapCond.InletEnthalpy;
    2791       12020 :             thisEvapCond.EvapCoolerEnergy = 0.0;
    2792       12020 :             thisEvapCond.EvapCoolerPower = 0.0;
    2793       12020 :             thisEvapCond.EvapWaterConsumpRate = 0.0;
    2794       12020 :             thisEvapCond.SecInletMassFlowRate = 0.0;
    2795       12020 :             thisEvapCond.IECOperatingStatus = 0;
    2796       12020 :             thisEvapCond.StageEff = 0.0;
    2797       12020 :             CalcSecondaryAirOutletCondition(state,
    2798             :                                             EvapCoolNum,
    2799             :                                             thisEvapCond.EvapCoolerRDDOperatingMode,
    2800             :                                             0.0,
    2801             :                                             InletDryBulbTempSec,
    2802             :                                             InletWetBulbTempSec,
    2803             :                                             InletHumRatioSec,
    2804             :                                             QHX,
    2805             :                                             QHXLatent);
    2806             :         }
    2807             : 
    2808             :     } else {
    2809             :         // The evap cooler is not running and does not change conditions from inlet to outlet
    2810       16452 :         thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    2811       16452 :         thisEvapCond.OuletWetBulbTemp = thisEvapCond.InletWetBulbTemp;
    2812       16452 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    2813       16452 :         thisEvapCond.OutletEnthalpy = thisEvapCond.InletEnthalpy;
    2814       16452 :         thisEvapCond.SecOutletTemp = thisEvapCond.SecInletTemp;
    2815       16452 :         thisEvapCond.SecOutletHumRat = thisEvapCond.SecInletHumRat;
    2816       16452 :         thisEvapCond.SecOutletEnthalpy = thisEvapCond.SecInletEnthalpy;
    2817       16452 :         thisEvapCond.SecOutletMassFlowRate = thisEvapCond.SecInletMassFlowRate;
    2818       16452 :         thisEvapCond.EvapCoolerEnergy = 0.0;
    2819       16452 :         thisEvapCond.EvapCoolerPower = 0.0;
    2820       16452 :         thisEvapCond.EvapWaterConsumpRate = 0.0;
    2821       16452 :         thisEvapCond.SecInletMassFlowRate = 0.0;
    2822       16452 :         thisEvapCond.IECOperatingStatus = 0;
    2823       16452 :         thisEvapCond.StageEff = 0.0;
    2824             :     }
    2825       34744 : }
    2826             : 
    2827       34744 : OperatingMode IndirectResearchSpecialEvapCoolerOperatingMode(EnergyPlusData &state,
    2828             :                                                              int const EvapCoolNum,
    2829             :                                                              Real64 const InletDryBulbTempSec,
    2830             :                                                              Real64 const InletWetBulbTempSec,
    2831             :                                                              Real64 const TdbOutSysWetMin,
    2832             :                                                              Real64 const TdbOutSysDryMin)
    2833             : {
    2834             : 
    2835             :     // PURPOSE OF THIS SUBROUTINE:
    2836             :     // Determines current operating mode of indirect research special evaporative cooler
    2837             :     // from the five valid operating modes depending the primary and secondary air
    2838             :     // temperatures, setpoint temperature, and full capacity air outlet temperature.
    2839             : 
    2840             :     // METHODOLOGY EMPLOYED:
    2841             :     // compares various temperatures to determine the operating mode
    2842             : 
    2843             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2844             :     Real64 InletDryBulbTempPri;  // entering air dry bulb temperature of primary air
    2845             :     Real64 SysTempSetPoint;      // evaporative cooler outlet setpoint temperature, drybulb
    2846             :     OperatingMode OperatingMode; // current operating mode of indrect evaporative cooler
    2847             : 
    2848       34744 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2849             : 
    2850       34744 :     InletDryBulbTempPri = thisEvapCond.InletTemp;
    2851       34744 :     SysTempSetPoint = thisEvapCond.DesiredOutletTemp;
    2852             : 
    2853             :     // Now determine the operating modes of indirect evaporative cooler research special. There are five allowed operating modes
    2854       64652 :     if ((InletDryBulbTempPri <= SysTempSetPoint) ||
    2855       42176 :         (InletDryBulbTempPri > thisEvapCond.MaxOATDBEvapCooler && InletWetBulbTempSec > thisEvapCond.MaxOATWBEvapCooler) ||
    2856             :         (InletDryBulbTempPri < InletDryBulbTempSec)) {
    2857       16452 :         OperatingMode = OperatingMode::None;
    2858       18292 :     } else if ((InletDryBulbTempSec < thisEvapCond.MinOATDBEvapCooler && TdbOutSysDryMin < SysTempSetPoint)) {
    2859       13540 :         OperatingMode = OperatingMode::DryModulated; // dry mode capacity modulated
    2860        4752 :     } else if ((InletDryBulbTempSec < thisEvapCond.MinOATDBEvapCooler && SysTempSetPoint <= TdbOutSysDryMin)) {
    2861           8 :         OperatingMode = OperatingMode::DryFull; // dry mode in full capacity
    2862        4744 :     } else if ((InletDryBulbTempSec >= thisEvapCond.MinOATDBEvapCooler && InletWetBulbTempSec < thisEvapCond.MaxOATWBEvapCooler &&
    2863             :                 SysTempSetPoint <= TdbOutSysWetMin)) {
    2864         236 :         OperatingMode = OperatingMode::WetFull; // wet mode in full capacity
    2865        4508 :     } else if ((InletDryBulbTempSec >= thisEvapCond.MinOATDBEvapCooler && InletWetBulbTempSec < thisEvapCond.MaxOATWBEvapCooler &&
    2866             :                 TdbOutSysWetMin < SysTempSetPoint)) { // && SysTempSetPoint < TdbOutSysDryMin
    2867        4508 :         OperatingMode = OperatingMode::WetModulated;  // wet mode capacity modulated
    2868           0 :     } else if ((InletDryBulbTempSec >= thisEvapCond.MinOATDBEvapCooler && InletDryBulbTempSec < thisEvapCond.MaxOATDBEvapCooler &&
    2869           0 :                 InletWetBulbTempSec < thisEvapCond.MaxOATWBEvapCooler && SysTempSetPoint < TdbOutSysDryMin && TdbOutSysWetMin < SysTempSetPoint)) {
    2870           0 :         OperatingMode = OperatingMode::DryWetModulated; // modulated in dry and wet mode, and the lower total power will be used
    2871             :     } else {
    2872           0 :         OperatingMode = OperatingMode::None; // this condition should not happen unless the bounds do not cover all combinations possible
    2873             :     }
    2874       34744 :     return OperatingMode;
    2875             : }
    2876             : 
    2877      170606 : void CalcIndirectRDDEvapCoolerOutletTemp(EnergyPlusData &state,
    2878             :                                          int const EvapCoolNum,
    2879             :                                          OperatingMode DryOrWetOperatingMode,
    2880             :                                          Real64 const AirMassFlowSec,
    2881             :                                          Real64 const EDBTSec,
    2882             :                                          Real64 const EWBTSec,
    2883             :                                          Real64 const EHumRatSec)
    2884             : {
    2885             :     // SUBROUTINE INFORMATION:
    2886             :     //       AUTHOR         B. Nigusse
    2887             :     //       DATE WRITTEN   Sep 2014
    2888             :     //       MODIFIED       na
    2889             :     //       RE-ENGINEERED  na
    2890             : 
    2891             :     // PURPOSE OF THIS SUBROUTINE:
    2892             :     // Indirect research special evaporative cooler perfomance:
    2893             :     // determines the IEC primary air outlet temperature
    2894             : 
    2895             :     // METHODOLOGY EMPLOYED:
    2896             :     // Uses effectiveness and energy balance equations to determine
    2897             :     // primary air outlet temperature.  The dry and wet effectiveness
    2898             :     // values are used depending on operating modes.
    2899             : 
    2900             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2901             :     Real64 OutletTemp;       // evaporative cooler current outlet air drybulb temperature
    2902             :     Real64 RhoAirSec;        // density of secondary air at inlet condition
    2903             :     Real64 RhoAirSys;        // density of primary air at inlet condition
    2904             :     Real64 EffectivenessDry; // dry coil effectiveness
    2905             :     Real64 EffectivenessWet; // wet coil effectiveness
    2906             :     Real64 FlowRatio;        // flow ratio based on current to the design of secondary air flow rate
    2907             :     Real64 EffModDryMode;    // dry mode effectiveness modifier for flow ratio
    2908             :     Real64 EffModWetMode;    // wet mode effectiveness modifier for flow ratio
    2909             :     Real64 CapFlowSys;       // capacity flow (massFlowRate * Specific Heat) of primary air system
    2910             :     Real64 CapFlowSec;       // capacity flow (massFlowRate * Specific Heat) of secondary system
    2911             :     Real64 CpAirSec;         // specific heat of secondary air at inlet condition
    2912             :     Real64 CpAirSys;         // specific heat of primary air at inlet condition
    2913             : 
    2914             :     Real64 QHXRate;            // total heat transfer rate
    2915             :     Real64 OutletTempSec;      // secondary air outlet temperature
    2916             :     Real64 SecOutletAirHumRat; // secondary air humidity ratio at constant temperature (Pure mass transfer)
    2917             :     Real64 SecOutletEnthalpy;  // secondary air outlet enthalpy
    2918             : 
    2919      170606 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    2920             : 
    2921      170606 :     if (thisEvapCond.InletMassFlowRate > 0.0) {
    2922      170606 :         FlowRatio = AirMassFlowSec / thisEvapCond.InletMassFlowRate; // ratio of current secondary air flow to current primary air flow
    2923             :     } else {
    2924           0 :         FlowRatio = 1.0;
    2925             :     }
    2926      170606 :     if (AirMassFlowSec > 0.0) {
    2927      152558 :         RhoAirSec = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EDBTSec, EHumRatSec);
    2928      152558 :         RhoAirSys = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisEvapCond.InletTemp, thisEvapCond.InletHumRat);
    2929      152558 :         if (DryOrWetOperatingMode == OperatingMode::DryModulated || DryOrWetOperatingMode == OperatingMode::DryFull) {
    2930       69014 :             if (thisEvapCond.DrybulbEffecCurveIndex > 0) {
    2931       69014 :                 EffModDryMode = Curve::CurveValue(state, thisEvapCond.DrybulbEffecCurveIndex, FlowRatio);
    2932             :             } else {
    2933           0 :                 EffModDryMode = 1.0;
    2934             :             }
    2935       69014 :             EffectivenessDry = thisEvapCond.DryCoilMaxEfficiency * EffModDryMode;
    2936       69014 :             thisEvapCond.StageEff = EffectivenessDry;
    2937       69014 :             OutletTemp = thisEvapCond.InletTemp - EffectivenessDry * (thisEvapCond.InletTemp - EDBTSec);
    2938       69014 :             if (OutletTemp > thisEvapCond.InletTemp) {
    2939       11646 :                 OutletTemp = thisEvapCond.InletTemp;
    2940             :             }
    2941       69014 :             CpAirSys = Psychrometrics::PsyCpAirFnW(thisEvapCond.InletHumRat);
    2942       69014 :             CapFlowSys = thisEvapCond.InletMassFlowRate * CpAirSys;
    2943       69014 :             QHXRate = CapFlowSys * (thisEvapCond.InletTemp - OutletTemp);
    2944       69014 :             CpAirSec = Psychrometrics::PsyCpAirFnW(EHumRatSec);
    2945       69014 :             CapFlowSec = AirMassFlowSec * CpAirSec;
    2946       69014 :             OutletTempSec = EDBTSec + QHXRate / CapFlowSec;
    2947       69014 :             if (OutletTempSec >= thisEvapCond.InletTemp) {
    2948       25850 :                 OutletTempSec = thisEvapCond.InletTemp - 0.2;
    2949       25850 :                 QHXRate = CapFlowSec * (OutletTempSec - EDBTSec);
    2950       25850 :                 OutletTemp = thisEvapCond.InletTemp - QHXRate / CapFlowSys;
    2951             :             }
    2952       69014 :             thisEvapCond.SecOutletTemp = OutletTempSec;
    2953       83544 :         } else if (DryOrWetOperatingMode == OperatingMode::WetModulated || DryOrWetOperatingMode == OperatingMode::WetFull) {
    2954       83544 :             if (thisEvapCond.WetbulbEffecCurveIndex > 0) {
    2955       83544 :                 EffModWetMode = Curve::CurveValue(state, thisEvapCond.WetbulbEffecCurveIndex, FlowRatio);
    2956             :             } else {
    2957           0 :                 EffModWetMode = 1.0;
    2958             :             }
    2959       83544 :             EffectivenessWet = thisEvapCond.WetCoilMaxEfficiency * EffModWetMode;
    2960       83544 :             thisEvapCond.StageEff = EffectivenessWet;
    2961       83544 :             OutletTemp = thisEvapCond.InletTemp - EffectivenessWet * (thisEvapCond.InletTemp - EWBTSec);
    2962       83544 :             if (OutletTemp > thisEvapCond.InletTemp) {
    2963       11530 :                 OutletTemp = thisEvapCond.InletTemp;
    2964             :             }
    2965       83544 :             CpAirSys = Psychrometrics::PsyCpAirFnW(thisEvapCond.InletHumRat);
    2966       83544 :             CapFlowSys = thisEvapCond.InletMassFlowRate * CpAirSys;
    2967       83544 :             QHXRate = CapFlowSys * (thisEvapCond.InletTemp - OutletTemp);
    2968       83544 :             SecOutletEnthalpy = thisEvapCond.SecInletEnthalpy + QHXRate / AirMassFlowSec;
    2969       83544 :             SecOutletAirHumRat = Psychrometrics::PsyWFnTdbH(state, EDBTSec, SecOutletEnthalpy); // assumes constant temperature moisture addition
    2970             :             // we may need check based on maximum allowed humidity ratio
    2971       83544 :             thisEvapCond.SecOutletTemp = EDBTSec;
    2972       83544 :             thisEvapCond.SecOutletHumRat = SecOutletAirHumRat;
    2973       83544 :             thisEvapCond.SecOutletEnthalpy = SecOutletEnthalpy;
    2974             :         } else {
    2975           0 :             OutletTemp = thisEvapCond.InletTemp;
    2976           0 :             thisEvapCond.StageEff = 0.0;
    2977             :         }
    2978             :     } else {
    2979       18048 :         OutletTemp = thisEvapCond.InletTemp;
    2980       18048 :         thisEvapCond.StageEff = 0.0;
    2981             :     }
    2982             :     // set results to into output variables
    2983      170606 :     thisEvapCond.OutletTemp = OutletTemp;
    2984      170606 : }
    2985             : 
    2986       18292 : void CalcSecondaryAirOutletCondition(EnergyPlusData &state,
    2987             :                                      int const EvapCoolNum,
    2988             :                                      OperatingMode OperatingMode,
    2989             :                                      Real64 const AirMassFlowSec,
    2990             :                                      Real64 const EDBTSec,
    2991             :                                      Real64 const EWBTSec,
    2992             :                                      Real64 const EHumRatSec,
    2993             :                                      Real64 const QHXTotal,
    2994             :                                      Real64 &QHXLatent)
    2995             : {
    2996             :     // SUBROUTINE INFORMATION:
    2997             :     //       AUTHOR         B. Nigusse
    2998             :     //       DATE WRITTEN   Oct 2014
    2999             :     //       MODIFIED       na
    3000             :     //       RE-ENGINEERED  na
    3001             : 
    3002             :     // PURPOSE OF THIS SUBROUTINE:
    3003             :     // Indirect research special evaporative cooler: determines the secondary air outlet conditions
    3004             : 
    3005             :     // METHODOLOGY EMPLOYED:
    3006             :     // applies energy balance equations to determine the secondary air outlet condition
    3007             :     // For wt operations assumes the secondary air leaves at at inlet temperature, i.e.,
    3008             :     // latent heat transfer only.  For dry operation the humdity ratio remains constant.
    3009             : 
    3010             :     // REFERENCES:
    3011             :     // CalculateWaterUsage routine of cooling towers for wet operation mode
    3012             : 
    3013             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3014             :     Real64 SecOutletAirHumRat; // secondary air humidity ratio at the outlet node
    3015             :     Real64 SecOutletEnthalpy;  // secondary air outlet enthalpy
    3016             :     Real64 CpAirSec;           // specific heat of secondary air at inlet condition
    3017             :     Real64 hfg;                // secondary air side enthaly of evaporation
    3018             : 
    3019       18292 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    3020             : 
    3021       18292 :     QHXLatent = 0.0;
    3022       18292 :     if (AirMassFlowSec > 0.0) {
    3023        6272 :         if ((OperatingMode == OperatingMode::DryModulated || OperatingMode == OperatingMode::DryFull)) {
    3024        1528 :             thisEvapCond.SecOutletHumRat = EHumRatSec;
    3025        1528 :             CpAirSec = Psychrometrics::PsyCpAirFnW(EHumRatSec);
    3026        1528 :             thisEvapCond.SecOutletTemp = EDBTSec + QHXTotal / AirMassFlowSec / CpAirSec;
    3027        1528 :             thisEvapCond.SecOutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.SecOutletTemp, EHumRatSec);
    3028        3056 :             thisEvapCond.SecOuletWetBulbTemp =
    3029        3056 :                 Psychrometrics::PsyTwbFnTdbWPb(state, thisEvapCond.SecOutletTemp, EHumRatSec, state.dataEnvrn->OutBaroPress);
    3030        4744 :         } else if ((OperatingMode == OperatingMode::WetModulated || OperatingMode == OperatingMode::WetFull)) {
    3031        4744 :             SecOutletEnthalpy = thisEvapCond.SecInletEnthalpy + QHXTotal / AirMassFlowSec;
    3032        4744 :             SecOutletAirHumRat = Psychrometrics::PsyWFnTdbH(state, EDBTSec, SecOutletEnthalpy); // assumes a constant temperature moisture addition
    3033        4744 :             thisEvapCond.SecOutletTemp = EDBTSec;
    3034        4744 :             thisEvapCond.SecOutletHumRat = SecOutletAirHumRat;
    3035        4744 :             thisEvapCond.SecOutletEnthalpy = SecOutletEnthalpy;
    3036        4744 :             thisEvapCond.SecOuletWetBulbTemp =
    3037        9488 :                 Psychrometrics::PsyTwbFnTdbWPb(state, thisEvapCond.SecOutletTemp, SecOutletAirHumRat, state.dataEnvrn->OutBaroPress);
    3038        4744 :             hfg = Psychrometrics::PsyHfgAirFnWTdb(EHumRatSec, EDBTSec);
    3039        4744 :             QHXLatent = min(QHXTotal, AirMassFlowSec * (SecOutletAirHumRat - EHumRatSec) * hfg);
    3040             :         } else {
    3041             :             // set results to into output variables
    3042           0 :             thisEvapCond.SecOutletTemp = EDBTSec;
    3043           0 :             thisEvapCond.SecOuletWetBulbTemp = EWBTSec;
    3044           0 :             thisEvapCond.SecOutletHumRat = EHumRatSec;
    3045           0 :             thisEvapCond.SecOutletEnthalpy = thisEvapCond.SecInletEnthalpy;
    3046             :         }
    3047             :     } else {
    3048       12020 :         thisEvapCond.SecOutletTemp = EDBTSec;
    3049       12020 :         thisEvapCond.SecOuletWetBulbTemp = EWBTSec;
    3050       12020 :         thisEvapCond.SecOutletHumRat = EHumRatSec;
    3051       12020 :         thisEvapCond.SecOutletEnthalpy = thisEvapCond.SecInletEnthalpy;
    3052             :     }
    3053       18292 : }
    3054             : 
    3055       18292 : Real64 IndEvapCoolerPower(EnergyPlusData &state,
    3056             :                           int const EvapCoolIndex,  // Unit index
    3057             :                           OperatingMode DryWetMode, // dry or wet operating mode of evaporator cooler
    3058             :                           Real64 const FlowRatio    // secondary air flow fraction
    3059             : )
    3060             : {
    3061             : 
    3062             :     // SUBROUTINE INFORMATION:
    3063             :     //       AUTHOR         B. Nigusse
    3064             :     //       DATE WRITTEN   Sep 2014
    3065             :     //       MODIFIED       na
    3066             :     //       RE-ENGINEERED  na
    3067             : 
    3068             :     // PURPOSE OF THIS SUBROUTINE:
    3069             :     // Calculates the Indirect Evaporative Cooler Total Electric Power
    3070             : 
    3071             :     // METHODOLOGY EMPLOYED:
    3072             :     // Scales the design fan and pump power depending on secondary air flow fraction
    3073             :     // and sums the two to determine the evaporative cooler total electric power.
    3074             : 
    3075             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3076             :     Real64 FanPowerModCurveValue;  // fan power modifier curve value
    3077             :     Real64 PumpPowerModCurveValue; // fan power modifier curve value
    3078             :     Real64 EvapCoolertotalPower;   // current evaporative cooler total electric power
    3079             : 
    3080       18292 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolIndex));
    3081             : 
    3082       18292 :     EvapCoolertotalPower = 0.0;
    3083       18292 :     if (FlowRatio > 0.0) {
    3084       18292 :         if (thisEvapCond.FanPowerModifierCurveIndex > 0) {
    3085       18292 :             FanPowerModCurveValue = Curve::CurveValue(state, thisEvapCond.FanPowerModifierCurveIndex, FlowRatio);
    3086             :         } else {
    3087           0 :             FanPowerModCurveValue = thisEvapCond.PartLoadFract * FlowRatio;
    3088             :         }
    3089       18292 :         EvapCoolertotalPower += thisEvapCond.IndirectFanPower * FanPowerModCurveValue;
    3090       18292 :         if (DryWetMode == OperatingMode::WetModulated || DryWetMode == OperatingMode::WetFull) {
    3091             :             // Add the pump power to the total Evap Cooler power for wet operating mode
    3092        4744 :             if (thisEvapCond.PumpPowerModifierCurveIndex > 0) {
    3093        4744 :                 PumpPowerModCurveValue = Curve::CurveValue(state, thisEvapCond.PumpPowerModifierCurveIndex, FlowRatio);
    3094             :             } else {
    3095             :                 // linearly scale pump power using part-load-fraction when pump power modifier curve is not specified
    3096           0 :                 PumpPowerModCurveValue = thisEvapCond.PartLoadFract * FlowRatio;
    3097             :             }
    3098        4744 :             EvapCoolertotalPower += thisEvapCond.IndirectRecircPumpPower * PumpPowerModCurveValue;
    3099             :         }
    3100             :     } else {
    3101           0 :         EvapCoolertotalPower = 0.0;
    3102             :     }
    3103       18292 :     return EvapCoolertotalPower;
    3104             : }
    3105             : 
    3106     2684809 : void CalcDirectResearchSpecialEvapCooler(EnergyPlusData &state, int const EvapCoolNum, Real64 const FanPLR)
    3107             : {
    3108             : 
    3109             :     // SUBROUTINE INFORMATION:
    3110             :     //       AUTHOR         B. Griffith
    3111             :     //       DATE WRITTEN   March 2009
    3112             :     //       MODIFIED       na
    3113             :     //       RE-ENGINEERED  na
    3114             : 
    3115             :     // PURPOSE OF THIS SUBROUTINE:
    3116             :     // calculate model for direct evaporative cooler that is simple and controllable
    3117             : 
    3118             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3119             :     Real64 SatEff; // Saturation Efficiency of the CelDek Pad
    3120             :     Real64 TEDB;   // Entering Dry Bulb Temperature
    3121             :     Real64 TEWB;   // Entering Wet Bulb Temperature
    3122             :     Real64 RhoWater;
    3123             :     Real64 PartLoad;
    3124             :     Real64 EffModCurveValue;       // effectiveness modifier curve value
    3125             :     Real64 PumpPowerModCurveValue; // recirculation pump power modifier curve value
    3126     2684809 :     Real64 FlowRatio(0);           // primary air flow frcation (current flow divided by the design flow rate)
    3127             :     Real64 MassFlowRateSysDesign;  // primary air design mass flow rate
    3128             :     Real64 MassFlowRateSys;        // primary air current mass flow rate
    3129             :     int InletNode;                 // inlet node number
    3130     2684809 :     Real64 BlowDownVdot(0.0);
    3131     2684809 :     Real64 DriftVdot(0.0);
    3132     2684809 :     Real64 EvapVdot(0.0);
    3133     2684809 :     bool EvapCoolerOperatingLimitFlag(false);
    3134             : 
    3135     2684809 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    3136             : 
    3137     2684809 :     EvapCoolerOperatingLimitFlag = false;
    3138     2684809 :     TEDB = thisEvapCond.InletTemp;
    3139     2684809 :     TEWB = thisEvapCond.InletWetBulbTemp;
    3140     2684809 :     if (thisEvapCond.EvapCoolerOperationControlFlag) {
    3141       34824 :         if (TEDB >= thisEvapCond.MinOATDBEvapCooler && (TEWB <= thisEvapCond.MaxOATWBEvapCooler || TEDB <= thisEvapCond.MaxOATDBEvapCooler)) {
    3142       24710 :             EvapCoolerOperatingLimitFlag = true;
    3143             :         }
    3144             :     } else {
    3145     2649985 :         EvapCoolerOperatingLimitFlag = true;
    3146             :     }
    3147             : 
    3148             :     // If the Evaporative Cooler  is operating there should be some mass flow rate
    3149             :     //  Also the evap cooler has to be scheduled to be available
    3150     2684809 :     if ((thisEvapCond.InletMassFlowRate > 0.0) && (ScheduleManager::GetCurrentScheduleValue(state, thisEvapCond.SchedPtr) > 0.0) &&
    3151             :         EvapCoolerOperatingLimitFlag) {
    3152             : 
    3153             :         //***************************************************************************
    3154             :         //   TEMP LEAVING DRY BULB IS CALCULATED FROM SATURATION EFFICIENCY AS THE
    3155             :         //   DRY BULB TEMP APPROACHES THE WET BULB TEMP. WET BULB TEMP IS CONSTANT
    3156             :         //   ACROSS A DIRECT EVAPORATION COOLER.
    3157     2643195 :         TEWB = thisEvapCond.InletWetBulbTemp;
    3158     2643195 :         TEDB = thisEvapCond.InletTemp;
    3159     2643195 :         InletNode = thisEvapCond.InletNode;
    3160             : 
    3161     2643195 :         MassFlowRateSys = thisEvapCond.InletMassFlowRate;
    3162     2643195 :         MassFlowRateSysDesign = state.dataLoopNodes->Node(InletNode).MassFlowRateMax;
    3163     2643195 :         if (MassFlowRateSysDesign > 0.0) {
    3164      680760 :             if (MassFlowRateSys > 0.0) {
    3165      680760 :                 FlowRatio = MassFlowRateSys / MassFlowRateSysDesign;
    3166             :             } else {
    3167           0 :                 FlowRatio = 1.0;
    3168             :             }
    3169             :         }
    3170     2643195 :         if (thisEvapCond.WetbulbEffecCurveIndex > 0) {
    3171           0 :             EffModCurveValue = Curve::CurveValue(state, thisEvapCond.WetbulbEffecCurveIndex, FlowRatio);
    3172             :         } else {
    3173             :             // if no curve specified assume constant effectiveness
    3174     2643195 :             EffModCurveValue = 1.0;
    3175             :         }
    3176     2643195 :         SatEff = thisEvapCond.DirectEffectiveness * EffModCurveValue;
    3177     2643195 :         thisEvapCond.StageEff = SatEff;
    3178     2643195 :         PartLoad = thisEvapCond.PartLoadFract;
    3179     2643195 :         if (PartLoad == 1.0) {
    3180     2578909 :             thisEvapCond.OutletTemp = TEDB - ((TEDB - TEWB) * SatEff);
    3181     2578909 :             thisEvapCond.OuletWetBulbTemp = TEWB;
    3182     2578909 :             thisEvapCond.OutletHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, thisEvapCond.OutletTemp, TEWB, state.dataEnvrn->OutBaroPress);
    3183     2578909 :             thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    3184       64286 :         } else if ((PartLoad < 1.0) && (PartLoad > 0.0)) {
    3185             :             // assume perfect control Use PLF for energy consumption
    3186        1934 :             if (thisEvapCond.DesiredOutletTemp < TEDB) {
    3187         967 :                 thisEvapCond.OutletTemp = thisEvapCond.DesiredOutletTemp;
    3188         967 :                 thisEvapCond.OuletWetBulbTemp = TEWB;
    3189         967 :                 thisEvapCond.OutletHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, thisEvapCond.OutletTemp, TEWB, state.dataEnvrn->OutBaroPress);
    3190             : 
    3191         967 :                 thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    3192             :             } else { // do no cooling
    3193           0 :                 thisEvapCond.OutletTemp = TEDB;
    3194           0 :                 thisEvapCond.OuletWetBulbTemp = TEWB;
    3195           0 :                 thisEvapCond.OutletHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, thisEvapCond.OutletTemp, TEWB, state.dataEnvrn->OutBaroPress);
    3196           0 :                 thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    3197             :             }
    3198             :         } else {
    3199             :             // part load set to zero so no cooling
    3200       63319 :             thisEvapCond.OutletTemp = TEDB;
    3201       63319 :             thisEvapCond.OuletWetBulbTemp = TEWB;
    3202       63319 :             thisEvapCond.OutletHumRat = Psychrometrics::PsyWFnTdbTwbPb(state, thisEvapCond.OutletTemp, TEWB, state.dataEnvrn->OutBaroPress);
    3203       63319 :             thisEvapCond.OutletEnthalpy = Psychrometrics::PsyHFnTdbW(thisEvapCond.OutletTemp, thisEvapCond.OutletHumRat);
    3204             :         }
    3205             : 
    3206             :         //***************************************************************************
    3207             :         //                  ENERGY CONSUMED BY THE RECIRCULATING PUMP
    3208             :         // Add the pump energy to the total Evap Cooler energy comsumption
    3209     2643195 :         if (thisEvapCond.PumpPowerModifierCurveIndex > 0) {
    3210           0 :             PumpPowerModCurveValue = Curve::CurveValue(state, thisEvapCond.PumpPowerModifierCurveIndex, FlowRatio);
    3211             :         } else {
    3212             :             // if no pump power modifier curve specified, then assume linear variation with part-load and primary fan PLR
    3213     2643195 :             PumpPowerModCurveValue = PartLoad * FanPLR;
    3214             :         }
    3215     2643195 :         thisEvapCond.EvapCoolerPower = thisEvapCond.RecircPumpPower * PumpPowerModCurveValue;
    3216             :         //******************
    3217             :         //             WATER CONSUMPTION IN m3 OF WATER FOR DIRECT
    3218             :         //             H2O [m3/s] = Delta W[kgWater/kgDryAir]*Mass Flow Air[kgDryAir]
    3219             :         //                                /RhoWater [kgWater/m3]
    3220             :         //******************
    3221     2643195 :         RhoWater = Psychrometrics::RhoH2O(thisEvapCond.OutletTemp);
    3222     2643195 :         EvapVdot = (thisEvapCond.OutletHumRat - thisEvapCond.InletHumRat) * thisEvapCond.InletMassFlowRate / RhoWater;
    3223     2643195 :         DriftVdot = EvapVdot * thisEvapCond.DriftFraction;
    3224             : 
    3225     2643195 :         if (thisEvapCond.BlowDownRatio > 0.0) {
    3226     2643195 :             BlowDownVdot = EvapVdot / (thisEvapCond.BlowDownRatio - 1.0) - DriftVdot;
    3227     2643195 :             if (BlowDownVdot < 0.0) BlowDownVdot = 0.0;
    3228             :         } else {
    3229           0 :             BlowDownVdot = 0.0;
    3230             :         }
    3231             : 
    3232     2643195 :         thisEvapCond.EvapWaterConsumpRate = EvapVdot + DriftVdot + BlowDownVdot;
    3233             : 
    3234             :         // A numerical check to keep from having very tiny negative water consumption values being reported
    3235     2643195 :         if (thisEvapCond.EvapWaterConsumpRate < 0.0) thisEvapCond.EvapWaterConsumpRate = 0.0;
    3236             : 
    3237             :     } else {
    3238             :         // The evap cooler is not running and does not change conditions from inlet to outlet
    3239       41614 :         thisEvapCond.OutletTemp = thisEvapCond.InletTemp;
    3240             : 
    3241       41614 :         thisEvapCond.OuletWetBulbTemp = thisEvapCond.InletWetBulbTemp;
    3242             : 
    3243       41614 :         thisEvapCond.OutletHumRat = thisEvapCond.InletHumRat;
    3244             : 
    3245       41614 :         thisEvapCond.OutletEnthalpy = thisEvapCond.InletEnthalpy;
    3246       41614 :         thisEvapCond.EvapCoolerPower = 0.0;
    3247       41614 :         thisEvapCond.EvapCoolerEnergy = 0.0;
    3248             : 
    3249       41614 :         thisEvapCond.EvapWaterConsumpRate = 0.0;
    3250             :     }
    3251             :     // all of the mass flowrates are not changed across the evap cooler
    3252     2684809 :     thisEvapCond.OutletMassFlowRate = thisEvapCond.InletMassFlowRate;
    3253     2684809 :     thisEvapCond.OutletMassFlowRateMaxAvail = thisEvapCond.InletMassFlowRateMaxAvail;
    3254     2684809 :     thisEvapCond.OutletMassFlowRateMinAvail = thisEvapCond.InletMassFlowRateMinAvail;
    3255             : 
    3256             :     // the pressure is not changed across the evap cooler
    3257     2684809 :     thisEvapCond.OutletPressure = thisEvapCond.InletPressure;
    3258     2684809 : }
    3259             : 
    3260     5196305 : void UpdateEvapCooler(EnergyPlusData &state, int const EvapCoolNum)
    3261             : {
    3262             : 
    3263             :     // SUBROUTINE INFORMATION:
    3264             :     //       AUTHOR         Richard J. Liesen
    3265             :     //       DATE WRITTEN   October 2000
    3266             :     //       MODIFIED       na
    3267             :     //       RE-ENGINEERED  na
    3268             : 
    3269     5196305 :     auto &thisEvapCond = state.dataEvapCoolers->EvapCond(EvapCoolNum);
    3270     5196305 :     auto &thisOutletNode = state.dataLoopNodes->Node(thisEvapCond.OutletNode);
    3271     5196305 :     auto &thisInletNode = state.dataLoopNodes->Node(thisEvapCond.InletNode);
    3272             : 
    3273             :     // Set the outlet air nodes of the EvapCooler
    3274     5196305 :     thisOutletNode.MassFlowRate = thisEvapCond.OutletMassFlowRate;
    3275     5196305 :     thisOutletNode.MassFlowRateMaxAvail = thisEvapCond.OutletMassFlowRateMaxAvail;
    3276     5196305 :     thisOutletNode.MassFlowRateMinAvail = thisEvapCond.OutletMassFlowRateMinAvail;
    3277     5196305 :     thisOutletNode.Temp = thisEvapCond.OutletTemp;
    3278     5196305 :     thisOutletNode.HumRat = thisEvapCond.OutletHumRat;
    3279     5196305 :     thisOutletNode.Enthalpy = thisEvapCond.OutletEnthalpy;
    3280     5196305 :     thisOutletNode.Press = thisEvapCond.OutletPressure;
    3281             : 
    3282     5196305 :     if (thisEvapCond.SecondaryOutletNode > 0) {
    3283     2156668 :         auto &thisOutletNodeSec = state.dataLoopNodes->Node(thisEvapCond.SecondaryOutletNode);
    3284             :         // set outlet nodes of the secondary air side of the EvapCooler (mass Flow Rate Only)
    3285     2156668 :         if (thisEvapCond.evapCoolerType == EvapCoolerType::IndirectRDDSpecial && thisEvapCond.EvapCoolerOperationControlFlag) {
    3286       34744 :             thisOutletNodeSec.Temp = thisEvapCond.SecOutletTemp;
    3287       34744 :             thisOutletNodeSec.HumRat = thisEvapCond.SecOutletHumRat;
    3288       34744 :             thisOutletNodeSec.Enthalpy = thisEvapCond.SecOutletEnthalpy;
    3289       34744 :             thisOutletNodeSec.MassFlowRate = thisEvapCond.SecOutletMassFlowRate;
    3290             :         }
    3291             :     }
    3292             : 
    3293             :     // Set the outlet nodes for properties that just pass through & not used
    3294     5196305 :     thisOutletNode.Quality = thisInletNode.Quality;
    3295             : 
    3296             :     // Set the demand request for supply water from water storage tank (if needed)
    3297     5196305 :     if (thisEvapCond.EvapWaterSupplyMode == WaterSupply::FromTank) {
    3298           0 :         state.dataWaterData->WaterStorage(thisEvapCond.EvapWaterSupTankID).VdotRequestDemand(thisEvapCond.EvapWaterTankDemandARRID) =
    3299           0 :             thisEvapCond.EvapWaterConsumpRate;
    3300             :     }
    3301             : 
    3302             :     // check if should be starved by restricted flow from tank
    3303     5196305 :     if (thisEvapCond.EvapWaterSupplyMode == WaterSupply::FromTank) {
    3304             :         Real64 AvailWaterRate =
    3305           0 :             state.dataWaterData->WaterStorage(thisEvapCond.EvapWaterSupTankID).VdotAvailDemand(thisEvapCond.EvapWaterTankDemandARRID);
    3306           0 :         if (AvailWaterRate < thisEvapCond.EvapWaterConsumpRate) {
    3307           0 :             thisEvapCond.EvapWaterStarvMakupRate = thisEvapCond.EvapWaterConsumpRate - AvailWaterRate;
    3308           0 :             thisEvapCond.EvapWaterConsumpRate = AvailWaterRate;
    3309             :         } else {
    3310           0 :             thisEvapCond.EvapWaterStarvMakupRate = 0.0;
    3311             :         }
    3312             :     }
    3313             : 
    3314     5196305 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    3315           0 :         thisOutletNode.CO2 = thisInletNode.CO2;
    3316             :     }
    3317             : 
    3318     5196305 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    3319           0 :         thisOutletNode.GenContam = thisInletNode.GenContam;
    3320             :     }
    3321     5196305 : }
    3322             : 
    3323     2882159 : void ReportEvapCooler(EnergyPlusData &state, int const EvapCoolNum)
    3324             : {
    3325             : 
    3326             :     // SUBROUTINE INFORMATION:
    3327             :     //       AUTHOR         Richard J. Liesen
    3328             :     //       DATE WRITTEN   Oct 2000
    3329             :     //       MODIFIED       na
    3330             :     //       RE-ENGINEERED  na
    3331             : 
    3332     2882159 :     auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    3333     2882159 :     auto &thisEvapCond(state.dataEvapCoolers->EvapCond(EvapCoolNum));
    3334             : 
    3335             :     // report the Evap Cooler energy from this component
    3336     2882159 :     thisEvapCond.EvapCoolerPower = thisEvapCond.EvapCoolerPower;
    3337     2882159 :     thisEvapCond.EvapCoolerEnergy = thisEvapCond.EvapCoolerPower * TimeStepSys * DataGlobalConstants::SecInHour;
    3338             : 
    3339             :     // Report Water comsumption in cubic meters per timestep
    3340     2882159 :     thisEvapCond.EvapWaterConsump = thisEvapCond.EvapWaterConsumpRate * TimeStepSys * DataGlobalConstants::SecInHour;
    3341     2882159 :     thisEvapCond.EvapWaterStarvMakup = thisEvapCond.EvapWaterStarvMakupRate * TimeStepSys * DataGlobalConstants::SecInHour;
    3342     2882159 : }
    3343             : 
    3344      127940 : void SimZoneEvaporativeCoolerUnit(EnergyPlusData &state,
    3345             :                                   std::string_view CompName,      // name of the packaged terminal heat pump
    3346             :                                   int const ZoneNum,              // number of zone being served
    3347             :                                   Real64 &SensibleOutputProvided, // sensible capacity delivered to zone
    3348             :                                   Real64 &LatentOutputProvided,   // Latent add/removal  (kg/s), dehumid = negative
    3349             :                                   int &CompIndex                  // index to zone hvac unit
    3350             : )
    3351             : {
    3352             : 
    3353             :     // SUBROUTINE INFORMATION:
    3354             :     //       AUTHOR         B. Griffith
    3355             :     //       DATE WRITTEN   July 2013
    3356             :     //       MODIFIED       na
    3357             :     //       RE-ENGINEERED  na
    3358             : 
    3359             :     // PURPOSE OF THIS SUBROUTINE:
    3360             :     // public simulation routine for managing zone hvac evaporative cooler unit
    3361             : 
    3362             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3363             :     int CompNum;
    3364             : 
    3365      127940 :     auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    3366             : 
    3367      127940 :     if (state.dataEvapCoolers->GetInputZoneEvapUnit) {
    3368           3 :         GetInputZoneEvaporativeCoolerUnit(state);
    3369           3 :         state.dataEvapCoolers->GetInputZoneEvapUnit = false;
    3370             :     }
    3371             : 
    3372             :     // Find the correct Equipment
    3373      127940 :     if (CompIndex == 0) {
    3374          30 :         CompNum = UtilityRoutines::FindItemInList(CompName, ZoneEvapUnit);
    3375          30 :         if (CompNum == 0) {
    3376           0 :             ShowFatalError(state, "SimZoneEvaporativeCoolerUnit: Zone evaporative cooler unit not found.");
    3377             :         }
    3378          30 :         CompIndex = CompNum;
    3379             :     } else {
    3380      127910 :         CompNum = CompIndex;
    3381      127910 :         if (CompNum < 1 || CompNum > state.dataEvapCoolers->NumZoneEvapUnits) {
    3382           0 :             ShowFatalError(state,
    3383           0 :                            format("SimZoneEvaporativeCoolerUnit: Invalid CompIndex passed={}, Number of units ={}, Entered Unit name = {}",
    3384             :                                   CompNum,
    3385           0 :                                   state.dataEvapCoolers->NumZoneEvapUnits,
    3386           0 :                                   CompName));
    3387             :         }
    3388      127910 :         if (state.dataEvapCoolers->CheckZoneEvapUnitName(CompNum)) {
    3389          30 :             if (CompName != ZoneEvapUnit(CompNum).Name) {
    3390           0 :                 ShowFatalError(state,
    3391           0 :                                format("SimZoneEvaporativeCoolerUnit: Invalid CompIndex passed={}, Unit name={}, stored unit name for that index={}",
    3392             :                                       CompNum,
    3393             :                                       CompName,
    3394           0 :                                       ZoneEvapUnit(CompNum).Name));
    3395             :             }
    3396          30 :             state.dataEvapCoolers->CheckZoneEvapUnitName(CompNum) = false;
    3397             :         }
    3398             :     }
    3399             : 
    3400      127940 :     InitZoneEvaporativeCoolerUnit(state, CompNum, ZoneNum);
    3401             : 
    3402      127940 :     CalcZoneEvaporativeCoolerUnit(state, CompNum, ZoneNum, SensibleOutputProvided, LatentOutputProvided);
    3403             : 
    3404      127940 :     ReportZoneEvaporativeCoolerUnit(state, CompNum);
    3405      127940 : }
    3406             : 
    3407           3 : void GetInputZoneEvaporativeCoolerUnit(EnergyPlusData &state)
    3408             : {
    3409             : 
    3410             :     // SUBROUTINE INFORMATION:
    3411             :     //       AUTHOR         B. Griffith
    3412             :     //       DATE WRITTEN   July 2013
    3413             :     //       MODIFIED       na
    3414             :     //       RE-ENGINEERED  na
    3415             : 
    3416             :     // PURPOSE OF THIS SUBROUTINE:
    3417             :     // get input for zone evap cooler unit
    3418             : 
    3419             :     // SUBROUTINE PARAMETER DEFINITIONS:
    3420             :     static constexpr std::string_view RoutineName("GetInputZoneEvaporativeCoolerUnit: ");
    3421             : 
    3422             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3423           6 :     std::string CurrentModuleObject; // Object type for getting and error messages
    3424           6 :     Array1D_string Alphas;           // Alpha items for object
    3425           6 :     Array1D<Real64> Numbers;         // Numeric items for object
    3426           6 :     Array1D_string cAlphaFields;     // Alpha field names
    3427           6 :     Array1D_string cNumericFields;   // Numeric field names
    3428           6 :     Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
    3429           6 :     Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
    3430             :     int NumAlphas;                   // Number of Alphas for each GetObjectItem call
    3431             :     int NumNumbers;                  // Number of Numbers for each GetObjectItem call
    3432             :     int MaxAlphas;                   // Maximum number of alpha fields in all objects
    3433             :     int MaxNumbers;                  // Maximum number of numeric fields in all objects
    3434             :     int NumFields;                   // Total number of fields in object
    3435             :     int IOStatus;                    // Used in GetObjectItem
    3436           3 :     bool ErrorsFound(false);         // Set to true if errors in input, fatal at end of routine
    3437             :     bool errFlag;
    3438             :     Real64 FanVolFlow;
    3439             :     int UnitLoop;
    3440             :     int CtrlZone; // index to loop counter
    3441             :     int NodeNum;  // index to loop counter
    3442             : 
    3443           3 :     auto &EvapCond(state.dataEvapCoolers->EvapCond);
    3444           3 :     auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    3445             : 
    3446           3 :     if (state.dataEvapCoolers->GetInputEvapComponentsFlag) {
    3447           3 :         GetEvapInput(state);
    3448           3 :         state.dataEvapCoolers->GetInputEvapComponentsFlag = false;
    3449             :     }
    3450             : 
    3451           3 :     state.dataEvapCoolers->GetInputZoneEvapUnit = false;
    3452           3 :     MaxNumbers = 0;
    3453           3 :     MaxAlphas = 0;
    3454             : 
    3455           3 :     CurrentModuleObject = "ZoneHVAC:EvaporativeCoolerUnit";
    3456           3 :     state.dataEvapCoolers->NumZoneEvapUnits = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
    3457           3 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumFields, NumAlphas, NumNumbers);
    3458           3 :     MaxNumbers = max(MaxNumbers, NumNumbers);
    3459           3 :     MaxAlphas = max(MaxAlphas, NumAlphas);
    3460           3 :     Alphas.allocate(MaxAlphas);
    3461           3 :     Numbers.dimension(MaxNumbers, 0.0);
    3462           3 :     cAlphaFields.allocate(MaxAlphas);
    3463           3 :     cNumericFields.allocate(MaxNumbers);
    3464           3 :     lAlphaBlanks.dimension(MaxAlphas, true);
    3465           3 :     lNumericBlanks.dimension(MaxNumbers, true);
    3466             : 
    3467           3 :     if (state.dataEvapCoolers->NumZoneEvapUnits > 0) {
    3468           3 :         state.dataEvapCoolers->CheckZoneEvapUnitName.dimension(state.dataEvapCoolers->NumZoneEvapUnits, true);
    3469           3 :         ZoneEvapUnit.allocate(state.dataEvapCoolers->NumZoneEvapUnits);
    3470             : 
    3471          33 :         for (UnitLoop = 1; UnitLoop <= state.dataEvapCoolers->NumZoneEvapUnits; ++UnitLoop) {
    3472          30 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    3473             :                                                                      CurrentModuleObject,
    3474             :                                                                      UnitLoop,
    3475             :                                                                      Alphas,
    3476             :                                                                      NumAlphas,
    3477             :                                                                      Numbers,
    3478             :                                                                      NumNumbers,
    3479             :                                                                      IOStatus,
    3480             :                                                                      lNumericBlanks,
    3481             :                                                                      lAlphaBlanks,
    3482             :                                                                      cAlphaFields,
    3483             :                                                                      cNumericFields);
    3484             : 
    3485          30 :             UtilityRoutines::IsNameEmpty(state, Alphas(1), CurrentModuleObject, ErrorsFound);
    3486             : 
    3487          30 :             auto &thisZoneEvapUnit = ZoneEvapUnit(UnitLoop);
    3488          30 :             thisZoneEvapUnit.Name = Alphas(1);
    3489          30 :             if (lAlphaBlanks(2)) {
    3490           0 :                 thisZoneEvapUnit.AvailSchedIndex = DataGlobalConstants::ScheduleAlwaysOn;
    3491             :             } else {
    3492          30 :                 thisZoneEvapUnit.AvailSchedIndex =
    3493          30 :                     ScheduleManager::GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer (index number)
    3494          30 :                 if (thisZoneEvapUnit.AvailSchedIndex == 0) {
    3495           0 :                     ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3496           0 :                     ShowContinueError(state, "invalid-not found " + cAlphaFields(2) + "=\"" + Alphas(2) + "\".");
    3497           0 :                     ErrorsFound = true;
    3498             :                 }
    3499             :             }
    3500             : 
    3501          30 :             if (!lAlphaBlanks(3)) {
    3502           0 :                 thisZoneEvapUnit.AvailManagerListName = Alphas(3);
    3503             :             }
    3504             : 
    3505          30 :             thisZoneEvapUnit.OAInletNodeNum = GetOnlySingleNode(state,
    3506          30 :                                                                 Alphas(4),
    3507             :                                                                 ErrorsFound,
    3508             :                                                                 DataLoopNode::ConnectionObjectType::ZoneHVACEvaporativeCoolerUnit,
    3509          30 :                                                                 Alphas(1),
    3510             :                                                                 DataLoopNode::NodeFluidType::Air,
    3511             :                                                                 DataLoopNode::ConnectionType::OutsideAir,
    3512             :                                                                 NodeInputManager::CompFluidStream::Primary,
    3513          30 :                                                                 DataLoopNode::ObjectIsParent);
    3514             : 
    3515          30 :             thisZoneEvapUnit.UnitOutletNodeNum = GetOnlySingleNode(state,
    3516          30 :                                                                    Alphas(5),
    3517             :                                                                    ErrorsFound,
    3518             :                                                                    DataLoopNode::ConnectionObjectType::ZoneHVACEvaporativeCoolerUnit,
    3519          30 :                                                                    Alphas(1),
    3520             :                                                                    DataLoopNode::NodeFluidType::Air,
    3521             :                                                                    DataLoopNode::ConnectionType::Outlet,
    3522             :                                                                    NodeInputManager::CompFluidStream::Primary,
    3523          30 :                                                                    DataLoopNode::ObjectIsParent);
    3524             : 
    3525          30 :             if (!lAlphaBlanks(6)) {
    3526          30 :                 thisZoneEvapUnit.UnitReliefNodeNum = GetOnlySingleNode(state,
    3527          30 :                                                                        Alphas(6),
    3528             :                                                                        ErrorsFound,
    3529             :                                                                        DataLoopNode::ConnectionObjectType::ZoneHVACEvaporativeCoolerUnit,
    3530          30 :                                                                        Alphas(1),
    3531             :                                                                        DataLoopNode::NodeFluidType::Air,
    3532             :                                                                        DataLoopNode::ConnectionType::Inlet,
    3533             :                                                                        NodeInputManager::CompFluidStream::Primary,
    3534          30 :                                                                        DataLoopNode::ObjectIsParent);
    3535             :             }
    3536             : 
    3537          30 :             thisZoneEvapUnit.FanObjectClassName = Alphas(7);
    3538          30 :             thisZoneEvapUnit.FanName = Alphas(8);
    3539          30 :             errFlag = false;
    3540          30 :             if (!UtilityRoutines::SameString(thisZoneEvapUnit.FanObjectClassName, "Fan:SystemModel")) {
    3541          21 :                 Fans::GetFanType(state, thisZoneEvapUnit.FanName, thisZoneEvapUnit.FanType_Num, errFlag, CurrentModuleObject, thisZoneEvapUnit.Name);
    3542          21 :                 Fans::GetFanIndex(state, thisZoneEvapUnit.FanName, thisZoneEvapUnit.FanIndex, errFlag, CurrentModuleObject);
    3543          21 :                 thisZoneEvapUnit.FanInletNodeNum =
    3544          21 :                     Fans::GetFanInletNode(state, thisZoneEvapUnit.FanObjectClassName, thisZoneEvapUnit.FanName, errFlag);
    3545          21 :                 thisZoneEvapUnit.FanOutletNodeNum =
    3546          21 :                     Fans::GetFanOutletNode(state, thisZoneEvapUnit.FanObjectClassName, thisZoneEvapUnit.FanName, errFlag);
    3547          21 :                 Fans::GetFanVolFlow(state, thisZoneEvapUnit.FanIndex, FanVolFlow);
    3548          21 :                 thisZoneEvapUnit.ActualFanVolFlowRate = FanVolFlow;
    3549             :                 // Get the fan's availability schedule
    3550          21 :                 thisZoneEvapUnit.FanAvailSchedPtr =
    3551          21 :                     Fans::GetFanAvailSchPtr(state, thisZoneEvapUnit.FanObjectClassName, thisZoneEvapUnit.FanName, errFlag);
    3552          21 :                 if (errFlag) {
    3553           0 :                     ShowContinueError(state, "...specified in " + CurrentModuleObject + " = " + thisZoneEvapUnit.Name);
    3554           0 :                     ErrorsFound = true;
    3555             :                 }
    3556           9 :             } else if (UtilityRoutines::SameString(thisZoneEvapUnit.FanObjectClassName, "Fan:SystemModel")) {
    3557             : 
    3558           9 :                 thisZoneEvapUnit.FanType_Num = DataHVACGlobals::FanType_SystemModelObject;
    3559           9 :                 state.dataHVACFan->fanObjs.emplace_back(new HVACFan::FanSystem(state, thisZoneEvapUnit.FanName)); // call constructor
    3560           9 :                 thisZoneEvapUnit.FanIndex = HVACFan::getFanObjectVectorIndex(state, thisZoneEvapUnit.FanName);
    3561           9 :                 thisZoneEvapUnit.FanInletNodeNum = state.dataHVACFan->fanObjs[thisZoneEvapUnit.FanIndex]->inletNodeNum;
    3562           9 :                 thisZoneEvapUnit.FanOutletNodeNum = state.dataHVACFan->fanObjs[thisZoneEvapUnit.FanIndex]->outletNodeNum;
    3563           9 :                 thisZoneEvapUnit.ActualFanVolFlowRate = state.dataHVACFan->fanObjs[thisZoneEvapUnit.FanIndex]->designAirVolFlowRate;
    3564           9 :                 thisZoneEvapUnit.FanAvailSchedPtr = state.dataHVACFan->fanObjs[thisZoneEvapUnit.FanIndex]->availSchedIndex;
    3565             :             }
    3566             : 
    3567             :             // set evap unit to cycling mode for all fan types. Note OpMode var is not used
    3568             :             // with used for ZONECOOLINGLOADVARIABLESPEEDFAN Cooler Unit Control Method
    3569          30 :             thisZoneEvapUnit.OpMode = DataHVACGlobals::CycFanCycCoil;
    3570             : 
    3571          30 :             FanVolFlow = 0.0;
    3572          30 :             if (errFlag) {
    3573           0 :                 ShowContinueError(state, "specified in " + CurrentModuleObject + " = " + thisZoneEvapUnit.Name);
    3574           0 :                 ErrorsFound = true;
    3575             :             }
    3576             : 
    3577          30 :             thisZoneEvapUnit.DesignAirVolumeFlowRate = Numbers(1);
    3578             : 
    3579          30 :             constexpr std::array<std::string_view, static_cast<int>(FanPlacement::Num)> fanPlacementNamesUC = {"BLOWTHROUGH", "DRAWTHROUGH"};
    3580          30 :             thisZoneEvapUnit.FanLocation = static_cast<FanPlacement>(getEnumerationValue(fanPlacementNamesUC, Alphas(9)));
    3581          30 :             if (thisZoneEvapUnit.FanLocation == FanPlacement::Invalid) {
    3582           0 :                 ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3583           0 :                 ShowContinueError(state, "invalid choice found " + cAlphaFields(9) + "=\"" + Alphas(9) + "\".");
    3584           0 :                 ErrorsFound = true;
    3585             :             }
    3586             : 
    3587             :             // get the zone numer served by the zoneHVAC evaporative cooler
    3588         330 :             for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    3589         300 :                 if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
    3590         570 :                 for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
    3591         300 :                     if (thisZoneEvapUnit.UnitOutletNodeNum == state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
    3592          30 :                         thisZoneEvapUnit.ZonePtr = CtrlZone;
    3593          30 :                         break;
    3594             :                     }
    3595             :                 }
    3596             :             }
    3597             : 
    3598          30 :             constexpr std::array<std::string_view, static_cast<int>(ControlType::Num)> controlTypeNamesUC = {
    3599             :                 "ZONETEMPERATUREDEADBANDONOFFCYCLING", "ZONECOOLINGLOADONOFFCYCLING", "ZONECOOLINGLOADVARIABLESPEEDFAN"};
    3600          30 :             thisZoneEvapUnit.ControlSchemeType = static_cast<ControlType>(getEnumerationValue(controlTypeNamesUC, Alphas(10)));
    3601          30 :             if (thisZoneEvapUnit.ControlSchemeType == ControlType::Invalid) {
    3602           0 :                 ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3603           0 :                 ShowContinueError(state, "invalid choice found " + cAlphaFields(10) + "=\"" + Alphas(10) + "\".");
    3604           0 :                 ErrorsFound = true;
    3605             :             }
    3606             : 
    3607          30 :             thisZoneEvapUnit.ThrottlingRange = Numbers(2);
    3608          30 :             thisZoneEvapUnit.ThresholdCoolingLoad = Numbers(3);
    3609             : 
    3610          30 :             thisZoneEvapUnit.EvapCooler_1_Type_Num = static_cast<EvapCoolerType>(getEnumerationValue(evapCoolerTypeNamesUC, Alphas(11)));
    3611          30 :             if (thisZoneEvapUnit.EvapCooler_1_Type_Num != EvapCoolerType::Invalid) {
    3612          30 :                 thisZoneEvapUnit.EvapCooler_1_ObjectClassName = evapCoolerTypeNames[static_cast<int>(thisZoneEvapUnit.EvapCooler_1_Type_Num)];
    3613             :             } else {
    3614           0 :                 ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3615           0 :                 ShowContinueError(state, "invalid choice found " + cAlphaFields(11) + "=\"" + Alphas(11) + "\".");
    3616           0 :                 ErrorsFound = true;
    3617             :             }
    3618             : 
    3619          30 :             thisZoneEvapUnit.EvapCooler_1_Name = Alphas(12);
    3620          30 :             thisZoneEvapUnit.EvapCooler_1_Index = UtilityRoutines::FindItemInList(Alphas(12), state.dataEvapCoolers->EvapCond, &EvapConditions::Name);
    3621          30 :             if (thisZoneEvapUnit.EvapCooler_1_Index == 0) {
    3622           0 :                 ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3623           0 :                 ShowContinueError(state, "invalid, not found " + cAlphaFields(12) + "=\"" + Alphas(12) + "\".");
    3624           0 :                 ErrorsFound = true;
    3625             :             }
    3626             : 
    3627          30 :             if (!lAlphaBlanks(13)) {
    3628           9 :                 thisZoneEvapUnit.EvapCooler_2_Type_Num = static_cast<EvapCoolerType>(getEnumerationValue(evapCoolerTypeNamesUC, Alphas(13)));
    3629           9 :                 if (thisZoneEvapUnit.EvapCooler_2_Type_Num != EvapCoolerType::Invalid) {
    3630           9 :                     thisZoneEvapUnit.EvapCooler_2_ObjectClassName = evapCoolerTypeNames[static_cast<int>(thisZoneEvapUnit.EvapCooler_2_Type_Num)];
    3631             :                 } else {
    3632           0 :                     ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3633           0 :                     ShowContinueError(state, "invalid choice found " + cAlphaFields(13) + "=\"" + Alphas(13) + "\".");
    3634           0 :                     ErrorsFound = true;
    3635             :                 }
    3636             : 
    3637           9 :                 if (!lAlphaBlanks(14)) {
    3638           9 :                     thisZoneEvapUnit.EvapCooler_2_Name = Alphas(14);
    3639           9 :                     thisZoneEvapUnit.EvapCooler_2_Index =
    3640           9 :                         UtilityRoutines::FindItemInList(Alphas(14), state.dataEvapCoolers->EvapCond, &EvapConditions::Name);
    3641           9 :                     if (thisZoneEvapUnit.EvapCooler_2_Index == 0) {
    3642           0 :                         ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3643           0 :                         ShowContinueError(state, "invalid, not found " + cAlphaFields(14) + "=\"" + Alphas(14) + "\".");
    3644           0 :                         ErrorsFound = true;
    3645             :                     }
    3646             :                 } else {
    3647           0 :                     ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3648           0 :                     ShowContinueError(state, "missing input for " + cAlphaFields(14));
    3649           0 :                     ErrorsFound = true;
    3650             :                 }
    3651             :             }
    3652             : 
    3653          30 :             thisZoneEvapUnit.HVACSizingIndex = 0;
    3654          30 :             if (!lAlphaBlanks(15)) {
    3655           0 :                 thisZoneEvapUnit.HVACSizingIndex = UtilityRoutines::FindItemInList(Alphas(15), state.dataSize->ZoneHVACSizing);
    3656           0 :                 if (thisZoneEvapUnit.HVACSizingIndex == 0) {
    3657           0 :                     ShowSevereError(state, cAlphaFields(15) + " = " + Alphas(15) + " not found.");
    3658           0 :                     ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + thisZoneEvapUnit.Name);
    3659           0 :                     ErrorsFound = true;
    3660             :                 }
    3661             :             }
    3662             : 
    3663             :             // Add fan to component sets array
    3664          60 :             BranchNodeConnections::SetUpCompSets(state,
    3665             :                                                  CurrentModuleObject,
    3666             :                                                  thisZoneEvapUnit.Name,
    3667             :                                                  thisZoneEvapUnit.FanObjectClassName,
    3668             :                                                  thisZoneEvapUnit.FanName,
    3669          30 :                                                  state.dataLoopNodes->NodeID(thisZoneEvapUnit.FanInletNodeNum),
    3670          30 :                                                  state.dataLoopNodes->NodeID(thisZoneEvapUnit.FanOutletNodeNum));
    3671             : 
    3672             :             // Add first evap cooler to component sets array
    3673          60 :             BranchNodeConnections::SetUpCompSets(state,
    3674             :                                                  CurrentModuleObject,
    3675             :                                                  thisZoneEvapUnit.Name,
    3676             :                                                  thisZoneEvapUnit.EvapCooler_1_ObjectClassName,
    3677             :                                                  thisZoneEvapUnit.EvapCooler_1_Name,
    3678          30 :                                                  state.dataLoopNodes->NodeID(EvapCond(thisZoneEvapUnit.EvapCooler_1_Index).InletNode),
    3679          30 :                                                  state.dataLoopNodes->NodeID(EvapCond(thisZoneEvapUnit.EvapCooler_1_Index).OutletNode));
    3680             : 
    3681          30 :             if (thisZoneEvapUnit.EvapCooler_2_Index > 0) {
    3682             :                 // Add second evap cooler to component sets array
    3683          18 :                 BranchNodeConnections::SetUpCompSets(state,
    3684             :                                                      CurrentModuleObject,
    3685             :                                                      thisZoneEvapUnit.Name,
    3686             :                                                      thisZoneEvapUnit.EvapCooler_2_ObjectClassName,
    3687             :                                                      thisZoneEvapUnit.EvapCooler_2_Name,
    3688           9 :                                                      state.dataLoopNodes->NodeID(EvapCond(thisZoneEvapUnit.EvapCooler_2_Index).InletNode),
    3689           9 :                                                      state.dataLoopNodes->NodeID(EvapCond(thisZoneEvapUnit.EvapCooler_2_Index).OutletNode));
    3690             :             }
    3691             : 
    3692             :             // check that fan type is consistent with control method
    3693          30 :             if (thisZoneEvapUnit.ControlSchemeType == ControlType::ZoneCoolingLoadVariableSpeedFan) { // must have a VS fan type
    3694          15 :                 if (thisZoneEvapUnit.FanType_Num == DataHVACGlobals::FanType_SimpleConstVolume) {
    3695           0 :                     ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3696           0 :                     ShowContinueError(state, "Fan:ConstantVolume is not consistent with control method ZoneCoolingLoadVariableSpeedFan.");
    3697           0 :                     ShowContinueError(state, "Change to a variable speed fan object type");
    3698           0 :                     ErrorsFound = true;
    3699          15 :                 } else if (thisZoneEvapUnit.FanType_Num == DataHVACGlobals::FanType_SimpleOnOff) {
    3700           0 :                     ShowSevereError(state, CurrentModuleObject + "=\"" + thisZoneEvapUnit.Name + "\" invalid data.");
    3701           0 :                     ShowContinueError(state, "Fan:OnOff is not consistent with control method ZoneCoolingLoadVariableSpeedFan.");
    3702           0 :                     ShowContinueError(state, "Change to a variable speed fan object type");
    3703           0 :                     ErrorsFound = true;
    3704             :                 }
    3705             :             }
    3706             : 
    3707             :         } // unit loop
    3708             :     }
    3709             : 
    3710             :     //***********************************************************************************
    3711             : 
    3712           3 :     Alphas.deallocate();
    3713           3 :     Numbers.deallocate();
    3714           3 :     cAlphaFields.deallocate();
    3715           3 :     cNumericFields.deallocate();
    3716           3 :     lAlphaBlanks.deallocate();
    3717           3 :     lNumericBlanks.deallocate();
    3718             : 
    3719           3 :     if (ErrorsFound) {
    3720           0 :         ShowFatalError(state, std::string{RoutineName} + "Errors found in getting input.");
    3721           0 :         ShowContinueError(state, "... Preceding condition causes termination.");
    3722             :     }
    3723             : 
    3724             :     // setup output variables
    3725          33 :     for (UnitLoop = 1; UnitLoop <= state.dataEvapCoolers->NumZoneEvapUnits; ++UnitLoop) {
    3726          30 :         auto &thisZoneEvapUnit = ZoneEvapUnit(UnitLoop);
    3727          60 :         SetupOutputVariable(state,
    3728             :                             "Zone Evaporative Cooler Unit Total Cooling Rate",
    3729             :                             OutputProcessor::Unit::W,
    3730             :                             thisZoneEvapUnit.UnitTotalCoolingRate,
    3731             :                             OutputProcessor::SOVTimeStepType::System,
    3732             :                             OutputProcessor::SOVStoreType::Average,
    3733          30 :                             thisZoneEvapUnit.Name);
    3734          60 :         SetupOutputVariable(state,
    3735             :                             "Zone Evaporative Cooler Unit Total Cooling Energy",
    3736             :                             OutputProcessor::Unit::J,
    3737             :                             thisZoneEvapUnit.UnitTotalCoolingEnergy,
    3738             :                             OutputProcessor::SOVTimeStepType::System,
    3739             :                             OutputProcessor::SOVStoreType::Summed,
    3740             :                             thisZoneEvapUnit.Name,
    3741             :                             _,
    3742             :                             "ENERGYTRANSFER",
    3743             :                             "COOLINGCOILS",
    3744             :                             _,
    3745          30 :                             "System");
    3746          60 :         SetupOutputVariable(state,
    3747             :                             "Zone Evaporative Cooler Unit Sensible Cooling Rate",
    3748             :                             OutputProcessor::Unit::W,
    3749             :                             thisZoneEvapUnit.UnitSensibleCoolingRate,
    3750             :                             OutputProcessor::SOVTimeStepType::System,
    3751             :                             OutputProcessor::SOVStoreType::Average,
    3752          30 :                             thisZoneEvapUnit.Name);
    3753          60 :         SetupOutputVariable(state,
    3754             :                             "Zone Evaporative Cooler Unit Sensible Cooling Energy",
    3755             :                             OutputProcessor::Unit::J,
    3756             :                             thisZoneEvapUnit.UnitSensibleCoolingEnergy,
    3757             :                             OutputProcessor::SOVTimeStepType::System,
    3758             :                             OutputProcessor::SOVStoreType::Summed,
    3759          30 :                             thisZoneEvapUnit.Name);
    3760          60 :         SetupOutputVariable(state,
    3761             :                             "Zone Evaporative Cooler Unit Latent Heating Rate",
    3762             :                             OutputProcessor::Unit::W,
    3763             :                             thisZoneEvapUnit.UnitLatentHeatingRate,
    3764             :                             OutputProcessor::SOVTimeStepType::System,
    3765             :                             OutputProcessor::SOVStoreType::Average,
    3766          30 :                             thisZoneEvapUnit.Name);
    3767          60 :         SetupOutputVariable(state,
    3768             :                             "Zone Evaporative Cooler Unit Latent Heating Energy",
    3769             :                             OutputProcessor::Unit::J,
    3770             :                             thisZoneEvapUnit.UnitLatentHeatingEnergy,
    3771             :                             OutputProcessor::SOVTimeStepType::System,
    3772             :                             OutputProcessor::SOVStoreType::Summed,
    3773          30 :                             thisZoneEvapUnit.Name);
    3774          60 :         SetupOutputVariable(state,
    3775             :                             "Zone Evaporative Cooler Unit Latent Cooling Rate",
    3776             :                             OutputProcessor::Unit::W,
    3777             :                             thisZoneEvapUnit.UnitLatentCoolingRate,
    3778             :                             OutputProcessor::SOVTimeStepType::System,
    3779             :                             OutputProcessor::SOVStoreType::Average,
    3780          30 :                             thisZoneEvapUnit.Name);
    3781          60 :         SetupOutputVariable(state,
    3782             :                             "Zone Evaporative Cooler Unit Latent Cooling Energy",
    3783             :                             OutputProcessor::Unit::J,
    3784             :                             thisZoneEvapUnit.UnitLatentCoolingEnergy,
    3785             :                             OutputProcessor::SOVTimeStepType::System,
    3786             :                             OutputProcessor::SOVStoreType::Summed,
    3787          30 :                             thisZoneEvapUnit.Name);
    3788          60 :         SetupOutputVariable(state,
    3789             :                             "Zone Evaporative Cooler Unit Fan Speed Ratio",
    3790             :                             OutputProcessor::Unit::None,
    3791             :                             thisZoneEvapUnit.UnitFanSpeedRatio,
    3792             :                             OutputProcessor::SOVTimeStepType::System,
    3793             :                             OutputProcessor::SOVStoreType::Average,
    3794          30 :                             thisZoneEvapUnit.Name);
    3795          60 :         SetupOutputVariable(state,
    3796             :                             "Zone Evaporative Cooler Unit Fan Availability Status",
    3797             :                             OutputProcessor::Unit::None,
    3798             :                             thisZoneEvapUnit.FanAvailStatus,
    3799             :                             OutputProcessor::SOVTimeStepType::System,
    3800             :                             OutputProcessor::SOVStoreType::Average,
    3801          30 :                             thisZoneEvapUnit.Name);
    3802          30 :         if (thisZoneEvapUnit.ControlSchemeType != ControlType::ZoneCoolingLoadVariableSpeedFan) {
    3803          30 :             SetupOutputVariable(state,
    3804             :                                 "Zone Evaporative Cooler Unit Part Load Ratio",
    3805             :                                 OutputProcessor::Unit::None,
    3806             :                                 thisZoneEvapUnit.UnitPartLoadRatio,
    3807             :                                 OutputProcessor::SOVTimeStepType::System,
    3808             :                                 OutputProcessor::SOVStoreType::Average,
    3809          15 :                                 thisZoneEvapUnit.Name);
    3810             :         }
    3811             :     }
    3812           3 : }
    3813             : 
    3814      127940 : void InitZoneEvaporativeCoolerUnit(EnergyPlusData &state,
    3815             :                                    int const UnitNum, // unit number
    3816             :                                    int const ZoneNum  // number of zone being served
    3817             : )
    3818             : {
    3819             : 
    3820             :     // SUBROUTINE INFORMATION:
    3821             :     //       AUTHOR         B. Griffith
    3822             :     //       DATE WRITTEN   July 2013
    3823             :     //       MODIFIED       na
    3824             :     //       RE-ENGINEERED  na
    3825             : 
    3826             :     // Using/Aliasing
    3827      127940 :     auto &SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
    3828      127940 :     auto &ZoneComp = state.dataHVACGlobal->ZoneComp;
    3829             : 
    3830             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3831             :     Real64 TimeElapsed;
    3832             : 
    3833      127940 :     auto &EvapCond(state.dataEvapCoolers->EvapCond);
    3834      127940 :     auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    3835             : 
    3836      127940 :     if (allocated(ZoneComp)) {
    3837      127910 :         if (ZoneEvapUnit(UnitNum).MyZoneEq) { // initialize the name of each availability manager list and zone number
    3838          60 :             ZoneComp(DataZoneEquipment::ZoneEquip::ZoneEvaporativeCoolerUnit).ZoneCompAvailMgrs(UnitNum).AvailManagerListName =
    3839          60 :                 ZoneEvapUnit(UnitNum).AvailManagerListName;
    3840          30 :             ZoneComp(DataZoneEquipment::ZoneEquip::ZoneEvaporativeCoolerUnit).ZoneCompAvailMgrs(UnitNum).ZoneNum = ZoneNum;
    3841          30 :             ZoneEvapUnit(UnitNum).MyZoneEq = false;
    3842             :         }
    3843      127910 :         ZoneEvapUnit(UnitNum).FanAvailStatus =
    3844      127910 :             ZoneComp(DataZoneEquipment::ZoneEquip::ZoneEvaporativeCoolerUnit).ZoneCompAvailMgrs(UnitNum).AvailStatus;
    3845             :     }
    3846             : 
    3847      127940 :     if (!state.dataEvapCoolers->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
    3848           3 :         state.dataEvapCoolers->ZoneEquipmentListChecked = true;
    3849          33 :         for (int Loop = 1; Loop <= state.dataEvapCoolers->NumZoneEvapUnits; ++Loop) {
    3850          30 :             if (DataZoneEquipment::CheckZoneEquipmentList(state, "ZoneHVAC:EvaporativeCoolerUnit", ZoneEvapUnit(Loop).Name)) {
    3851          30 :                 ZoneEvapUnit(Loop).ZoneNodeNum = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ZoneNode;
    3852             :             } else {
    3853           0 :                 ShowSevereError(state,
    3854           0 :                                 "InitZoneEvaporativeCoolerUnit: ZoneHVAC:EvaporativeCoolerUnit = " + ZoneEvapUnit(Loop).Name +
    3855             :                                     ", is not on any ZoneHVAC:EquipmentList.  It will not be simulated.");
    3856             :             }
    3857             :         }
    3858             :     }
    3859             : 
    3860      127940 :     if (!state.dataGlobal->SysSizingCalc && ZoneEvapUnit(UnitNum).MySize) {
    3861          30 :         SizeZoneEvaporativeCoolerUnit(state, UnitNum);
    3862          30 :         ZoneEvapUnit(UnitNum).MySize = false;
    3863             :     }
    3864             : 
    3865      127940 :     if (ZoneEvapUnit(UnitNum).MyFan) {
    3866          84 :         if (ZoneEvapUnit(UnitNum).ActualFanVolFlowRate != DataSizing::AutoSize) {
    3867             : 
    3868          30 :             if (ZoneEvapUnit(UnitNum).ActualFanVolFlowRate < ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate) {
    3869           4 :                 ShowSevereError(state, "InitZoneEvaporativeCoolerUnit: ZoneHVAC:EvaporativeCoolerUnit = " + ZoneEvapUnit(UnitNum).Name);
    3870           4 :                 ShowContinueError(state, "...unit fan volumetric flow rate less than evaporative cooler unit design supply air flow rate.");
    3871           4 :                 ShowContinueError(state, format("...fan volumetric flow rate = {:.5T} m3/s.", ZoneEvapUnit(UnitNum).ActualFanVolFlowRate));
    3872          12 :                 ShowContinueError(state,
    3873           8 :                                   format("...evap cooler unit volumetric flow rate = {:.5T} m3/s.", ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate));
    3874           4 :                 ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate = ZoneEvapUnit(UnitNum).ActualFanVolFlowRate;
    3875           4 :                 ShowContinueError(state, "...evaporative cooler unit design supply air flow rate will match fan flow rate and simulation continues.");
    3876           4 :                 ZoneEvapUnit(UnitNum).MyEnvrn = true; // re-initialize to set mass flow rate and max mass flow rate
    3877             :             }
    3878             : 
    3879          30 :             if (ZoneEvapUnit(UnitNum).ActualFanVolFlowRate > 0.0) {
    3880          30 :                 ZoneEvapUnit(UnitNum).DesignFanSpeedRatio =
    3881          30 :                     ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate / ZoneEvapUnit(UnitNum).ActualFanVolFlowRate;
    3882             :             }
    3883             : 
    3884          30 :             ZoneEvapUnit(UnitNum).MyFan = false;
    3885             :         } else {
    3886          54 :             if (ZoneEvapUnit(UnitNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    3887          39 :                 Fans::GetFanVolFlow(state, ZoneEvapUnit(UnitNum).FanIndex, ZoneEvapUnit(UnitNum).ActualFanVolFlowRate);
    3888             :             } else {
    3889          15 :                 ZoneEvapUnit(UnitNum).ActualFanVolFlowRate = state.dataHVACFan->fanObjs[ZoneEvapUnit(UnitNum).FanIndex]->designAirVolFlowRate;
    3890             :             }
    3891             :         }
    3892             :     }
    3893             : 
    3894      127940 :     if (ZoneEvapUnit(UnitNum).FanAvailSchedPtr > 0) {
    3895             :         // include fan is not available, then unit is not available
    3896      255880 :         ZoneEvapUnit(UnitNum).UnitIsAvailable = ((ScheduleManager::GetCurrentScheduleValue(state, ZoneEvapUnit(UnitNum).FanAvailSchedPtr) > 0.0) &&
    3897      127940 :                                                  (ScheduleManager::GetCurrentScheduleValue(state, ZoneEvapUnit(UnitNum).AvailSchedIndex) > 0.0));
    3898             :     } else {
    3899           0 :         ZoneEvapUnit(UnitNum).UnitIsAvailable = (ScheduleManager::GetCurrentScheduleValue(state, ZoneEvapUnit(UnitNum).AvailSchedIndex) > 0.0);
    3900             :     }
    3901             : 
    3902      127940 :     ZoneEvapUnit(UnitNum).EvapCooler_1_AvailStatus =
    3903      127940 :         (ScheduleManager::GetCurrentScheduleValue(state, EvapCond(ZoneEvapUnit(UnitNum).EvapCooler_1_Index).SchedPtr) > 0.0);
    3904             : 
    3905      127940 :     if (ZoneEvapUnit(UnitNum).EvapCooler_2_Index > 0) {
    3906       38382 :         ZoneEvapUnit(UnitNum).EvapCooler_2_AvailStatus =
    3907       38382 :             (ScheduleManager::GetCurrentScheduleValue(state, EvapCond(ZoneEvapUnit(UnitNum).EvapCooler_2_Index).SchedPtr) > 0.0);
    3908             :     }
    3909             :     // Do the Begin Environment initializations
    3910      127940 :     if (state.dataGlobal->BeginEnvrnFlag && ZoneEvapUnit(UnitNum).MyEnvrn) {
    3911             : 
    3912         150 :         ZoneEvapUnit(UnitNum).DesignAirMassFlowRate = state.dataEnvrn->StdRhoAir * ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate;
    3913         150 :         state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRateMax = ZoneEvapUnit(UnitNum).DesignAirMassFlowRate;
    3914         150 :         state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRateMin = 0.0;
    3915         150 :         state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRateMinAvail = 0.0;
    3916             : 
    3917         150 :         state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).MassFlowRateMax = ZoneEvapUnit(UnitNum).DesignAirMassFlowRate;
    3918         150 :         state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).MassFlowRateMin = 0.0;
    3919         150 :         state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).MassFlowRateMinAvail = 0.0;
    3920             : 
    3921         150 :         if (ZoneEvapUnit(UnitNum).UnitReliefNodeNum > 0) {
    3922         150 :             state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).UnitReliefNodeNum).MassFlowRateMax = ZoneEvapUnit(UnitNum).DesignAirMassFlowRate;
    3923         150 :             state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).UnitReliefNodeNum).MassFlowRateMin = 0.0;
    3924         150 :             state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).UnitReliefNodeNum).MassFlowRateMinAvail = 0.0;
    3925             :         }
    3926         150 :         ZoneEvapUnit(UnitNum).WasOnLastTimestep = false;
    3927         150 :         ZoneEvapUnit(UnitNum).IsOnThisTimestep = false;
    3928         150 :         ZoneEvapUnit(UnitNum).FanSpeedRatio = 0.0;
    3929         150 :         ZoneEvapUnit(UnitNum).UnitFanSpeedRatio = 0.0;
    3930         150 :         ZoneEvapUnit(UnitNum).UnitTotalCoolingRate = 0.0;
    3931         150 :         ZoneEvapUnit(UnitNum).UnitTotalCoolingEnergy = 0.0;
    3932         150 :         ZoneEvapUnit(UnitNum).UnitSensibleCoolingRate = 0.0;
    3933         150 :         ZoneEvapUnit(UnitNum).UnitSensibleCoolingEnergy = 0.0;
    3934         150 :         ZoneEvapUnit(UnitNum).UnitLatentHeatingRate = 0.0;
    3935         150 :         ZoneEvapUnit(UnitNum).UnitLatentHeatingEnergy = 0.0;
    3936         150 :         ZoneEvapUnit(UnitNum).UnitLatentCoolingRate = 0.0;
    3937         150 :         ZoneEvapUnit(UnitNum).UnitLatentCoolingEnergy = 0.0;
    3938         150 :         ZoneEvapUnit(UnitNum).FanAvailStatus = 0.0;
    3939             : 
    3940             :         // place default cold setpoints on control nodes of select evap coolers
    3941         285 :         if ((ZoneEvapUnit(UnitNum).EvapCooler_1_Type_Num == EvapCoolerType::DirectResearchSpecial) ||
    3942         135 :             (ZoneEvapUnit(UnitNum).EvapCooler_1_Type_Num == EvapCoolerType::IndirectRDDSpecial)) {
    3943          45 :             if (EvapCond(ZoneEvapUnit(UnitNum).EvapCooler_1_Index).EvapControlNodeNum > 0) {
    3944          45 :                 state.dataLoopNodes->Node(EvapCond(ZoneEvapUnit(UnitNum).EvapCooler_1_Index).EvapControlNodeNum).TempSetPoint = -20.0;
    3945             :             }
    3946             :         }
    3947         270 :         if ((ZoneEvapUnit(UnitNum).EvapCooler_2_Type_Num == EvapCoolerType::DirectResearchSpecial) ||
    3948         120 :             (ZoneEvapUnit(UnitNum).EvapCooler_2_Type_Num == EvapCoolerType::IndirectRDDSpecial)) {
    3949          30 :             if (EvapCond(ZoneEvapUnit(UnitNum).EvapCooler_2_Index).EvapControlNodeNum > 0) {
    3950          30 :                 state.dataLoopNodes->Node(EvapCond(ZoneEvapUnit(UnitNum).EvapCooler_2_Index).EvapControlNodeNum).TempSetPoint = -20.0;
    3951             :             }
    3952             :         }
    3953             : 
    3954         150 :         ZoneEvapUnit(UnitNum).MyEnvrn = false;
    3955             :     }
    3956      127940 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    3957      126970 :         ZoneEvapUnit(UnitNum).MyEnvrn = true;
    3958             :     }
    3959             : 
    3960      127940 :     TimeElapsed = state.dataGlobal->HourOfDay + state.dataGlobal->TimeStep * state.dataGlobal->TimeStepZone + SysTimeElapsed;
    3961      127940 :     if (ZoneEvapUnit(UnitNum).TimeElapsed != TimeElapsed) {
    3962       63010 :         ZoneEvapUnit(UnitNum).WasOnLastTimestep = ZoneEvapUnit(UnitNum).IsOnThisTimestep;
    3963             : 
    3964       63010 :         ZoneEvapUnit(UnitNum).TimeElapsed = TimeElapsed;
    3965             :     }
    3966      127940 : }
    3967             : 
    3968          30 : void SizeZoneEvaporativeCoolerUnit(EnergyPlusData &state, int const UnitNum) // unit number
    3969             : {
    3970             : 
    3971             :     // SUBROUTINE INFORMATION:
    3972             :     //       AUTHOR         B. Griffith
    3973             :     //       DATE WRITTEN   July 2013
    3974             :     //       MODIFIED       August 2014 Bereket Nigusse, added scalable sizing
    3975             :     //       MODIFIED       January 2013 Daeho Kang, add component sizing table entries
    3976             :     //       RE-ENGINEERED  na
    3977             : 
    3978             :     // SUBROUTINE PARAMETER DEFINITIONS:
    3979             :     static constexpr std::string_view RoutineName("SizeZoneEvaporativeCoolerUnit: "); // include trailing blank space
    3980             : 
    3981             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3982          60 :     std::string CompName;     // component name
    3983          60 :     std::string CompType;     // component type
    3984          60 :     std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
    3985             :     Real64 TempSize;          // autosized value of coil input field
    3986             :     int SizingMethod;         // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing,
    3987             :                               // CoolingCapacitySizing, HeatingCapacitySizing, etc.)
    3988             :     bool PrintFlag;           // TRUE when sizing information is reported in the eio file
    3989             :     int zoneHVACIndex;        // index of zoneHVAC equipment sizing specification
    3990          30 :     int SAFMethod(0);         // supply air flow rate sizing method (SupplyAirFlowRate, FlowPerFloorArea, FractionOfAutosizedCoolingAirflow,
    3991             :                               // FractionOfAutosizedHeatingAirflow ...)
    3992             : 
    3993          30 :     auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    3994             : 
    3995          30 :     state.dataSize->DataScalableSizingON = false;
    3996          30 :     state.dataSize->ZoneHeatingOnlyFan = false;
    3997          30 :     state.dataSize->ZoneCoolingOnlyFan = false;
    3998             : 
    3999          30 :     CompType = "ZoneHVAC:EvaporativeCoolerUnit";
    4000          30 :     CompName = ZoneEvapUnit(UnitNum).Name;
    4001          30 :     state.dataSize->DataZoneNumber = ZoneEvapUnit(UnitNum).ZonePtr;
    4002          30 :     PrintFlag = true;
    4003          30 :     bool errorsFound = false;
    4004             : 
    4005          30 :     auto &ZoneEqSizing(state.dataSize->ZoneEqSizing);
    4006          30 :     auto &CurZoneEqNum(state.dataSize->CurZoneEqNum);
    4007             : 
    4008          30 :     if (CurZoneEqNum > 0) {
    4009             : 
    4010          30 :         if (ZoneEvapUnit(UnitNum).HVACSizingIndex > 0) {
    4011           0 :             state.dataSize->ZoneCoolingOnlyFan = true;
    4012           0 :             zoneHVACIndex = ZoneEvapUnit(UnitNum).HVACSizingIndex;
    4013           0 :             SizingMethod = DataHVACGlobals::CoolingAirflowSizing;
    4014           0 :             SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod;
    4015           0 :             ZoneEqSizing(CurZoneEqNum).SizingMethod(SizingMethod) = SAFMethod;
    4016           0 :             if (SAFMethod == DataSizing::None || SAFMethod == DataSizing::SupplyAirFlowRate || SAFMethod == DataSizing::FlowPerFloorArea ||
    4017             :                 SAFMethod == DataSizing::FractionOfAutosizedCoolingAirflow) {
    4018           0 :                 switch (SAFMethod) {
    4019           0 :                 case DataSizing::SupplyAirFlowRate:
    4020           0 :                     if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow > 0.0) {
    4021           0 :                         ZoneEqSizing(CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    4022           0 :                         ZoneEqSizing(CurZoneEqNum).SystemAirFlow = true;
    4023             :                     }
    4024           0 :                     TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    4025           0 :                     if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow > 0.0) {
    4026           0 :                         PrintFlag = false;
    4027             :                     }
    4028           0 :                     break;
    4029           0 :                 case DataSizing::FlowPerFloorArea:
    4030           0 :                     ZoneEqSizing(CurZoneEqNum).SystemAirFlow = true;
    4031           0 :                     ZoneEqSizing(CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow *
    4032           0 :                                                             state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
    4033           0 :                     TempSize = ZoneEqSizing(CurZoneEqNum).AirVolFlow;
    4034           0 :                     state.dataSize->DataScalableSizingON = true;
    4035           0 :                     break;
    4036           0 :                 case DataSizing::FractionOfAutosizedCoolingAirflow:
    4037           0 :                     state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    4038           0 :                     TempSize = DataSizing::AutoSize;
    4039           0 :                     state.dataSize->DataScalableSizingON = true;
    4040           0 :                     break;
    4041           0 :                 default:
    4042           0 :                     TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    4043             :                 }
    4044             : 
    4045           0 :                 CoolingAirFlowSizer sizingCoolingAirFlow;
    4046           0 :                 std::string stringOverride = "Design Supply Air Flow Rate [m3/s]";
    4047           0 :                 if (state.dataGlobal->isEpJSON) stringOverride = "design_supply_air_flow_rate [m3/s]";
    4048           0 :                 sizingCoolingAirFlow.overrideSizingString(stringOverride);
    4049           0 :                 sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    4050           0 :                 ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    4051             : 
    4052           0 :             } else if (SAFMethod == DataSizing::FlowPerCoolingCapacity) {
    4053           0 :                 SizingMethod = DataHVACGlobals::CoolingCapacitySizing;
    4054           0 :                 TempSize = DataSizing::AutoSize;
    4055           0 :                 PrintFlag = false;
    4056           0 :                 state.dataSize->DataScalableSizingON = true;
    4057           0 :                 state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
    4058           0 :                 if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod == DataSizing::FractionOfAutosizedCoolingCapacity) {
    4059           0 :                     state.dataSize->DataFracOfAutosizedCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
    4060             :                 }
    4061           0 :                 CoolingCapacitySizer sizerCoolingCapacity;
    4062           0 :                 sizerCoolingCapacity.overrideSizingString(SizingString);
    4063           0 :                 sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    4064           0 :                 state.dataSize->DataCapacityUsedForSizing = sizerCoolingCapacity.size(state, TempSize, errorsFound);
    4065           0 :                 state.dataSize->DataFlowPerCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
    4066           0 :                 PrintFlag = true;
    4067           0 :                 TempSize = DataSizing::AutoSize;
    4068             : 
    4069           0 :                 CoolingAirFlowSizer sizingCoolingAirFlow;
    4070           0 :                 std::string stringOverride = "Design Supply Air Flow Rate [m3/s]";
    4071           0 :                 if (state.dataGlobal->isEpJSON) stringOverride = "design_supply_air_flow_rate [m3/s]";
    4072           0 :                 sizingCoolingAirFlow.overrideSizingString(stringOverride);
    4073           0 :                 sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    4074           0 :                 ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    4075             :             }
    4076           0 :             state.dataSize->DataScalableSizingON = false;
    4077           0 :             state.dataSize->ZoneCoolingOnlyFan = false;
    4078             :         } else {
    4079             :             // no scalble sizing method has been specified. Sizing proceeds using the method
    4080             :             // specified in the zoneHVAC object
    4081             :             // N1 , \field Maximum Supply Air Flow Rate
    4082          30 :             state.dataSize->ZoneCoolingOnlyFan = true;
    4083          30 :             if (ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate > 0.0) {
    4084          12 :                 PrintFlag = false;
    4085             :             }
    4086          30 :             TempSize = ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate;
    4087          60 :             CoolingAirFlowSizer sizingCoolingAirFlow;
    4088          60 :             std::string stringOverride = "Design Supply Air Flow Rate [m3/s]";
    4089          30 :             if (state.dataGlobal->isEpJSON) stringOverride = "design_supply_air_flow_rate [m3/s]";
    4090          30 :             sizingCoolingAirFlow.overrideSizingString(stringOverride);
    4091          30 :             sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
    4092          30 :             ZoneEvapUnit(UnitNum).DesignAirVolumeFlowRate = sizingCoolingAirFlow.size(state, TempSize, errorsFound);
    4093          30 :             state.dataSize->ZoneCoolingOnlyFan = false;
    4094             :         }
    4095             :     }
    4096          30 : }
    4097             : 
    4098      127940 : void CalcZoneEvaporativeCoolerUnit(EnergyPlusData &state,
    4099             :                                    int const UnitNum,              // unit number
    4100             :                                    int const ZoneNum,              // number of zone being served
    4101             :                                    Real64 &SensibleOutputProvided, // sensible capacity delivered to zone
    4102             :                                    Real64 &LatentOutputProvided    // Latent add/removal  (kg/s), dehumid = negative
    4103             : )
    4104             : {
    4105             : 
    4106             :     // SUBROUTINE INFORMATION:
    4107             :     //       AUTHOR         B. Griffith
    4108             :     //       DATE WRITTEN   July 2013
    4109             :     //       MODIFIED       na
    4110             :     //       RE-ENGINEERED  na
    4111             : 
    4112             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4113             :     Real64 ZoneCoolingLoad;
    4114             :     Real64 CoolingLoadThreashold;
    4115             :     Real64 ZoneTemp;
    4116             :     Real64 CoolSetLowThrottle;
    4117             :     Real64 CoolSetHiThrottle;
    4118             :     Real64 PartLoadRatio;
    4119             : 
    4120             :     {
    4121      127940 :         auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    4122             : 
    4123      127940 :         if (ZoneEvapUnit(UnitNum).ControlSchemeType == ControlType::ZoneTemperatureDeadBandOnOffCycling) {
    4124       38382 :             ZoneTemp = state.dataLoopNodes->Node(ZoneEvapUnit(UnitNum).ZoneNodeNum).Temp;
    4125       38382 :             CoolSetLowThrottle = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum) - (0.5 * ZoneEvapUnit(UnitNum).ThrottlingRange);
    4126       38382 :             CoolSetHiThrottle = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum) + (0.5 * ZoneEvapUnit(UnitNum).ThrottlingRange);
    4127             : 
    4128       38382 :             if ((ZoneTemp < CoolSetLowThrottle) || !ZoneEvapUnit(UnitNum).UnitIsAvailable) {
    4129       26418 :                 ZoneEvapUnit(UnitNum).IsOnThisTimestep = false;
    4130       11964 :             } else if (ZoneTemp > CoolSetHiThrottle) {
    4131        5850 :                 ZoneEvapUnit(UnitNum).IsOnThisTimestep = true;
    4132             :             } else {
    4133        6114 :                 if (ZoneEvapUnit(UnitNum).WasOnLastTimestep) {
    4134        6114 :                     ZoneEvapUnit(UnitNum).IsOnThisTimestep = true;
    4135             :                 } else {
    4136           0 :                     ZoneEvapUnit(UnitNum).IsOnThisTimestep = false;
    4137             :                 }
    4138             :             }
    4139             : 
    4140       38382 :             if (ZoneEvapUnit(UnitNum).IsOnThisTimestep) {
    4141             : 
    4142       11964 :                 if (ZoneEvapUnit(UnitNum).OpMode == DataHVACGlobals::ContFanCycCoil) {
    4143           0 :                     PartLoadRatio = 1.0;
    4144           0 :                     ZoneEvapUnit(UnitNum).UnitPartLoadRatio = PartLoadRatio;
    4145           0 :                     CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, SensibleOutputProvided, LatentOutputProvided);
    4146             :                 } else {
    4147       11964 :                     ZoneCoolingLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
    4148             :                     // calculate part load ratio for cycling fan/unit first
    4149       11964 :                     ControlZoneEvapUnitOutput(state, UnitNum, ZoneCoolingLoad);
    4150       11964 :                     PartLoadRatio = ZoneEvapUnit(UnitNum).UnitPartLoadRatio;
    4151       11964 :                     CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, SensibleOutputProvided, LatentOutputProvided);
    4152             :                 }
    4153             : 
    4154             :             } else { // not running
    4155             : 
    4156       26418 :                 PartLoadRatio = 0.0;
    4157       26418 :                 ZoneEvapUnit(UnitNum).UnitPartLoadRatio = PartLoadRatio;
    4158       26418 :                 CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, SensibleOutputProvided, LatentOutputProvided);
    4159             :             }
    4160             : 
    4161       89558 :         } else if (ZoneEvapUnit(UnitNum).ControlSchemeType == ControlType::ZoneCoolingLoadOnOffCycling) {
    4162             : 
    4163             :             // get zone loads
    4164       25588 :             ZoneCoolingLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
    4165       25588 :             CoolingLoadThreashold = -1.0 * ZoneEvapUnit(UnitNum).ThresholdCoolingLoad;
    4166             : 
    4167       25588 :             if ((ZoneCoolingLoad < CoolingLoadThreashold) && ZoneEvapUnit(UnitNum).UnitIsAvailable) {
    4168             : 
    4169        7976 :                 if (ZoneEvapUnit(UnitNum).OpMode == DataHVACGlobals::ContFanCycCoil) {
    4170           0 :                     PartLoadRatio = 1.0;
    4171           0 :                     ZoneEvapUnit(UnitNum).UnitPartLoadRatio = PartLoadRatio;
    4172           0 :                     CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, SensibleOutputProvided, LatentOutputProvided);
    4173             :                 } else {
    4174             :                     // calculate part load ratio for cycling fan/unit first
    4175        7976 :                     ControlZoneEvapUnitOutput(state, UnitNum, ZoneCoolingLoad);
    4176        7976 :                     PartLoadRatio = ZoneEvapUnit(UnitNum).UnitPartLoadRatio;
    4177        7976 :                     CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, SensibleOutputProvided, LatentOutputProvided);
    4178             :                 }
    4179             : 
    4180             :             } else {
    4181             :                 // unit is off
    4182       17612 :                 PartLoadRatio = 0.0;
    4183       17612 :                 ZoneEvapUnit(UnitNum).UnitPartLoadRatio = PartLoadRatio;
    4184       17612 :                 CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, SensibleOutputProvided, LatentOutputProvided);
    4185             :             }
    4186             : 
    4187       63970 :         } else if (ZoneEvapUnit(UnitNum).ControlSchemeType == ControlType::ZoneCoolingLoadVariableSpeedFan) {
    4188             :             // get zone loads
    4189       63970 :             ZoneCoolingLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
    4190       63970 :             CoolingLoadThreashold = -1.0 * ZoneEvapUnit(UnitNum).ThresholdCoolingLoad;
    4191       63970 :             if ((ZoneCoolingLoad < CoolingLoadThreashold) && ZoneEvapUnit(UnitNum).UnitIsAvailable) {
    4192             : 
    4193             :                 // determine fan speed to meet load
    4194       19908 :                 ControlVSEvapUnitToMeetLoad(state, UnitNum, ZoneCoolingLoad);
    4195             :                 // variable speed fan used fan speed ratio instead of partload ratio
    4196       19908 :                 CalcZoneEvapUnitOutput(state, UnitNum, ZoneEvapUnit(UnitNum).FanSpeedRatio, SensibleOutputProvided, LatentOutputProvided);
    4197             : 
    4198             :             } else {
    4199             :                 // unit is off
    4200       44062 :                 PartLoadRatio = 0.0;
    4201       44062 :                 CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, SensibleOutputProvided, LatentOutputProvided);
    4202             :             }
    4203             :         }
    4204             :     }
    4205      127940 : }
    4206             : 
    4207      196520 : void CalcZoneEvapUnitOutput(EnergyPlusData &state,
    4208             :                             int const UnitNum,              // unit number
    4209             :                             Real64 const PartLoadRatio,     // zone evap unit part load ratiod
    4210             :                             Real64 &SensibleOutputProvided, // target cooling load
    4211             :                             Real64 &LatentOutputProvided    // target cooling load
    4212             : )
    4213             : {
    4214             :     // caculates zone evaporative cooler sensible and latent outputs
    4215             : 
    4216             :     Real64 MinHumRat; // minimum humidity ratio
    4217             : 
    4218      196520 :     auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    4219      196520 :     auto &Node(state.dataLoopNodes->Node);
    4220             : 
    4221      196520 :     int const ZoneNodeNum = ZoneEvapUnit(UnitNum).ZoneNodeNum;
    4222      196520 :     int const OAInletNodeNum = ZoneEvapUnit(UnitNum).OAInletNodeNum;
    4223      196520 :     int const OutletNodeNum = ZoneEvapUnit(UnitNum).UnitOutletNodeNum;
    4224      196520 :     int const ReliefNodeNum = ZoneEvapUnit(UnitNum).UnitReliefNodeNum;
    4225      196520 :     int const FanInletNodeNum = ZoneEvapUnit(UnitNum).FanInletNodeNum;
    4226      196520 :     int const FanOutletNodeNum = ZoneEvapUnit(UnitNum).FanOutletNodeNum;
    4227      196520 :     int const EvapCooler_1_Index = ZoneEvapUnit(UnitNum).EvapCooler_1_Index;
    4228      196520 :     int const EvapCooler_2_Index = ZoneEvapUnit(UnitNum).EvapCooler_2_Index;
    4229             : 
    4230      196520 :     auto &EvapCond(state.dataEvapCoolers->EvapCond);
    4231             : 
    4232             :     // calculate unit sensible cooling output
    4233      196520 :     if (PartLoadRatio > 0) {
    4234       99322 :         Node(OAInletNodeNum).MassFlowRate = ZoneEvapUnit(UnitNum).DesignAirMassFlowRate * PartLoadRatio;
    4235       99322 :         Node(OAInletNodeNum).MassFlowRateMaxAvail = Node(OAInletNodeNum).MassFlowRate;
    4236       99322 :         Node(OutletNodeNum).MassFlowRate = Node(OAInletNodeNum).MassFlowRate;
    4237       99322 :         Node(OutletNodeNum).MassFlowRateMaxAvail = Node(OutletNodeNum).MassFlowRate;
    4238             :     } else { // not running
    4239       97198 :         Node(OAInletNodeNum).MassFlowRate = 0.0;
    4240       97198 :         Node(OAInletNodeNum).MassFlowRateMaxAvail = 0.0;
    4241       97198 :         Node(FanInletNodeNum).MassFlowRate = 0.0;
    4242       97198 :         Node(FanInletNodeNum).MassFlowRateMaxAvail = 0.0;
    4243       97198 :         Node(FanOutletNodeNum).MassFlowRate = 0.0;
    4244       97198 :         Node(FanOutletNodeNum).MassFlowRateMaxAvail = 0.0;
    4245       97198 :         Node(OutletNodeNum).MassFlowRate = 0.0;
    4246       97198 :         Node(OutletNodeNum).MassFlowRateMaxAvail = 0.0;
    4247             : 
    4248       97198 :         Node(EvapCond(EvapCooler_1_Index).InletNode).MassFlowRate = 0.0;
    4249       97198 :         Node(EvapCond(EvapCooler_1_Index).InletNode).MassFlowRateMaxAvail = 0.0;
    4250       97198 :         Node(EvapCond(EvapCooler_1_Index).OutletNode).MassFlowRate = 0.0;
    4251       97198 :         Node(EvapCond(EvapCooler_1_Index).OutletNode).MassFlowRateMaxAvail = 0.0;
    4252             : 
    4253       97198 :         if (EvapCooler_2_Index > 0) {
    4254       29608 :             Node(EvapCond(EvapCooler_2_Index).InletNode).MassFlowRate = 0.0;
    4255       29608 :             Node(EvapCond(EvapCooler_2_Index).InletNode).MassFlowRateMaxAvail = 0.0;
    4256       29608 :             Node(EvapCond(EvapCooler_2_Index).OutletNode).MassFlowRate = 0.0;
    4257       29608 :             Node(EvapCond(EvapCooler_2_Index).OutletNode).MassFlowRateMaxAvail = 0.0;
    4258             :         }
    4259             :     }
    4260      196520 :     if (ReliefNodeNum > 0) {
    4261      196520 :         Node(ReliefNodeNum).MassFlowRate = Node(OAInletNodeNum).MassFlowRate;
    4262      196520 :         Node(ReliefNodeNum).MassFlowRateMaxAvail = Node(OAInletNodeNum).MassFlowRate;
    4263             :     }
    4264      196520 :     if (ZoneEvapUnit(UnitNum).FanLocation == FanPlacement::BlowThruFan) {
    4265       77418 :         Node(FanOutletNodeNum).MassFlowRate = Node(OAInletNodeNum).MassFlowRate;
    4266       77418 :         Node(FanOutletNodeNum).MassFlowRateMaxAvail = Node(OAInletNodeNum).MassFlowRate;
    4267       77418 :         if (ZoneEvapUnit(UnitNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4268      281880 :             Fans::SimulateFanComponents(state,
    4269       56376 :                                         ZoneEvapUnit(UnitNum).FanName,
    4270             :                                         false,
    4271       56376 :                                         ZoneEvapUnit(UnitNum).FanIndex,
    4272             :                                         _,
    4273       56376 :                                         state.dataHVACGlobal->ZoneCompTurnFansOn,
    4274       56376 :                                         state.dataHVACGlobal->ZoneCompTurnFansOff);
    4275             :         } else {
    4276       63126 :             state.dataHVACFan->fanObjs[ZoneEvapUnit(UnitNum).FanIndex]->simulate(
    4277       42084 :                 state, _, state.dataHVACGlobal->ZoneCompTurnFansOn, state.dataHVACGlobal->ZoneCompTurnFansOff, _);
    4278             :         }
    4279             :     }
    4280             : 
    4281      196520 :     if (ZoneEvapUnit(UnitNum).EvapCooler_1_AvailStatus) {
    4282      196520 :         SimEvapCooler(state, ZoneEvapUnit(UnitNum).EvapCooler_1_Name, ZoneEvapUnit(UnitNum).EvapCooler_1_Index, PartLoadRatio);
    4283             :     }
    4284             : 
    4285      196520 :     if ((ZoneEvapUnit(UnitNum).EvapCooler_2_Index > 0) && ZoneEvapUnit(UnitNum).EvapCooler_2_AvailStatus) {
    4286       60790 :         SimEvapCooler(state, ZoneEvapUnit(UnitNum).EvapCooler_2_Name, ZoneEvapUnit(UnitNum).EvapCooler_2_Index, PartLoadRatio);
    4287             :     }
    4288      196520 :     if (ZoneEvapUnit(UnitNum).FanLocation == FanPlacement::DrawThruFan) {
    4289      119102 :         if (ZoneEvapUnit(UnitNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4290      414020 :             Fans::SimulateFanComponents(state,
    4291       82804 :                                         ZoneEvapUnit(UnitNum).FanName,
    4292             :                                         false,
    4293       82804 :                                         ZoneEvapUnit(UnitNum).FanIndex,
    4294             :                                         _,
    4295       82804 :                                         state.dataHVACGlobal->ZoneCompTurnFansOn,
    4296       82804 :                                         state.dataHVACGlobal->ZoneCompTurnFansOff);
    4297             :         } else {
    4298      108894 :             state.dataHVACFan->fanObjs[ZoneEvapUnit(UnitNum).FanIndex]->simulate(
    4299       72596 :                 state, _, state.dataHVACGlobal->ZoneCompTurnFansOn, state.dataHVACGlobal->ZoneCompTurnFansOff, _);
    4300             :         }
    4301             :     }
    4302             : 
    4303             :     // calculate sensible and latent outputs delivered
    4304      196520 :     MinHumRat = min(Node(ZoneNodeNum).HumRat, Node(OutletNodeNum).HumRat);
    4305      393040 :     SensibleOutputProvided = Node(OutletNodeNum).MassFlowRate * (Psychrometrics::PsyHFnTdbW(Node(OutletNodeNum).Temp, MinHumRat) -
    4306      196520 :                                                                  Psychrometrics::PsyHFnTdbW(Node(ZoneNodeNum).Temp, MinHumRat));
    4307      196520 :     LatentOutputProvided = Node(OutletNodeNum).MassFlowRate * (Node(OutletNodeNum).HumRat - Node(ZoneNodeNum).HumRat);
    4308      196520 : }
    4309             : 
    4310       19940 : void ControlZoneEvapUnitOutput(EnergyPlusData &state,
    4311             :                                int const UnitNum,           // unit number
    4312             :                                Real64 const ZoneCoolingLoad // target cooling load
    4313             : )
    4314             : {
    4315             : 
    4316             :     // calculates unit cooling part load ratio using root solver numerical method
    4317             : 
    4318             :     // local variables
    4319       19940 :     int constexpr MaxIte(50);      // maximum number of iterations
    4320       19940 :     Real64 constexpr Tol(0.01);    // error tolerance
    4321             :     int SolFla;                    // Flag of root solver
    4322             :     Real64 PartLoadRatio;          // cooling part load ratio
    4323             :     Real64 FullFlowSensibleOutput; // full flow sensible cooling output
    4324             :     Real64 FullFlowLatentOutput;   // full flow sensible cooling output
    4325             : 
    4326       19940 :     auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    4327             : 
    4328             :     // get full flow sensible cooling output
    4329       19940 :     PartLoadRatio = 1.0;
    4330       19940 :     CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, FullFlowSensibleOutput, FullFlowLatentOutput);
    4331             : 
    4332             :     // calculate part load ratio
    4333       19940 :     if (FullFlowSensibleOutput < ZoneCoolingLoad) {
    4334       97280 :         auto f = [&state, UnitNum, ZoneCoolingLoad](Real64 PartLoadRatio) {
    4335             :             // calculates cooling load residual by varying part load ratio
    4336             :             Real64 QSensOutputProvided; // sensible output at a given PLR
    4337             :             Real64 QLatOutputProvided;  // latent output at a given PLR
    4338       48640 :             CalcZoneEvapUnitOutput(state, UnitNum, PartLoadRatio, QSensOutputProvided, QLatOutputProvided);
    4339       97280 :             return QSensOutputProvided - ZoneCoolingLoad;
    4340        9106 :         };
    4341        9106 :         General::SolveRoot(state, Tol, MaxIte, SolFla, PartLoadRatio, f, 0.0, 1.0);
    4342        9106 :         if (SolFla == -1) {
    4343           0 :             if (ZoneEvapUnit(UnitNum).UnitLoadControlMaxIterErrorIndex == 0) {
    4344           0 :                 ShowWarningError(state, "Iteration limit exceeded calculating evap unit part load ratio, for unit=" + ZoneEvapUnit(UnitNum).Name);
    4345           0 :                 ShowContinueErrorTimeStamp(state, "");
    4346           0 :                 ShowContinueError(state, format("Unit part load ratio returned={:.2R}", PartLoadRatio));
    4347           0 :                 ShowContinueError(state, "Check input for Fan Placement.");
    4348             :             }
    4349           0 :             ShowRecurringWarningErrorAtEnd(
    4350             :                 state,
    4351           0 :                 format("Zone Evaporative Cooler unit part load ratio control failed (iteration limit [{}]) for ZoneHVAC:EvaporativeCoolerUnit =\"{}",
    4352             :                        MaxIte,
    4353           0 :                        ZoneEvapUnit(UnitNum).Name),
    4354           0 :                 ZoneEvapUnit(UnitNum).UnitLoadControlMaxIterErrorIndex);
    4355             : 
    4356        9106 :         } else if (SolFla == -2) {
    4357           0 :             if (ZoneEvapUnit(UnitNum).UnitLoadControlLimitsErrorIndex == 0) {
    4358           0 :                 ShowWarningError(state,
    4359           0 :                                  "Zone Evaporative Cooler unit calculation failed: unit part load ratio limits exceeded, for unit = " +
    4360           0 :                                      ZoneEvapUnit(UnitNum).Name);
    4361           0 :                 ShowContinueError(state, "Check input for Fan Placement.");
    4362           0 :                 ShowContinueErrorTimeStamp(state, "");
    4363           0 :                 if (state.dataGlobal->WarmupFlag) ShowContinueError(state, "Error occurred during warmup days.");
    4364             :             }
    4365           0 :             ShowRecurringWarningErrorAtEnd(
    4366             :                 state,
    4367           0 :                 "Zone Evaporative Cooler unit part load ratio control failed (limits exceeded) for ZoneHVAC:EvaporativeCoolerUnit =\"" +
    4368           0 :                     ZoneEvapUnit(UnitNum).Name,
    4369           0 :                 ZoneEvapUnit(UnitNum).UnitLoadControlLimitsErrorIndex);
    4370             :         }
    4371             : 
    4372             :     } else {
    4373       10834 :         PartLoadRatio = 1.0;
    4374             :     }
    4375       19940 :     ZoneEvapUnit(UnitNum).UnitPartLoadRatio = PartLoadRatio;
    4376       19940 : }
    4377             : 
    4378       19908 : void ControlVSEvapUnitToMeetLoad(EnergyPlusData &state,
    4379             :                                  int const UnitNum,           // unit number
    4380             :                                  Real64 const ZoneCoolingLoad // target cooling load
    4381             : )
    4382             : {
    4383             : 
    4384             :     // SUBROUTINE INFORMATION:
    4385             :     //       AUTHOR         <author>
    4386             :     //       DATE WRITTEN   <date_written>
    4387             :     //       MODIFIED       na
    4388             :     //       RE-ENGINEERED  na
    4389             : 
    4390             :     // Using/Aliasing
    4391       19908 :     auto &ZoneCompTurnFansOff = state.dataHVACGlobal->ZoneCompTurnFansOff;
    4392       19908 :     auto &ZoneCompTurnFansOn = state.dataHVACGlobal->ZoneCompTurnFansOn;
    4393             : 
    4394             :     // SUBROUTINE PARAMETER DEFINITIONS:
    4395       19908 :     int constexpr MaxIte(500); // maximum number of iterations
    4396             : 
    4397             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4398             :     Real64 MinHumRat;
    4399             :     Real64 FanSpeedRatio;
    4400       19908 :     Real64 ErrorToler(0.001); // error tolerance
    4401             :     int SolFla;               // Flag of RegulaFalsi solver
    4402             :     Real64 FullFlowSensibleOutputProvided;
    4403             : 
    4404       19908 :     auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    4405       19908 :     auto &Node(state.dataLoopNodes->Node);
    4406             : 
    4407             :     // first get full load result
    4408       19908 :     ErrorToler = 0.01;
    4409             : 
    4410       19908 :     ZoneEvapUnit(UnitNum).FanSpeedRatio = 1.0;
    4411       19908 :     Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRate = ZoneEvapUnit(UnitNum).DesignAirMassFlowRate;
    4412       19908 :     Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRateMaxAvail = Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRate;
    4413       19908 :     Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).MassFlowRate = Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRate;
    4414       19908 :     Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).MassFlowRateMaxAvail = Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).MassFlowRate;
    4415             : 
    4416       19908 :     if (ZoneEvapUnit(UnitNum).UnitReliefNodeNum > 0) {
    4417       19908 :         Node(ZoneEvapUnit(UnitNum).UnitReliefNodeNum).MassFlowRate = Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRate;
    4418       19908 :         Node(ZoneEvapUnit(UnitNum).UnitReliefNodeNum).MassFlowRateMaxAvail = Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRate;
    4419             :     }
    4420       19908 :     if (ZoneEvapUnit(UnitNum).FanLocation == FanPlacement::BlowThruFan) {
    4421       15920 :         Node(ZoneEvapUnit(UnitNum).FanOutletNodeNum).MassFlowRate = Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRate;
    4422       15920 :         Node(ZoneEvapUnit(UnitNum).FanOutletNodeNum).MassFlowRateMaxAvail = Node(ZoneEvapUnit(UnitNum).OAInletNodeNum).MassFlowRate;
    4423       15920 :         if (ZoneEvapUnit(UnitNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4424       35820 :             Fans::SimulateFanComponents(
    4425       23880 :                 state, ZoneEvapUnit(UnitNum).FanName, false, ZoneEvapUnit(UnitNum).FanIndex, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff);
    4426             :         } else {
    4427        3980 :             state.dataHVACFan->fanObjs[ZoneEvapUnit(UnitNum).FanIndex]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    4428             :         }
    4429             :     }
    4430             : 
    4431       19908 :     if (ZoneEvapUnit(UnitNum).EvapCooler_1_AvailStatus) {
    4432       19908 :         SimEvapCooler(state, ZoneEvapUnit(UnitNum).EvapCooler_1_Name, ZoneEvapUnit(UnitNum).EvapCooler_1_Index);
    4433             :     }
    4434             : 
    4435       19908 :     if ((ZoneEvapUnit(UnitNum).EvapCooler_2_Index > 0) && ZoneEvapUnit(UnitNum).EvapCooler_2_AvailStatus) {
    4436        7944 :         SimEvapCooler(state, ZoneEvapUnit(UnitNum).EvapCooler_2_Name, ZoneEvapUnit(UnitNum).EvapCooler_2_Index);
    4437             :     }
    4438       19908 :     if (ZoneEvapUnit(UnitNum).FanLocation == FanPlacement::DrawThruFan) {
    4439        3988 :         if (ZoneEvapUnit(UnitNum).FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4440        7974 :             Fans::SimulateFanComponents(
    4441        5316 :                 state, ZoneEvapUnit(UnitNum).FanName, false, ZoneEvapUnit(UnitNum).FanIndex, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff);
    4442             :         } else {
    4443        1330 :             state.dataHVACFan->fanObjs[ZoneEvapUnit(UnitNum).FanIndex]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    4444             :         }
    4445             :     }
    4446             : 
    4447             :     // calculate sensible load met using delta enthalpy at a constant (minimum) humidity ratio)
    4448       19908 :     MinHumRat = min(Node(ZoneEvapUnit(UnitNum).ZoneNodeNum).HumRat, Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).HumRat);
    4449       39816 :     FullFlowSensibleOutputProvided = Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).MassFlowRate *
    4450       39816 :                                      (Psychrometrics::PsyHFnTdbW(Node(ZoneEvapUnit(UnitNum).UnitOutletNodeNum).Temp, MinHumRat) -
    4451       19908 :                                       Psychrometrics::PsyHFnTdbW(Node(ZoneEvapUnit(UnitNum).ZoneNodeNum).Temp, MinHumRat));
    4452             : 
    4453       19908 :     if (FullFlowSensibleOutputProvided < ZoneCoolingLoad) { // find speed ratio by regula falsi numerical method
    4454        7908 :         FanSpeedRatio = 1.0;
    4455      368798 :         auto f = [&state, UnitNum, ZoneCoolingLoad](Real64 FanSpeedRatio) {
    4456       42234 :             auto &ZoneCompTurnFansOff = state.dataHVACGlobal->ZoneCompTurnFansOff;
    4457       42234 :             auto &ZoneCompTurnFansOn = state.dataHVACGlobal->ZoneCompTurnFansOn;
    4458       42234 :             auto &Node(state.dataLoopNodes->Node);
    4459       84468 :             auto &unit = state.dataEvapCoolers->ZoneEvapUnit(UnitNum);
    4460             : 
    4461       42234 :             Node(unit.OAInletNodeNum).MassFlowRate = unit.DesignAirMassFlowRate * FanSpeedRatio;
    4462       42234 :             Node(unit.OAInletNodeNum).MassFlowRateMaxAvail = Node(unit.OAInletNodeNum).MassFlowRate;
    4463       42234 :             Node(unit.UnitOutletNodeNum).MassFlowRate = Node(unit.OAInletNodeNum).MassFlowRate;
    4464       42234 :             Node(unit.UnitOutletNodeNum).MassFlowRateMaxAvail = Node(unit.UnitOutletNodeNum).MassFlowRate;
    4465             : 
    4466       42234 :             if (unit.UnitReliefNodeNum > 0) {
    4467       42234 :                 Node(unit.UnitReliefNodeNum).MassFlowRate = Node(unit.OAInletNodeNum).MassFlowRate;
    4468       42234 :                 Node(unit.UnitReliefNodeNum).MassFlowRateMaxAvail = Node(unit.OAInletNodeNum).MassFlowRate;
    4469             :             }
    4470       42234 :             if (unit.FanLocation == FanPlacement::BlowThruFan) {
    4471       33670 :                 Node(unit.FanOutletNodeNum).MassFlowRate = Node(unit.OAInletNodeNum).MassFlowRate;
    4472       33670 :                 Node(unit.FanOutletNodeNum).MassFlowRateMaxAvail = Node(unit.OAInletNodeNum).MassFlowRate;
    4473       33670 :                 if (unit.FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4474       51336 :                     Fans::SimulateFanComponents(state, unit.FanName, false, unit.FanIndex, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff);
    4475             :                 } else {
    4476       16004 :                     state.dataHVACFan->fanObjs[unit.FanIndex]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    4477             :                 }
    4478             :             }
    4479             : 
    4480       42234 :             if (unit.EvapCooler_1_AvailStatus) {
    4481       84468 :                 SimEvapCooler(state, unit.EvapCooler_1_Name, unit.EvapCooler_1_Index, FanSpeedRatio);
    4482             :             }
    4483             : 
    4484       42234 :             if ((unit.EvapCooler_2_Index > 0) && unit.EvapCooler_2_AvailStatus) {
    4485       40180 :                 SimEvapCooler(state, unit.EvapCooler_2_Name, unit.EvapCooler_2_Index, FanSpeedRatio);
    4486             :             }
    4487       42234 :             if (unit.FanLocation == FanPlacement::DrawThruFan) {
    4488        8564 :                 if (unit.FanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
    4489       11460 :                     Fans::SimulateFanComponents(state, unit.FanName, false, unit.FanIndex, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff);
    4490             :                 } else {
    4491        5668 :                     state.dataHVACFan->fanObjs[unit.FanIndex]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
    4492             :                 }
    4493             :             }
    4494             : 
    4495       42234 :             Real64 const MinHumRat = min(Node(unit.ZoneNodeNum).HumRat, Node(unit.UnitOutletNodeNum).HumRat);
    4496             :             Real64 const SensibleOutputProvided =
    4497       84468 :                 Node(unit.UnitOutletNodeNum).MassFlowRate * (Psychrometrics::PsyHFnTdbW(Node(unit.UnitOutletNodeNum).Temp, MinHumRat) -
    4498       84468 :                                                              Psychrometrics::PsyHFnTdbW(Node(unit.ZoneNodeNum).Temp, MinHumRat));
    4499             : 
    4500       42234 :             return SensibleOutputProvided - ZoneCoolingLoad;
    4501        7908 :         };
    4502        7908 :         General::SolveRoot(state, ErrorToler, MaxIte, SolFla, FanSpeedRatio, f, 0.0, 1.0);
    4503        7908 :         if (SolFla == -1) {
    4504           0 :             if (ZoneEvapUnit(UnitNum).UnitVSControlMaxIterErrorIndex == 0) {
    4505           0 :                 ShowWarningError(
    4506           0 :                     state, "Iteration limit exceeded calculating variable speed evap unit fan speed ratio, for unit=" + ZoneEvapUnit(UnitNum).Name);
    4507           0 :                 ShowContinueErrorTimeStamp(state, "");
    4508           0 :                 ShowContinueError(state, format("Fan speed ratio returned={:.2R}", FanSpeedRatio));
    4509           0 :                 ShowContinueError(state, "Check input for Fan Placement.");
    4510             :             }
    4511           0 :             ShowRecurringWarningErrorAtEnd(
    4512             :                 state,
    4513           0 :                 format("Zone Evaporative Cooler unit control failed (iteration limit [{}]) for ZoneHVAC:EvaporativeCoolerUnit =\"{}",
    4514             :                        MaxIte,
    4515           0 :                        ZoneEvapUnit(UnitNum).Name),
    4516           0 :                 ZoneEvapUnit(UnitNum).UnitVSControlMaxIterErrorIndex);
    4517             : 
    4518        7908 :         } else if (SolFla == -2) {
    4519           0 :             if (ZoneEvapUnit(UnitNum).UnitVSControlLimitsErrorIndex == 0) {
    4520           0 :                 ShowWarningError(state,
    4521           0 :                                  "Variable speed evaporative cooler unit calculation failed: fan speed ratio limits exceeded, for unit = " +
    4522           0 :                                      ZoneEvapUnit(UnitNum).Name);
    4523           0 :                 ShowContinueError(state, "Check input for Fan Placement.");
    4524           0 :                 ShowContinueErrorTimeStamp(state, "");
    4525           0 :                 if (state.dataGlobal->WarmupFlag) ShowContinueError(state, "Error occurred during warmup days.");
    4526             :             }
    4527           0 :             ShowRecurringWarningErrorAtEnd(state,
    4528           0 :                                            "Zone Evaporative Cooler unit control failed (limits exceeded) for ZoneHVAC:EvaporativeCoolerUnit =\"" +
    4529           0 :                                                ZoneEvapUnit(UnitNum).Name,
    4530           0 :                                            ZoneEvapUnit(UnitNum).UnitVSControlLimitsErrorIndex);
    4531             :         }
    4532        7908 :         ZoneEvapUnit(UnitNum).FanSpeedRatio = FanSpeedRatio;
    4533             :     }
    4534       19908 : }
    4535             : 
    4536      127940 : void ReportZoneEvaporativeCoolerUnit(EnergyPlusData &state, int const UnitNum) // unit number
    4537             : {
    4538             : 
    4539             :     // SUBROUTINE INFORMATION:
    4540             :     //       AUTHOR         B. Griffith
    4541             :     //       DATE WRITTEN   July 2013
    4542             :     //       MODIFIED       na
    4543             :     //       RE-ENGINEERED  na
    4544             : 
    4545             :     // PURPOSE OF THIS SUBROUTINE:
    4546             :     // update output variables for the zone evap unit
    4547             : 
    4548             :     // Using/Aliasing
    4549      127940 :     auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    4550             : 
    4551             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4552             :     int ZoneNodeNum;
    4553             :     int UnitOutletNodeNum;
    4554             :     Real64 AirMassFlow;
    4555             :     Real64 MinHumRat;
    4556             :     Real64 QTotUnitOut;
    4557             :     Real64 QSensUnitOut;
    4558             : 
    4559      127940 :     auto &ZoneEvapUnit(state.dataEvapCoolers->ZoneEvapUnit);
    4560             : 
    4561      127940 :     ZoneNodeNum = ZoneEvapUnit(UnitNum).ZoneNodeNum;
    4562      127940 :     UnitOutletNodeNum = ZoneEvapUnit(UnitNum).UnitOutletNodeNum;
    4563      127940 :     AirMassFlow = state.dataLoopNodes->Node(UnitOutletNodeNum).MassFlowRate;
    4564      127940 :     QTotUnitOut = AirMassFlow * (state.dataLoopNodes->Node(UnitOutletNodeNum).Enthalpy - state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy);
    4565      127940 :     MinHumRat = min(state.dataLoopNodes->Node(ZoneNodeNum).HumRat, state.dataLoopNodes->Node(UnitOutletNodeNum).HumRat);
    4566      255880 :     QSensUnitOut = AirMassFlow * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(UnitOutletNodeNum).Temp, MinHumRat) -
    4567      127940 :                                   Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(ZoneNodeNum).Temp, MinHumRat));
    4568             : 
    4569      127940 :     ZoneEvapUnit(UnitNum).UnitTotalCoolingRate = std::abs(min(0.0, QTotUnitOut));
    4570      127940 :     ZoneEvapUnit(UnitNum).UnitTotalCoolingEnergy = ZoneEvapUnit(UnitNum).UnitTotalCoolingRate * TimeStepSys * DataGlobalConstants::SecInHour;
    4571      127940 :     ZoneEvapUnit(UnitNum).UnitSensibleCoolingRate = std::abs(min(0.0, QSensUnitOut));
    4572      127940 :     ZoneEvapUnit(UnitNum).UnitSensibleCoolingEnergy = ZoneEvapUnit(UnitNum).UnitSensibleCoolingRate * TimeStepSys * DataGlobalConstants::SecInHour;
    4573      127940 :     ZoneEvapUnit(UnitNum).UnitLatentHeatingRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
    4574      127940 :     ZoneEvapUnit(UnitNum).UnitLatentHeatingEnergy = ZoneEvapUnit(UnitNum).UnitLatentHeatingRate * TimeStepSys * DataGlobalConstants::SecInHour;
    4575      127940 :     ZoneEvapUnit(UnitNum).UnitLatentCoolingRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
    4576      127940 :     ZoneEvapUnit(UnitNum).UnitLatentCoolingEnergy = ZoneEvapUnit(UnitNum).UnitLatentCoolingRate * TimeStepSys * DataGlobalConstants::SecInHour;
    4577      127940 :     ZoneEvapUnit(UnitNum).UnitFanSpeedRatio = ZoneEvapUnit(UnitNum).FanSpeedRatio;
    4578      127940 : }
    4579             : 
    4580           0 : int GetInletNodeNum(EnergyPlusData &state, std::string const &EvapCondName, bool &ErrorsFound)
    4581             : {
    4582             :     // FUNCTION INFORMATION:
    4583             :     //       AUTHOR         Lixing Gu
    4584             :     //       DATE WRITTEN   May 2019
    4585             :     //       MODIFIED       na
    4586             :     //       RE-ENGINEERED  na
    4587             : 
    4588             :     // PURPOSE OF THIS FUNCTION:
    4589             :     // This function looks up the given EvapCond and returns the air inlet node number.
    4590             :     // If incorrect EvapCond name is given, ErrorsFound is returned as true and node number as zero.
    4591             : 
    4592           0 :     if (state.dataEvapCoolers->GetInputEvapComponentsFlag) { // First time subroutine has been entered
    4593           0 :         GetEvapInput(state);
    4594           0 :         state.dataEvapCoolers->GetInputEvapComponentsFlag = false;
    4595             :     }
    4596             : 
    4597             :     int WhichEvapCond =
    4598           0 :         UtilityRoutines::FindItemInList(EvapCondName, state.dataEvapCoolers->EvapCond, &EvapConditions::Name, state.dataEvapCoolers->NumEvapCool);
    4599           0 :     if (WhichEvapCond != 0) {
    4600           0 :         return state.dataEvapCoolers->EvapCond(WhichEvapCond).InletNode;
    4601             :     } else {
    4602           0 :         ShowSevereError(state, "GetInletNodeNum: Could not find EvaporativeCooler = \"" + EvapCondName + "\"");
    4603           0 :         ErrorsFound = true;
    4604           0 :         return 0;
    4605             :     }
    4606             : }
    4607             : 
    4608           0 : int GetOutletNodeNum(EnergyPlusData &state, std::string const &EvapCondName, bool &ErrorsFound)
    4609             : {
    4610             :     // FUNCTION INFORMATION:
    4611             :     //       AUTHOR         Lixing Gu
    4612             :     //       DATE WRITTEN   May 2019
    4613             :     //       MODIFIED       na
    4614             :     //       RE-ENGINEERED  na
    4615             : 
    4616             :     // PURPOSE OF THIS FUNCTION:
    4617             :     // This function looks up the given EvapCond and returns the air outlet node number.
    4618             :     // If incorrect EvapCond name is given, ErrorsFound is returned as true and node number as zero.
    4619             : 
    4620           0 :     if (state.dataEvapCoolers->GetInputEvapComponentsFlag) { // First time subroutine has been entered
    4621           0 :         GetEvapInput(state);
    4622           0 :         state.dataEvapCoolers->GetInputEvapComponentsFlag = false;
    4623             :     }
    4624             :     int WhichEvapCond =
    4625           0 :         UtilityRoutines::FindItemInList(EvapCondName, state.dataEvapCoolers->EvapCond, &EvapConditions::Name, state.dataEvapCoolers->NumEvapCool);
    4626           0 :     if (WhichEvapCond != 0) {
    4627           0 :         return state.dataEvapCoolers->EvapCond(WhichEvapCond).OutletNode;
    4628             :     } else {
    4629           0 :         ShowSevereError(state, "GetOutletNodeNum: Could not find EvaporativeCooler = \"" + EvapCondName + "\"");
    4630           0 :         ErrorsFound = true;
    4631           0 :         return 0;
    4632             :     }
    4633             : }
    4634             : 
    4635        2313 : } // namespace EnergyPlus::EvaporativeCoolers

Generated by: LCOV version 1.13