LCOV - code coverage report
Current view: top level - EnergyPlus - ChillerElectricEIR.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 58.5 % 1348 789
Test Date: 2025-06-02 12:03:30 Functions: 94.1 % 17 16

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cassert>
      50              : #include <cmath>
      51              : #include <string>
      52              : 
      53              : // ObjexxFCL Headers
      54              : #include <ObjexxFCL/Fmath.hh>
      55              : #include <ObjexxFCL/string.functions.hh>
      56              : 
      57              : // EnergyPlus Headers
      58              : #include <EnergyPlus/Autosizing/All_Simple_Sizing.hh>
      59              : #include <EnergyPlus/BranchNodeConnections.hh>
      60              : #include <EnergyPlus/ChillerElectricEIR.hh>
      61              : #include <EnergyPlus/CurveManager.hh>
      62              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      63              : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      64              : #include <EnergyPlus/DataEnvironment.hh>
      65              : #include <EnergyPlus/DataHVACGlobals.hh>
      66              : #include <EnergyPlus/DataIPShortCuts.hh>
      67              : #include <EnergyPlus/DataLoopNode.hh>
      68              : #include <EnergyPlus/DataSizing.hh>
      69              : #include <EnergyPlus/EMSManager.hh>
      70              : #include <EnergyPlus/FaultsManager.hh>
      71              : #include <EnergyPlus/FluidProperties.hh>
      72              : #include <EnergyPlus/General.hh>
      73              : #include <EnergyPlus/GeneralRoutines.hh>
      74              : #include <EnergyPlus/GlobalNames.hh>
      75              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      76              : #include <EnergyPlus/NodeInputManager.hh>
      77              : #include <EnergyPlus/OutAirNodeManager.hh>
      78              : #include <EnergyPlus/OutputProcessor.hh>
      79              : #include <EnergyPlus/OutputReportPredefined.hh>
      80              : #include <EnergyPlus/Plant/DataPlant.hh>
      81              : #include <EnergyPlus/Plant/PlantLocation.hh>
      82              : #include <EnergyPlus/PlantUtilities.hh>
      83              : #include <EnergyPlus/Psychrometrics.hh>
      84              : #include <EnergyPlus/ScheduleManager.hh>
      85              : #include <EnergyPlus/StandardRatings.hh>
      86              : #include <EnergyPlus/UtilityRoutines.hh>
      87              : 
      88              : namespace EnergyPlus::ChillerElectricEIR {
      89              : 
      90              : // NOTES:
      91              : // The Electric EIR and Reformulated EIR chiller models are similar.
      92              : // They only differ in the independent variable used to evaluate the performance curves.
      93              : 
      94              : // MODULE INFORMATION:
      95              : //       AUTHOR         Richard Raustad
      96              : //       DATE WRITTEN   June 2004
      97              : //       MODIFIED       Chandan Sharma, FSEC, February 2010, Added basin heater
      98              : //                      Brent Griffith, NREL, Sept 2010, revised for plant changes
      99              : //                      generalized fluid properties
     100              : 
     101              : // PURPOSE OF THIS MODULE:
     102              : //  This module simulates the performance of the electric vapor
     103              : //  compression chiller used in DOE-2.
     104              : 
     105              : // METHODOLOGY EMPLOYED:
     106              : //  Once the PlantLoopManager determines that the Electric EIR chiller
     107              : //  is available to meet a loop cooling demand, it calls SimElectricEIRChiller
     108              : //  which in turn calls the electric EIR model. The EIR chiller model is based on
     109              : //  polynomial fits of chiller performance data.
     110              : 
     111              : // REFERENCES:
     112              : // 1. DOE-2 Engineers Manual, Version 2.1A, November 1982, LBL-11353
     113              : 
     114            1 : ElectricEIRChillerSpecs *ElectricEIRChillerSpecs::factory(EnergyPlusData &state, std::string const &objectName)
     115              : {
     116              :     // Process the input data if it hasn't been done already
     117            1 :     if (state.dataChillerElectricEIR->getInputFlag) {
     118            1 :         GetElectricEIRChillerInput(state);
     119            1 :         state.dataChillerElectricEIR->getInputFlag = false;
     120              :     }
     121              :     // Now look for this particular object in the list
     122            1 :     auto thisObj = std::find_if(state.dataChillerElectricEIR->ElectricEIRChiller.begin(),
     123            1 :                                 state.dataChillerElectricEIR->ElectricEIRChiller.end(),
     124            1 :                                 [&objectName](const ElectricEIRChillerSpecs &myObj) { return myObj.Name == objectName; });
     125            1 :     if (thisObj != state.dataChillerElectricEIR->ElectricEIRChiller.end()) {
     126            1 :         return thisObj;
     127              :     }
     128              :     // If we didn't find it, fatal
     129              :     ShowFatalError(state, format("LocalElectEIRChillerFactory: Error getting inputs for object named: {}", objectName)); // LCOV_EXCL_LINE
     130              :     // Shut up the compiler
     131              :     return nullptr; // LCOV_EXCL_LINE
     132              : }
     133              : 
     134         1430 : void ElectricEIRChillerSpecs::simulate(
     135              :     EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag)
     136              : {
     137              :     // SUBROUTINE INFORMATION:
     138              :     //       AUTHOR         Richard Raustad
     139              :     //       DATE WRITTEN   June 2004
     140              : 
     141              :     // PURPOSE OF THIS SUBROUTINE:
     142              :     //  This is the electric EIR chiller model driver. It gets the input for the
     143              :     //  model, initializes simulation variables, calls the appropriate model and sets
     144              :     //  up reporting variables.
     145              : 
     146         1430 :     if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) {
     147         1430 :         this->initialize(state, RunFlag, CurLoad);
     148         1430 :         this->calculate(state, CurLoad, RunFlag);
     149         1430 :         this->update(state, CurLoad, RunFlag);
     150              : 
     151            0 :     } else if (calledFromLocation.loopNum == this->CDPlantLoc.loopNum) {
     152            0 :         PlantUtilities::UpdateChillerComponentCondenserSide(state,
     153            0 :                                                             calledFromLocation.loopNum,
     154              :                                                             this->CDPlantLoc.loopSideNum,
     155              :                                                             DataPlant::PlantEquipmentType::Chiller_ElectricEIR,
     156              :                                                             this->CondInletNodeNum,
     157              :                                                             this->CondOutletNodeNum,
     158              :                                                             this->QCondenser,
     159              :                                                             this->CondInletTemp,
     160              :                                                             this->CondOutletTemp,
     161              :                                                             this->CondMassFlowRate,
     162              :                                                             FirstHVACIteration);
     163              : 
     164            0 :     } else if (calledFromLocation.loopNum == this->HRPlantLoc.loopNum) {
     165            0 :         PlantUtilities::UpdateComponentHeatRecoverySide(state,
     166              :                                                         this->HRPlantLoc.loopNum,
     167              :                                                         this->HRPlantLoc.loopSideNum,
     168              :                                                         DataPlant::PlantEquipmentType::Chiller_ElectricEIR,
     169              :                                                         this->HeatRecInletNodeNum,
     170              :                                                         this->HeatRecOutletNodeNum,
     171              :                                                         this->QHeatRecovered,
     172              :                                                         this->HeatRecInletTemp,
     173              :                                                         this->HeatRecOutletTemp,
     174              :                                                         this->HeatRecMassFlow,
     175              :                                                         FirstHVACIteration);
     176              :     }
     177         1430 : }
     178              : 
     179            5 : void ElectricEIRChillerSpecs::getDesignCapacities(
     180              :     [[maybe_unused]] EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
     181              : {
     182            5 :     if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) {
     183            5 :         MinLoad = this->RefCap * this->MinPartLoadRat;
     184            5 :         MaxLoad = this->RefCap * this->MaxPartLoadRat;
     185            5 :         OptLoad = this->RefCap * this->OptPartLoadRat;
     186              :     } else {
     187            0 :         MinLoad = 0.0;
     188            0 :         MaxLoad = 0.0;
     189            0 :         OptLoad = 0.0;
     190              :     }
     191            5 : }
     192              : 
     193            5 : void ElectricEIRChillerSpecs::getDesignTemperatures(Real64 &TempDesCondIn, Real64 &TempDesEvapOut)
     194              : {
     195            5 :     TempDesCondIn = this->TempRefCondIn;
     196            5 :     TempDesEvapOut = this->TempRefEvapOut;
     197            5 : }
     198              : 
     199            1 : void ElectricEIRChillerSpecs::getSizingFactor(Real64 &sizFac)
     200              : {
     201            1 :     sizFac = this->SizFac;
     202            1 : }
     203              : 
     204            5 : void ElectricEIRChillerSpecs::onInitLoopEquip(EnergyPlusData &state, const PlantLocation &calledFromLocation)
     205              : {
     206            5 :     bool runFlag = true;
     207            5 :     Real64 myLoad = 0.0;
     208              : 
     209            5 :     this->initialize(state, runFlag, myLoad);
     210              : 
     211            5 :     if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) {
     212            5 :         this->size(state);
     213              :     }
     214            5 : }
     215              : 
     216            5 : void GetElectricEIRChillerInput(EnergyPlusData &state)
     217              : {
     218              :     // SUBROUTINE INFORMATION:
     219              :     //       AUTHOR:          Richard Raustad, FSEC
     220              :     //       DATE WRITTEN:    June 2004
     221              : 
     222              :     // PURPOSE OF THIS SUBROUTINE:
     223              :     //  This routine will get the input required by the Electric EIR Chiller model.
     224              : 
     225              :     static constexpr std::string_view RoutineName("GetElectricEIRChillerInput: "); // include trailing blank space
     226              :     static constexpr std::string_view routineName = "GetElectricEIRChillerInput";  // include trailing blank space
     227              : 
     228            5 :     bool ErrorsFound(false); // True when input errors are found
     229              : 
     230            5 :     auto &s_ipsc = state.dataIPShortCut;
     231              : 
     232            5 :     s_ipsc->cCurrentModuleObject = "Chiller:Electric:EIR";
     233            5 :     int NumElectricEIRChillers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, s_ipsc->cCurrentModuleObject);
     234              : 
     235            5 :     if (NumElectricEIRChillers <= 0) {
     236            0 :         ShowSevereError(state, format("No {} equipment specified in input file", s_ipsc->cCurrentModuleObject));
     237            0 :         ErrorsFound = true;
     238              :     }
     239              : 
     240              :     // ALLOCATE ARRAYS
     241            5 :     state.dataChillerElectricEIR->ElectricEIRChiller.allocate(NumElectricEIRChillers);
     242              : 
     243              :     // Load arrays with electric EIR chiller data
     244           10 :     for (int EIRChillerNum = 1; EIRChillerNum <= NumElectricEIRChillers; ++EIRChillerNum) {
     245            5 :         int NumAlphas = 0; // Number of elements in the alpha array
     246            5 :         int NumNums = 0;   // Number of elements in the numeric array
     247            5 :         int IOStat = 0;    // IO Status when calling get input subroutine
     248           10 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     249            5 :                                                                  s_ipsc->cCurrentModuleObject,
     250              :                                                                  EIRChillerNum,
     251            5 :                                                                  s_ipsc->cAlphaArgs,
     252              :                                                                  NumAlphas,
     253            5 :                                                                  s_ipsc->rNumericArgs,
     254              :                                                                  NumNums,
     255              :                                                                  IOStat,
     256            5 :                                                                  s_ipsc->lNumericFieldBlanks,
     257            5 :                                                                  s_ipsc->lAlphaFieldBlanks,
     258            5 :                                                                  s_ipsc->cAlphaFieldNames,
     259            5 :                                                                  s_ipsc->cNumericFieldNames);
     260              : 
     261            5 :         ErrorObjectHeader eoh{routineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)};
     262              : 
     263              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
     264            5 :         GlobalNames::VerifyUniqueChillerName(
     265           10 :             state, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1), ErrorsFound, s_ipsc->cCurrentModuleObject + " Name");
     266              : 
     267            5 :         auto &thisChiller = state.dataChillerElectricEIR->ElectricEIRChiller(EIRChillerNum);
     268            5 :         thisChiller.Name = s_ipsc->cAlphaArgs(1);
     269              : 
     270              :         //   Performance curves
     271            5 :         thisChiller.ChillerCapFTIndex = Curve::GetCurveIndex(state, s_ipsc->cAlphaArgs(2));
     272            5 :         if (thisChiller.ChillerCapFTIndex == 0) {
     273            0 :             ShowSevereError(state, format("{}{} \"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     274            0 :             ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(2), s_ipsc->cAlphaArgs(2)));
     275            0 :             ErrorsFound = true;
     276              :         }
     277              : 
     278            5 :         thisChiller.ChillerEIRFTIndex = Curve::GetCurveIndex(state, s_ipsc->cAlphaArgs(3));
     279            5 :         if (thisChiller.ChillerEIRFTIndex == 0) {
     280            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     281            0 :             ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(3), s_ipsc->cAlphaArgs(3)));
     282            0 :             ErrorsFound = true;
     283              :         }
     284              : 
     285            5 :         thisChiller.ChillerEIRFPLRIndex = Curve::GetCurveIndex(state, s_ipsc->cAlphaArgs(4));
     286            5 :         if (thisChiller.ChillerEIRFPLRIndex == 0) {
     287            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     288            0 :             ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(4), s_ipsc->cAlphaArgs(4)));
     289            0 :             ErrorsFound = true;
     290              :         }
     291              : 
     292            5 :         thisChiller.EvapInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     293            5 :                                                                            s_ipsc->cAlphaArgs(5),
     294              :                                                                            ErrorsFound,
     295              :                                                                            DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     296            5 :                                                                            s_ipsc->cAlphaArgs(1),
     297              :                                                                            DataLoopNode::NodeFluidType::Water,
     298              :                                                                            DataLoopNode::ConnectionType::Inlet,
     299              :                                                                            NodeInputManager::CompFluidStream::Primary,
     300              :                                                                            DataLoopNode::ObjectIsNotParent);
     301           10 :         thisChiller.EvapOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     302            5 :                                                                             s_ipsc->cAlphaArgs(6),
     303              :                                                                             ErrorsFound,
     304              :                                                                             DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     305            5 :                                                                             s_ipsc->cAlphaArgs(1),
     306              :                                                                             DataLoopNode::NodeFluidType::Water,
     307              :                                                                             DataLoopNode::ConnectionType::Outlet,
     308              :                                                                             NodeInputManager::CompFluidStream::Primary,
     309              :                                                                             DataLoopNode::ObjectIsNotParent);
     310           10 :         BranchNodeConnections::TestCompSet(
     311            5 :             state, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1), s_ipsc->cAlphaArgs(5), s_ipsc->cAlphaArgs(6), "Chilled Water Nodes");
     312              : 
     313            5 :         if (Util::SameString(s_ipsc->cAlphaArgs(9), "WaterCooled")) {
     314            2 :             thisChiller.CondenserType = DataPlant::CondenserType::WaterCooled;
     315            3 :         } else if (Util::SameString(s_ipsc->cAlphaArgs(9), "AirCooled")) {
     316            2 :             thisChiller.CondenserType = DataPlant::CondenserType::AirCooled;
     317            1 :         } else if (Util::SameString(s_ipsc->cAlphaArgs(9), "EvaporativelyCooled")) {
     318            1 :             thisChiller.CondenserType = DataPlant::CondenserType::EvapCooled;
     319              :         } else {
     320            0 :             ShowSevereError(state, format("{}{}: {}", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     321            0 :             ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(9), s_ipsc->cAlphaArgs(9)));
     322            0 :             ShowContinueError(state, "Valid entries are AirCooled, WaterCooled, or EvaporativelyCooled");
     323            0 :             ErrorsFound = true;
     324              :         }
     325              : 
     326            5 :         if (thisChiller.CondenserType == DataPlant::CondenserType::AirCooled || thisChiller.CondenserType == DataPlant::CondenserType::EvapCooled) {
     327              :             // Connection not required for air or evap cooled condenser
     328              :             // If the condenser inlet is blank for air cooled and evap cooled condensers then supply a generic name
     329              :             // since it is not used elsewhere for connection
     330            3 :             if (s_ipsc->lAlphaFieldBlanks(7)) {
     331            0 :                 if (len(s_ipsc->cAlphaArgs(1)) < Constant::MaxNameLength - 25) { // protect against long name leading to > 100 chars
     332            0 :                     s_ipsc->cAlphaArgs(7) = s_ipsc->cAlphaArgs(1) + " INLET NODE FOR CONDENSER";
     333              :                 } else {
     334            0 :                     s_ipsc->cAlphaArgs(7) = s_ipsc->cAlphaArgs(1).substr(0, 75) + " INLET NODE FOR CONDENSER";
     335              :                 }
     336              :             }
     337            3 :             if (s_ipsc->lAlphaFieldBlanks(8)) {
     338            0 :                 if (len(s_ipsc->cAlphaArgs(1)) < Constant::MaxNameLength - 26) { // protect against long name leading to > 100 chars
     339            0 :                     s_ipsc->cAlphaArgs(8) = s_ipsc->cAlphaArgs(1) + " OUTLET NODE FOR CONDENSER";
     340              :                 } else {
     341            0 :                     s_ipsc->cAlphaArgs(8) = s_ipsc->cAlphaArgs(1).substr(0, 74) + " OUTLET NODE FOR CONDENSER";
     342              :                 }
     343              :             }
     344              : 
     345            3 :             thisChiller.CondInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     346            3 :                                                                                s_ipsc->cAlphaArgs(7),
     347              :                                                                                ErrorsFound,
     348              :                                                                                DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     349            3 :                                                                                s_ipsc->cAlphaArgs(1),
     350              :                                                                                DataLoopNode::NodeFluidType::Air,
     351              :                                                                                DataLoopNode::ConnectionType::OutsideAirReference,
     352              :                                                                                NodeInputManager::CompFluidStream::Secondary,
     353              :                                                                                DataLoopNode::ObjectIsNotParent);
     354            3 :             bool Okay = true;
     355            3 :             OutAirNodeManager::CheckAndAddAirNodeNumber(state, thisChiller.CondInletNodeNum, Okay);
     356            3 :             if (!Okay) {
     357            2 :                 ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     358            2 :                 ShowContinueError(state, format("Adding OutdoorAir:Node={}", s_ipsc->cAlphaArgs(7)));
     359              :             }
     360              : 
     361            3 :             thisChiller.CondOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     362            3 :                                                                                 s_ipsc->cAlphaArgs(8),
     363              :                                                                                 ErrorsFound,
     364              :                                                                                 DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     365            3 :                                                                                 s_ipsc->cAlphaArgs(1),
     366              :                                                                                 DataLoopNode::NodeFluidType::Air,
     367              :                                                                                 DataLoopNode::ConnectionType::Outlet,
     368              :                                                                                 NodeInputManager::CompFluidStream::Secondary,
     369              :                                                                                 DataLoopNode::ObjectIsNotParent);
     370              : 
     371            5 :         } else if (thisChiller.CondenserType == DataPlant::CondenserType::WaterCooled) {
     372              :             // Condenser inlet node name is necessary for water-cooled condenser
     373            2 :             if (s_ipsc->lAlphaFieldBlanks(7) || s_ipsc->lAlphaFieldBlanks(8)) {
     374            0 :                 ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     375            0 :                 ShowContinueError(state, "Condenser Inlet or Outlet Node Name is blank.");
     376            0 :                 ErrorsFound = true;
     377              :             }
     378              : 
     379            2 :             thisChiller.CondInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     380            2 :                                                                                s_ipsc->cAlphaArgs(7),
     381              :                                                                                ErrorsFound,
     382              :                                                                                DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     383            2 :                                                                                s_ipsc->cAlphaArgs(1),
     384              :                                                                                DataLoopNode::NodeFluidType::Water,
     385              :                                                                                DataLoopNode::ConnectionType::Inlet,
     386              :                                                                                NodeInputManager::CompFluidStream::Secondary,
     387              :                                                                                DataLoopNode::ObjectIsNotParent);
     388              : 
     389            4 :             thisChiller.CondOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     390            2 :                                                                                 s_ipsc->cAlphaArgs(8),
     391              :                                                                                 ErrorsFound,
     392              :                                                                                 DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     393            2 :                                                                                 s_ipsc->cAlphaArgs(1),
     394              :                                                                                 DataLoopNode::NodeFluidType::Water,
     395              :                                                                                 DataLoopNode::ConnectionType::Outlet,
     396              :                                                                                 NodeInputManager::CompFluidStream::Secondary,
     397              :                                                                                 DataLoopNode::ObjectIsNotParent);
     398              : 
     399            6 :             BranchNodeConnections::TestCompSet(
     400            2 :                 state, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1), s_ipsc->cAlphaArgs(7), s_ipsc->cAlphaArgs(8), "Condenser Water Nodes");
     401              : 
     402              :         } else {
     403              :             // Condenser inlet node name is necessary (never should reach this part of code)
     404            0 :             if (s_ipsc->lAlphaFieldBlanks(7) || s_ipsc->lAlphaFieldBlanks(8)) {
     405            0 :                 ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     406            0 :                 ShowContinueError(state, "Condenser Inlet or Outlet Node Name is blank.");
     407            0 :                 ErrorsFound = true;
     408              :             }
     409            0 :             thisChiller.CondInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     410            0 :                                                                                s_ipsc->cAlphaArgs(7),
     411              :                                                                                ErrorsFound,
     412              :                                                                                DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     413            0 :                                                                                s_ipsc->cAlphaArgs(1),
     414              :                                                                                DataLoopNode::NodeFluidType::Blank,
     415              :                                                                                DataLoopNode::ConnectionType::Inlet,
     416              :                                                                                NodeInputManager::CompFluidStream::Secondary,
     417              :                                                                                DataLoopNode::ObjectIsNotParent);
     418              : 
     419            0 :             thisChiller.CondOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     420            0 :                                                                                 s_ipsc->cAlphaArgs(8),
     421              :                                                                                 ErrorsFound,
     422              :                                                                                 DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     423            0 :                                                                                 s_ipsc->cAlphaArgs(1),
     424              :                                                                                 DataLoopNode::NodeFluidType::Blank,
     425              :                                                                                 DataLoopNode::ConnectionType::Outlet,
     426              :                                                                                 NodeInputManager::CompFluidStream::Secondary,
     427              :                                                                                 DataLoopNode::ObjectIsNotParent);
     428              : 
     429            0 :             BranchNodeConnections::TestCompSet(state,
     430            0 :                                                s_ipsc->cCurrentModuleObject,
     431            0 :                                                s_ipsc->cAlphaArgs(1),
     432            0 :                                                s_ipsc->cAlphaArgs(7),
     433            0 :                                                s_ipsc->cAlphaArgs(8),
     434              :                                                "Condenser (unknown?) Nodes");
     435              :         }
     436              : 
     437            5 :         thisChiller.FlowMode = static_cast<DataPlant::FlowMode>(getEnumValue(DataPlant::FlowModeNamesUC, s_ipsc->cAlphaArgs(10)));
     438            5 :         if (thisChiller.FlowMode == DataPlant::FlowMode::Invalid) {
     439            0 :             ShowSevereError(state, format("{}{}=\"{}\",", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     440            0 :             ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(10), s_ipsc->cAlphaArgs(10)));
     441            0 :             ShowContinueError(state, "Available choices are ConstantFlow, NotModulated, or LeavingSetpointModulated");
     442            0 :             ShowContinueError(state, "Flow mode NotModulated is assumed and the simulation continues.");
     443            0 :             thisChiller.FlowMode = DataPlant::FlowMode::NotModulated;
     444              :         };
     445              : 
     446              :         //   Chiller rated performance data
     447            5 :         thisChiller.RefCap = s_ipsc->rNumericArgs(1);
     448            5 :         if (thisChiller.RefCap == DataSizing::AutoSize) {
     449            5 :             thisChiller.RefCapWasAutoSized = true;
     450              :         }
     451            5 :         if (s_ipsc->rNumericArgs(1) == 0.0) {
     452            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     453            0 :             ShowContinueError(state, format("Invalid {}={:.2R}", s_ipsc->cNumericFieldNames(1), s_ipsc->rNumericArgs(1)));
     454            0 :             ErrorsFound = true;
     455              :         }
     456            5 :         thisChiller.RefCOP = s_ipsc->rNumericArgs(2);
     457            5 :         if (s_ipsc->rNumericArgs(2) == 0.0) {
     458            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     459            0 :             ShowContinueError(state, format("Invalid {}={:.2R}", s_ipsc->cNumericFieldNames(2), s_ipsc->rNumericArgs(2)));
     460            0 :             ErrorsFound = true;
     461              :         }
     462            5 :         thisChiller.TempRefEvapOut = s_ipsc->rNumericArgs(3);
     463            5 :         thisChiller.TempRefCondIn = s_ipsc->rNumericArgs(4);
     464            5 :         thisChiller.EvapVolFlowRate = s_ipsc->rNumericArgs(5);
     465            5 :         if (thisChiller.EvapVolFlowRate == DataSizing::AutoSize) {
     466            5 :             thisChiller.EvapVolFlowRateWasAutoSized = true;
     467              :         }
     468            5 :         thisChiller.CondVolFlowRate = s_ipsc->rNumericArgs(6);
     469            5 :         if (thisChiller.CondVolFlowRate == DataSizing::AutoSize) {
     470            4 :             thisChiller.CondVolFlowRateWasAutoSized = true;
     471              :         }
     472              : 
     473            5 :         thisChiller.MinPartLoadRat = s_ipsc->rNumericArgs(7);
     474            5 :         thisChiller.MaxPartLoadRat = s_ipsc->rNumericArgs(8);
     475            5 :         thisChiller.OptPartLoadRat = s_ipsc->rNumericArgs(9);
     476            5 :         thisChiller.MinUnloadRat = s_ipsc->rNumericArgs(10);
     477            5 :         thisChiller.SizFac = s_ipsc->rNumericArgs(15);
     478            5 :         if (thisChiller.SizFac <= 0.0) {
     479            0 :             thisChiller.SizFac = 1.0;
     480              :         }
     481              : 
     482            5 :         if (thisChiller.MinPartLoadRat > thisChiller.MaxPartLoadRat) {
     483            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     484            0 :             ShowContinueError(state,
     485            0 :                               format("{} [{:.3R}] > {} [{:.3R}]",
     486            0 :                                      s_ipsc->cNumericFieldNames(7),
     487            0 :                                      s_ipsc->rNumericArgs(7),
     488            0 :                                      s_ipsc->cNumericFieldNames(8),
     489            0 :                                      s_ipsc->rNumericArgs(8)));
     490            0 :             ShowContinueError(state, "Minimum part load ratio must be less than or equal to the maximum part load ratio ");
     491            0 :             ErrorsFound = true;
     492              :         }
     493              : 
     494            5 :         if (thisChiller.MinUnloadRat < thisChiller.MinPartLoadRat || thisChiller.MinUnloadRat > thisChiller.MaxPartLoadRat) {
     495            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     496            0 :             ShowContinueError(state, format("{} = {:.3R}", s_ipsc->cNumericFieldNames(10), s_ipsc->rNumericArgs(10)));
     497            0 :             ShowContinueError(state,
     498            0 :                               format("{} must be greater than or equal to the {}", s_ipsc->cNumericFieldNames(10), s_ipsc->cNumericFieldNames(7)));
     499            0 :             ShowContinueError(state,
     500            0 :                               format("{} must be less than or equal to the {}", s_ipsc->cNumericFieldNames(10), s_ipsc->cNumericFieldNames(8)));
     501            0 :             ErrorsFound = true;
     502              :         }
     503              : 
     504            5 :         if (thisChiller.OptPartLoadRat < thisChiller.MinPartLoadRat || thisChiller.OptPartLoadRat > thisChiller.MaxPartLoadRat) {
     505            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     506            0 :             ShowContinueError(state, format("{} = {:.3R}", s_ipsc->cNumericFieldNames(9), s_ipsc->rNumericArgs(9)));
     507            0 :             ShowContinueError(state,
     508            0 :                               format("{} must be greater than or equal to the {}", s_ipsc->cNumericFieldNames(9), s_ipsc->cNumericFieldNames(7)));
     509            0 :             ShowContinueError(state, format("{} must be less than or equal to the {}", s_ipsc->cNumericFieldNames(9), s_ipsc->cNumericFieldNames(8)));
     510            0 :             ErrorsFound = true;
     511              :         }
     512              : 
     513            5 :         thisChiller.CondenserFanPowerRatio = s_ipsc->rNumericArgs(11);
     514            5 :         thisChiller.CompPowerToCondenserFrac = s_ipsc->rNumericArgs(12);
     515              : 
     516            5 :         if (thisChiller.CompPowerToCondenserFrac < 0.0 || thisChiller.CompPowerToCondenserFrac > 1.0) {
     517            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     518            0 :             ShowContinueError(state, format("{} = {:.3R}", s_ipsc->cNumericFieldNames(12), s_ipsc->rNumericArgs(12)));
     519            0 :             ShowContinueError(state, format("{} must be greater than or equal to zero", s_ipsc->cNumericFieldNames(12)));
     520            0 :             ShowContinueError(state, format("{} must be less than or equal to one", s_ipsc->cNumericFieldNames(12)));
     521            0 :             ErrorsFound = true;
     522              :         }
     523              : 
     524            5 :         thisChiller.TempLowLimitEvapOut = s_ipsc->rNumericArgs(13);
     525              : 
     526              :         // These are the heat recovery inputs
     527            5 :         thisChiller.DesignHeatRecVolFlowRate = s_ipsc->rNumericArgs(14);
     528            5 :         if (thisChiller.DesignHeatRecVolFlowRate == DataSizing::AutoSize) {
     529            1 :             thisChiller.DesignHeatRecVolFlowRateWasAutoSized = true;
     530              :         }
     531            5 :         if ((thisChiller.DesignHeatRecVolFlowRate > 0.0) || (thisChiller.DesignHeatRecVolFlowRate == DataSizing::AutoSize)) {
     532            1 :             thisChiller.HeatRecActive = true;
     533            1 :             thisChiller.HeatRecInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     534            1 :                                                                                   s_ipsc->cAlphaArgs(11),
     535              :                                                                                   ErrorsFound,
     536              :                                                                                   DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     537            1 :                                                                                   s_ipsc->cAlphaArgs(1),
     538              :                                                                                   DataLoopNode::NodeFluidType::Water,
     539              :                                                                                   DataLoopNode::ConnectionType::Inlet,
     540              :                                                                                   NodeInputManager::CompFluidStream::Tertiary,
     541              :                                                                                   DataLoopNode::ObjectIsNotParent);
     542            1 :             if (thisChiller.HeatRecInletNodeNum == 0) {
     543            0 :                 ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     544            0 :                 ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(11), s_ipsc->cAlphaArgs(11)));
     545            0 :                 ErrorsFound = true;
     546              :             }
     547            1 :             thisChiller.HeatRecOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     548            1 :                                                                                    s_ipsc->cAlphaArgs(12),
     549              :                                                                                    ErrorsFound,
     550              :                                                                                    DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     551            1 :                                                                                    s_ipsc->cAlphaArgs(1),
     552              :                                                                                    DataLoopNode::NodeFluidType::Water,
     553              :                                                                                    DataLoopNode::ConnectionType::Outlet,
     554              :                                                                                    NodeInputManager::CompFluidStream::Tertiary,
     555              :                                                                                    DataLoopNode::ObjectIsNotParent);
     556            1 :             if (thisChiller.HeatRecOutletNodeNum == 0) {
     557            0 :                 ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     558            0 :                 ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(12), s_ipsc->cAlphaArgs(12)));
     559            0 :                 ErrorsFound = true;
     560              :             }
     561              : 
     562            2 :             BranchNodeConnections::TestCompSet(
     563            1 :                 state, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1), s_ipsc->cAlphaArgs(11), s_ipsc->cAlphaArgs(12), "Heat Recovery Nodes");
     564              :             // store heat recovery volume flow for plant sizing
     565            1 :             if (thisChiller.DesignHeatRecVolFlowRate > 0.0) {
     566            0 :                 PlantUtilities::RegisterPlantCompDesignFlow(state, thisChiller.HeatRecInletNodeNum,
     567              :                                                             thisChiller.DesignHeatRecVolFlowRate); // CR 6953
     568              :             }
     569            1 :             if (NumNums > 17) {
     570            1 :                 if (!s_ipsc->lNumericFieldBlanks(18)) {
     571            1 :                     thisChiller.HeatRecCapacityFraction = s_ipsc->rNumericArgs(18);
     572              :                 } else {
     573            0 :                     thisChiller.HeatRecCapacityFraction = 1.0;
     574              :                 }
     575              :             } else {
     576            0 :                 thisChiller.HeatRecCapacityFraction = 1.0;
     577              :             }
     578              : 
     579            1 :             if (NumAlphas <= 13 || s_ipsc->lAlphaFieldBlanks(14)) {
     580            1 :                 thisChiller.heatRecInletLimitSched = nullptr; // Ok for this schedule to remain null if field is empty
     581            0 :             } else if ((thisChiller.heatRecInletLimitSched = Sched::GetSchedule(state, s_ipsc->cAlphaArgs(14))) == nullptr) {
     582            0 :                 ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(14), s_ipsc->cAlphaArgs(14));
     583            0 :                 ErrorsFound = true;
     584              :             }
     585              : 
     586            1 :             if (NumAlphas > 14) {
     587            1 :                 if (!s_ipsc->lAlphaFieldBlanks(15)) {
     588            2 :                     thisChiller.HeatRecSetPointNodeNum = NodeInputManager::GetOnlySingleNode(state,
     589            1 :                                                                                              s_ipsc->cAlphaArgs(15),
     590              :                                                                                              ErrorsFound,
     591              :                                                                                              DataLoopNode::ConnectionObjectType::ChillerElectricEIR,
     592            1 :                                                                                              s_ipsc->cAlphaArgs(1),
     593              :                                                                                              DataLoopNode::NodeFluidType::Water,
     594              :                                                                                              DataLoopNode::ConnectionType::Sensor,
     595              :                                                                                              NodeInputManager::CompFluidStream::Primary,
     596              :                                                                                              DataLoopNode::ObjectIsNotParent);
     597              :                 } else {
     598            0 :                     thisChiller.HeatRecSetPointNodeNum = 0;
     599              :                 }
     600              :             } else {
     601            0 :                 thisChiller.HeatRecSetPointNodeNum = 0;
     602              :             }
     603              : 
     604              :         } else {
     605            4 :             thisChiller.HeatRecActive = false;
     606            4 :             thisChiller.DesignHeatRecMassFlowRate = 0.0;
     607            4 :             thisChiller.HeatRecInletNodeNum = 0;
     608            4 :             thisChiller.HeatRecOutletNodeNum = 0;
     609            4 :             if (!s_ipsc->lAlphaFieldBlanks(11) || !s_ipsc->lAlphaFieldBlanks(12)) {
     610            0 :                 ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     611            0 :                 ShowContinueError(state, "Since Reference Heat Reclaim Volume Flow Rate = 0.0, heat recovery is inactive.");
     612            0 :                 ShowContinueError(state, "However, node names were specified for heat recovery inlet or outlet nodes.");
     613              :             }
     614              :         }
     615              : 
     616            5 :         if (NumAlphas > 16) {
     617            3 :             thisChiller.CondenserFlowControl =
     618            3 :                 static_cast<DataPlant::CondenserFlowControl>(getEnumValue(DataPlant::CondenserFlowControlNamesUC, s_ipsc->cAlphaArgs(17)));
     619              :         } else {
     620            2 :             thisChiller.CondenserFlowControl = DataPlant::CondenserFlowControl::ConstantFlow;
     621              :         }
     622              : 
     623            5 :         if (thisChiller.CondenserFlowControl == DataPlant::CondenserFlowControl::Invalid) {
     624            0 :             ShowSevereError(state, format("{}{}=\"{}\",", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     625            0 :             ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(17), s_ipsc->cAlphaArgs(17)));
     626            0 :             ShowContinueError(state, "Available choices are ConstantFlow, ModulatedChillerPLR, ModulatedLoopPLR, or ModulatedDeltaTemperature");
     627            0 :             ShowContinueError(state, "Flow mode ConstantFlow is assumed and the simulation continues.");
     628            0 :             thisChiller.CondenserFlowControl = DataPlant::CondenserFlowControl::ConstantFlow;
     629              :         };
     630              : 
     631            5 :         if (NumAlphas > 17) {
     632            3 :             thisChiller.ChillerCondLoopFlowFLoopPLRIndex = Curve::GetCurveIndex(state, s_ipsc->cAlphaArgs(18));
     633              :         }
     634            5 :         if ((thisChiller.ChillerCondLoopFlowFLoopPLRIndex == 0) &&
     635            3 :             (thisChiller.CondenserFlowControl == DataPlant::CondenserFlowControl::ModulatedLoopPLR)) {
     636            0 :             ShowSevereError(state, format("{}{} \"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     637            0 :             ShowContinueError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(18), s_ipsc->cAlphaArgs(18)));
     638            0 :             ErrorsFound = true;
     639              :         }
     640              : 
     641            5 :         if (NumAlphas <= 18 || s_ipsc->lAlphaFieldBlanks(19)) {
     642            3 :             thisChiller.condDTSched = nullptr; // Okay for this schedule to remain nullptr if field is empty
     643            2 :         } else if (((thisChiller.condDTSched = Sched::GetSchedule(state, s_ipsc->cAlphaArgs(19))) == nullptr) &&
     644            0 :                    thisChiller.CondenserFlowControl == DataPlant::CondenserFlowControl::ModulatedDeltaTemperature) {
     645            0 :             ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(19), s_ipsc->cAlphaArgs(19));
     646            0 :             ErrorsFound = true;
     647              :         }
     648              : 
     649            5 :         if (NumNums > 18) {
     650            3 :             thisChiller.MinCondFlowRatio = s_ipsc->rNumericArgs(19);
     651              :         }
     652              : 
     653              :         //   Check the CAP-FT, EIR-FT, and PLR curves and warn user if different from 1.0 by more than +-10%
     654            5 :         if (thisChiller.ChillerCapFTIndex > 0) {
     655            5 :             Real64 CurveVal = Curve::CurveValue(state, thisChiller.ChillerCapFTIndex, thisChiller.TempRefEvapOut, thisChiller.TempRefCondIn);
     656            5 :             if (CurveVal > 1.10 || CurveVal < 0.90) {
     657            0 :                 ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     658            0 :                 ShowContinueError(
     659              :                     state, "Capacity ratio as a function of temperature curve output is not equal to 1.0 (+ or - 10%) at reference conditions.");
     660            0 :                 ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
     661              :             }
     662              :         }
     663              : 
     664            5 :         if (thisChiller.ChillerEIRFTIndex > 0) {
     665            5 :             Real64 CurveVal = Curve::CurveValue(state, thisChiller.ChillerEIRFTIndex, thisChiller.TempRefEvapOut, thisChiller.TempRefCondIn);
     666            5 :             if (CurveVal > 1.10 || CurveVal < 0.90) {
     667            0 :                 ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     668            0 :                 ShowContinueError(
     669              :                     state, "Energy input ratio as a function of temperature curve output is not equal to 1.0 (+ or - 10%) at reference conditions.");
     670            0 :                 ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
     671              :             }
     672              :         }
     673              : 
     674            5 :         if (thisChiller.ChillerEIRFPLRIndex > 0) {
     675            5 :             Real64 CurveVal = Curve::CurveValue(state, thisChiller.ChillerEIRFPLRIndex, 1.0);
     676              : 
     677            5 :             if (CurveVal > 1.10 || CurveVal < 0.90) {
     678            0 :                 ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     679            0 :                 ShowContinueError(
     680              :                     state,
     681              :                     "Energy input ratio as a function of part-load ratio curve output is not equal to 1.0 (+ or - 10%) at reference conditions.");
     682            0 :                 ShowContinueError(state, format("Curve output at reference conditions = {:.3T}", CurveVal));
     683              :             }
     684              :         }
     685              : 
     686            5 :         if (thisChiller.ChillerEIRFPLRIndex > 0) {
     687            5 :             bool FoundNegValue = false;
     688            5 :             Array1D<Real64> CurveValArray(11); // Used to evaluate PLFFPLR curve objects
     689           60 :             for (int CurveCheck = 0; CurveCheck <= 10; ++CurveCheck) {
     690           55 :                 Real64 CurveValTmp = Curve::CurveValue(state, thisChiller.ChillerEIRFPLRIndex, double(CurveCheck / 10.0));
     691           55 :                 if (CurveValTmp < 0.0) {
     692            0 :                     FoundNegValue = true;
     693              :                 }
     694           55 :                 CurveValArray(CurveCheck + 1) = int(CurveValTmp * 100.0) / 100.0;
     695              :             }
     696            5 :             if (FoundNegValue) {
     697            0 :                 ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     698            0 :                 ShowContinueError(state, "Energy input ratio as a function of part-load ratio curve shows negative values.");
     699            0 :                 ShowContinueError(state, "EIR as a function of PLR curve output at various part-load ratios shown below:");
     700            0 :                 ShowContinueError(state, "PLR          =    0.00   0.10   0.20   0.30   0.40   0.50   0.60   0.70   0.80   0.90   1.00");
     701            0 :                 ShowContinueError(state, fmt::format("Curve Output = {:7.2F}", fmt::join(CurveValArray, ",")));
     702            0 :                 ErrorsFound = true;
     703              :             }
     704            5 :         }
     705              :         //   Basin heater power as a function of temperature must be greater than or equal to 0
     706            5 :         thisChiller.BasinHeaterPowerFTempDiff = s_ipsc->rNumericArgs(16);
     707            5 :         if (s_ipsc->rNumericArgs(16) < 0.0) {
     708            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     709            0 :             ShowContinueError(state, format("{} must be >= 0", s_ipsc->cNumericFieldNames(16)));
     710            0 :             ErrorsFound = true;
     711              :         }
     712              : 
     713            5 :         thisChiller.BasinHeaterSetPointTemp = s_ipsc->rNumericArgs(17);
     714              : 
     715            5 :         if (thisChiller.BasinHeaterPowerFTempDiff > 0.0) {
     716            0 :             if (NumNums < 17) {
     717            0 :                 thisChiller.BasinHeaterSetPointTemp = 2.0;
     718              :             }
     719            0 :             if (thisChiller.BasinHeaterSetPointTemp < 2.0) {
     720            0 :                 ShowWarningError(state, format("{}{} \"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     721            0 :                 ShowContinueError(state, format("{} is less than 2 deg C. Freezing could occur.", s_ipsc->cNumericFieldNames(17)));
     722              :             }
     723              :         }
     724              : 
     725            5 :         if (!s_ipsc->lAlphaFieldBlanks(13)) {
     726            0 :             if ((thisChiller.basinHeaterSched = Sched::GetSchedule(state, s_ipsc->cAlphaArgs(13))) == nullptr) {
     727            0 :                 ShowWarningItemNotFound(state,
     728              :                                         eoh,
     729            0 :                                         s_ipsc->cAlphaFieldNames(13),
     730            0 :                                         s_ipsc->cAlphaArgs(13),
     731              :                                         "Basin heater operation will not be modeled and the simulation continues");
     732              :             }
     733              :         }
     734              : 
     735            5 :         if (NumAlphas > 15) {
     736            3 :             thisChiller.EndUseSubcategory = s_ipsc->cAlphaArgs(16);
     737              :         } else {
     738            2 :             thisChiller.EndUseSubcategory = "General";
     739              :         }
     740            5 :         if (!s_ipsc->lAlphaFieldBlanks(20)) {
     741            1 :             thisChiller.thermosiphonTempCurveIndex = Curve::GetCurveIndex(state, Util::makeUPPER(s_ipsc->cAlphaArgs(20)));
     742            1 :             if (thisChiller.thermosiphonTempCurveIndex == 0) {
     743            0 :                 ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, s_ipsc->cCurrentModuleObject, thisChiller.Name));
     744            0 :                 ShowContinueError(state, format("Invalid {} = {}", s_ipsc->cAlphaFieldNames(20), s_ipsc->cAlphaArgs(20)));
     745            0 :                 ErrorsFound = true;
     746              :             }
     747              :         }
     748            5 :         thisChiller.thermosiphonMinTempDiff = s_ipsc->rNumericArgs(20);
     749              :     }
     750              : 
     751            5 :     if (ErrorsFound) {
     752            0 :         ShowFatalError(state, format("Errors found in processing input for {}", s_ipsc->cCurrentModuleObject));
     753              :     }
     754            5 : }
     755              : 
     756            5 : void ElectricEIRChillerSpecs::setupOutputVars(EnergyPlusData &state)
     757              : {
     758           10 :     SetupOutputVariable(state,
     759              :                         "Chiller Part Load Ratio",
     760              :                         Constant::Units::None,
     761            5 :                         this->ChillerPartLoadRatio,
     762              :                         OutputProcessor::TimeStepType::System,
     763              :                         OutputProcessor::StoreType::Average,
     764            5 :                         this->Name);
     765              : 
     766           10 :     SetupOutputVariable(state,
     767              :                         "Chiller Cycling Ratio",
     768              :                         Constant::Units::None,
     769            5 :                         this->ChillerCyclingRatio,
     770              :                         OutputProcessor::TimeStepType::System,
     771              :                         OutputProcessor::StoreType::Average,
     772            5 :                         this->Name);
     773              : 
     774           10 :     SetupOutputVariable(state,
     775              :                         "Chiller Electricity Rate",
     776              :                         Constant::Units::W,
     777            5 :                         this->Power,
     778              :                         OutputProcessor::TimeStepType::System,
     779              :                         OutputProcessor::StoreType::Average,
     780            5 :                         this->Name);
     781              : 
     782           10 :     SetupOutputVariable(state,
     783              :                         "Chiller Electricity Energy",
     784              :                         Constant::Units::J,
     785            5 :                         this->Energy,
     786              :                         OutputProcessor::TimeStepType::System,
     787              :                         OutputProcessor::StoreType::Sum,
     788            5 :                         this->Name,
     789              :                         Constant::eResource::Electricity,
     790              :                         OutputProcessor::Group::Plant,
     791              :                         OutputProcessor::EndUseCat::Cooling,
     792              :                         this->EndUseSubcategory);
     793              : 
     794           10 :     SetupOutputVariable(state,
     795              :                         "Chiller Evaporator Cooling Rate",
     796              :                         Constant::Units::W,
     797            5 :                         this->QEvaporator,
     798              :                         OutputProcessor::TimeStepType::System,
     799              :                         OutputProcessor::StoreType::Average,
     800            5 :                         this->Name);
     801              : 
     802           10 :     SetupOutputVariable(state,
     803              :                         "Chiller Evaporator Cooling Energy",
     804              :                         Constant::Units::J,
     805            5 :                         this->EvapEnergy,
     806              :                         OutputProcessor::TimeStepType::System,
     807              :                         OutputProcessor::StoreType::Sum,
     808            5 :                         this->Name,
     809              :                         Constant::eResource::EnergyTransfer,
     810              :                         OutputProcessor::Group::Plant,
     811              :                         OutputProcessor::EndUseCat::Chillers);
     812              : 
     813           10 :     SetupOutputVariable(state,
     814              :                         "Chiller False Load Heat Transfer Rate",
     815              :                         Constant::Units::W,
     816            5 :                         this->ChillerFalseLoadRate,
     817              :                         OutputProcessor::TimeStepType::System,
     818              :                         OutputProcessor::StoreType::Average,
     819            5 :                         this->Name);
     820              : 
     821           10 :     SetupOutputVariable(state,
     822              :                         "Chiller False Load Heat Transfer Energy",
     823              :                         Constant::Units::J,
     824            5 :                         this->ChillerFalseLoad,
     825              :                         OutputProcessor::TimeStepType::System,
     826              :                         OutputProcessor::StoreType::Sum,
     827            5 :                         this->Name);
     828              : 
     829           10 :     SetupOutputVariable(state,
     830              :                         "Chiller Evaporator Inlet Temperature",
     831              :                         Constant::Units::C,
     832            5 :                         this->EvapInletTemp,
     833              :                         OutputProcessor::TimeStepType::System,
     834              :                         OutputProcessor::StoreType::Average,
     835            5 :                         this->Name);
     836              : 
     837           10 :     SetupOutputVariable(state,
     838              :                         "Chiller Evaporator Outlet Temperature",
     839              :                         Constant::Units::C,
     840            5 :                         this->EvapOutletTemp,
     841              :                         OutputProcessor::TimeStepType::System,
     842              :                         OutputProcessor::StoreType::Average,
     843            5 :                         this->Name);
     844              : 
     845           10 :     SetupOutputVariable(state,
     846              :                         "Chiller Evaporator Mass Flow Rate",
     847              :                         Constant::Units::kg_s,
     848            5 :                         this->EvapMassFlowRate,
     849              :                         OutputProcessor::TimeStepType::System,
     850              :                         OutputProcessor::StoreType::Average,
     851            5 :                         this->Name);
     852              : 
     853           10 :     SetupOutputVariable(state,
     854              :                         "Chiller Condenser Heat Transfer Rate",
     855              :                         Constant::Units::W,
     856            5 :                         this->QCondenser,
     857              :                         OutputProcessor::TimeStepType::System,
     858              :                         OutputProcessor::StoreType::Average,
     859            5 :                         this->Name);
     860              : 
     861           10 :     SetupOutputVariable(state,
     862              :                         "Chiller Condenser Heat Transfer Energy",
     863              :                         Constant::Units::J,
     864            5 :                         this->CondEnergy,
     865              :                         OutputProcessor::TimeStepType::System,
     866              :                         OutputProcessor::StoreType::Sum,
     867            5 :                         this->Name,
     868              :                         Constant::eResource::EnergyTransfer,
     869              :                         OutputProcessor::Group::Plant,
     870              :                         OutputProcessor::EndUseCat::HeatRejection);
     871              : 
     872           10 :     SetupOutputVariable(state,
     873              :                         "Chiller COP",
     874              :                         Constant::Units::W_W,
     875            5 :                         this->ActualCOP,
     876              :                         OutputProcessor::TimeStepType::System,
     877              :                         OutputProcessor::StoreType::Average,
     878            5 :                         this->Name);
     879              : 
     880           10 :     SetupOutputVariable(state,
     881              :                         "Chiller Capacity Temperature Modifier Multiplier",
     882              :                         Constant::Units::None,
     883            5 :                         this->ChillerCapFT,
     884              :                         OutputProcessor::TimeStepType::System,
     885              :                         OutputProcessor::StoreType::Average,
     886            5 :                         this->Name);
     887              : 
     888           10 :     SetupOutputVariable(state,
     889              :                         "Chiller EIR Temperature Modifier Multiplier",
     890              :                         Constant::Units::None,
     891            5 :                         this->ChillerEIRFT,
     892              :                         OutputProcessor::TimeStepType::System,
     893              :                         OutputProcessor::StoreType::Average,
     894            5 :                         this->Name);
     895              : 
     896           10 :     SetupOutputVariable(state,
     897              :                         "Chiller EIR Part Load Modifier Multiplier",
     898              :                         Constant::Units::None,
     899            5 :                         this->ChillerEIRFPLR,
     900              :                         OutputProcessor::TimeStepType::System,
     901              :                         OutputProcessor::StoreType::Average,
     902            5 :                         this->Name);
     903              : 
     904            5 :     SetupOutputVariable(state,
     905              :                         "Thermosiphon Status",
     906              :                         Constant::Units::None,
     907            5 :                         this->thermosiphonStatus,
     908              :                         OutputProcessor::TimeStepType::System,
     909              :                         OutputProcessor::StoreType::Average,
     910            5 :                         this->Name);
     911              : 
     912              :     // Condenser mass flow and outlet temp are valid for water cooled
     913            5 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
     914            4 :         SetupOutputVariable(state,
     915              :                             "Chiller Condenser Inlet Temperature",
     916              :                             Constant::Units::C,
     917            2 :                             this->CondInletTemp,
     918              :                             OutputProcessor::TimeStepType::System,
     919              :                             OutputProcessor::StoreType::Average,
     920            2 :                             this->Name);
     921              : 
     922            4 :         SetupOutputVariable(state,
     923              :                             "Chiller Condenser Outlet Temperature",
     924              :                             Constant::Units::C,
     925            2 :                             this->CondOutletTemp,
     926              :                             OutputProcessor::TimeStepType::System,
     927              :                             OutputProcessor::StoreType::Average,
     928            2 :                             this->Name);
     929              : 
     930            4 :         SetupOutputVariable(state,
     931              :                             "Chiller Condenser Mass Flow Rate",
     932              :                             Constant::Units::kg_s,
     933            2 :                             this->CondMassFlowRate,
     934              :                             OutputProcessor::TimeStepType::System,
     935              :                             OutputProcessor::StoreType::Average,
     936            2 :                             this->Name);
     937              : 
     938              :         // If heat recovery is active then setup report variables
     939            2 :         if (this->HeatRecActive) {
     940            2 :             SetupOutputVariable(state,
     941              :                                 "Chiller Total Recovered Heat Rate",
     942              :                                 Constant::Units::W,
     943            1 :                                 this->QHeatRecovered,
     944              :                                 OutputProcessor::TimeStepType::System,
     945              :                                 OutputProcessor::StoreType::Average,
     946            1 :                                 this->Name);
     947              : 
     948            2 :             SetupOutputVariable(state,
     949              :                                 "Chiller Total Recovered Heat Energy",
     950              :                                 Constant::Units::J,
     951            1 :                                 this->EnergyHeatRecovery,
     952              :                                 OutputProcessor::TimeStepType::System,
     953              :                                 OutputProcessor::StoreType::Sum,
     954            1 :                                 this->Name,
     955              :                                 Constant::eResource::EnergyTransfer,
     956              :                                 OutputProcessor::Group::Plant,
     957              :                                 OutputProcessor::EndUseCat::HeatRecovery);
     958              : 
     959            2 :             SetupOutputVariable(state,
     960              :                                 "Chiller Heat Recovery Inlet Temperature",
     961              :                                 Constant::Units::C,
     962            1 :                                 this->HeatRecInletTemp,
     963              :                                 OutputProcessor::TimeStepType::System,
     964              :                                 OutputProcessor::StoreType::Average,
     965            1 :                                 this->Name);
     966              : 
     967            2 :             SetupOutputVariable(state,
     968              :                                 "Chiller Heat Recovery Outlet Temperature",
     969              :                                 Constant::Units::C,
     970            1 :                                 this->HeatRecOutletTemp,
     971              :                                 OutputProcessor::TimeStepType::System,
     972              :                                 OutputProcessor::StoreType::Average,
     973            1 :                                 this->Name);
     974              : 
     975            2 :             SetupOutputVariable(state,
     976              :                                 "Chiller Heat Recovery Mass Flow Rate",
     977              :                                 Constant::Units::kg_s,
     978            1 :                                 this->HeatRecMassFlow,
     979              :                                 OutputProcessor::TimeStepType::System,
     980              :                                 OutputProcessor::StoreType::Average,
     981            1 :                                 this->Name);
     982              : 
     983            2 :             SetupOutputVariable(state,
     984              :                                 "Chiller Effective Heat Rejection Temperature",
     985              :                                 Constant::Units::C,
     986            1 :                                 this->ChillerCondAvgTemp,
     987              :                                 OutputProcessor::TimeStepType::System,
     988              :                                 OutputProcessor::StoreType::Average,
     989            1 :                                 this->Name);
     990              :         }
     991              : 
     992              :     } else {
     993            6 :         SetupOutputVariable(state,
     994              :                             "Chiller Condenser Inlet Temperature",
     995              :                             Constant::Units::C,
     996            3 :                             this->CondInletTemp,
     997              :                             OutputProcessor::TimeStepType::System,
     998              :                             OutputProcessor::StoreType::Average,
     999            3 :                             this->Name);
    1000              : 
    1001            3 :         if (this->CondenserFanPowerRatio > 0) {
    1002            6 :             SetupOutputVariable(state,
    1003              :                                 "Chiller Condenser Fan Electricity Rate",
    1004              :                                 Constant::Units::W,
    1005            3 :                                 this->CondenserFanPower,
    1006              :                                 OutputProcessor::TimeStepType::System,
    1007              :                                 OutputProcessor::StoreType::Average,
    1008            3 :                                 this->Name);
    1009              : 
    1010            6 :             SetupOutputVariable(state,
    1011              :                                 "Chiller Condenser Fan Electricity Energy",
    1012              :                                 Constant::Units::J,
    1013            3 :                                 this->CondenserFanEnergyConsumption,
    1014              :                                 OutputProcessor::TimeStepType::System,
    1015              :                                 OutputProcessor::StoreType::Sum,
    1016            3 :                                 this->Name,
    1017              :                                 Constant::eResource::Electricity,
    1018              :                                 OutputProcessor::Group::Plant,
    1019              :                                 OutputProcessor::EndUseCat::Cooling);
    1020              :         }
    1021            3 :         if (this->CondenserType == DataPlant::CondenserType::EvapCooled) {
    1022            2 :             SetupOutputVariable(state,
    1023              :                                 "Chiller Evaporative Condenser Water Volume",
    1024              :                                 Constant::Units::m3,
    1025            1 :                                 this->EvapWaterConsump,
    1026              :                                 OutputProcessor::TimeStepType::System,
    1027              :                                 OutputProcessor::StoreType::Sum,
    1028            1 :                                 this->Name,
    1029              :                                 Constant::eResource::Water,
    1030              :                                 OutputProcessor::Group::HVAC,
    1031              :                                 OutputProcessor::EndUseCat::Cooling);
    1032              : 
    1033            2 :             SetupOutputVariable(state,
    1034              :                                 "Chiller Evaporative Condenser Mains Supply Water Volume",
    1035              :                                 Constant::Units::m3,
    1036            1 :                                 this->EvapWaterConsump,
    1037              :                                 OutputProcessor::TimeStepType::System,
    1038              :                                 OutputProcessor::StoreType::Sum,
    1039            1 :                                 this->Name,
    1040              :                                 Constant::eResource::MainsWater,
    1041              :                                 OutputProcessor::Group::HVAC,
    1042              :                                 OutputProcessor::EndUseCat::Cooling);
    1043              : 
    1044            1 :             if (this->BasinHeaterPowerFTempDiff > 0.0) {
    1045            0 :                 SetupOutputVariable(state,
    1046              :                                     "Chiller Basin Heater Electricity Rate",
    1047              :                                     Constant::Units::W,
    1048            0 :                                     this->BasinHeaterPower,
    1049              :                                     OutputProcessor::TimeStepType::System,
    1050              :                                     OutputProcessor::StoreType::Average,
    1051            0 :                                     this->Name);
    1052              : 
    1053            0 :                 SetupOutputVariable(state,
    1054              :                                     "Chiller Basin Heater Electricity Energy",
    1055              :                                     Constant::Units::J,
    1056            0 :                                     this->BasinHeaterConsumption,
    1057              :                                     OutputProcessor::TimeStepType::System,
    1058              :                                     OutputProcessor::StoreType::Sum,
    1059            0 :                                     this->Name,
    1060              :                                     Constant::eResource::Electricity,
    1061              :                                     OutputProcessor::Group::Plant,
    1062              :                                     OutputProcessor::EndUseCat::Chillers);
    1063              :             }
    1064              :         }
    1065              :     }
    1066            5 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1067            0 :         SetupEMSInternalVariable(state, "Chiller Nominal Capacity", this->Name, "[W]", this->RefCap);
    1068              :     }
    1069            5 : }
    1070              : 
    1071            5 : void ElectricEIRChillerSpecs::oneTimeInit(EnergyPlusData &state)
    1072              : {
    1073            5 :     this->setupOutputVars(state);
    1074              : 
    1075              :     // Locate the chillers on the plant loops for later usage
    1076            5 :     bool errFlag = false;
    1077           15 :     PlantUtilities::ScanPlantLoopsForObject(state,
    1078              :                                             this->Name,
    1079              :                                             DataPlant::PlantEquipmentType::Chiller_ElectricEIR,
    1080            5 :                                             this->CWPlantLoc,
    1081              :                                             errFlag,
    1082            5 :                                             this->TempLowLimitEvapOut,
    1083              :                                             _,
    1084              :                                             _,
    1085            5 :                                             this->EvapInletNodeNum,
    1086              :                                             _);
    1087            5 :     if (this->CondenserType != DataPlant::CondenserType::AirCooled && this->CondenserType != DataPlant::CondenserType::EvapCooled) {
    1088            6 :         PlantUtilities::ScanPlantLoopsForObject(
    1089            4 :             state, this->Name, DataPlant::PlantEquipmentType::Chiller_ElectricEIR, this->CDPlantLoc, errFlag, _, _, _, this->CondInletNodeNum, _);
    1090            2 :         PlantUtilities::InterConnectTwoPlantLoopSides(
    1091            2 :             state, this->CWPlantLoc, this->CDPlantLoc, DataPlant::PlantEquipmentType::Chiller_ElectricEIR, true);
    1092              :     }
    1093            5 :     if (this->HeatRecActive) {
    1094            3 :         PlantUtilities::ScanPlantLoopsForObject(
    1095            2 :             state, this->Name, DataPlant::PlantEquipmentType::Chiller_ElectricEIR, this->HRPlantLoc, errFlag, _, _, _, this->HeatRecInletNodeNum, _);
    1096            1 :         PlantUtilities::InterConnectTwoPlantLoopSides(
    1097            1 :             state, this->CWPlantLoc, this->HRPlantLoc, DataPlant::PlantEquipmentType::Chiller_ElectricEIR, true);
    1098              :     }
    1099              : 
    1100            5 :     if (this->CondenserType != DataPlant::CondenserType::AirCooled && this->CondenserType != DataPlant::CondenserType::EvapCooled &&
    1101            2 :         this->HeatRecActive) {
    1102            1 :         PlantUtilities::InterConnectTwoPlantLoopSides(
    1103            1 :             state, this->CDPlantLoc, this->HRPlantLoc, DataPlant::PlantEquipmentType::Chiller_ElectricEIR, false);
    1104              :     }
    1105              : 
    1106            5 :     if (errFlag) {
    1107            0 :         ShowFatalError(state, "InitElectricEIRChiller: Program terminated due to previous condition(s).");
    1108              :     }
    1109              : 
    1110            5 :     if (this->FlowMode == DataPlant::FlowMode::Constant) {
    1111              :         // reset flow priority
    1112            1 :         DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyIfLoopOn;
    1113              :     }
    1114              : 
    1115            5 :     if (this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) {
    1116              :         // reset flow priority
    1117            0 :         DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyIfLoopOn;
    1118              :         // check if setpoint on outlet node
    1119            0 :         if ((state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) &&
    1120            0 :             (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi == DataLoopNode::SensedNodeFlagValue)) {
    1121            0 :             if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1122            0 :                 if (!this->ModulatedFlowErrDone) {
    1123            0 :                     ShowWarningError(state, format("Missing temperature setpoint for LeavingSetpointModulated mode chiller named {}", this->Name));
    1124            0 :                     ShowContinueError(
    1125              :                         state, "  A temperature setpoint is needed at the outlet node of a chiller in variable flow mode, use a SetpointManager");
    1126            0 :                     ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
    1127            0 :                     this->ModulatedFlowErrDone = true;
    1128              :                 }
    1129              :             } else {
    1130              :                 // need call to EMS to check node
    1131            0 :                 bool fatalError = false; // but not really fatal yet, but should be.
    1132            0 :                 EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->EvapOutletNodeNum, HVAC::CtrlVarType::Temp, fatalError);
    1133            0 :                 state.dataLoopNodes->NodeSetpointCheck(this->EvapOutletNodeNum).needsSetpointChecking = false;
    1134            0 :                 if (fatalError) {
    1135            0 :                     if (!this->ModulatedFlowErrDone) {
    1136            0 :                         ShowWarningError(state,
    1137            0 :                                          format("Missing temperature setpoint for LeavingSetpointModulated mode chiller named {}", this->Name));
    1138            0 :                         ShowContinueError(state,
    1139              :                                           "  A temperature setpoint is needed at the outlet node of a chiller evaporator in variable flow mode");
    1140            0 :                         ShowContinueError(state, "  use a Setpoint Manager to establish a setpoint at the chiller evaporator outlet node ");
    1141            0 :                         ShowContinueError(state, "  or use an EMS actuator to establish a setpoint at the outlet node ");
    1142            0 :                         ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
    1143            0 :                         this->ModulatedFlowErrDone = true;
    1144              :                     }
    1145              :                 }
    1146              :             }
    1147            0 :             this->ModulatedFlowSetToLoop = true;
    1148            0 :             state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint =
    1149            0 :                 state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPoint;
    1150            0 :             state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi =
    1151            0 :                 state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPointHi;
    1152              :         }
    1153              :     }
    1154            5 : }
    1155              : 
    1156            6 : void ElectricEIRChillerSpecs::initEachEnvironment(EnergyPlusData &state)
    1157              : {
    1158              : 
    1159              :     static constexpr std::string_view RoutineName("ElectricEIRChillerSpecs::initEachEnvironment");
    1160              : 
    1161            6 :     Real64 rho = this->CWPlantLoc.loop->glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    1162              : 
    1163            6 :     this->EvapMassFlowRateMax = this->EvapVolFlowRate * rho;
    1164              : 
    1165            6 :     PlantUtilities::InitComponentNodes(state, 0.0, this->EvapMassFlowRateMax, this->EvapInletNodeNum, this->EvapOutletNodeNum);
    1166              : 
    1167            6 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1168              : 
    1169            2 :         rho = this->CDPlantLoc.loop->glycol->getDensity(state, this->TempRefCondIn, RoutineName);
    1170            2 :         this->CondMassFlowRateMax = rho * this->CondVolFlowRate;
    1171            2 :         PlantUtilities::InitComponentNodes(state, 0.0, this->CondMassFlowRateMax, this->CondInletNodeNum, this->CondOutletNodeNum);
    1172            2 :         state.dataLoopNodes->Node(this->CondInletNodeNum).Temp = this->TempRefCondIn;
    1173              :     } else { // air or evap air condenser
    1174              :         // Initialize maximum available condenser flow rate
    1175            4 :         rho = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, this->TempRefCondIn, 0.0, RoutineName);
    1176            4 :         this->CondMassFlowRateMax = rho * this->CondVolFlowRate;
    1177              : 
    1178            4 :         state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate = this->CondMassFlowRateMax;
    1179            4 :         state.dataLoopNodes->Node(this->CondOutletNodeNum).MassFlowRate = state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate;
    1180            4 :         state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRateMaxAvail = state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate;
    1181            4 :         state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRateMax = state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate;
    1182            4 :         state.dataLoopNodes->Node(this->CondOutletNodeNum).MassFlowRateMax = state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate;
    1183            4 :         state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRateMinAvail = 0.0;
    1184            4 :         state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRateMin = 0.0;
    1185            4 :         state.dataLoopNodes->Node(this->CondOutletNodeNum).MassFlowRateMinAvail = 0.0;
    1186            4 :         state.dataLoopNodes->Node(this->CondOutletNodeNum).MassFlowRateMin = 0.0;
    1187            4 :         state.dataLoopNodes->Node(this->CondInletNodeNum).Temp = this->TempRefCondIn;
    1188              :     }
    1189              : 
    1190            6 :     if (this->HeatRecActive) {
    1191            1 :         rho = this->HRPlantLoc.loop->glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    1192            1 :         this->DesignHeatRecMassFlowRate = rho * this->DesignHeatRecVolFlowRate;
    1193              : 
    1194            1 :         PlantUtilities::InitComponentNodes(state, 0.0, this->DesignHeatRecMassFlowRate, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum);
    1195              :         // overall capacity limit
    1196            1 :         this->HeatRecMaxCapacityLimit = this->HeatRecCapacityFraction * (this->RefCap + this->RefCap / this->RefCOP);
    1197              : 
    1198            1 :         if (this->HeatRecSetPointNodeNum > 0) {
    1199            1 :             Real64 THeatRecSetPoint(0.0); // tests set point node for proper set point value
    1200            1 :             switch (this->HRPlantLoc.loop->LoopDemandCalcScheme) {
    1201            1 :             case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1202            1 :                 THeatRecSetPoint = state.dataLoopNodes->Node(this->HeatRecSetPointNodeNum).TempSetPoint;
    1203            1 :             } break;
    1204            0 :             case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1205            0 :                 THeatRecSetPoint = state.dataLoopNodes->Node(this->HeatRecSetPointNodeNum).TempSetPointHi;
    1206            0 :             } break;
    1207            0 :             default: {
    1208            0 :                 assert(false);
    1209              :             } break;
    1210              :             }
    1211            1 :             if (THeatRecSetPoint == DataLoopNode::SensedNodeFlagValue) {
    1212            0 :                 if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1213            0 :                     if (!this->HRSPErrDone) {
    1214            0 :                         ShowWarningError(state, format("Missing heat recovery temperature setpoint for chiller named {}", this->Name));
    1215            0 :                         ShowContinueError(state,
    1216              :                                           "  A temperature setpoint is needed at the heat recovery leaving temperature setpoint node "
    1217              :                                           "specified, use a SetpointManager");
    1218            0 :                         ShowContinueError(state, "  The overall loop setpoint will be assumed for heat recovery. The simulation continues ...");
    1219            0 :                         this->HeatRecSetPointNodeNum = this->HRPlantLoc.loop->TempSetPointNodeNum;
    1220            0 :                         this->HRSPErrDone = true;
    1221              :                     }
    1222              :                 } else {
    1223              :                     // need call to EMS to check node
    1224            0 :                     bool fatalError = false; // but not really fatal yet, but should be.
    1225            0 :                     EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->EvapOutletNodeNum, HVAC::CtrlVarType::Temp, fatalError);
    1226            0 :                     state.dataLoopNodes->NodeSetpointCheck(this->EvapOutletNodeNum).needsSetpointChecking = false;
    1227            0 :                     if (fatalError) {
    1228            0 :                         if (!this->HRSPErrDone) {
    1229            0 :                             ShowWarningError(state, format("Missing heat recovery temperature setpoint for chiller named {}", this->Name));
    1230            0 :                             ShowContinueError(state,
    1231              :                                               "  A temperature setpoint is needed at the heat recovery leaving temperature setpoint node "
    1232              :                                               "specified, use a SetpointManager to establish a setpoint");
    1233            0 :                             ShowContinueError(state, "  or use an EMS actuator to establish a setpoint at this node ");
    1234            0 :                             ShowContinueError(state, "  The overall loop setpoint will be assumed for heat recovery. The simulation continues ...");
    1235            0 :                             this->HeatRecSetPointNodeNum = this->HRPlantLoc.loop->TempSetPointNodeNum;
    1236            0 :                             this->HRSPErrDone = true;
    1237              :                         }
    1238              :                     }
    1239              :                 } // IF (.NOT. AnyEnergyManagementSystemInModel) THEN
    1240              :             } // IF(THeatRecSetPoint == SensedNodeFlagValue)THEN
    1241              :         } // IF(ElectricEIRChiller(EIRChillNum)%HeatRecSetPointNodeNum > 0)THEN
    1242              :     } // IF (ElectricEIRChiller(EIRChillNum)%HeatRecActive) THEN
    1243            6 : }
    1244              : 
    1245         1448 : void ElectricEIRChillerSpecs::initialize(EnergyPlusData &state, bool const RunFlag, Real64 const MyLoad)
    1246              : {
    1247              : 
    1248              :     // SUBROUTINE INFORMATION:
    1249              :     //       AUTHOR         Richard Raustad, FSEC
    1250              :     //       DATE WRITTEN   June 2004
    1251              : 
    1252              :     // PURPOSE OF THIS SUBROUTINE:
    1253              :     //  This subroutine is for initializations of the Electric EIR Chiller variables
    1254              : 
    1255              :     // METHODOLOGY EMPLOYED:
    1256              :     //  Uses the status flags to trigger initializations.
    1257              : 
    1258              :     // Init more variables
    1259         1448 :     if (this->oneTimeFlag) {
    1260            5 :         this->oneTimeInit(state);
    1261            5 :         this->oneTimeFlag = false;
    1262              :     }
    1263              : 
    1264         1448 :     this->EquipFlowCtrl = DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowCtrl;
    1265              : 
    1266         1448 :     if (this->MyEnvrnFlag && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
    1267            6 :         this->initEachEnvironment(state);
    1268            6 :         this->MyEnvrnFlag = false;
    1269              :     }
    1270         1448 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    1271         1356 :         this->MyEnvrnFlag = true;
    1272              :     }
    1273              : 
    1274         1448 :     if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) && this->ModulatedFlowSetToLoop) {
    1275              :         // fix for clumsy old input that worked because loop setpoint was spread.
    1276              :         //  could be removed with transition, testing , model change, period of being obsolete.
    1277            0 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint =
    1278            0 :             state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPoint;
    1279            0 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi =
    1280            0 :             state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPointHi;
    1281              :     }
    1282              : 
    1283         1448 :     Real64 mdot = 0.0;
    1284         1448 :     Real64 mdotCond = 0.0;
    1285         1448 :     if ((std::abs(MyLoad) > 0.0) && RunFlag) {
    1286           11 :         mdot = this->EvapMassFlowRateMax;
    1287           11 :         mdotCond = this->CondMassFlowRateMax;
    1288              :     }
    1289              : 
    1290         1448 :     PlantUtilities::SetComponentFlowRate(state, mdot, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    1291              : 
    1292         1448 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1293            6 :         PlantUtilities::SetComponentFlowRate(state, mdotCond, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
    1294              :         // get minimum condenser plant loop pump mass flow rate
    1295            6 :         this->VSBranchPumpMinLimitMassFlowCond =
    1296            6 :             PlantUtilities::MinFlowIfBranchHasVSPump(state, this->CDPlantLoc, this->VSBranchPumpFoundCond, this->VSLoopPumpFoundCond, false);
    1297              :     }
    1298              :     // Initialize heat recovery flow rates at node
    1299         1448 :     if (this->HeatRecActive) {
    1300            2 :         mdot = RunFlag ? this->DesignHeatRecMassFlowRate : 0.0; // if RunFlag is true, mdot = this->DesignHeatRecMassFlowRate, else mdot = 0.0
    1301            2 :         PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum, this->HRPlantLoc);
    1302              :     }
    1303              : 
    1304         1448 :     if (this->CondenserType == DataPlant::CondenserType::EvapCooled) {
    1305            2 :         this->BasinHeaterPower = 0.0;
    1306              :     }
    1307         1448 : }
    1308              : 
    1309           11 : void ElectricEIRChillerSpecs::size(EnergyPlusData &state)
    1310              : {
    1311              : 
    1312              :     // SUBROUTINE INFORMATION:
    1313              :     //       AUTHOR         Richard Raustad, FSEC
    1314              :     //       DATE WRITTEN   June 2004
    1315              :     //       MODIFIED       October 2013 Daeho Kang, add component sizing table entries
    1316              : 
    1317              :     // PURPOSE OF THIS SUBROUTINE:
    1318              :     //  This subroutine is for sizing Electric EIR Chiller Components for which capacities and flow rates
    1319              :     //  have not been specified in the input.
    1320              : 
    1321              :     // METHODOLOGY EMPLOYED:
    1322              :     //  Obtains evaporator flow rate from the plant sizing array. Calculates reference capacity from
    1323              :     //  the evaporator flow rate and the chilled water loop design delta T. The condenser flow rate
    1324              :     //  is calculated from the reference capacity, the COP, and the condenser loop design delta T.
    1325              : 
    1326              :     static constexpr std::string_view RoutineName("SizeElectricEIRChiller");
    1327              : 
    1328           11 :     int PltSizCondNum = 0;
    1329           11 :     bool ErrorsFound = false;
    1330           11 :     Real64 tmpNomCap = this->RefCap;
    1331           11 :     Real64 tmpEvapVolFlowRate = this->EvapVolFlowRate;
    1332           11 :     Real64 tmpCondVolFlowRate = this->CondVolFlowRate;
    1333              : 
    1334           11 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1335            4 :         PltSizCondNum = this->CDPlantLoc.loop->PlantSizNum;
    1336              :     }
    1337              : 
    1338              :     // find the appropriate Plant Sizing object
    1339           11 :     int PltSizNum = this->CWPlantLoc.loop->PlantSizNum;
    1340              : 
    1341           11 :     if (PltSizNum > 0) {
    1342           11 :         if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1343           10 :             tmpEvapVolFlowRate = state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate * this->SizFac;
    1344              :         } else {
    1345            1 :             if (this->EvapVolFlowRateWasAutoSized) {
    1346            1 :                 tmpEvapVolFlowRate = 0.0;
    1347              :             }
    1348              :         }
    1349           11 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1350            7 :             if (this->EvapVolFlowRateWasAutoSized) {
    1351            6 :                 this->EvapVolFlowRate = tmpEvapVolFlowRate;
    1352            6 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1353            5 :                     BaseSizer::reportSizerOutput(
    1354              :                         state, "Chiller:Electric:EIR", this->Name, "Design Size Reference Chilled Water Flow Rate [m3/s]", tmpEvapVolFlowRate);
    1355              :                 }
    1356            6 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1357            5 :                     BaseSizer::reportSizerOutput(state,
    1358              :                                                  "Chiller:Electric:EIR",
    1359              :                                                  this->Name,
    1360              :                                                  "Initial Design Size Reference Chilled Water Flow Rate [m3/s]",
    1361              :                                                  tmpEvapVolFlowRate);
    1362              :                 }
    1363              :             } else { // Hard-size with sizing data
    1364            1 :                 if (this->EvapVolFlowRate > 0.0 && tmpEvapVolFlowRate > 0.0) {
    1365            1 :                     Real64 EvapVolFlowRateUser = this->EvapVolFlowRate;
    1366            1 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1367            0 :                         BaseSizer::reportSizerOutput(state,
    1368              :                                                      "Chiller:Electric:EIR",
    1369              :                                                      this->Name,
    1370              :                                                      "Design Size Reference Chilled Water Flow Rate [m3/s]",
    1371              :                                                      tmpEvapVolFlowRate,
    1372              :                                                      "User-Specified Reference Chilled Water Flow Rate [m3/s]",
    1373              :                                                      EvapVolFlowRateUser);
    1374            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1375            0 :                             if ((std::abs(tmpEvapVolFlowRate - EvapVolFlowRateUser) / EvapVolFlowRateUser) >
    1376            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1377            0 :                                 ShowMessage(state, format("SizeChillerElectricEIR: Potential issue with equipment sizing for {}", this->Name));
    1378            0 :                                 ShowContinueError(state,
    1379            0 :                                                   format("User-Specified Reference Chilled Water Flow Rate of {:.5R} [m3/s]", EvapVolFlowRateUser));
    1380            0 :                                 ShowContinueError(
    1381            0 :                                     state, format("differs from Design Size Reference Chilled Water Flow Rate of {:.5R} [m3/s]", tmpEvapVolFlowRate));
    1382            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1383            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1384              :                             }
    1385              :                         }
    1386              :                     }
    1387            1 :                     tmpEvapVolFlowRate = EvapVolFlowRateUser;
    1388              :                 }
    1389              :             }
    1390              :         }
    1391              :     } else {
    1392            0 :         if (this->EvapVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1393            0 :             ShowSevereError(state, "Autosizing of Electric Chiller evap flow rate requires a loop Sizing:Plant object");
    1394            0 :             ShowContinueError(state, format("Occurs in Electric Chiller object={}", this->Name));
    1395            0 :             ErrorsFound = true;
    1396              :         }
    1397            0 :         if (!this->EvapVolFlowRateWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && (this->EvapVolFlowRate > 0.0)) {
    1398            0 :             BaseSizer::reportSizerOutput(
    1399              :                 state, "Chiller:Electric:EIR", this->Name, "User-Specified Reference Chilled Water Flow Rate [m3/s]", this->EvapVolFlowRate);
    1400              :         }
    1401              :     }
    1402              : 
    1403           11 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->EvapInletNodeNum, tmpEvapVolFlowRate);
    1404              : 
    1405           11 :     if (PltSizNum > 0) {
    1406           11 :         if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1407           10 :             Real64 Cp = this->CWPlantLoc.loop->glycol->getSpecificHeat(state, Constant::CWInitConvTemp, RoutineName);
    1408              : 
    1409           10 :             Real64 rho = this->CWPlantLoc.loop->glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    1410           10 :             tmpNomCap = Cp * rho * state.dataSize->PlantSizData(PltSizNum).DeltaT * tmpEvapVolFlowRate;
    1411              :         } else {
    1412            1 :             tmpNomCap = 0.0;
    1413              :         }
    1414           11 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1415            7 :             if (this->RefCapWasAutoSized) {
    1416            6 :                 this->RefCap = tmpNomCap;
    1417            6 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1418            5 :                     BaseSizer::reportSizerOutput(state, "Chiller:Electric:EIR", this->Name, "Design Size Reference Capacity [W]", tmpNomCap);
    1419              :                 }
    1420            6 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1421            5 :                     BaseSizer::reportSizerOutput(state, "Chiller:Electric:EIR", this->Name, "Initial Design Size Reference Capacity [W]", tmpNomCap);
    1422              :                 }
    1423              :             } else { // Hard-sized with sizing data
    1424            1 :                 if (this->RefCap > 0.0 && tmpNomCap > 0.0) {
    1425            1 :                     Real64 RefCapUser = this->RefCap;
    1426            1 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1427            0 :                         BaseSizer::reportSizerOutput(state,
    1428              :                                                      "Chiller:Electric:EIR",
    1429              :                                                      this->Name,
    1430              :                                                      "Design Size Reference Capacity [W]",
    1431              :                                                      tmpNomCap,
    1432              :                                                      "User-Specified Reference Capacity [W]",
    1433              :                                                      RefCapUser);
    1434            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1435            0 :                             if ((std::abs(tmpNomCap - RefCapUser) / RefCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1436            0 :                                 ShowMessage(state, format("SizeChillerElectricEIR: Potential issue with equipment sizing for {}", this->Name));
    1437            0 :                                 ShowContinueError(state, format("User-Specified Reference Capacity of {:.2R} [W]", RefCapUser));
    1438            0 :                                 ShowContinueError(state, format("differs from Design Size Reference Capacity of {:.2R} [W]", tmpNomCap));
    1439            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1440            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1441              :                             }
    1442              :                         }
    1443              :                     }
    1444            1 :                     tmpNomCap = RefCapUser;
    1445              :                 }
    1446              :             }
    1447              :         }
    1448              :     } else {
    1449            0 :         if (this->RefCapWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1450            0 :             ShowSevereError(state, "Autosizing of Electric Chiller reference capacity requires a loop Sizing:Plant object");
    1451            0 :             ShowContinueError(state, format("Occurs in Electric Chiller object={}", this->Name));
    1452            0 :             ErrorsFound = true;
    1453              :         }
    1454            0 :         if (!this->RefCapWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && (this->RefCap > 0.0)) { // Hard-sized with no sizing data
    1455            0 :             BaseSizer::reportSizerOutput(state, "Chiller:Electric:EIR", this->Name, "User-Specified Reference Capacity [W]", this->RefCap);
    1456              :         }
    1457              :     }
    1458              : 
    1459           11 :     if (PltSizCondNum > 0 && PltSizNum > 0) {
    1460            4 :         if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow && tmpNomCap > 0.0) {
    1461              : 
    1462            4 :             Real64 rho = this->CDPlantLoc.loop->glycol->getDensity(state, this->TempRefCondIn, RoutineName);
    1463            4 :             Real64 Cp = this->CDPlantLoc.loop->glycol->getSpecificHeat(state, this->TempRefCondIn, RoutineName);
    1464            8 :             tmpCondVolFlowRate = tmpNomCap * (1.0 + (1.0 / this->RefCOP) * this->CompPowerToCondenserFrac) /
    1465            4 :                                  (state.dataSize->PlantSizData(PltSizCondNum).DeltaT * Cp * rho);
    1466              : 
    1467              :         } else {
    1468            0 :             if (this->CondVolFlowRateWasAutoSized) {
    1469            0 :                 tmpCondVolFlowRate = 0.0;
    1470              :             }
    1471              :         }
    1472            4 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1473            4 :             if (this->CondVolFlowRateWasAutoSized) {
    1474            2 :                 this->CondVolFlowRate = tmpCondVolFlowRate;
    1475            2 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1476            1 :                     BaseSizer::reportSizerOutput(
    1477              :                         state, "Chiller:Electric:EIR", this->Name, "Design Size Reference Condenser Fluid Flow Rate [m3/s]", tmpCondVolFlowRate);
    1478              :                 }
    1479            2 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1480            2 :                     BaseSizer::reportSizerOutput(state,
    1481              :                                                  "Chiller:Electric:EIR",
    1482              :                                                  this->Name,
    1483              :                                                  "Initial Design Size Reference Condenser Fluid Flow Rate [m3/s]",
    1484              :                                                  tmpCondVolFlowRate);
    1485              :                 }
    1486              :             } else {
    1487            2 :                 if (this->CondVolFlowRate > 0.0 && tmpCondVolFlowRate > 0.0) {
    1488            2 :                     Real64 CondVolFlowRateUser = this->CondVolFlowRate;
    1489            2 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1490            1 :                         BaseSizer::reportSizerOutput(state,
    1491              :                                                      "Chiller:Electric:EIR",
    1492              :                                                      this->Name,
    1493              :                                                      "Design Size Reference Condenser Fluid Flow Rate [m3/s]",
    1494              :                                                      tmpCondVolFlowRate,
    1495              :                                                      "User-Specified Reference Condenser Fluid Flow Rate [m3/s]",
    1496              :                                                      CondVolFlowRateUser);
    1497            1 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1498            0 :                             if ((std::abs(tmpCondVolFlowRate - CondVolFlowRateUser) / CondVolFlowRateUser) >
    1499            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1500            0 :                                 ShowMessage(state, format("SizeChillerElectricEIR: Potential issue with equipment sizing for {}", this->Name));
    1501            0 :                                 ShowContinueError(state,
    1502            0 :                                                   format("User-Specified Reference Condenser Fluid Flow Rate of {:.5R} [m3/s]", CondVolFlowRateUser));
    1503            0 :                                 ShowContinueError(
    1504              :                                     state,
    1505            0 :                                     format("differs from Design Size Reference Condenser Fluid Flow Rate of {:.5R} [m3/s]", tmpCondVolFlowRate));
    1506            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1507            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1508              :                             }
    1509              :                         }
    1510              :                     }
    1511            2 :                     tmpCondVolFlowRate = CondVolFlowRateUser;
    1512              :                 }
    1513              :             }
    1514              :         }
    1515            4 :     } else {
    1516            7 :         if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1517              : 
    1518            0 :             if (this->CondVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1519            0 :                 ShowSevereError(state, "Autosizing of Electric EIR Chiller condenser fluid flow rate requires a condenser");
    1520            0 :                 ShowContinueError(state, "loop Sizing:Plant object");
    1521            0 :                 ShowContinueError(state, format("Occurs in Electric EIR Chiller object={}", this->Name));
    1522            0 :                 ErrorsFound = true;
    1523              :             }
    1524            0 :             if (!this->CondVolFlowRateWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && (this->CondVolFlowRate > 0.0)) {
    1525            0 :                 BaseSizer::reportSizerOutput(
    1526              :                     state, "Chiller:Electric:EIR", this->Name, "User-Specified Reference Condenser Fluid Flow Rate [m3/s]", this->CondVolFlowRate);
    1527              :             }
    1528              : 
    1529              :         } else {
    1530              : 
    1531              :             // Auto size condenser air flow to Total Capacity * 0.000114 m3/s/w (850 cfm/ton)
    1532            7 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1533            3 :                 std::string_view CompType = DataPlant::PlantEquipTypeNames[static_cast<int>(DataPlant::PlantEquipmentType::Chiller_ElectricEIR)];
    1534            3 :                 state.dataSize->DataConstantUsedForSizing = this->RefCap;
    1535            3 :                 state.dataSize->DataFractionUsedForSizing = 0.000114;
    1536            3 :                 Real64 TempSize = this->CondVolFlowRate;
    1537            3 :                 bool bPRINT = true; // TRUE if sizing is reported to output (eio)
    1538            3 :                 AutoCalculateSizer sizerCondAirFlow;
    1539            3 :                 std::string stringOverride = "Reference Condenser Fluid Flow Rate  [m3/s]";
    1540            3 :                 if (state.dataGlobal->isEpJSON) {
    1541            0 :                     stringOverride = "reference_condenser_fluid_flow_rate [m3/s]";
    1542              :                 }
    1543            3 :                 sizerCondAirFlow.overrideSizingString(stringOverride);
    1544            3 :                 sizerCondAirFlow.initializeWithinEP(state, CompType, this->Name, bPRINT, RoutineName);
    1545            3 :                 this->CondVolFlowRate = sizerCondAirFlow.size(state, TempSize, ErrorsFound);
    1546            3 :                 tmpCondVolFlowRate = this->CondVolFlowRate;
    1547            3 :             }
    1548              :         }
    1549              :     }
    1550              : 
    1551           11 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1552              :         // save the reference condenser water volumetric flow rate for use by the condenser water loop sizing algorithms
    1553            4 :         PlantUtilities::RegisterPlantCompDesignFlow(state, this->CondInletNodeNum, tmpCondVolFlowRate);
    1554              :     }
    1555              : 
    1556              :     // now do heat recovery flow rate sizing if active
    1557           11 :     if (this->HeatRecActive) {
    1558              :         Real64 tempHeatRecVolFlowRate;
    1559            3 :         if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1560            3 :             tempHeatRecVolFlowRate = tmpCondVolFlowRate * this->HeatRecCapacityFraction;
    1561              :         } else {
    1562            0 :             if (this->EvapVolFlowRateWasAutoSized) {
    1563            0 :                 tempHeatRecVolFlowRate = tmpEvapVolFlowRate;
    1564              :             } else {
    1565            0 :                 tempHeatRecVolFlowRate = this->EvapVolFlowRate;
    1566              :             }
    1567            0 :             tempHeatRecVolFlowRate *= (1.0 + (1.0 / this->RefCOP)) * this->CompPowerToCondenserFrac * this->HeatRecCapacityFraction;
    1568              :         }
    1569            3 :         if (this->DesignHeatRecVolFlowRateWasAutoSized) {
    1570              : 
    1571            3 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1572            3 :                 this->DesignHeatRecVolFlowRate = tempHeatRecVolFlowRate;
    1573            3 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1574            1 :                     BaseSizer::reportSizerOutput(
    1575              :                         state, "Chiller:Electric:EIR", this->Name, "Design Size Heat Recovery Water Flow Rate [m3/s]", tempHeatRecVolFlowRate);
    1576              :                 }
    1577            3 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1578            2 :                     BaseSizer::reportSizerOutput(
    1579              :                         state, "Chiller:Electric:EIR", this->Name, "Intial Design Size Heat Recovery Water Flow Rate [m3/s]", tempHeatRecVolFlowRate);
    1580              :                 }
    1581              :             }
    1582              :         } else {
    1583            0 :             if (this->DesignHeatRecVolFlowRate > 0.0 && tempHeatRecVolFlowRate > 0.0) {
    1584            0 :                 Real64 nomHeatRecVolFlowRateUser = this->DesignHeatRecVolFlowRate;
    1585            0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1586            0 :                     if (state.dataGlobal->DoPlantSizing) {
    1587            0 :                         BaseSizer::reportSizerOutput(state,
    1588              :                                                      "Chiller:Electric:EIR",
    1589              :                                                      this->Name,
    1590              :                                                      "Design Size Heat Recovery Water Flow Rate [m3/s]",
    1591              :                                                      tempHeatRecVolFlowRate,
    1592              :                                                      "User-Specified Heat Recovery Water Flow Rate [m3/s]",
    1593              :                                                      nomHeatRecVolFlowRateUser);
    1594              :                     } else {
    1595            0 :                         BaseSizer::reportSizerOutput(state,
    1596              :                                                      "Chiller:Electric:EIR",
    1597              :                                                      this->Name,
    1598              :                                                      "User-Specified Heat Recovery Water Flow Rate [m3/s]",
    1599              :                                                      nomHeatRecVolFlowRateUser);
    1600              :                     }
    1601              : 
    1602            0 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    1603            0 :                         if ((std::abs(tempHeatRecVolFlowRate - nomHeatRecVolFlowRateUser) / nomHeatRecVolFlowRateUser) >
    1604            0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    1605            0 :                             ShowMessage(state, format("SizeChillerElectricEIR: Potential issue with equipment sizing for {}", this->Name));
    1606            0 :                             ShowContinueError(state,
    1607            0 :                                               format("User-Specified Heat Recovery Water Flow Rate of {:.5R} [m3/s]", nomHeatRecVolFlowRateUser));
    1608            0 :                             ShowContinueError(
    1609            0 :                                 state, format("differs from Design Size Heat Recovery Water Flow Rate of {:.5R} [m3/s]", tempHeatRecVolFlowRate));
    1610            0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1611            0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1612              :                         }
    1613              :                     }
    1614              :                 }
    1615            0 :                 tempHeatRecVolFlowRate = nomHeatRecVolFlowRateUser;
    1616              :             }
    1617              :         }
    1618            3 :         if (!this->DesignHeatRecVolFlowRateWasAutoSized) {
    1619            0 :             tempHeatRecVolFlowRate = this->DesignHeatRecVolFlowRate;
    1620              :         }
    1621            3 :         PlantUtilities::RegisterPlantCompDesignFlow(state, this->HeatRecInletNodeNum, tempHeatRecVolFlowRate);
    1622              :     } // Heat recovery active
    1623              : 
    1624           11 :     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1625              : 
    1626            5 :         Real64 IPLVSI_rpt_std229 = 0.0;
    1627            5 :         Real64 IPLVIP_rpt_std229 = 0.0;
    1628              : 
    1629            5 :         if (this->IPLVFlag) {
    1630            5 :             Real64 IPLVSI = 0.0;
    1631            5 :             Real64 IPLVIP = 0.0;
    1632            5 :             StandardRatings::CalcChillerIPLV(state,
    1633            5 :                                              this->Name,
    1634              :                                              DataPlant::PlantEquipmentType::Chiller_ElectricEIR,
    1635              :                                              this->RefCap,
    1636              :                                              this->RefCOP,
    1637              :                                              this->CondenserType,
    1638              :                                              this->ChillerCapFTIndex,
    1639              :                                              this->ChillerEIRFTIndex,
    1640              :                                              this->ChillerEIRFPLRIndex,
    1641              :                                              this->MinUnloadRat,
    1642              :                                              IPLVSI,
    1643              :                                              IPLVIP,
    1644           10 :                                              ObjexxFCL::Optional<const Real64>(),
    1645           10 :                                              ObjexxFCL::Optional_int_const(),
    1646           10 :                                              ObjexxFCL::Optional<const Real64>());
    1647              : 
    1648            5 :             IPLVSI_rpt_std229 = IPLVSI;
    1649            5 :             IPLVIP_rpt_std229 = IPLVIP;
    1650              : 
    1651            5 :             this->IPLVFlag = false;
    1652              :         }
    1653              :         // create predefined report
    1654            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechType, this->Name, "Chiller:Electric:EIR");
    1655            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomEff, this->Name, this->RefCOP);
    1656            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, this->Name, this->RefCap);
    1657              : 
    1658              :         // std 229 new Chillers table
    1659            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerType, this->Name, "Chiller:Electric:EIR");
    1660            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefCap, this->Name, this->RefCap);
    1661            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefEff, this->Name, this->RefCOP); // Eff == COP?
    1662           10 :         OutputReportPredefined::PreDefTableEntry(
    1663            5 :             state, state.dataOutRptPredefined->pdchChillerRatedCap, this->Name, this->RefCap); // did not find rated cap
    1664           10 :         OutputReportPredefined::PreDefTableEntry(
    1665            5 :             state, state.dataOutRptPredefined->pdchChillerRatedEff, this->Name, this->RefCOP); // did not find rated eff or cop ; also Eff == COP?
    1666            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerIPLVinSI, this->Name, IPLVSI_rpt_std229);
    1667            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerIPLVinIP, this->Name, IPLVIP_rpt_std229);
    1668           10 :         OutputReportPredefined::PreDefTableEntry(state,
    1669            5 :                                                  state.dataOutRptPredefined->pdchChillerPlantloopName,
    1670              :                                                  this->Name,
    1671           10 :                                                  (this->CWPlantLoc.loop != nullptr) ? this->CWPlantLoc.loop->Name : "N/A");
    1672           10 :         OutputReportPredefined::PreDefTableEntry(state,
    1673            5 :                                                  state.dataOutRptPredefined->pdchChillerPlantloopBranchName,
    1674              :                                                  this->Name,
    1675           10 :                                                  (this->CWPlantLoc.branch != nullptr) ? this->CWPlantLoc.branch->Name : "N/A");
    1676           10 :         OutputReportPredefined::PreDefTableEntry(state,
    1677            5 :                                                  state.dataOutRptPredefined->pdchChillerCondLoopName,
    1678              :                                                  this->Name,
    1679           13 :                                                  (this->CDPlantLoc.loop != nullptr) ? this->CDPlantLoc.loop->Name : "N/A");
    1680           10 :         OutputReportPredefined::PreDefTableEntry(state,
    1681            5 :                                                  state.dataOutRptPredefined->pdchChillerCondLoopBranchName,
    1682              :                                                  this->Name,
    1683           13 :                                                  (this->CDPlantLoc.loop != nullptr) ? this->CDPlantLoc.branch->Name : "N/A");
    1684            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerMinPLR, this->Name, this->MinPartLoadRat);
    1685            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerFuelType, this->Name, "Electricity");
    1686           10 :         OutputReportPredefined::PreDefTableEntry(
    1687            5 :             state, state.dataOutRptPredefined->pdchChillerRatedEntCondTemp, this->Name, this->TempRefCondIn); // Rated==Ref?
    1688           10 :         OutputReportPredefined::PreDefTableEntry(
    1689            5 :             state, state.dataOutRptPredefined->pdchChillerRatedLevEvapTemp, this->Name, this->TempRefEvapOut); // Rated==Ref?
    1690            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefEntCondTemp, this->Name, this->TempRefCondIn);
    1691            5 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefLevEvapTemp, this->Name, this->TempRefEvapOut);
    1692              : 
    1693           10 :         OutputReportPredefined::PreDefTableEntry(state,
    1694            5 :                                                  state.dataOutRptPredefined->pdchChillerDesSizeRefCHWFlowRate,
    1695              :                                                  this->Name,
    1696              :                                                  this->EvapMassFlowRateMax); // flowrate Max==DesignSizeRef flowrate?
    1697           10 :         OutputReportPredefined::PreDefTableEntry(state,
    1698            5 :                                                  state.dataOutRptPredefined->pdchChillerDesSizeRefCondFluidFlowRate,
    1699              :                                                  this->Name,
    1700              :                                                  this->CondMassFlowRateMax); // Cond flowrate Max==DesignSizeRef Cond flowrate?
    1701           10 :         OutputReportPredefined::PreDefTableEntry(state,
    1702            5 :                                                  state.dataOutRptPredefined->pdchChillerHeatRecPlantloopName,
    1703              :                                                  this->Name,
    1704           14 :                                                  (this->HRPlantLoc.loop != nullptr) ? this->HRPlantLoc.loop->Name : "N/A");
    1705           10 :         OutputReportPredefined::PreDefTableEntry(state,
    1706            5 :                                                  state.dataOutRptPredefined->pdchChillerHeatRecPlantloopBranchName,
    1707              :                                                  this->Name,
    1708           14 :                                                  (this->HRPlantLoc.loop != nullptr) ? this->HRPlantLoc.branch->Name : "N/A");
    1709           10 :         OutputReportPredefined::PreDefTableEntry(
    1710            5 :             state, state.dataOutRptPredefined->pdchChillerRecRelCapFrac, this->Name, this->HeatRecCapacityFraction);
    1711              :     }
    1712              : 
    1713           11 :     if (ErrorsFound) {
    1714            0 :         ShowFatalError(state, "Preceding sizing errors cause program termination");
    1715              :     }
    1716           11 : }
    1717              : 
    1718         1440 : void ElectricEIRChillerSpecs::calculate(EnergyPlusData &state, Real64 &MyLoad, bool const RunFlag)
    1719              : {
    1720              :     // SUBROUTINE INFORMATION:
    1721              :     //       AUTHOR         Richard Raustad, FSEC
    1722              :     //       DATE WRITTEN   July 2004
    1723              :     //       MODIFIED       Feb. 2010, Chandan Sharma, FSEC, Added basin heater
    1724              :     //                      Jun. 2016, Rongpeng Zhang, Applied the chiller supply water temperature sensor fault model
    1725              :     //                      Nov. 2016, Rongpeng Zhang, LBNL. Added Fouling Chiller fault
    1726              : 
    1727              :     // PURPOSE OF THIS SUBROUTINE:
    1728              :     //  Simulate a vapor compression chiller using the DOE-2 model
    1729              : 
    1730              :     // METHODOLOGY EMPLOYED:
    1731              :     //  Use empirical curve fits to model performance at off-reference conditions
    1732              : 
    1733              :     // REFERENCES:
    1734              :     // 1. DOE-2 Engineers Manual, Version 2.1A, November 1982, LBL-11353
    1735              : 
    1736              :     static constexpr std::string_view RoutineName("CalcElectricEIRChillerModel");
    1737              : 
    1738         1440 :     Real64 EvapOutletTempSetPoint(0.0); // Evaporator outlet temperature setpoint [C]
    1739         1440 :     Real64 EvapDeltaTemp(0.0);          // Evaporator temperature difference [C]
    1740         1440 :     Real64 TempLoad(0.0);               // Actual load to be met by chiller. This value is compared to MyLoad
    1741              :     // and reset when necessary since this chiller can cycle, the load passed
    1742              :     // should be the actual load. Instead the minimum PLR * RefCap is
    1743              :     // passed in. [W]
    1744         1440 :     Real64 CurrentEndTime = 0.0; // end time of time step for current simulation time step
    1745              : 
    1746              :     // Set module level inlet and outlet nodes and initialize other local variables
    1747         1440 :     this->CondMassFlowRate = 0.0;
    1748         1440 :     Real64 FRAC = 1.0; // Chiller cycling ratio
    1749              : 
    1750              :     // Set performance curve outputs to 0.0 when chiller is off
    1751         1440 :     this->ChillerCapFT = 0.0;
    1752         1440 :     this->ChillerEIRFT = 0.0;
    1753         1440 :     this->ChillerEIRFPLR = 0.0;
    1754         1440 :     this->thermosiphonStatus = 0;
    1755              : 
    1756              :     // calculate end time of current time step
    1757         1440 :     CurrentEndTime = state.dataGlobal->CurrentTime + state.dataHVACGlobal->SysTimeElapsed;
    1758              : 
    1759              :     // Print warning messages only when valid and only for the first occurrence. Let summary provide statistics.
    1760              :     // Wait for next time step to print warnings. If simulation iterates, print out
    1761              :     // the warning for the last iteration only. Must wait for next time step to accomplish this.
    1762              :     // If a warning occurs and the simulation down shifts, the warning is not valid.
    1763         1440 :     if (CurrentEndTime > this->CurrentEndTimeLast && state.dataHVACGlobal->TimeStepSys >= this->TimeStepSysLast) {
    1764          169 :         if (this->PrintMessage) {
    1765            0 :             ++this->MsgErrorCount;
    1766              :             //     Show single warning and pass additional info to ShowRecurringWarningErrorAtEnd
    1767            0 :             if (this->MsgErrorCount < 2) {
    1768            0 :                 ShowWarningError(state, format("{}.", this->MsgBuffer1));
    1769            0 :                 ShowContinueError(state, this->MsgBuffer2);
    1770              :             } else {
    1771            0 :                 ShowRecurringWarningErrorAtEnd(
    1772            0 :                     state, this->MsgBuffer1 + " error continues.", this->ErrCount1, this->MsgDataLast, this->MsgDataLast, _, "[C]", "[C]");
    1773              :             }
    1774              :         }
    1775              :     }
    1776              : 
    1777              :     // save last system time step and last end time of current time step (used to determine if warning is valid)
    1778         1440 :     this->TimeStepSysLast = state.dataHVACGlobal->TimeStepSys;
    1779         1440 :     this->CurrentEndTimeLast = CurrentEndTime;
    1780              : 
    1781              :     // If no loop demand or chiller OFF, return
    1782              :     // If Chiller load is 0 or chiller is not running then leave the subroutine.Before leaving
    1783              :     // if the component control is SERIESACTIVE we set the component flow to inlet flow so that
    1784              :     // flow resolver will not shut down the branch
    1785         1440 :     if (MyLoad >= 0 || !RunFlag) {
    1786         1430 :         if (this->EquipFlowCtrl == DataBranchAirLoopPlant::ControlType::SeriesActive ||
    1787         1430 :             this->CWPlantLoc.side->FlowLock == DataPlant::FlowLock::Locked) {
    1788          712 :             this->EvapMassFlowRate = state.dataLoopNodes->Node(this->EvapInletNodeNum).MassFlowRate;
    1789              :         }
    1790         1430 :         if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1791            0 :             if (DataPlant::CompData::getPlantComponent(state, this->CDPlantLoc).FlowCtrl == DataBranchAirLoopPlant::ControlType::SeriesActive) {
    1792            0 :                 this->CondMassFlowRate = state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate;
    1793              :             }
    1794              :         }
    1795         1430 :         if (this->CondenserType == DataPlant::CondenserType::EvapCooled) {
    1796            0 :             CalcBasinHeaterPower(
    1797            0 :                 state, this->BasinHeaterPowerFTempDiff, this->basinHeaterSched, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    1798              :         }
    1799         1430 :         this->PrintMessage = false;
    1800         1431 :         return;
    1801              :     }
    1802              : 
    1803              :     // initialize outlet air humidity ratio of air or evap cooled chillers
    1804           10 :     this->CondOutletHumRat = state.dataLoopNodes->Node(this->CondInletNodeNum).HumRat;
    1805              : 
    1806           10 :     if (this->CondenserType == DataPlant::CondenserType::AirCooled) { // Condenser inlet temp = outdoor temp
    1807            3 :         state.dataLoopNodes->Node(this->CondInletNodeNum).Temp = state.dataLoopNodes->Node(this->CondInletNodeNum).OutAirDryBulb;
    1808              : 
    1809              :         // Warn user if entering condenser dry-bulb temperature falls below 0 C
    1810            3 :         if (state.dataLoopNodes->Node(this->CondInletNodeNum).Temp < 0.0 && std::abs(MyLoad) > 0 && RunFlag && !state.dataGlobal->WarmupFlag) {
    1811            0 :             this->PrintMessage = true;
    1812              : 
    1813              :             this->MsgBuffer1 =
    1814            0 :                 "ElectricEIRChillerModel - CHILLER:ELECTRIC:EIR \"" + this->Name + "\" - Air Cooled Condenser Inlet Temperature below 0C";
    1815            0 :             this->MsgBuffer2 = format("... Outdoor Dry-bulb Condition = {:6.2F} C. Occurrence info = {}, {} {}",
    1816            0 :                                       state.dataLoopNodes->Node(this->CondInletNodeNum).Temp,
    1817            0 :                                       state.dataEnvrn->EnvironmentName,
    1818            0 :                                       state.dataEnvrn->CurMnDy,
    1819            0 :                                       General::CreateSysTimeIntervalString(state));
    1820              : 
    1821            0 :             this->MsgDataLast = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1822              :         } else {
    1823            3 :             this->PrintMessage = false;
    1824              :         }
    1825            7 :     } else if (this->CondenserType == DataPlant::CondenserType::EvapCooled) { // Condenser inlet temp = (outdoor wet bulb)
    1826            1 :         state.dataLoopNodes->Node(this->CondInletNodeNum).Temp = state.dataLoopNodes->Node(this->CondInletNodeNum).OutAirWetBulb;
    1827              :         //  line above assumes evaporation pushes condenser inlet air humidity ratio to saturation
    1828            1 :         this->CondOutletHumRat = Psychrometrics::PsyWFnTdbTwbPb(state,
    1829            1 :                                                                 state.dataLoopNodes->Node(this->CondInletNodeNum).Temp,
    1830            1 :                                                                 state.dataLoopNodes->Node(this->CondInletNodeNum).Temp,
    1831            1 :                                                                 state.dataLoopNodes->Node(this->CondInletNodeNum).Press);
    1832              : 
    1833              :         // Warn user if evap condenser wet-bulb temperature falls below 10 C
    1834            1 :         if (state.dataLoopNodes->Node(this->CondInletNodeNum).Temp < 10.0 && std::abs(MyLoad) > 0 && RunFlag && !state.dataGlobal->WarmupFlag) {
    1835            0 :             this->PrintMessage = true;
    1836              :             this->MsgBuffer1 =
    1837            0 :                 "ElectricEIRChillerModel - CHILLER:ELECTRIC:EIR \"" + this->Name + "\" - Air Cooled Condenser Inlet Temperature below 10C";
    1838            0 :             this->MsgBuffer2 = format("... Outdoor Wet-bulb Condition = {:6.2F} C. Occurrence info = {}, {} {}",
    1839            0 :                                       state.dataLoopNodes->Node(this->CondInletNodeNum).Temp,
    1840            0 :                                       state.dataEnvrn->EnvironmentName,
    1841            0 :                                       state.dataEnvrn->CurMnDy,
    1842            0 :                                       General::CreateSysTimeIntervalString(state));
    1843            0 :             this->MsgDataLast = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1844              :         } else {
    1845            1 :             this->PrintMessage = false;
    1846              :         }
    1847              :     } // End of the Air Cooled/Evap Cooled Logic block
    1848              : 
    1849              :     // If not air or evap cooled then set to the condenser node that is attached to a cooling tower
    1850           10 :     Real64 condInletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1851           10 :     this->CondInletTemp = condInletTemp; // needed for thermosiphon model
    1852              : 
    1853              :     // LOAD LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
    1854           10 :     Real64 ChillerRefCap = this->RefCap;
    1855           10 :     Real64 ReferenceCOP = this->RefCOP;
    1856           10 :     this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;
    1857           10 :     Real64 TempLowLimitEout = this->TempLowLimitEvapOut;
    1858              : 
    1859              :     // If there is a fault of chiller fouling
    1860           10 :     if (this->FaultyChillerFoulingFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    1861            0 :         (!state.dataGlobal->KickOffSimulation)) {
    1862            0 :         int FaultIndex = this->FaultyChillerFoulingIndex;
    1863            0 :         Real64 NomCap_ff = ChillerRefCap;
    1864            0 :         Real64 ReferenceCOP_ff = ReferenceCOP;
    1865              : 
    1866              :         // calculate the Faulty Chiller Fouling Factor using fault information
    1867            0 :         this->FaultyChillerFoulingFactor = state.dataFaultsMgr->FaultsChillerFouling(FaultIndex).CalFoulingFactor(state);
    1868              : 
    1869              :         // update the Chiller nominal capacity and COP at faulty cases
    1870            0 :         ChillerRefCap = NomCap_ff * this->FaultyChillerFoulingFactor;
    1871            0 :         ReferenceCOP = ReferenceCOP_ff * this->FaultyChillerFoulingFactor;
    1872              :     }
    1873              : 
    1874              :     // Set initial mass flow rates
    1875           10 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    1876            6 :         this->CondMassFlowRate = this->CondMassFlowRateMax;
    1877            6 :         PlantUtilities::SetComponentFlowRate(state, this->CondMassFlowRate, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
    1878            6 :         PlantUtilities::PullCompInterconnectTrigger(
    1879            6 :             state, this->CWPlantLoc, this->CondMassFlowIndex, this->CDPlantLoc, DataPlant::CriteriaType::MassFlowRate, this->CondMassFlowRate);
    1880              : 
    1881            6 :         if (this->CondMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) {
    1882              :             // Shut chiller off if there is no condenser water flow
    1883            1 :             MyLoad = 0.0;
    1884            1 :             this->EvapMassFlowRate = 0.0;
    1885              :             // Use PlantUtilities::SetComponentFlowRate to decide actual flow
    1886            1 :             PlantUtilities::SetComponentFlowRate(state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    1887            1 :             return;
    1888              :         }
    1889              :     }
    1890              : 
    1891            9 :     switch (this->CWPlantLoc.loop->LoopDemandCalcScheme) {
    1892            9 :     case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1893           27 :         if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) ||
    1894           18 :             (DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).CurOpSchemeType == DataPlant::OpScheme::CompSetPtBased) ||
    1895            9 :             (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint != DataLoopNode::SensedNodeFlagValue)) {
    1896              :             // there will be a valid setpoint on outlet
    1897            4 :             EvapOutletTempSetPoint = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    1898              :         } else { // use plant loop overall setpoint
    1899            5 :             EvapOutletTempSetPoint = state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPoint;
    1900              :         }
    1901            9 :     } break;
    1902            0 :     case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1903            0 :         if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) ||
    1904            0 :             (DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).CurOpSchemeType == DataPlant::OpScheme::CompSetPtBased) ||
    1905            0 :             (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi != DataLoopNode::SensedNodeFlagValue)) {
    1906              :             // there will be a valid setpoint on outlet
    1907            0 :             EvapOutletTempSetPoint = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    1908              :         } else { // use plant loop overall setpoint
    1909            0 :             EvapOutletTempSetPoint = state.dataLoopNodes->Node(this->CWPlantLoc.loop->TempSetPointNodeNum).TempSetPointHi;
    1910              :         }
    1911            0 :     } break;
    1912            0 :     default: {
    1913            0 :         assert(false);
    1914              :     } break;
    1915              :     }
    1916              : 
    1917              :     // If there is a fault of Chiller SWT Sensor
    1918            9 :     if (this->FaultyChillerSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation)) {
    1919            0 :         int FaultIndex = this->FaultyChillerSWTIndex;
    1920            0 :         Real64 EvapOutletTempSetPoint_ff = EvapOutletTempSetPoint;
    1921              : 
    1922              :         // calculate the sensor offset using fault information
    1923            0 :         this->FaultyChillerSWTOffset = state.dataFaultsMgr->FaultsChillerSWTSensor(FaultIndex).CalFaultOffsetAct(state);
    1924              :         // update the EvapOutletTempSetPoint
    1925            0 :         EvapOutletTempSetPoint =
    1926            0 :             max(this->TempLowLimitEvapOut,
    1927            0 :                 min(state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp, EvapOutletTempSetPoint_ff - this->FaultyChillerSWTOffset));
    1928            0 :         this->FaultyChillerSWTOffset = EvapOutletTempSetPoint_ff - EvapOutletTempSetPoint;
    1929              :     }
    1930              : 
    1931              :     // correct temperature if using heat recovery
    1932              :     // use report values for latest valid calculation, lagged somewhat
    1933            9 :     Real64 AvgCondSinkTemp = condInletTemp;
    1934            9 :     if (this->HeatRecActive) {
    1935            0 :         if ((this->QHeatRecovered + this->QCondenser) > 0.0) { // protect div by zero
    1936            0 :             AvgCondSinkTemp =
    1937            0 :                 (this->QHeatRecovered * this->HeatRecInletTemp + this->QCondenser * this->CondInletTemp) / (this->QHeatRecovered + this->QCondenser);
    1938              :         } else {
    1939            0 :             AvgCondSinkTemp = condInletTemp;
    1940              :         }
    1941              :     }
    1942              : 
    1943              :     // Get capacity curve info with respect to CW setpoint and entering condenser water temps
    1944            9 :     this->ChillerCapFT = Curve::CurveValue(state, this->ChillerCapFTIndex, EvapOutletTempSetPoint, AvgCondSinkTemp);
    1945              : 
    1946            9 :     if (this->ChillerCapFT < 0) {
    1947            0 :         if (this->ChillerCapFTError < 1 && this->CWPlantLoc.side->FlowLock != DataPlant::FlowLock::Unlocked && !state.dataGlobal->WarmupFlag) {
    1948            0 :             ++this->ChillerCapFTError;
    1949            0 :             ShowWarningError(state, format("CHILLER:ELECTRIC:EIR \"{}\":", this->Name));
    1950            0 :             ShowContinueError(state, format(" Chiller Capacity as a Function of Temperature curve output is negative ({:.3R}).", this->ChillerCapFT));
    1951            0 :             ShowContinueError(state,
    1952            0 :                               format(" Negative value occurs using an Evaporator Outlet Temp of {:.1R} and a Condenser Inlet Temp of {:.1R}.",
    1953              :                                      EvapOutletTempSetPoint,
    1954              :                                      condInletTemp));
    1955            0 :             ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    1956            0 :         } else if (this->CWPlantLoc.side->FlowLock != DataPlant::FlowLock::Unlocked && !state.dataGlobal->WarmupFlag) {
    1957            0 :             ++this->ChillerCapFTError;
    1958            0 :             ShowRecurringWarningErrorAtEnd(state,
    1959            0 :                                            "CHILLER:ELECTRIC:EIR \"" + this->Name +
    1960              :                                                "\": Chiller Capacity as a Function of Temperature curve output is negative warning continues...",
    1961            0 :                                            this->ChillerCapFTErrorIndex,
    1962            0 :                                            this->ChillerCapFT,
    1963            0 :                                            this->ChillerCapFT);
    1964              :         }
    1965            0 :         this->ChillerCapFT = 0.0;
    1966              :     }
    1967              : 
    1968              :     // Available chiller capacity as a function of temperature
    1969            9 :     Real64 AvailChillerCap = ChillerRefCap * this->ChillerCapFT;
    1970              : 
    1971              :     // Only perform this check for temperature setpoint control
    1972            9 :     if (DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).CurOpSchemeType == DataPlant::OpScheme::CompSetPtBased) {
    1973              :         // Calculate water side load
    1974              : 
    1975            0 :         Real64 Cp = this->CWPlantLoc.loop->glycol->getSpecificHeat(state, state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp, RoutineName);
    1976            0 :         this->EvapMassFlowRate = state.dataLoopNodes->Node(this->EvapInletNodeNum).MassFlowRate;
    1977            0 :         switch (this->CWPlantLoc.loop->LoopDemandCalcScheme) {
    1978            0 :         case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1979            0 :             TempLoad = this->EvapMassFlowRate * Cp *
    1980            0 :                        (state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint);
    1981            0 :         } break;
    1982            0 :         case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1983            0 :             TempLoad = this->EvapMassFlowRate * Cp *
    1984            0 :                        (state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi);
    1985            0 :         } break;
    1986            0 :         default: {
    1987            0 :             assert(false);
    1988              :         } break;
    1989              :         }
    1990            0 :         TempLoad = max(0.0, TempLoad);
    1991              : 
    1992              :         // MyLoad is capped at minimum PLR * RefCap, adjust load to actual water side load because this chiller can cycle
    1993            0 :         if (std::abs(MyLoad) > TempLoad) {
    1994            0 :             MyLoad = sign(TempLoad, MyLoad);
    1995              :         }
    1996              :     }
    1997              : 
    1998              :     // Part load ratio based on load and available chiller capacity, cap at max part load ratio
    1999            9 :     Real64 PartLoadRat = 0.0; // Operating part load ratio
    2000            9 :     if (AvailChillerCap > 0) {
    2001            9 :         PartLoadRat = max(0.0, min(std::abs(MyLoad) / AvailChillerCap, this->MaxPartLoadRat));
    2002              :     }
    2003              : 
    2004            9 :     Real64 Cp = this->CWPlantLoc.loop->glycol->getSpecificHeat(state, state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp, RoutineName);
    2005              : 
    2006            9 :     if (DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).CurOpSchemeType == DataPlant::OpScheme::CompSetPtBased) {
    2007            0 :         this->PossibleSubcooling = false;
    2008              :     } else {
    2009            9 :         this->PossibleSubcooling = true;
    2010              :     }
    2011              :     // Set evaporator heat transfer rate
    2012            9 :     this->QEvaporator = AvailChillerCap * PartLoadRat;
    2013              : 
    2014              :     // Either set the flow to the Constant value or calculate the flow for the variable volume
    2015            9 :     if ((this->FlowMode == DataPlant::FlowMode::Constant) || (this->FlowMode == DataPlant::FlowMode::NotModulated)) {
    2016              :         // Set the evaporator mass flow rate to design
    2017              :         // Start by assuming max (design) flow
    2018            9 :         this->EvapMassFlowRate = this->EvapMassFlowRateMax;
    2019              :         // Use PlantUtilities::SetComponentFlowRate to decide actual flow
    2020            9 :         PlantUtilities::SetComponentFlowRate(state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    2021            9 :         if (this->EvapMassFlowRate != 0.0) {
    2022            9 :             EvapDeltaTemp = this->QEvaporator / this->EvapMassFlowRate / Cp;
    2023              :         } else {
    2024            0 :             EvapDeltaTemp = 0.0;
    2025              :         }
    2026              :         // Evaluate outlet temp based on delta
    2027            9 :         this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - EvapDeltaTemp;
    2028              : 
    2029            0 :     } else if (this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) {
    2030              : 
    2031              :         // Calculate the Delta Temp from the inlet temp to the chiller outlet setpoint
    2032            0 :         switch (this->CWPlantLoc.loop->LoopDemandCalcScheme) {
    2033            0 :         case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    2034            0 :             EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    2035            0 :         } break;
    2036            0 :         case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    2037            0 :             EvapDeltaTemp =
    2038            0 :                 state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    2039            0 :         } break;
    2040            0 :         default: {
    2041            0 :             assert(false);
    2042              :         } break;
    2043              :         }
    2044              : 
    2045            0 :         if (EvapDeltaTemp != 0) {
    2046              :             // Calculate desired flow to request based on load
    2047            0 :             this->EvapMassFlowRate = std::abs(this->QEvaporator / Cp / EvapDeltaTemp);
    2048            0 :             if ((this->EvapMassFlowRate - this->EvapMassFlowRateMax) > DataBranchAirLoopPlant::MassFlowTolerance) {
    2049            0 :                 this->PossibleSubcooling = true;
    2050              :             }
    2051              :             // Check to see if the Maximum is exceeded, if so set to maximum
    2052            0 :             this->EvapMassFlowRate = min(this->EvapMassFlowRateMax, this->EvapMassFlowRate);
    2053              :             // Use PlantUtilities::SetComponentFlowRate to decide actual flow
    2054            0 :             PlantUtilities::SetComponentFlowRate(state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    2055              :             // Should we recalculate this with the corrected setpoint?
    2056            0 :             switch (this->CWPlantLoc.loop->LoopDemandCalcScheme) {
    2057            0 :             case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    2058            0 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    2059            0 :             } break;
    2060            0 :             case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    2061            0 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    2062            0 :             } break;
    2063            0 :             default:
    2064            0 :                 break;
    2065              :             }
    2066            0 :             this->QEvaporator = max(0.0, (this->EvapMassFlowRate * Cp * EvapDeltaTemp));
    2067              :         } else {
    2068              :             // Try to request zero flow
    2069            0 :             this->EvapMassFlowRate = 0.0;
    2070              :             // Use PlantUtilities::SetComponentFlowRate to decide actual flow
    2071            0 :             PlantUtilities::SetComponentFlowRate(state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    2072              :             // No deltaT since component is not running
    2073            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2074            0 :             this->QEvaporator = 0.0;
    2075            0 :             PartLoadRat = 0.0;
    2076            0 :             this->ChillerPartLoadRatio = PartLoadRat;
    2077              : 
    2078              :             // so what if the delta T is zero?  On FlowLock==0, the inlet temp could = setpoint, right?
    2079            0 :             if (this->DeltaTErrCount < 1 && !state.dataGlobal->WarmupFlag) {
    2080            0 :                 ++this->DeltaTErrCount;
    2081            0 :                 ShowWarningError(state, "Evaporator DeltaTemp = 0 in mass flow calculation (Tevapin = Tsetpoint).");
    2082            0 :                 ShowContinueErrorTimeStamp(state, "");
    2083            0 :             } else if (!state.dataGlobal->WarmupFlag) {
    2084            0 :                 ++this->ChillerCapFTError;
    2085            0 :                 ShowRecurringWarningErrorAtEnd(state,
    2086            0 :                                                "CHILLER:ELECTRIC:EIR \"" + this->Name +
    2087              :                                                    "\": Evaporator DeltaTemp = 0 in mass flow calculation warning continues...",
    2088            0 :                                                this->DeltaTErrCountIndex,
    2089              :                                                EvapDeltaTemp,
    2090              :                                                EvapDeltaTemp);
    2091              :             }
    2092              :         }
    2093              :     } // End of Constant Variable Flow If Block
    2094              : 
    2095            9 :     if (this->EvapMassFlowRate == 0.0) {
    2096            0 :         MyLoad = 0.0;
    2097            0 :         if (this->CondenserType == DataPlant::CondenserType::EvapCooled) {
    2098            0 :             CalcBasinHeaterPower(
    2099            0 :                 state, this->BasinHeaterPowerFTempDiff, this->basinHeaterSched, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    2100              :         }
    2101            0 :         this->PrintMessage = false;
    2102            0 :         return;
    2103              :     }
    2104            9 :     if (this->PossibleSubcooling) {
    2105            9 :         this->QEvaporator = std::abs(MyLoad);
    2106            9 :         EvapDeltaTemp = this->QEvaporator / this->EvapMassFlowRate / Cp;
    2107            9 :         this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - EvapDeltaTemp;
    2108              :     } else {
    2109            0 :         EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - EvapOutletTempSetPoint;
    2110            0 :         this->QEvaporator = max(0.0, (this->EvapMassFlowRate * Cp * EvapDeltaTemp));
    2111            0 :         this->EvapOutletTemp = EvapOutletTempSetPoint;
    2112              :     }
    2113              : 
    2114              :     // Check that the Evap outlet temp honors both plant loop temp low limit and also the chiller low limit
    2115            9 :     if (this->EvapOutletTemp < TempLowLimitEout) {
    2116            0 :         if ((state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - TempLowLimitEout) > DataPlant::DeltaTempTol) {
    2117            0 :             this->EvapOutletTemp = TempLowLimitEout;
    2118            0 :             EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->EvapOutletTemp;
    2119            0 :             this->QEvaporator = this->EvapMassFlowRate * Cp * EvapDeltaTemp;
    2120              :         } else {
    2121            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2122            0 :             EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->EvapOutletTemp;
    2123            0 :             this->QEvaporator = this->EvapMassFlowRate * Cp * EvapDeltaTemp;
    2124              :         }
    2125              :     }
    2126            9 :     if (this->EvapOutletTemp < state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempMin) {
    2127            0 :         if ((state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempMin) >
    2128              :             DataPlant::DeltaTempTol) {
    2129            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempMin;
    2130            0 :             EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->EvapOutletTemp;
    2131            0 :             this->QEvaporator = this->EvapMassFlowRate * Cp * EvapDeltaTemp;
    2132              :         } else {
    2133            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2134            0 :             EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->EvapOutletTemp;
    2135            0 :             this->QEvaporator = this->EvapMassFlowRate * Cp * EvapDeltaTemp;
    2136              :         }
    2137              :     }
    2138              :     // If load exceeds the distributed load set to the distributed load
    2139            9 :     if (this->QEvaporator > std::abs(MyLoad)) {
    2140            0 :         if (this->EvapMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
    2141            0 :             this->QEvaporator = std::abs(MyLoad);
    2142            0 :             EvapDeltaTemp = this->QEvaporator / this->EvapMassFlowRate / Cp;
    2143            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - EvapDeltaTemp;
    2144              :         } else {
    2145            0 :             this->QEvaporator = 0.0;
    2146            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2147              :         }
    2148              :     }
    2149              : 
    2150              :     // If there is a fault of Chiller SWT Sensor
    2151            9 :     if (this->FaultyChillerSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation) &&
    2152            0 :         (this->EvapMassFlowRate > 0)) {
    2153              :         // calculate directly affected variables at faulty case: EvapOutletTemp, EvapMassFlowRate, QEvaporator
    2154            0 :         int FaultIndex = this->FaultyChillerSWTIndex;
    2155            0 :         bool VarFlowFlag = (this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated);
    2156            0 :         state.dataFaultsMgr->FaultsChillerSWTSensor(FaultIndex)
    2157            0 :             .CalFaultChillerSWT(VarFlowFlag,
    2158              :                                 this->FaultyChillerSWTOffset,
    2159              :                                 Cp,
    2160            0 :                                 state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp,
    2161            0 :                                 this->EvapOutletTemp,
    2162            0 :                                 this->EvapMassFlowRate,
    2163            0 :                                 this->QEvaporator);
    2164              :         // update corresponding variables at faulty case
    2165            0 :         PartLoadRat = (AvailChillerCap > 0.0) ? (this->QEvaporator / AvailChillerCap) : 0.0;
    2166            0 :         PartLoadRat = max(0.0, min(PartLoadRat, this->MaxPartLoadRat));
    2167            0 :         this->ChillerPartLoadRatio = PartLoadRat;
    2168              :     }
    2169              : 
    2170              :     // Checks QEvaporator on the basis of the machine limits.
    2171            9 :     if (this->QEvaporator > (AvailChillerCap * this->MaxPartLoadRat)) {
    2172            0 :         if (this->EvapMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
    2173            0 :             this->QEvaporator = AvailChillerCap * this->MaxPartLoadRat;
    2174            0 :             EvapDeltaTemp = this->QEvaporator / this->EvapMassFlowRate / Cp;
    2175              :             // evaporator outlet temperature is allowed to float upwards (recalculate AvailChillerCap? iterate?)
    2176            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - EvapDeltaTemp;
    2177              :         } else {
    2178            0 :             this->QEvaporator = 0.0;
    2179            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2180              :         }
    2181              :     }
    2182              : 
    2183            9 :     if (AvailChillerCap > 0.0) {
    2184            9 :         PartLoadRat = max(0.0, min((this->QEvaporator / AvailChillerCap), this->MaxPartLoadRat));
    2185              :     } else {
    2186            0 :         PartLoadRat = 0.0;
    2187              :     }
    2188              : 
    2189              :     // Chiller cycles below minimum part load ratio, FRAC = amount of time chiller is ON during this time step
    2190            9 :     if (PartLoadRat < this->MinPartLoadRat) {
    2191            2 :         FRAC = min(1.0, (PartLoadRat / this->MinPartLoadRat));
    2192              :     }
    2193              : 
    2194              :     // set the module level variable used for reporting FRAC
    2195            9 :     this->ChillerCyclingRatio = FRAC;
    2196              : 
    2197              :     // Chiller is false loading below PLR = minimum unloading ratio, find PLR used for energy calculation
    2198            9 :     if (AvailChillerCap > 0.0) {
    2199            9 :         PartLoadRat = max(PartLoadRat, this->MinUnloadRat);
    2200              :     } else {
    2201            0 :         PartLoadRat = 0.0;
    2202              :     }
    2203              : 
    2204              :     // set the module level variable used for reporting PLR
    2205            9 :     this->ChillerPartLoadRatio = PartLoadRat;
    2206              : 
    2207              :     // calculate the load due to false loading on chiller over and above water side load
    2208            9 :     this->ChillerFalseLoadRate = (AvailChillerCap * PartLoadRat * FRAC) - this->QEvaporator;
    2209            9 :     if (this->ChillerFalseLoadRate < HVAC::SmallLoad) {
    2210            8 :         this->ChillerFalseLoadRate = 0.0;
    2211              :     }
    2212            9 :     if (this->QEvaporator == 0.0 && this->CondenserType == DataPlant::CondenserType::EvapCooled) {
    2213            0 :         CalcBasinHeaterPower(state, this->BasinHeaterPowerFTempDiff, this->basinHeaterSched, this->BasinHeaterSetPointTemp, this->BasinHeaterPower);
    2214              :     }
    2215              : 
    2216            9 :     this->ChillerEIRFT = Curve::CurveValue(state, this->ChillerEIRFTIndex, this->EvapOutletTemp, AvgCondSinkTemp);
    2217            9 :     if (this->ChillerEIRFT < 0.0) {
    2218            0 :         if (this->ChillerEIRFTError < 1 && this->CWPlantLoc.side->FlowLock != DataPlant::FlowLock::Unlocked && !state.dataGlobal->WarmupFlag) {
    2219            0 :             ++this->ChillerEIRFTError;
    2220            0 :             ShowWarningError(state, format("CHILLER:ELECTRIC:EIR \"{}\":", this->Name));
    2221            0 :             ShowContinueError(state, format(" Chiller EIR as a Function of Temperature curve output is negative ({:.3R}).", this->ChillerEIRFT));
    2222            0 :             ShowContinueError(state,
    2223            0 :                               format(" Negative value occurs using an Evaporator Outlet Temp of {:.1R} and a Condenser Inlet Temp of {:.1R}.",
    2224            0 :                                      this->EvapOutletTemp,
    2225              :                                      condInletTemp));
    2226            0 :             ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    2227            0 :         } else if (this->CWPlantLoc.side->FlowLock != DataPlant::FlowLock::Unlocked && !state.dataGlobal->WarmupFlag) {
    2228            0 :             ++this->ChillerEIRFTError;
    2229            0 :             ShowRecurringWarningErrorAtEnd(state,
    2230            0 :                                            "CHILLER:ELECTRIC:EIR \"" + this->Name +
    2231              :                                                "\": Chiller EIR as a Function of Temperature curve output is negative warning continues...",
    2232            0 :                                            this->ChillerEIRFTErrorIndex,
    2233            0 :                                            this->ChillerEIRFT,
    2234            0 :                                            this->ChillerEIRFT);
    2235              :         }
    2236            0 :         this->ChillerEIRFT = 0.0;
    2237              :     }
    2238              : 
    2239            9 :     this->ChillerEIRFPLR = Curve::CurveValue(state, this->ChillerEIRFPLRIndex, PartLoadRat);
    2240            9 :     if (this->ChillerEIRFPLR < 0.0) {
    2241            0 :         if (this->ChillerEIRFPLRError < 1 && this->CWPlantLoc.side->FlowLock != DataPlant::FlowLock::Unlocked && !state.dataGlobal->WarmupFlag) {
    2242            0 :             ++this->ChillerEIRFPLRError;
    2243            0 :             ShowWarningError(state, format("CHILLER:ELECTRIC:EIR \"{}\":", this->Name));
    2244            0 :             ShowContinueError(state, format(" Chiller EIR as a function of PLR curve output is negative ({:.3R}).", this->ChillerEIRFPLR));
    2245            0 :             ShowContinueError(state, format(" Negative value occurs using a part-load ratio of {:.3R}.", PartLoadRat));
    2246            0 :             ShowContinueErrorTimeStamp(state, " Resetting curve output to zero and continuing simulation.");
    2247            0 :         } else if (this->CWPlantLoc.side->FlowLock != DataPlant::FlowLock::Unlocked && !state.dataGlobal->WarmupFlag) {
    2248            0 :             ++this->ChillerEIRFPLRError;
    2249            0 :             ShowRecurringWarningErrorAtEnd(state,
    2250            0 :                                            "CHILLER:ELECTRIC:EIR \"" + this->Name +
    2251              :                                                "\": Chiller EIR as a function of PLR curve output is negative warning continues...",
    2252            0 :                                            this->ChillerEIRFPLRErrorIndex,
    2253            0 :                                            this->ChillerEIRFPLR,
    2254            0 :                                            this->ChillerEIRFPLR);
    2255              :         }
    2256            0 :         this->ChillerEIRFPLR = 0.0;
    2257              :     }
    2258            9 :     if (this->thermosiphonDisabled(state)) {
    2259            8 :         this->Power = (AvailChillerCap / ReferenceCOP) * this->ChillerEIRFPLR * this->ChillerEIRFT * FRAC;
    2260              :     }
    2261              : 
    2262            9 :     this->QCondenser = this->Power * this->CompPowerToCondenserFrac + this->QEvaporator + this->ChillerFalseLoadRate;
    2263              : 
    2264              :     // set condenser mass flow rate
    2265            9 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    2266            5 :         switch (this->CondenserFlowControl) {
    2267            1 :         case DataPlant::CondenserFlowControl::ConstantFlow: {
    2268            1 :             this->CondMassFlowRate = this->CondMassFlowRateMax;
    2269            1 :         } break;
    2270            2 :         case DataPlant::CondenserFlowControl::ModulatedChillerPLR: {
    2271            2 :             this->CondMassFlowRate = this->CondMassFlowRateMax * PartLoadRat;
    2272            2 :         } break;
    2273            1 :         case DataPlant::CondenserFlowControl::ModulatedLoopPLR: {
    2274            1 :             int PltSizNum = this->CWPlantLoc.loop->PlantSizNum;
    2275            1 :             int CondPltSizNum = this->CDPlantLoc.loop->PlantSizNum;
    2276            1 :             if (PltSizNum > 0 && CondPltSizNum > 0) {
    2277            1 :                 Real64 chwLoopCap = state.dataSize->PlantSizData(PltSizNum).DesCapacity;
    2278            1 :                 Real64 chwLoopDemand = std::abs(this->CWPlantLoc.side->UpdatedDemandToLoopSetPoint);
    2279            1 :                 Real64 cwhLoopPLR = 0.0;
    2280            1 :                 if (chwLoopDemand > 0) {
    2281            1 :                     cwhLoopPLR = chwLoopDemand / chwLoopCap;
    2282              :                 }
    2283            1 :                 Real64 condWaterFlowFrac = Curve::CurveValue(state, this->ChillerCondLoopFlowFLoopPLRIndex, cwhLoopPLR);
    2284            1 :                 Real64 cwLoopDesVolFlowRate = state.dataSize->PlantSizData(CondPltSizNum).DesVolFlowRate;
    2285            1 :                 Real64 cwLoopVolFlowRate = condWaterFlowFrac * cwLoopDesVolFlowRate;
    2286            1 :                 Real64 rho = this->CDPlantLoc.loop->glycol->getDensity(state, this->TempRefCondIn, RoutineName);
    2287            1 :                 if (chwLoopDemand > 0) {
    2288            1 :                     this->CondMassFlowRate = cwLoopVolFlowRate * rho * this->QEvaporator / chwLoopDemand;
    2289              :                 } else {
    2290            0 :                     this->CondMassFlowRate = 0.0;
    2291              :                 }
    2292            1 :             } else {
    2293            0 :                 ShowFatalError(state,
    2294            0 :                                format("{}: The ModulatedLoopPLR condenser flow control requires a Sizing:Plant object for "
    2295              :                                       "both loops connected to the condenser and evaporator of the chiller.",
    2296              :                                       RoutineName));
    2297              :             }
    2298            1 :         } break;
    2299            1 :         case DataPlant::CondenserFlowControl::ModulatedDeltaTemperature: {
    2300            1 :             Real64 CpCond = this->CWPlantLoc.loop->glycol->getSpecificHeat(state, this->CondInletTemp, RoutineName);
    2301            1 :             Real64 condDT = 0.0;
    2302            1 :             if (this->condDTSched != nullptr) {
    2303            1 :                 condDT = this->condDTSched->getCurrentVal();
    2304              :             }
    2305            1 :             this->CondMassFlowRate = this->QCondenser / (CpCond * condDT);
    2306            1 :         } break;
    2307            0 :         default: {
    2308            0 :             this->CondMassFlowRate = this->CondMassFlowRateMax;
    2309            0 :         } break;
    2310              :         }
    2311            5 :         Real64 minCondMassFlowRate = this->MinCondFlowRatio * this->CondMassFlowRateMax;
    2312            5 :         Real64 minPumpMassFlowRate = this->VSBranchPumpMinLimitMassFlowCond;
    2313            5 :         Real64 maxCondMassFlowRate = min(this->CondMassFlowRate, this->CondMassFlowRateMax);
    2314            5 :         this->CondMassFlowRate = max(maxCondMassFlowRate, minCondMassFlowRate, minPumpMassFlowRate);
    2315            5 :         PlantUtilities::SetComponentFlowRate(state, this->CondMassFlowRate, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
    2316            5 :         PlantUtilities::PullCompInterconnectTrigger(
    2317            5 :             state, this->CWPlantLoc, this->CondMassFlowIndex, this->CDPlantLoc, DataPlant::CriteriaType::MassFlowRate, this->CondMassFlowRate);
    2318              :     }
    2319              : 
    2320            9 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    2321            5 :         if (this->CondMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
    2322              :             // If Heat Recovery specified for this vapor compression chiller, then Qcondenser will be adjusted by this subroutine
    2323            5 :             if (this->HeatRecActive) {
    2324            0 :                 this->calcHeatRecovery(state, this->QCondenser, this->CondMassFlowRate, condInletTemp, this->QHeatRecovered);
    2325              :             }
    2326            5 :             Real64 CpCond = this->CDPlantLoc.loop->glycol->getSpecificHeat(state, condInletTemp, RoutineName);
    2327              : 
    2328            5 :             this->CondOutletTemp = this->QCondenser / this->CondMassFlowRate / CpCond + condInletTemp;
    2329              :         } else {
    2330            0 :             ShowSevereError(state, format("CalcElectricEIRChillerModel: Condenser flow = 0, for ElectricEIRChiller={}", this->Name));
    2331            0 :             ShowContinueErrorTimeStamp(state, "");
    2332              :             // maybe this could be handled earlier, check if this component has a load and an evap flow rate
    2333              :             // then if cond flow is zero, just make a request to the condenser,
    2334              :             // then just say it couldn't run until condenser loop wakes up.
    2335              :         }
    2336              :     } else { // Air Cooled or Evap Cooled
    2337              : 
    2338            4 :         if (this->QCondenser > 0.0) {
    2339            4 :             this->CondMassFlowRate = this->CondMassFlowRateMax * PartLoadRat;
    2340              :         } else {
    2341            0 :             this->CondMassFlowRate = 0.0;
    2342              :         }
    2343              : 
    2344              :         // If Heat Recovery specified for this vapor compression chiller, then Qcondenser will be adjusted by this subroutine
    2345            4 :         if (this->HeatRecActive) {
    2346            0 :             this->calcHeatRecovery(state, this->QCondenser, this->CondMassFlowRate, condInletTemp, this->QHeatRecovered);
    2347              :         }
    2348              : 
    2349            4 :         if (CondMassFlowRate > 0.0) {
    2350            4 :             Real64 CpCond = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->CondInletNodeNum).HumRat);
    2351            4 :             CondOutletTemp = CondInletTemp + QCondenser / CondMassFlowRate / CpCond;
    2352              :         } else {
    2353            0 :             this->CondOutletTemp = condInletTemp;
    2354              :         }
    2355              : 
    2356            4 :         if (this->CondenserType == DataPlant::CondenserType::EvapCooled) {
    2357            1 :             Real64 const RhoWater = Psychrometrics::RhoH2O(Constant::InitConvTemp);
    2358              :             // CondMassFlowRate is already multiplied by PLR, convert to water use rate
    2359            1 :             this->EvapWaterConsumpRate =
    2360            1 :                 ((this->CondOutletHumRat - state.dataLoopNodes->Node(this->CondInletNodeNum).HumRat) * this->CondMassFlowRate) / RhoWater;
    2361              :         }
    2362              :     }
    2363              : 
    2364              :     // Calculate condenser fan power
    2365            9 :     if (this->ChillerCapFT > 0.0) {
    2366            9 :         this->CondenserFanPower = ChillerRefCap * this->CondenserFanPowerRatio * FRAC;
    2367              :     } else {
    2368            0 :         this->CondenserFanPower = 0.0;
    2369              :     }
    2370              : }
    2371              : 
    2372            0 : void ElectricEIRChillerSpecs::calcHeatRecovery(EnergyPlusData &state,
    2373              :                                                Real64 &QCond,              // Current condenser load [W]
    2374              :                                                Real64 const CondMassFlow,  // Current condenser mass flow [kg/s]
    2375              :                                                Real64 const condInletTemp, // Current condenser inlet temp [C]
    2376              :                                                Real64 &QHeatRec            // Amount of heat recovered [W]
    2377              : )
    2378              : {
    2379              :     // SUBROUTINE INFORMATION:
    2380              :     //       AUTHOR:          Richard Liesen
    2381              :     //       DATE WRITTEN:    January 2004
    2382              :     //       MODIFIED:        Richard Raustad, FSEC (occurrences of EIR only, calcs are identical to electric chiller)
    2383              : 
    2384              :     // PURPOSE OF THIS SUBROUTINE:
    2385              :     //  Calculate the heat recovered from the chiller condenser
    2386              : 
    2387              :     static constexpr std::string_view RoutineName("EIRChillerHeatRecovery");
    2388              : 
    2389              :     // Inlet node to the heat recovery heat exchanger
    2390            0 :     Real64 heatRecInletTemp = state.dataLoopNodes->Node(this->HeatRecInletNodeNum).Temp;
    2391            0 :     Real64 HeatRecMassFlowRate = state.dataLoopNodes->Node(this->HeatRecInletNodeNum).MassFlowRate;
    2392              : 
    2393            0 :     Real64 CpHeatRec = this->HRPlantLoc.loop->glycol->getSpecificHeat(state, heatRecInletTemp, RoutineName);
    2394              :     Real64 CpCond;
    2395            0 :     if (this->CondenserType == DataPlant::CondenserType::WaterCooled) {
    2396            0 :         CpCond = this->CDPlantLoc.loop->glycol->getSpecificHeat(state, condInletTemp, RoutineName);
    2397              :     } else {
    2398            0 :         CpCond = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(this->HeatRecInletNodeNum).HumRat);
    2399              :     }
    2400              : 
    2401              :     // Before we modify the QCondenser, the total or original value is transferred to QTot
    2402            0 :     Real64 QTotal = QCond;
    2403              : 
    2404            0 :     if (this->HeatRecSetPointNodeNum == 0) { // use original algorithm that blends temps
    2405            0 :         Real64 TAvgIn = (HeatRecMassFlowRate * CpHeatRec * heatRecInletTemp + CondMassFlow * CpCond * condInletTemp) /
    2406            0 :                         (HeatRecMassFlowRate * CpHeatRec + CondMassFlow * CpCond);
    2407              : 
    2408            0 :         Real64 TAvgOut = QTotal / (HeatRecMassFlowRate * CpHeatRec + CondMassFlow * CpCond) + TAvgIn;
    2409              : 
    2410            0 :         QHeatRec = HeatRecMassFlowRate * CpHeatRec * (TAvgOut - heatRecInletTemp);
    2411            0 :         QHeatRec = max(QHeatRec, 0.0); // ensure non negative
    2412              :         // check if heat flow too large for physical size of bundle
    2413            0 :         QHeatRec = min(QHeatRec, this->HeatRecMaxCapacityLimit);
    2414              :     } else {                          // use new algorithm to meet setpoint
    2415            0 :         Real64 THeatRecSetPoint(0.0); // local value for heat recovery leaving setpoint [C]
    2416            0 :         switch (this->HRPlantLoc.loop->LoopDemandCalcScheme) {
    2417            0 :         case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    2418            0 :             THeatRecSetPoint = state.dataLoopNodes->Node(this->HeatRecSetPointNodeNum).TempSetPoint;
    2419            0 :         } break;
    2420            0 :         case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    2421            0 :             THeatRecSetPoint = state.dataLoopNodes->Node(this->HeatRecSetPointNodeNum).TempSetPointHi;
    2422            0 :         } break;
    2423            0 :         default: {
    2424            0 :             assert(false);
    2425              :         } break;
    2426              :         }
    2427              : 
    2428              :         // load to heat recovery setpoint
    2429            0 :         Real64 QHeatRecToSetPoint = HeatRecMassFlowRate * CpHeatRec * (THeatRecSetPoint - heatRecInletTemp);
    2430            0 :         QHeatRecToSetPoint = max(QHeatRecToSetPoint, 0.0);
    2431            0 :         QHeatRec = min(QTotal, QHeatRecToSetPoint);
    2432              :         // check if heat flow too large for physical size of bundle
    2433            0 :         QHeatRec = min(QHeatRec, this->HeatRecMaxCapacityLimit);
    2434              :     }
    2435              : 
    2436              :     // check if limit on inlet is present and exceeded.
    2437            0 :     if (this->heatRecInletLimitSched != nullptr) {
    2438            0 :         Real64 HeatRecHighInletLimit = this->heatRecInletLimitSched->getCurrentVal();
    2439            0 :         if (heatRecInletTemp > HeatRecHighInletLimit) { // shut down heat recovery
    2440            0 :             QHeatRec = 0.0;
    2441              :         }
    2442              :     }
    2443              : 
    2444            0 :     QCond = QTotal - QHeatRec;
    2445              : 
    2446              :     // Calculate a new Heat Recovery Coil Outlet Temp
    2447            0 :     if (HeatRecMassFlowRate > 0.0) {
    2448            0 :         this->HeatRecOutletTemp = QHeatRec / (HeatRecMassFlowRate * CpHeatRec) + heatRecInletTemp;
    2449              :     } else {
    2450            0 :         this->HeatRecOutletTemp = heatRecInletTemp;
    2451              :     }
    2452            0 : }
    2453              : 
    2454         1433 : void ElectricEIRChillerSpecs::update(EnergyPlusData &state, Real64 const MyLoad, bool const RunFlag)
    2455              : {
    2456              : 
    2457              :     // SUBROUTINE INFORMATION:
    2458              :     //       AUTHOR:          Richard Raustad, FSEC
    2459              :     //       DATE WRITTEN:    June 2004
    2460              : 
    2461              :     // PURPOSE OF THIS SUBROUTINE:
    2462              :     //  Reporting
    2463              : 
    2464              :     // Number of seconds per HVAC system time step, to convert from W (J/s) to J
    2465         1433 :     Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
    2466              : 
    2467         1433 :     if (MyLoad >= 0 || !RunFlag) { // Chiller not running so pass inlet states to outlet states
    2468              :         // Set node conditions
    2469         1431 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2470         1431 :         state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    2471         1431 :         if (this->CondenserType != DataPlant::CondenserType::WaterCooled) {
    2472         1430 :             state.dataLoopNodes->Node(this->CondOutletNodeNum).HumRat = state.dataLoopNodes->Node(this->CondInletNodeNum).HumRat;
    2473         1430 :             state.dataLoopNodes->Node(this->CondOutletNodeNum).Enthalpy = state.dataLoopNodes->Node(this->CondInletNodeNum).Enthalpy;
    2474         1430 :             state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate = 0.0;
    2475         1430 :             state.dataLoopNodes->Node(this->CondOutletNodeNum).MassFlowRate = 0.0;
    2476              :         }
    2477              : 
    2478         1431 :         this->ChillerPartLoadRatio = 0.0;
    2479         1431 :         this->ChillerCyclingRatio = 0.0;
    2480         1431 :         this->ChillerFalseLoadRate = 0.0;
    2481         1431 :         this->ChillerFalseLoad = 0.0;
    2482         1431 :         this->Power = 0.0;
    2483         1431 :         this->QEvaporator = 0.0;
    2484         1431 :         this->QCondenser = 0.0;
    2485         1431 :         this->Energy = 0.0;
    2486         1431 :         this->EvapEnergy = 0.0;
    2487         1431 :         this->CondEnergy = 0.0;
    2488         1431 :         this->EvapInletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2489         1431 :         this->CondInletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    2490         1431 :         this->CondOutletTemp = state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp;
    2491         1431 :         this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;
    2492         1431 :         this->ActualCOP = 0.0;
    2493         1431 :         this->CondenserFanPower = 0.0;
    2494         1431 :         this->CondenserFanEnergyConsumption = 0.0;
    2495         1431 :         if (this->CondenserType == DataPlant::CondenserType::EvapCooled) {
    2496            0 :             this->BasinHeaterConsumption = this->BasinHeaterPower * ReportingConstant;
    2497            0 :             this->EvapWaterConsump = 0.0;
    2498              :         }
    2499              : 
    2500         1431 :         if (this->HeatRecActive) {
    2501              : 
    2502            0 :             PlantUtilities::SafeCopyPlantNode(state, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum);
    2503              : 
    2504            0 :             this->QHeatRecovered = 0.0;
    2505            0 :             this->EnergyHeatRecovery = 0.0;
    2506            0 :             this->HeatRecInletTemp = state.dataLoopNodes->Node(this->HeatRecInletNodeNum).Temp;
    2507            0 :             this->HeatRecOutletTemp = state.dataLoopNodes->Node(this->HeatRecOutletNodeNum).Temp;
    2508            0 :             this->HeatRecMassFlow = state.dataLoopNodes->Node(this->HeatRecInletNodeNum).MassFlowRate;
    2509              :         }
    2510              : 
    2511              :     } else { // Chiller is running, so pass calculated values
    2512              :         // Set node temperatures
    2513            2 :         if (this->CondMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance &&
    2514            1 :             this->EvapMassFlowRate < DataBranchAirLoopPlant::MassFlowTolerance) {
    2515            1 :             state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2516            1 :             state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    2517            1 :             if (this->CondenserType != DataPlant::CondenserType::WaterCooled) {
    2518            1 :                 state.dataLoopNodes->Node(this->CondOutletNodeNum).HumRat = state.dataLoopNodes->Node(this->CondInletNodeNum).HumRat;
    2519            1 :                 state.dataLoopNodes->Node(this->CondOutletNodeNum).Enthalpy = state.dataLoopNodes->Node(this->CondInletNodeNum).Enthalpy;
    2520            1 :                 state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate = 0.0;
    2521            1 :                 state.dataLoopNodes->Node(this->CondOutletNodeNum).MassFlowRate = 0.0;
    2522              :             }
    2523              :         } else {
    2524            1 :             state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp = this->EvapOutletTemp;
    2525            1 :             state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp = this->CondOutletTemp;
    2526            1 :             if (this->CondenserType != DataPlant::CondenserType::WaterCooled) {
    2527            0 :                 state.dataLoopNodes->Node(this->CondOutletNodeNum).HumRat = this->CondOutletHumRat;
    2528            0 :                 state.dataLoopNodes->Node(this->CondOutletNodeNum).Enthalpy =
    2529            0 :                     Psychrometrics::PsyHFnTdbW(this->CondOutletTemp, this->CondOutletHumRat);
    2530            0 :                 state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate = this->CondMassFlowRate;
    2531            0 :                 state.dataLoopNodes->Node(this->CondOutletNodeNum).MassFlowRate = this->CondMassFlowRate;
    2532              :             }
    2533              :         }
    2534              : 
    2535              :         // Set node flow rates;  for these load based models
    2536              :         // assume that sufficient evaporator flow rate is available
    2537            2 :         this->ChillerFalseLoad = this->ChillerFalseLoadRate * state.dataHVACGlobal->TimeStepSysSec;
    2538            2 :         this->Energy = this->Power * state.dataHVACGlobal->TimeStepSysSec;
    2539            2 :         this->EvapEnergy = this->QEvaporator * state.dataHVACGlobal->TimeStepSysSec;
    2540            2 :         this->CondEnergy = this->QCondenser * state.dataHVACGlobal->TimeStepSysSec;
    2541            2 :         this->EvapInletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    2542            2 :         this->CondInletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    2543            2 :         this->CondOutletTemp = state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp;
    2544            2 :         this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;
    2545            2 :         this->CondenserFanEnergyConsumption = this->CondenserFanPower * state.dataHVACGlobal->TimeStepSysSec;
    2546            2 :         if (this->Power != 0.0) {
    2547            1 :             this->ActualCOP = (this->QEvaporator + this->ChillerFalseLoadRate) / this->Power;
    2548              :         } else {
    2549            1 :             this->ActualCOP = 0.0;
    2550              :         }
    2551            2 :         if (this->CondenserType == DataPlant::CondenserType::EvapCooled) {
    2552            0 :             this->BasinHeaterConsumption = this->BasinHeaterPower * ReportingConstant;
    2553            0 :             this->EvapWaterConsump = this->EvapWaterConsumpRate * ReportingConstant;
    2554              :         }
    2555              : 
    2556            2 :         if (this->HeatRecActive) {
    2557              : 
    2558            0 :             PlantUtilities::SafeCopyPlantNode(state, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum);
    2559            0 :             this->EnergyHeatRecovery = this->QHeatRecovered * state.dataHVACGlobal->TimeStepSysSec;
    2560            0 :             state.dataLoopNodes->Node(this->HeatRecOutletNodeNum).Temp = this->HeatRecOutletTemp;
    2561            0 :             this->HeatRecInletTemp = state.dataLoopNodes->Node(this->HeatRecInletNodeNum).Temp;
    2562            0 :             this->HeatRecMassFlow = state.dataLoopNodes->Node(this->HeatRecInletNodeNum).MassFlowRate;
    2563              :         }
    2564              :     }
    2565         1433 : }
    2566              : 
    2567            9 : bool ElectricEIRChillerSpecs::thermosiphonDisabled(EnergyPlusData &state)
    2568              : {
    2569            9 :     if (this->thermosiphonTempCurveIndex > 0) {
    2570            3 :         this->thermosiphonStatus = 0;
    2571            3 :         Real64 dT = this->EvapOutletTemp - this->CondInletTemp;
    2572            3 :         if (dT < this->thermosiphonMinTempDiff) {
    2573            1 :             return true;
    2574              :         }
    2575            2 :         Real64 thermosiphonCapFrac = Curve::CurveValue(state, this->thermosiphonTempCurveIndex, dT);
    2576            2 :         Real64 capFrac = this->ChillerPartLoadRatio * this->ChillerCyclingRatio;
    2577            2 :         if (thermosiphonCapFrac >= capFrac) {
    2578            1 :             this->thermosiphonStatus = 1;
    2579            1 :             this->Power = 0.0;
    2580            1 :             return false;
    2581              :         }
    2582            1 :         return true;
    2583              :     } else {
    2584            6 :         return true;
    2585              :     }
    2586              : }
    2587              : 
    2588              : } // namespace EnergyPlus::ChillerElectricEIR
        

Generated by: LCOV version 2.0-1