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

Generated by: LCOV version 2.0-1