LCOV - code coverage report
Current view: top level - EnergyPlus - ChillerExhaustAbsorption.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 30.7 % 1018 313
Test Date: 2025-06-02 12:03:30 Functions: 27.8 % 18 5

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cassert>
      50              : #include <cmath>
      51              : 
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Array.functions.hh>
      54              : #include <ObjexxFCL/Fmath.hh>
      55              : 
      56              : // EnergyPlus Headers
      57              : #include <EnergyPlus/Autosizing/Base.hh>
      58              : #include <EnergyPlus/BranchNodeConnections.hh>
      59              : #include <EnergyPlus/ChillerExhaustAbsorption.hh>
      60              : #include <EnergyPlus/CurveManager.hh>
      61              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      62              : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      63              : #include <EnergyPlus/DataGlobalConstants.hh>
      64              : #include <EnergyPlus/DataHVACGlobals.hh>
      65              : #include <EnergyPlus/DataIPShortCuts.hh>
      66              : #include <EnergyPlus/DataLoopNode.hh>
      67              : #include <EnergyPlus/DataSizing.hh>
      68              : #include <EnergyPlus/EMSManager.hh>
      69              : #include <EnergyPlus/FluidProperties.hh>
      70              : #include <EnergyPlus/GlobalNames.hh>
      71              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      72              : #include <EnergyPlus/MicroturbineElectricGenerator.hh>
      73              : #include <EnergyPlus/NodeInputManager.hh>
      74              : #include <EnergyPlus/OutAirNodeManager.hh>
      75              : #include <EnergyPlus/OutputProcessor.hh>
      76              : #include <EnergyPlus/OutputReportPredefined.hh>
      77              : #include <EnergyPlus/Plant/DataPlant.hh>
      78              : #include <EnergyPlus/PlantUtilities.hh>
      79              : #include <EnergyPlus/Psychrometrics.hh>
      80              : #include <EnergyPlus/UtilityRoutines.hh>
      81              : 
      82              : namespace EnergyPlus::ChillerExhaustAbsorption {
      83              : 
      84              : // MODULE INFORMATION:
      85              : //    AUTHOR         Jason Glazer of GARD Analytics, Inc.
      86              : //                   for Gas Research Institute (Original module GasAbsoptionChiller)
      87              : //    DATE WRITTEN   March 2001
      88              : //    MODIFIED       Brent Griffith, Nov 2010 plant upgrades, generalize fluid properties
      89              : //                   Mahabir Bhandari, ORNL, Aug 2011, modified to accommodate Exhaust Fired Absorption Chiller
      90              : 
      91              : // PURPOSE OF THIS MODULE:
      92              : //    This module simulates the performance of the Exhaust fired double effect
      93              : //    absorption chiller.
      94              : // METHODOLOGY EMPLOYED:
      95              : //    Once the PlantLoopManager determines that the exhaust fired absorber chiller
      96              : //    is available to meet a loop cooling demand, it calls SimExhaustAbsorption
      97              : //    which in turn calls the appropriate Exhaust Fired Absorption Chiller model.
      98              : // REFERENCES:
      99              : //    DOE-2.1e Supplement
     100              : //    PG&E CoolToolsGas Mod
     101              : //    Performance curves obtained from manufacturer
     102              : // OTHER NOTES:
     103              : //    The curves on this model follow the DOE-2 approach of using
     104              : //    electric and heat input ratios.  In addition, the temperature
     105              : //    correction curve has two independent variables for the
     106              : //    chilled water temperature and either the entering or leaving
     107              : //    condenser water temperature.
     108              : //    The code was originally adopted from the ChillerAbsorption
     109              : //    routine but has been extensively modified.
     110              : //    Development of the original(GasAbsoptionChiller) module was funded by the Gas Research Institute.
     111              : //    (Please see copyright and disclaimer information at end of module)
     112              : 
     113            0 : ExhaustAbsorberSpecs *ExhaustAbsorberSpecs::factory(EnergyPlusData &state, std::string const &objectName)
     114              : {
     115              :     // Process the input data if it hasn't been done already
     116            0 :     if (state.dataChillerExhaustAbsorption->Sim_GetInput) {
     117            0 :         GetExhaustAbsorberInput(state);
     118            0 :         state.dataChillerExhaustAbsorption->Sim_GetInput = false;
     119              :     }
     120              :     // Now look for this particular pipe in the list
     121            0 :     auto thisObj = std::find_if(state.dataChillerExhaustAbsorption->ExhaustAbsorber.begin(),
     122            0 :                                 state.dataChillerExhaustAbsorption->ExhaustAbsorber.end(),
     123            0 :                                 [&objectName](const ExhaustAbsorberSpecs &myObj) { return myObj.Name == objectName; });
     124            0 :     if (thisObj != state.dataChillerExhaustAbsorption->ExhaustAbsorber.end()) {
     125            0 :         return thisObj;
     126              :     }
     127              :     // If we didn't find it, fatal
     128              :     ShowFatalError(state, format("LocalExhaustAbsorberFactory: Error getting inputs for comp named: {}", objectName)); // LCOV_EXCL_LINE
     129              :     // Shut up the compiler
     130              :     return nullptr; // LCOV_EXCL_LINE
     131              : }
     132              : 
     133            0 : void ExhaustAbsorberSpecs::simulate(
     134              :     EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag)
     135              : {
     136            0 :     DataPlant::BrLoopType brIdentity(DataPlant::BrLoopType::NoMatch);
     137              : 
     138            0 :     int branchTotalComp = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
     139            0 :                               .LoopSide(calledFromLocation.loopSideNum)
     140            0 :                               .Branch(calledFromLocation.branchNum)
     141            0 :                               .TotalComponents;
     142              : 
     143            0 :     for (int iComp = 1; iComp <= branchTotalComp; iComp++) {
     144              :         // kind of a hacky way to find the location of this, but it's what plantloopequip was doing
     145            0 :         int compInletNodeNum = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
     146            0 :                                    .LoopSide(calledFromLocation.loopSideNum)
     147            0 :                                    .Branch(calledFromLocation.branchNum)
     148            0 :                                    .Comp(iComp)
     149            0 :                                    .NodeNumIn;
     150              : 
     151              :         // Match inlet node name of calling branch to determine if this call is for heating or cooling
     152            0 :         if (compInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller
     153            0 :             brIdentity = DataPlant::BrLoopType::Chiller;    // chiller
     154            0 :             break;
     155            0 :         } else if (compInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater
     156            0 :             brIdentity = DataPlant::BrLoopType::Heater;           // heater
     157            0 :             break;
     158            0 :         } else if (compInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop
     159            0 :             brIdentity = DataPlant::BrLoopType::Condenser;        // condenser
     160            0 :             break;
     161              :         } else {
     162            0 :             brIdentity = DataPlant::BrLoopType::NoMatch;
     163              :         }
     164              :     }
     165              : 
     166            0 :     if (brIdentity == DataPlant::BrLoopType::Chiller) {
     167            0 :         this->InCoolingMode = RunFlag != 0;
     168            0 :         this->initialize(state);
     169            0 :         this->calcChiller(state, CurLoad);
     170            0 :         this->updateCoolRecords(state, CurLoad, RunFlag);
     171            0 :     } else if (brIdentity == DataPlant::BrLoopType::Heater) {
     172            0 :         this->InHeatingMode = RunFlag != 0;
     173            0 :         this->initialize(state);
     174            0 :         this->calcHeater(state, CurLoad, RunFlag);
     175            0 :         this->updateHeatRecords(state, CurLoad, RunFlag);
     176            0 :     } else if (brIdentity == DataPlant::BrLoopType::Condenser) {
     177            0 :         if (this->CDPlantLoc.loopNum > 0) {
     178            0 :             PlantUtilities::UpdateChillerComponentCondenserSide(state,
     179              :                                                                 this->CDPlantLoc.loopNum,
     180              :                                                                 this->CDPlantLoc.loopSideNum,
     181              :                                                                 DataPlant::PlantEquipmentType::Chiller_ExhFiredAbsorption,
     182              :                                                                 this->CondReturnNodeNum,
     183              :                                                                 this->CondSupplyNodeNum,
     184              :                                                                 this->TowerLoad,
     185              :                                                                 this->CondReturnTemp,
     186              :                                                                 this->CondSupplyTemp,
     187              :                                                                 this->CondWaterFlowRate,
     188              :                                                                 FirstHVACIteration);
     189              :         }
     190              :     } else {
     191              :         // Error, nodes do not match
     192            0 :         ShowSevereError(state, format("Invalid call to Exhaust Absorber Chiller {}", this->Name));
     193            0 :         ShowContinueError(state, "Node connections in branch are not consistent with object nodes.");
     194            0 :         ShowFatalError(state, "Preceding conditions cause termination.");
     195              :     }
     196            0 : }
     197              : 
     198            3 : void ExhaustAbsorberSpecs::getDesignCapacities(
     199              :     EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
     200              : {
     201            3 :     bool matchfound(false);
     202              : 
     203            3 :     int branchTotalComp = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
     204            3 :                               .LoopSide(calledFromLocation.loopSideNum)
     205            3 :                               .Branch(calledFromLocation.branchNum)
     206            3 :                               .TotalComponents;
     207              : 
     208            6 :     for (int iComp = 1; iComp <= branchTotalComp; iComp++) {
     209              :         // kind of a hacky way to find the location of this, but it's what plantloopequip was doing
     210            6 :         int compInletNodeNum = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
     211            6 :                                    .LoopSide(calledFromLocation.loopSideNum)
     212            6 :                                    .Branch(calledFromLocation.branchNum)
     213            6 :                                    .Comp(iComp)
     214            6 :                                    .NodeNumIn;
     215              : 
     216              :         // Match inlet node name of calling branch to determine if this call is for heating or cooling
     217            6 :         if (compInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller
     218            1 :             MinLoad = this->NomCoolingCap * this->MinPartLoadRat;
     219            1 :             MaxLoad = this->NomCoolingCap * this->MaxPartLoadRat;
     220            1 :             OptLoad = this->NomCoolingCap * this->OptPartLoadRat;
     221            1 :             matchfound = true;
     222            1 :             break;
     223            5 :         } else if (compInletNodeNum == this->HeatReturnNodeNum) {              // Operate as heater
     224            1 :             Real64 Sim_HeatCap = this->NomCoolingCap * this->NomHeatCoolRatio; // W - nominal heating capacity
     225            1 :             MinLoad = Sim_HeatCap * this->MinPartLoadRat;
     226            1 :             MaxLoad = Sim_HeatCap * this->MaxPartLoadRat;
     227            1 :             OptLoad = Sim_HeatCap * this->OptPartLoadRat;
     228            1 :             matchfound = true;
     229            1 :             break;
     230            4 :         } else if (compInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop
     231            1 :             MinLoad = 0.0;
     232            1 :             MaxLoad = 0.0;
     233            1 :             OptLoad = 0.0;
     234            1 :             matchfound = true;
     235            1 :             break;
     236              :         } else {
     237            3 :             matchfound = false;
     238              :         }
     239              :     }
     240              : 
     241            3 :     if (!matchfound) {
     242              :         // Error, nodes do not match
     243            0 :         ShowSevereError(state, format("SimExhaustAbsorber: Invalid call to Exhaust Absorption Chiller-Heater {}", this->Name));
     244            0 :         ShowContinueError(state, "Node connections in branch are not consistent with object nodes.");
     245            0 :         ShowFatalError(state, "Preceding conditions cause termination.");
     246              :     } // Operate as Chiller or Heater
     247            3 : }
     248              : 
     249            0 : void ExhaustAbsorberSpecs::getSizingFactor(Real64 &_SizFac)
     250              : {
     251            0 :     _SizFac = this->SizFac;
     252            0 : }
     253              : 
     254            0 : void ExhaustAbsorberSpecs::onInitLoopEquip(EnergyPlusData &state, const PlantLocation &calledFromLocation)
     255              : {
     256            0 :     this->initialize(state);
     257              : 
     258              :     // kind of a hacky way to find the location of this, but it's what plantloopequip was doing
     259              :     int BranchInletNodeNum =
     260            0 :         state.dataPlnt->PlantLoop(calledFromLocation.loopNum).LoopSide(calledFromLocation.loopSideNum).Branch(calledFromLocation.branchNum).NodeNumIn;
     261              : 
     262            0 :     if (BranchInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller
     263            0 :         this->size(state);                                // only call from chilled water loop
     264              :     } else {
     265              :         // don't do anything here
     266              :     }
     267            0 : }
     268              : 
     269            0 : void ExhaustAbsorberSpecs::getDesignTemperatures(Real64 &TempDesCondIn, Real64 &TempDesEvapOut)
     270              : {
     271            0 :     TempDesEvapOut = this->TempDesCHWSupply;
     272            0 :     TempDesCondIn = this->TempDesCondReturn;
     273            0 : }
     274              : 
     275            4 : void GetExhaustAbsorberInput(EnergyPlusData &state)
     276              : {
     277              :     // SUBROUTINE INFORMATION:
     278              :     //       AUTHOR:          Jason Glazer
     279              :     //       DATE WRITTEN:    March 2001
     280              :     //       MODIFIED         Mahabir Bhandari, ORNL, Aug 2011, modified to accommodate Exhaust Fired Double Effect Absorption Chiller
     281              : 
     282              :     // PURPOSE OF THIS SUBROUTINE:
     283              :     // This routine will get the input
     284              :     // required by the Exhaust Fired Absorption chiller model in the object ChillerHeater:Absorption:DoubleEffect
     285              : 
     286              :     // METHODOLOGY EMPLOYED:
     287              :     // EnergyPlus input processor
     288              :     static constexpr std::string_view routineName = "GetExhaustAbsorberInput";
     289              : 
     290              :     // LOCAL VARIABLES
     291              :     int NumAlphas; // Number of elements in the alpha array
     292              :     int NumNums;   // Number of elements in the numeric array
     293              :     int IOStat;    // IO Status when calling get input subroutine
     294              :     bool Okay;
     295            4 :     bool Get_ErrorsFound(false);
     296              : 
     297            4 :     auto &s_ipsc = state.dataIPShortCut;
     298              : 
     299            4 :     std::string_view cCurrentModuleObject = "ChillerHeater:Absorption:DoubleEffect";
     300            4 :     int NumExhaustAbsorbers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     301              : 
     302            4 :     if (NumExhaustAbsorbers <= 0) {
     303            0 :         ShowSevereError(state, format("No {} equipment found in input file", cCurrentModuleObject));
     304            0 :         Get_ErrorsFound = true;
     305              :     }
     306              : 
     307            4 :     if (allocated(state.dataChillerExhaustAbsorption->ExhaustAbsorber)) {
     308            0 :         return;
     309              :     }
     310              : 
     311              :     // ALLOCATE ARRAYS
     312            4 :     state.dataChillerExhaustAbsorption->ExhaustAbsorber.allocate(NumExhaustAbsorbers);
     313              : 
     314              :     // LOAD ARRAYS
     315              : 
     316           10 :     for (int AbsorberNum = 1; AbsorberNum <= NumExhaustAbsorbers; ++AbsorberNum) {
     317           18 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     318              :                                                                  cCurrentModuleObject,
     319              :                                                                  AbsorberNum,
     320            6 :                                                                  s_ipsc->cAlphaArgs,
     321              :                                                                  NumAlphas,
     322            6 :                                                                  s_ipsc->rNumericArgs,
     323              :                                                                  NumNums,
     324              :                                                                  IOStat,
     325              :                                                                  _,
     326            6 :                                                                  s_ipsc->lAlphaFieldBlanks,
     327            6 :                                                                  s_ipsc->cAlphaFieldNames,
     328            6 :                                                                  s_ipsc->cNumericFieldNames);
     329              : 
     330            6 :         ErrorObjectHeader eoh{routineName, cCurrentModuleObject, s_ipsc->cAlphaArgs(1)};
     331              : 
     332              :         // Get_ErrorsFound will be set to True if problem was found, left untouched otherwise
     333            6 :         GlobalNames::VerifyUniqueChillerName(
     334            6 :             state, cCurrentModuleObject, s_ipsc->cAlphaArgs(1), Get_ErrorsFound, fmt::format("{} Name", cCurrentModuleObject));
     335              : 
     336            6 :         auto &thisChiller = state.dataChillerExhaustAbsorption->ExhaustAbsorber(AbsorberNum);
     337            6 :         thisChiller.Name = s_ipsc->cAlphaArgs(1);
     338            6 :         std::string ChillerName = fmt::format("{} Named {}", cCurrentModuleObject, thisChiller.Name);
     339              : 
     340              :         // Assign capacities
     341            6 :         thisChiller.NomCoolingCap = s_ipsc->rNumericArgs(1);
     342            6 :         if (thisChiller.NomCoolingCap == DataSizing::AutoSize) {
     343            0 :             thisChiller.NomCoolingCapWasAutoSized = true;
     344              :         }
     345            6 :         thisChiller.NomHeatCoolRatio = s_ipsc->rNumericArgs(2);
     346              :         // Assign efficiencies
     347            6 :         thisChiller.ThermalEnergyCoolRatio = s_ipsc->rNumericArgs(3);
     348            6 :         thisChiller.ThermalEnergyHeatRatio = s_ipsc->rNumericArgs(4);
     349            6 :         thisChiller.ElecCoolRatio = s_ipsc->rNumericArgs(5);
     350            6 :         thisChiller.ElecHeatRatio = s_ipsc->rNumericArgs(6);
     351              : 
     352              :         // Assign Node Numbers to specified nodes
     353            6 :         thisChiller.ChillReturnNodeNum = NodeInputManager::GetOnlySingleNode(state,
     354            6 :                                                                              s_ipsc->cAlphaArgs(2),
     355              :                                                                              Get_ErrorsFound,
     356              :                                                                              DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDoubleEffect,
     357            6 :                                                                              s_ipsc->cAlphaArgs(1),
     358              :                                                                              DataLoopNode::NodeFluidType::Water,
     359              :                                                                              DataLoopNode::ConnectionType::Inlet,
     360              :                                                                              NodeInputManager::CompFluidStream::Primary,
     361              :                                                                              DataLoopNode::ObjectIsNotParent);
     362           12 :         thisChiller.ChillSupplyNodeNum = NodeInputManager::GetOnlySingleNode(state,
     363            6 :                                                                              s_ipsc->cAlphaArgs(3),
     364              :                                                                              Get_ErrorsFound,
     365              :                                                                              DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDoubleEffect,
     366            6 :                                                                              s_ipsc->cAlphaArgs(1),
     367              :                                                                              DataLoopNode::NodeFluidType::Water,
     368              :                                                                              DataLoopNode::ConnectionType::Outlet,
     369              :                                                                              NodeInputManager::CompFluidStream::Primary,
     370              :                                                                              DataLoopNode::ObjectIsNotParent);
     371           12 :         BranchNodeConnections::TestCompSet(
     372            6 :             state, cCurrentModuleObject, s_ipsc->cAlphaArgs(1), s_ipsc->cAlphaArgs(2), s_ipsc->cAlphaArgs(3), "Chilled Water Nodes");
     373              :         // Condenser node processing depends on condenser type, see below
     374            6 :         thisChiller.HeatReturnNodeNum = NodeInputManager::GetOnlySingleNode(state,
     375            6 :                                                                             s_ipsc->cAlphaArgs(6),
     376              :                                                                             Get_ErrorsFound,
     377              :                                                                             DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDoubleEffect,
     378            6 :                                                                             s_ipsc->cAlphaArgs(1),
     379              :                                                                             DataLoopNode::NodeFluidType::Water,
     380              :                                                                             DataLoopNode::ConnectionType::Inlet,
     381              :                                                                             NodeInputManager::CompFluidStream::Tertiary,
     382              :                                                                             DataLoopNode::ObjectIsNotParent);
     383           12 :         thisChiller.HeatSupplyNodeNum = NodeInputManager::GetOnlySingleNode(state,
     384            6 :                                                                             s_ipsc->cAlphaArgs(7),
     385              :                                                                             Get_ErrorsFound,
     386              :                                                                             DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDoubleEffect,
     387            6 :                                                                             s_ipsc->cAlphaArgs(1),
     388              :                                                                             DataLoopNode::NodeFluidType::Water,
     389              :                                                                             DataLoopNode::ConnectionType::Outlet,
     390              :                                                                             NodeInputManager::CompFluidStream::Tertiary,
     391              :                                                                             DataLoopNode::ObjectIsNotParent);
     392           12 :         BranchNodeConnections::TestCompSet(
     393            6 :             state, cCurrentModuleObject, s_ipsc->cAlphaArgs(1), s_ipsc->cAlphaArgs(6), s_ipsc->cAlphaArgs(7), "Hot Water Nodes");
     394            6 :         if (Get_ErrorsFound) {
     395            0 :             ShowFatalError(state, format("Errors found in processing node input for {}={}", cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     396            0 :             Get_ErrorsFound = false;
     397              :         }
     398              : 
     399              :         // Assign Part Load Ratios
     400            6 :         thisChiller.MinPartLoadRat = s_ipsc->rNumericArgs(7);
     401            6 :         thisChiller.MaxPartLoadRat = s_ipsc->rNumericArgs(8);
     402            6 :         thisChiller.OptPartLoadRat = s_ipsc->rNumericArgs(9);
     403              :         // Assign Design Conditions
     404            6 :         thisChiller.TempDesCondReturn = s_ipsc->rNumericArgs(10);
     405            6 :         thisChiller.TempDesCHWSupply = s_ipsc->rNumericArgs(11);
     406            6 :         thisChiller.EvapVolFlowRate = s_ipsc->rNumericArgs(12);
     407            6 :         if (thisChiller.EvapVolFlowRate == DataSizing::AutoSize) {
     408            0 :             thisChiller.EvapVolFlowRateWasAutoSized = true;
     409              :         }
     410            6 :         if (Util::SameString(s_ipsc->cAlphaArgs(16), "AirCooled")) {
     411            6 :             thisChiller.CondVolFlowRate = 0.0011; // Condenser flow rate not used for this cond type
     412              :         } else {
     413            0 :             thisChiller.CondVolFlowRate = s_ipsc->rNumericArgs(13);
     414            0 :             if (thisChiller.CondVolFlowRate == DataSizing::AutoSize) {
     415            0 :                 thisChiller.CondVolFlowRateWasAutoSized = true;
     416              :             }
     417              :         }
     418            6 :         thisChiller.HeatVolFlowRate = s_ipsc->rNumericArgs(14);
     419            6 :         if (thisChiller.HeatVolFlowRate == DataSizing::AutoSize) {
     420            0 :             thisChiller.HeatVolFlowRateWasAutoSized = true;
     421              :         }
     422              :         // Assign Curve Numbers
     423            6 :         if (s_ipsc->lAlphaFieldBlanks(8)) {
     424            0 :             ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(8));
     425            0 :             Get_ErrorsFound = true;
     426            6 :         } else if ((thisChiller.CoolCapFTCurve = Curve::GetCurve(state, s_ipsc->cAlphaArgs(8))) == nullptr) {
     427            0 :             ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(8), s_ipsc->cAlphaArgs(8));
     428            0 :             Get_ErrorsFound = true;
     429              :         }
     430              : 
     431            6 :         if (s_ipsc->lAlphaFieldBlanks(9)) {
     432            0 :             ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(9));
     433            0 :             Get_ErrorsFound = true;
     434            6 :         } else if ((thisChiller.ThermalEnergyCoolFTCurve = Curve::GetCurve(state, s_ipsc->cAlphaArgs(9))) == nullptr) {
     435            0 :             ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(9), s_ipsc->cAlphaArgs(9));
     436            0 :             Get_ErrorsFound = true;
     437              :         }
     438              : 
     439            6 :         if (s_ipsc->lAlphaFieldBlanks(10)) {
     440            0 :             ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(10));
     441            0 :             Get_ErrorsFound = true;
     442            6 :         } else if ((thisChiller.ThermalEnergyCoolFPLRCurve = Curve::GetCurve(state, s_ipsc->cAlphaArgs(10))) == nullptr) {
     443            0 :             ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(10), s_ipsc->cAlphaArgs(10));
     444            0 :             Get_ErrorsFound = true;
     445              :         }
     446              : 
     447            6 :         if (s_ipsc->lAlphaFieldBlanks(11)) {
     448            0 :             ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(11));
     449            0 :             Get_ErrorsFound = true;
     450            6 :         } else if ((thisChiller.ElecCoolFTCurve = Curve::GetCurve(state, s_ipsc->cAlphaArgs(11))) == nullptr) {
     451            0 :             ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(11), s_ipsc->cAlphaArgs(11));
     452            0 :             Get_ErrorsFound = true;
     453              :         }
     454              : 
     455            6 :         if (s_ipsc->lAlphaFieldBlanks(12)) {
     456            0 :             ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(12));
     457            0 :             Get_ErrorsFound = true;
     458            6 :         } else if ((thisChiller.ElecCoolFPLRCurve = Curve::GetCurve(state, s_ipsc->cAlphaArgs(12))) == nullptr) {
     459            0 :             ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(12), s_ipsc->cAlphaArgs(12));
     460            0 :             Get_ErrorsFound = true;
     461              :         }
     462              : 
     463            6 :         if (s_ipsc->lAlphaFieldBlanks(13)) {
     464            0 :             ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(13));
     465            0 :             Get_ErrorsFound = true;
     466            6 :         } else if ((thisChiller.HeatCapFCoolCurve = Curve::GetCurve(state, s_ipsc->cAlphaArgs(13))) == nullptr) {
     467            0 :             ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(13), s_ipsc->cAlphaArgs(13));
     468            0 :             Get_ErrorsFound = true;
     469              :         }
     470              : 
     471            6 :         if (s_ipsc->lAlphaFieldBlanks(14)) {
     472            0 :             ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(14));
     473            0 :             Get_ErrorsFound = true;
     474            6 :         } else if ((thisChiller.ThermalEnergyHeatFHPLRCurve = Curve::GetCurve(state, s_ipsc->cAlphaArgs(14))) == nullptr) {
     475            0 :             ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(14), s_ipsc->cAlphaArgs(14));
     476            0 :             Get_ErrorsFound = true;
     477              :         }
     478              : 
     479            6 :         if (Get_ErrorsFound) {
     480            0 :             ShowFatalError(state, format("Errors found in processing curve input for {}={}", cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     481            0 :             Get_ErrorsFound = false;
     482              :         }
     483            6 :         if (Util::SameString(s_ipsc->cAlphaArgs(15), "LeavingCondenser")) {
     484            0 :             thisChiller.isEnterCondensTemp = false;
     485            6 :         } else if (Util::SameString(s_ipsc->cAlphaArgs(15), "EnteringCondenser")) {
     486            6 :             thisChiller.isEnterCondensTemp = true;
     487              :         } else {
     488            0 :             thisChiller.isEnterCondensTemp = true;
     489            0 :             ShowWarningError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(15), s_ipsc->cAlphaArgs(15)));
     490            0 :             ShowContinueError(state, format("Entered in {}={}", cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     491            0 :             ShowContinueError(state, "resetting to ENTERING-CONDENSER, simulation continues");
     492              :         }
     493              :         // Assign Other Parameters
     494            6 :         if (Util::SameString(s_ipsc->cAlphaArgs(16), "AirCooled")) {
     495            6 :             thisChiller.isWaterCooled = false;
     496            0 :         } else if (Util::SameString(s_ipsc->cAlphaArgs(16), "WaterCooled")) {
     497            0 :             thisChiller.isWaterCooled = true;
     498              :         } else {
     499            0 :             thisChiller.isWaterCooled = true;
     500            0 :             ShowWarningError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(16), s_ipsc->cAlphaArgs(16)));
     501            0 :             ShowContinueError(state, format("Entered in {}={}", cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     502            0 :             ShowContinueError(state, "resetting to WATER-COOLED, simulation continues");
     503              :         }
     504            6 :         if (!thisChiller.isEnterCondensTemp && !thisChiller.isWaterCooled) {
     505            0 :             thisChiller.isEnterCondensTemp = true;
     506            0 :             ShowWarningError(state, format("{}=\"{}\", invalid value", cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     507            0 :             ShowContinueError(state, "Invalid to have both LeavingCondenser and AirCooled.");
     508            0 :             ShowContinueError(state, "resetting to EnteringCondenser, simulation continues");
     509              :         }
     510            6 :         if (thisChiller.isWaterCooled) {
     511            0 :             if (s_ipsc->lAlphaFieldBlanks(5)) {
     512            0 :                 ShowSevereError(state, format("{}=\"{}\", invalid value", cCurrentModuleObject, s_ipsc->cAlphaArgs(1)));
     513            0 :                 ShowContinueError(state, "For WaterCooled chiller the condenser outlet node is required.");
     514            0 :                 Get_ErrorsFound = true;
     515              :             }
     516            0 :             thisChiller.CondReturnNodeNum =
     517            0 :                 NodeInputManager::GetOnlySingleNode(state,
     518            0 :                                                     s_ipsc->cAlphaArgs(4),
     519              :                                                     Get_ErrorsFound,
     520              :                                                     DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDoubleEffect,
     521            0 :                                                     s_ipsc->cAlphaArgs(1),
     522              :                                                     DataLoopNode::NodeFluidType::Water,
     523              :                                                     DataLoopNode::ConnectionType::Inlet,
     524              :                                                     NodeInputManager::CompFluidStream::Secondary,
     525              :                                                     DataLoopNode::ObjectIsNotParent);
     526            0 :             thisChiller.CondSupplyNodeNum =
     527            0 :                 NodeInputManager::GetOnlySingleNode(state,
     528            0 :                                                     s_ipsc->cAlphaArgs(5),
     529              :                                                     Get_ErrorsFound,
     530              :                                                     DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDoubleEffect,
     531            0 :                                                     s_ipsc->cAlphaArgs(1),
     532              :                                                     DataLoopNode::NodeFluidType::Water,
     533              :                                                     DataLoopNode::ConnectionType::Outlet,
     534              :                                                     NodeInputManager::CompFluidStream::Secondary,
     535              :                                                     DataLoopNode::ObjectIsNotParent);
     536            0 :             BranchNodeConnections::TestCompSet(
     537            0 :                 state, cCurrentModuleObject, s_ipsc->cAlphaArgs(1), s_ipsc->cAlphaArgs(4), s_ipsc->cAlphaArgs(5), "Condenser Water Nodes");
     538              :         } else {
     539            6 :             thisChiller.CondReturnNodeNum =
     540            6 :                 NodeInputManager::GetOnlySingleNode(state,
     541            6 :                                                     s_ipsc->cAlphaArgs(4),
     542              :                                                     Get_ErrorsFound,
     543              :                                                     DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDoubleEffect,
     544            6 :                                                     s_ipsc->cAlphaArgs(1),
     545              :                                                     DataLoopNode::NodeFluidType::Air,
     546              :                                                     DataLoopNode::ConnectionType::OutsideAirReference,
     547              :                                                     NodeInputManager::CompFluidStream::Secondary,
     548              :                                                     DataLoopNode::ObjectIsNotParent);
     549              :             // Condenser outlet node not used for air or evap cooled condenser so ignore cAlphaArgs( 5 )
     550              :             // Connection not required for air or evap cooled condenser so no call to TestCompSet here
     551            6 :             OutAirNodeManager::CheckAndAddAirNodeNumber(state, thisChiller.CondReturnNodeNum, Okay);
     552            6 :             if (!Okay) {
     553            0 :                 ShowWarningError(state, format("{}, Adding OutdoorAir:Node={}", cCurrentModuleObject, s_ipsc->cAlphaArgs(4)));
     554              :             }
     555              :         }
     556              : 
     557            6 :         thisChiller.CHWLowLimitTemp = s_ipsc->rNumericArgs(15);
     558            6 :         thisChiller.SizFac = s_ipsc->rNumericArgs(16);
     559            6 :         thisChiller.TypeOf = s_ipsc->cAlphaArgs(17);
     560              : 
     561            6 :         if (Util::SameString(s_ipsc->cAlphaArgs(17), "Generator:MicroTurbine")) {
     562            6 :             thisChiller.CompType_Num = GeneratorType::Microturbine;
     563            6 :             thisChiller.ExhaustSourceName = s_ipsc->cAlphaArgs(18);
     564              : 
     565            6 :             auto *thisMTG = MicroturbineElectricGenerator::MTGeneratorSpecs::factory(state, thisChiller.ExhaustSourceName);
     566            6 :             thisChiller.ExhaustAirInletNodeNum = dynamic_cast<MicroturbineElectricGenerator::MTGeneratorSpecs *>(thisMTG)->CombustionAirOutletNodeNum;
     567              :         }
     568            6 :     }
     569              : 
     570            4 :     if (Get_ErrorsFound) {
     571            0 :         ShowFatalError(state, format("Errors found in processing input for {}", cCurrentModuleObject));
     572              :     }
     573              : }
     574              : 
     575            0 : void ExhaustAbsorberSpecs::setupOutputVariables(EnergyPlusData &state)
     576              : {
     577            0 :     std::string const ChillerName = this->Name;
     578              : 
     579            0 :     SetupOutputVariable(state,
     580              :                         "Chiller Heater Evaporator Cooling Rate",
     581              :                         Constant::Units::W,
     582            0 :                         this->CoolingLoad,
     583              :                         OutputProcessor::TimeStepType::System,
     584              :                         OutputProcessor::StoreType::Average,
     585              :                         ChillerName);
     586            0 :     SetupOutputVariable(state,
     587              :                         "Chiller Heater Evaporator Cooling Energy",
     588              :                         Constant::Units::J,
     589            0 :                         this->CoolingEnergy,
     590              :                         OutputProcessor::TimeStepType::System,
     591              :                         OutputProcessor::StoreType::Sum,
     592              :                         ChillerName,
     593              :                         Constant::eResource::EnergyTransfer,
     594              :                         OutputProcessor::Group::Plant,
     595              :                         OutputProcessor::EndUseCat::Chillers);
     596              : 
     597            0 :     SetupOutputVariable(state,
     598              :                         "Chiller Heater Heating Rate",
     599              :                         Constant::Units::W,
     600            0 :                         this->HeatingLoad,
     601              :                         OutputProcessor::TimeStepType::System,
     602              :                         OutputProcessor::StoreType::Average,
     603              :                         ChillerName);
     604            0 :     SetupOutputVariable(state,
     605              :                         "Chiller Heater Heating Energy",
     606              :                         Constant::Units::J,
     607            0 :                         this->HeatingEnergy,
     608              :                         OutputProcessor::TimeStepType::System,
     609              :                         OutputProcessor::StoreType::Sum,
     610              :                         ChillerName,
     611              :                         Constant::eResource::EnergyTransfer,
     612              :                         OutputProcessor::Group::Plant,
     613              :                         OutputProcessor::EndUseCat::Boilers);
     614              : 
     615            0 :     SetupOutputVariable(state,
     616              :                         "Chiller Heater Condenser Heat Transfer Rate",
     617              :                         Constant::Units::W,
     618            0 :                         this->TowerLoad,
     619              :                         OutputProcessor::TimeStepType::System,
     620              :                         OutputProcessor::StoreType::Average,
     621              :                         ChillerName);
     622            0 :     SetupOutputVariable(state,
     623              :                         "Chiller Heater Condenser Heat Transfer Energy",
     624              :                         Constant::Units::J,
     625            0 :                         this->TowerEnergy,
     626              :                         OutputProcessor::TimeStepType::System,
     627              :                         OutputProcessor::StoreType::Sum,
     628              :                         ChillerName,
     629              :                         Constant::eResource::EnergyTransfer,
     630              :                         OutputProcessor::Group::Plant,
     631              :                         OutputProcessor::EndUseCat::HeatRejection);
     632              : 
     633            0 :     SetupOutputVariable(state,
     634              :                         "Chiller Heater Cooling Source Heat COP",
     635              :                         Constant::Units::W_W,
     636            0 :                         this->ThermalEnergyCOP,
     637              :                         OutputProcessor::TimeStepType::System,
     638              :                         OutputProcessor::StoreType::Average,
     639              :                         ChillerName);
     640              : 
     641            0 :     SetupOutputVariable(state,
     642              :                         "Chiller Heater Electricity Rate",
     643              :                         Constant::Units::W,
     644            0 :                         this->ElectricPower,
     645              :                         OutputProcessor::TimeStepType::System,
     646              :                         OutputProcessor::StoreType::Average,
     647              :                         ChillerName);
     648              :     // Do not include this on meters, this would duplicate the cool electric and heat electric
     649            0 :     SetupOutputVariable(state,
     650              :                         "Chiller Heater Electricity Energy",
     651              :                         Constant::Units::J,
     652            0 :                         this->ElectricEnergy,
     653              :                         OutputProcessor::TimeStepType::System,
     654              :                         OutputProcessor::StoreType::Sum,
     655              :                         ChillerName);
     656              : 
     657            0 :     SetupOutputVariable(state,
     658              :                         "Chiller Heater Cooling Electricity Rate",
     659              :                         Constant::Units::W,
     660            0 :                         this->CoolElectricPower,
     661              :                         OutputProcessor::TimeStepType::System,
     662              :                         OutputProcessor::StoreType::Average,
     663              :                         ChillerName);
     664            0 :     SetupOutputVariable(state,
     665              :                         "Chiller Heater Cooling Electricity Energy",
     666              :                         Constant::Units::J,
     667            0 :                         this->CoolElectricEnergy,
     668              :                         OutputProcessor::TimeStepType::System,
     669              :                         OutputProcessor::StoreType::Sum,
     670              :                         ChillerName,
     671              :                         Constant::eResource::Electricity,
     672              :                         OutputProcessor::Group::Plant,
     673              :                         OutputProcessor::EndUseCat::Cooling);
     674              : 
     675            0 :     SetupOutputVariable(state,
     676              :                         "Chiller Heater Heating Electricity Rate",
     677              :                         Constant::Units::W,
     678            0 :                         this->HeatElectricPower,
     679              :                         OutputProcessor::TimeStepType::System,
     680              :                         OutputProcessor::StoreType::Average,
     681              :                         ChillerName);
     682            0 :     SetupOutputVariable(state,
     683              :                         "Chiller Heater Heating Electricity Energy",
     684              :                         Constant::Units::J,
     685            0 :                         this->HeatElectricEnergy,
     686              :                         OutputProcessor::TimeStepType::System,
     687              :                         OutputProcessor::StoreType::Sum,
     688              :                         ChillerName,
     689              :                         Constant::eResource::Electricity,
     690              :                         OutputProcessor::Group::Plant,
     691              :                         OutputProcessor::EndUseCat::Heating);
     692              : 
     693            0 :     SetupOutputVariable(state,
     694              :                         "Chiller Heater Evaporator Inlet Temperature",
     695              :                         Constant::Units::C,
     696            0 :                         this->ChillReturnTemp,
     697              :                         OutputProcessor::TimeStepType::System,
     698              :                         OutputProcessor::StoreType::Average,
     699              :                         ChillerName);
     700            0 :     SetupOutputVariable(state,
     701              :                         "Chiller Heater Evaporator Outlet Temperature",
     702              :                         Constant::Units::C,
     703            0 :                         this->ChillSupplyTemp,
     704              :                         OutputProcessor::TimeStepType::System,
     705              :                         OutputProcessor::StoreType::Average,
     706              :                         ChillerName);
     707            0 :     SetupOutputVariable(state,
     708              :                         "Chiller Heater Evaporator Mass Flow Rate",
     709              :                         Constant::Units::kg_s,
     710            0 :                         this->ChillWaterFlowRate,
     711              :                         OutputProcessor::TimeStepType::System,
     712              :                         OutputProcessor::StoreType::Average,
     713              :                         ChillerName);
     714              : 
     715            0 :     if (this->isWaterCooled) {
     716            0 :         SetupOutputVariable(state,
     717              :                             "Chiller Heater Condenser Inlet Temperature",
     718              :                             Constant::Units::C,
     719            0 :                             this->CondReturnTemp,
     720              :                             OutputProcessor::TimeStepType::System,
     721              :                             OutputProcessor::StoreType::Average,
     722              :                             ChillerName);
     723            0 :         SetupOutputVariable(state,
     724              :                             "Chiller Heater Condenser Outlet Temperature",
     725              :                             Constant::Units::C,
     726            0 :                             this->CondSupplyTemp,
     727              :                             OutputProcessor::TimeStepType::System,
     728              :                             OutputProcessor::StoreType::Average,
     729              :                             ChillerName);
     730            0 :         SetupOutputVariable(state,
     731              :                             "Chiller Heater Condenser Mass Flow Rate",
     732              :                             Constant::Units::kg_s,
     733            0 :                             this->CondWaterFlowRate,
     734              :                             OutputProcessor::TimeStepType::System,
     735              :                             OutputProcessor::StoreType::Average,
     736              :                             ChillerName);
     737              :     } else {
     738            0 :         SetupOutputVariable(state,
     739              :                             "Chiller Heater Condenser Inlet Temperature",
     740              :                             Constant::Units::C,
     741            0 :                             this->CondReturnTemp,
     742              :                             OutputProcessor::TimeStepType::System,
     743              :                             OutputProcessor::StoreType::Average,
     744              :                             ChillerName);
     745              :     }
     746              : 
     747            0 :     SetupOutputVariable(state,
     748              :                         "Chiller Heater Heating Inlet Temperature",
     749              :                         Constant::Units::C,
     750            0 :                         this->HotWaterReturnTemp,
     751              :                         OutputProcessor::TimeStepType::System,
     752              :                         OutputProcessor::StoreType::Average,
     753              :                         ChillerName);
     754            0 :     SetupOutputVariable(state,
     755              :                         "Chiller Heater Heating Outlet Temperature",
     756              :                         Constant::Units::C,
     757            0 :                         this->HotWaterSupplyTemp,
     758              :                         OutputProcessor::TimeStepType::System,
     759              :                         OutputProcessor::StoreType::Average,
     760              :                         ChillerName);
     761            0 :     SetupOutputVariable(state,
     762              :                         "Chiller Heater Heating Mass Flow Rate",
     763              :                         Constant::Units::kg_s,
     764            0 :                         this->HotWaterFlowRate,
     765              :                         OutputProcessor::TimeStepType::System,
     766              :                         OutputProcessor::StoreType::Average,
     767              :                         ChillerName);
     768              : 
     769            0 :     SetupOutputVariable(state,
     770              :                         "Chiller Heater Cooling Part Load Ratio",
     771              :                         Constant::Units::None,
     772            0 :                         this->CoolPartLoadRatio,
     773              :                         OutputProcessor::TimeStepType::System,
     774              :                         OutputProcessor::StoreType::Average,
     775              :                         ChillerName);
     776            0 :     SetupOutputVariable(state,
     777              :                         "Chiller Heater Maximum Cooling Rate",
     778              :                         Constant::Units::W,
     779            0 :                         this->CoolingCapacity,
     780              :                         OutputProcessor::TimeStepType::System,
     781              :                         OutputProcessor::StoreType::Average,
     782              :                         ChillerName);
     783            0 :     SetupOutputVariable(state,
     784              :                         "Chiller Heater Heating Part Load Ratio",
     785              :                         Constant::Units::None,
     786            0 :                         this->HeatPartLoadRatio,
     787              :                         OutputProcessor::TimeStepType::System,
     788              :                         OutputProcessor::StoreType::Average,
     789              :                         ChillerName);
     790            0 :     SetupOutputVariable(state,
     791              :                         "Chiller Heater Maximum Heating Rate",
     792              :                         Constant::Units::W,
     793            0 :                         this->HeatingCapacity,
     794              :                         OutputProcessor::TimeStepType::System,
     795              :                         OutputProcessor::StoreType::Average,
     796              :                         ChillerName);
     797              : 
     798            0 :     SetupOutputVariable(state,
     799              :                         "Chiller Heater Runtime Fraction",
     800              :                         Constant::Units::None,
     801            0 :                         this->FractionOfPeriodRunning,
     802              :                         OutputProcessor::TimeStepType::System,
     803              :                         OutputProcessor::StoreType::Average,
     804              :                         ChillerName);
     805              : 
     806            0 :     SetupOutputVariable(state,
     807              :                         "Chiller Heater Source Exhaust Inlet Temperature",
     808              :                         Constant::Units::C,
     809            0 :                         this->ExhaustInTemp,
     810              :                         OutputProcessor::TimeStepType::System,
     811              :                         OutputProcessor::StoreType::Average,
     812              :                         ChillerName);
     813            0 :     SetupOutputVariable(state,
     814              :                         "Chiller Heater Source Exhaust Inlet Mass Flow Rate",
     815              :                         Constant::Units::kg_s,
     816            0 :                         this->ExhaustInFlow,
     817              :                         OutputProcessor::TimeStepType::System,
     818              :                         OutputProcessor::StoreType::Average,
     819              :                         ChillerName);
     820              : 
     821            0 :     SetupOutputVariable(state,
     822              :                         "Chiller Heater Heating Heat Recovery Potential Rate",
     823              :                         Constant::Units::W,
     824            0 :                         this->ExhHeatRecPotentialHeat,
     825              :                         OutputProcessor::TimeStepType::System,
     826              :                         OutputProcessor::StoreType::Average,
     827              :                         ChillerName);
     828            0 :     SetupOutputVariable(state,
     829              :                         "Chiller Heater Cooling Heat Recovery Potential Rate",
     830              :                         Constant::Units::W,
     831            0 :                         this->ExhHeatRecPotentialCool,
     832              :                         OutputProcessor::TimeStepType::System,
     833              :                         OutputProcessor::StoreType::Average,
     834              :                         ChillerName);
     835              : 
     836            0 :     SetupOutputVariable(state,
     837              :                         "Chiller Heater Cooling Source Heat Transfer Rate",
     838              :                         Constant::Units::W,
     839            0 :                         this->CoolThermalEnergyUseRate,
     840              :                         OutputProcessor::TimeStepType::System,
     841              :                         OutputProcessor::StoreType::Average,
     842              :                         ChillerName);
     843            0 :     SetupOutputVariable(state,
     844              :                         "Chiller Heater Heating Source Heat Transfer Rate",
     845              :                         Constant::Units::W,
     846            0 :                         this->HeatThermalEnergyUseRate,
     847              :                         OutputProcessor::TimeStepType::System,
     848              :                         OutputProcessor::StoreType::Average,
     849              :                         ChillerName);
     850            0 : }
     851              : 
     852            0 : void ExhaustAbsorberSpecs::oneTimeInit_new(EnergyPlusData &state)
     853              : {
     854            0 :     this->setupOutputVariables(state);
     855              : 
     856            0 :     bool errFlag = false;
     857            0 :     PlantUtilities::ScanPlantLoopsForObject(state,
     858              :                                             this->Name,
     859              :                                             DataPlant::PlantEquipmentType::Chiller_ExhFiredAbsorption,
     860            0 :                                             this->CWPlantLoc,
     861              :                                             errFlag,
     862            0 :                                             this->CHWLowLimitTemp,
     863              :                                             _,
     864              :                                             _,
     865            0 :                                             this->ChillReturnNodeNum,
     866              :                                             _);
     867            0 :     if (errFlag) {
     868            0 :         ShowFatalError(state, "InitExhaustAbsorber: Program terminated due to previous condition(s).");
     869              :     }
     870              : 
     871            0 :     PlantUtilities::ScanPlantLoopsForObject(
     872            0 :         state, this->Name, DataPlant::PlantEquipmentType::Chiller_ExhFiredAbsorption, this->HWPlantLoc, errFlag, _, _, _, this->HeatReturnNodeNum, _);
     873            0 :     if (errFlag) {
     874            0 :         ShowFatalError(state, "InitExhaustAbsorber: Program terminated due to previous condition(s).");
     875              :     }
     876              : 
     877            0 :     if (this->isWaterCooled) {
     878            0 :         PlantUtilities::ScanPlantLoopsForObject(state,
     879              :                                                 this->Name,
     880              :                                                 DataPlant::PlantEquipmentType::Chiller_ExhFiredAbsorption,
     881            0 :                                                 this->CDPlantLoc,
     882              :                                                 errFlag,
     883              :                                                 _,
     884              :                                                 _,
     885              :                                                 _,
     886            0 :                                                 this->CondReturnNodeNum,
     887              :                                                 _);
     888            0 :         if (errFlag) {
     889            0 :             ShowFatalError(state, "InitExhaustAbsorber: Program terminated due to previous condition(s).");
     890              :         }
     891            0 :         PlantUtilities::InterConnectTwoPlantLoopSides(
     892            0 :             state, this->CWPlantLoc, this->CDPlantLoc, DataPlant::PlantEquipmentType::Chiller_ExhFiredAbsorption, true);
     893            0 :         PlantUtilities::InterConnectTwoPlantLoopSides(
     894            0 :             state, this->HWPlantLoc, this->CDPlantLoc, DataPlant::PlantEquipmentType::Chiller_ExhFiredAbsorption, true);
     895              :     }
     896              : 
     897            0 :     PlantUtilities::InterConnectTwoPlantLoopSides(
     898            0 :         state, this->CWPlantLoc, this->HWPlantLoc, DataPlant::PlantEquipmentType::Chiller_ExhFiredAbsorption, true);
     899              : 
     900              :     // check if outlet node of chilled water side has a setpoint.
     901            0 :     if ((state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) &&
     902            0 :         (state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPointHi == DataLoopNode::SensedNodeFlagValue)) {
     903            0 :         if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
     904            0 :             if (!this->ChillSetPointErrDone) {
     905            0 :                 ShowWarningError(state, format("Missing temperature setpoint on cool side for chiller heater named {}", this->Name));
     906            0 :                 ShowContinueError(state, "  A temperature setpoint is needed at the outlet node of this chiller, use a SetpointManager");
     907            0 :                 ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
     908            0 :                 this->ChillSetPointErrDone = true;
     909              :             }
     910              :         } else {
     911              :             // need call to EMS to check node
     912            0 :             errFlag = false; // but not really fatal yet, but should be.
     913            0 :             EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->ChillSupplyNodeNum, HVAC::CtrlVarType::Temp, errFlag);
     914            0 :             state.dataLoopNodes->NodeSetpointCheck(this->ChillSupplyNodeNum).needsSetpointChecking = false;
     915            0 :             if (errFlag) {
     916            0 :                 if (!this->ChillSetPointErrDone) {
     917            0 :                     ShowWarningError(state, format("Missing temperature setpoint on cool side for chiller heater named {}", this->Name));
     918            0 :                     ShowContinueError(state, "  A temperature setpoint is needed at the outlet node of this chiller evaporator ");
     919            0 :                     ShowContinueError(state, "  use a Setpoint Manager to establish a setpoint at the chiller evaporator outlet node ");
     920            0 :                     ShowContinueError(state, "  or use an EMS actuator to establish a setpoint at the outlet node ");
     921            0 :                     ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
     922            0 :                     this->ChillSetPointErrDone = true;
     923              :                 }
     924              :             }
     925              :         }
     926            0 :         this->ChillSetPointSetToLoop = true;
     927            0 :         state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPoint =
     928            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
     929            0 :         state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPointHi =
     930            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
     931              :     }
     932              :     // check if outlet node of hot water side has a setpoint.
     933            0 :     if ((state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) &&
     934            0 :         (state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPointLo == DataLoopNode::SensedNodeFlagValue)) {
     935            0 :         if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
     936            0 :             if (!this->HeatSetPointErrDone) {
     937            0 :                 ShowWarningError(state, format("Missing temperature setpoint on heat side for chiller heater named {}", this->Name));
     938            0 :                 ShowContinueError(state, "  A temperature setpoint is needed at the outlet node of this chiller, use a SetpointManager");
     939            0 :                 ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
     940            0 :                 this->HeatSetPointErrDone = true;
     941              :             }
     942              :         } else {
     943              :             // need call to EMS to check node
     944            0 :             errFlag = false; // but not really fatal yet, but should be.
     945            0 :             EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->HeatSupplyNodeNum, HVAC::CtrlVarType::Temp, errFlag);
     946            0 :             state.dataLoopNodes->NodeSetpointCheck(this->HeatSupplyNodeNum).needsSetpointChecking = false;
     947            0 :             if (errFlag) {
     948            0 :                 if (!this->HeatSetPointErrDone) {
     949            0 :                     ShowWarningError(state, format("Missing temperature setpoint on heat side for chiller heater named {}", this->Name));
     950            0 :                     ShowContinueError(state, "  A temperature setpoint is needed at the outlet node of this chiller heater ");
     951            0 :                     ShowContinueError(state, "  use a Setpoint Manager to establish a setpoint at the heater side outlet node ");
     952            0 :                     ShowContinueError(state, "  or use an EMS actuator to establish a setpoint at the outlet node ");
     953            0 :                     ShowContinueError(state, "  The overall loop setpoint will be assumed for heater side. The simulation continues ... ");
     954            0 :                     this->HeatSetPointErrDone = true;
     955              :                 }
     956              :             }
     957              :         }
     958            0 :         this->HeatSetPointSetToLoop = true;
     959            0 :         state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPoint =
     960            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
     961            0 :         state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPointLo =
     962            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointLo;
     963              :     }
     964            0 : }
     965              : 
     966            0 : void ExhaustAbsorberSpecs::initialize(EnergyPlusData &state)
     967              : {
     968              : 
     969              :     // SUBROUTINE INFORMATION:
     970              :     //       AUTHOR         Fred Buhl
     971              :     //       DATE WRITTEN   June 2003
     972              : 
     973              :     // PURPOSE OF THIS SUBROUTINE:
     974              :     // This subroutine is for initializations of Exhaust Fired absorption chiller components.
     975              : 
     976              :     // METHODOLOGY EMPLOYED:
     977              :     // Uses the status flags to trigger initializations.
     978              : 
     979              :     // SUBROUTINE PARAMETER DEFINITIONS:
     980              :     static constexpr std::string_view RoutineName("InitExhaustAbsorber");
     981              : 
     982              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     983              :     Real64 rho;  // local fluid density
     984              :     Real64 mdot; // local fluid mass flow rate
     985              : 
     986            0 :     int CondInletNode = this->CondReturnNodeNum;
     987            0 :     int CondOutletNode = this->CondSupplyNodeNum;
     988            0 :     int HeatInletNode = this->HeatReturnNodeNum;
     989            0 :     int HeatOutletNode = this->HeatSupplyNodeNum;
     990              : 
     991            0 :     if (this->envrnInit && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
     992              : 
     993            0 :         if (this->isWaterCooled) {
     994              :             // init max available condenser water flow rate
     995            0 :             if (this->CDPlantLoc.loopNum > 0) {
     996            0 :                 rho = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
     997              :             } else {
     998            0 :                 rho = Psychrometrics::RhoH2O(Constant::InitConvTemp);
     999              :             }
    1000              : 
    1001            0 :             this->DesCondMassFlowRate = rho * this->CondVolFlowRate;
    1002            0 :             PlantUtilities::InitComponentNodes(state, 0.0, this->DesCondMassFlowRate, CondInletNode, CondOutletNode);
    1003              :         }
    1004              : 
    1005            0 :         if (this->HWPlantLoc.loopNum > 0) {
    1006            0 :             rho = state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    1007              :         } else {
    1008            0 :             rho = Psychrometrics::RhoH2O(Constant::InitConvTemp);
    1009              :         }
    1010            0 :         this->DesHeatMassFlowRate = rho * this->HeatVolFlowRate;
    1011              :         // init available hot water flow rate
    1012            0 :         PlantUtilities::InitComponentNodes(state, 0.0, this->DesHeatMassFlowRate, HeatInletNode, HeatOutletNode);
    1013              : 
    1014            0 :         if (this->CWPlantLoc.loopNum > 0) {
    1015            0 :             rho = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    1016              :         } else {
    1017            0 :             rho = Psychrometrics::RhoH2O(Constant::InitConvTemp);
    1018              :         }
    1019            0 :         this->DesEvapMassFlowRate = rho * this->EvapVolFlowRate;
    1020              :         // init available hot water flow rate
    1021            0 :         PlantUtilities::InitComponentNodes(state, 0.0, this->DesEvapMassFlowRate, this->ChillReturnNodeNum, this->ChillSupplyNodeNum);
    1022              : 
    1023            0 :         this->envrnInit = false;
    1024              :     }
    1025              : 
    1026            0 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    1027            0 :         this->envrnInit = true;
    1028              :     }
    1029              : 
    1030              :     // this component model works off setpoints on the leaving node
    1031              :     // fill from plant if needed
    1032            0 :     if (this->ChillSetPointSetToLoop) {
    1033            0 :         state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPoint =
    1034            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
    1035            0 :         state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPointHi =
    1036            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
    1037              :     }
    1038              : 
    1039            0 :     if (this->HeatSetPointSetToLoop) {
    1040            0 :         state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPoint =
    1041            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
    1042            0 :         state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPointLo =
    1043            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointLo;
    1044              :     }
    1045              : 
    1046            0 :     if ((this->isWaterCooled) &&
    1047            0 :         ((this->InHeatingMode) || (this->InCoolingMode))) { // combining oneTimeInit and plantScanInit could cause a diff here
    1048            0 :         mdot = this->DesCondMassFlowRate;
    1049              : 
    1050            0 :         PlantUtilities::SetComponentFlowRate(state, mdot, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDPlantLoc);
    1051              : 
    1052              :     } else {
    1053            0 :         mdot = 0.0;
    1054            0 :         if (this->CDPlantLoc.loopNum > 0) {
    1055            0 :             PlantUtilities::SetComponentFlowRate(state, mdot, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDPlantLoc);
    1056              :         }
    1057              :     }
    1058            0 : }
    1059              : 
    1060            0 : void ExhaustAbsorberSpecs::size(EnergyPlusData &state)
    1061              : {
    1062              : 
    1063              :     // SUBROUTINE INFORMATION:
    1064              :     //       AUTHOR         Fred Buhl
    1065              :     //       DATE WRITTEN   June 2003
    1066              :     //       MODIFIED       November 2013 Daeho Kang, add component sizing table entries
    1067              : 
    1068              :     // PURPOSE OF THIS SUBROUTINE:
    1069              :     // This subroutine is for sizing Exhaust Fired absorption chiller components for which
    1070              :     // capacities and flow rates have not been specified in the input.
    1071              : 
    1072              :     // METHODOLOGY EMPLOYED:
    1073              :     // Obtains evaporator flow rate from the plant sizing array. Calculates nominal capacity from
    1074              :     // the evaporator flow rate and the chilled water loop design delta T. The condenser flow rate
    1075              :     // is calculated from the nominal capacity, the COP, and the condenser loop design delta T.
    1076              : 
    1077              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1078              :     static constexpr std::string_view RoutineName("SizeExhaustAbsorber");
    1079              : 
    1080              :     Real64 Cp;                     // local fluid specific heat
    1081              :     Real64 rho;                    // local fluid density
    1082              :     Real64 NomCapUser;             // Hardsized nominal capacity for reporting
    1083              :     Real64 EvapVolFlowRateUser;    // Hardsized evaporator volume flow rate for reporting
    1084              :     Real64 CondVolFlowRateUser;    // Hardsized condenser flow rate for reporting
    1085              :     Real64 HeatRecVolFlowRateUser; // Hardsized generator flow rate for reporting
    1086              : 
    1087            0 :     bool ErrorsFound = false;
    1088            0 :     Real64 tmpNomCap = this->NomCoolingCap;
    1089            0 :     Real64 tmpEvapVolFlowRate = this->EvapVolFlowRate;
    1090            0 :     Real64 tmpCondVolFlowRate = this->CondVolFlowRate;
    1091            0 :     Real64 tmpHeatRecVolFlowRate = this->HeatVolFlowRate;
    1092              : 
    1093            0 :     int PltSizCondNum = 0; // Plant Sizing index for condenser loop
    1094            0 :     if (this->isWaterCooled) {
    1095            0 :         PltSizCondNum = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).PlantSizNum;
    1096              :     }
    1097              : 
    1098            0 :     int PltSizHeatNum = state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).PlantSizNum;
    1099            0 :     int PltSizCoolNum = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).PlantSizNum;
    1100              : 
    1101            0 :     if (PltSizCoolNum > 0) {
    1102            0 :         if (state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1103            0 :             Cp = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getSpecificHeat(state, Constant::CWInitConvTemp, RoutineName);
    1104            0 :             rho = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    1105            0 :             tmpNomCap = Cp * rho * state.dataSize->PlantSizData(PltSizCoolNum).DeltaT * state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate *
    1106            0 :                         this->SizFac;
    1107            0 :             if (!this->NomCoolingCapWasAutoSized) {
    1108            0 :                 tmpNomCap = this->NomCoolingCap;
    1109              :             }
    1110              :         } else {
    1111            0 :             if (this->NomCoolingCapWasAutoSized) {
    1112            0 :                 tmpNomCap = 0.0;
    1113              :             }
    1114              :         }
    1115            0 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1116            0 :             if (this->NomCoolingCapWasAutoSized) {
    1117            0 :                 this->NomCoolingCap = tmpNomCap;
    1118            0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1119            0 :                     BaseSizer::reportSizerOutput(
    1120              :                         state, "ChillerHeater:Absorption:DoubleEffect", this->Name, "Design Size Nominal Cooling Capacity [W]", tmpNomCap);
    1121              :                 }
    1122            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1123            0 :                     BaseSizer::reportSizerOutput(
    1124              :                         state, "ChillerHeater:Absorption:DoubleEffect", this->Name, "Initial Design Size Nominal Cooling Capacity [W]", tmpNomCap);
    1125              :                 }
    1126              :             } else {
    1127            0 :                 if (this->NomCoolingCap > 0.0 && tmpNomCap > 0.0) {
    1128            0 :                     NomCapUser = this->NomCoolingCap;
    1129            0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1130            0 :                         BaseSizer::reportSizerOutput(state,
    1131              :                                                      "ChillerHeater:Absorption:DoubleEffect",
    1132              :                                                      this->Name,
    1133              :                                                      "Design Size Nominal Cooling Capacity [W]",
    1134              :                                                      tmpNomCap,
    1135              :                                                      "User-Specified Nominal Cooling Capacity [W]",
    1136              :                                                      NomCapUser);
    1137            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1138            0 :                             if ((std::abs(tmpNomCap - NomCapUser) / NomCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1139            0 :                                 ShowMessage(
    1140              :                                     state,
    1141            0 :                                     format("SizeChillerHeaterAbsorptionDoubleEffect: Potential issue with equipment sizing for {}", this->Name));
    1142            0 :                                 ShowContinueError(state, format("User-Specified Nominal Capacity of {:.2R} [W]", NomCapUser));
    1143            0 :                                 ShowContinueError(state, format("differs from Design Size Nominal Capacity of {:.2R} [W]", tmpNomCap));
    1144            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1145            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1146              :                             }
    1147              :                         }
    1148              :                     }
    1149            0 :                     tmpNomCap = NomCapUser;
    1150              :                 }
    1151              :             }
    1152              :         }
    1153              :     } else {
    1154            0 :         if (this->NomCoolingCapWasAutoSized) {
    1155            0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1156            0 :                 ShowSevereError(state, format("SizeExhaustAbsorber: ChillerHeater:Absorption:DoubleEffect=\"{}\", autosize error.", this->Name));
    1157            0 :                 ShowContinueError(state, "Autosizing of Exhaust Fired Absorption Chiller nominal cooling capacity requires");
    1158            0 :                 ShowContinueError(state, "a cooling loop Sizing:Plant object.");
    1159            0 :                 ErrorsFound = true;
    1160              :             }
    1161              :         } else {
    1162            0 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1163            0 :                 if (this->NomCoolingCap > 0.0) {
    1164            0 :                     BaseSizer::reportSizerOutput(
    1165              :                         state, "Chiller:Absorption:DoubleEffect", this->Name, "User-Specified Nominal Capacity [W]", this->NomCoolingCap);
    1166              :                 }
    1167              :             }
    1168              :         }
    1169              :     }
    1170              : 
    1171            0 :     if (PltSizCoolNum > 0) {
    1172            0 :         if (state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1173            0 :             tmpEvapVolFlowRate = state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate * this->SizFac;
    1174            0 :             if (!this->EvapVolFlowRateWasAutoSized) {
    1175            0 :                 tmpEvapVolFlowRate = this->EvapVolFlowRate;
    1176              :             }
    1177              : 
    1178              :         } else {
    1179            0 :             if (this->EvapVolFlowRateWasAutoSized) {
    1180            0 :                 tmpEvapVolFlowRate = 0.0;
    1181              :             }
    1182              :         }
    1183            0 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1184            0 :             if (this->EvapVolFlowRateWasAutoSized) {
    1185            0 :                 this->EvapVolFlowRate = tmpEvapVolFlowRate;
    1186            0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1187            0 :                     BaseSizer::reportSizerOutput(state,
    1188              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1189              :                                                  this->Name,
    1190              :                                                  "Design Size Design Chilled Water Flow Rate [m3/s]",
    1191              :                                                  tmpEvapVolFlowRate);
    1192              :                 }
    1193            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1194            0 :                     BaseSizer::reportSizerOutput(state,
    1195              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1196              :                                                  this->Name,
    1197              :                                                  "Initial Design Size Design Chilled Water Flow Rate [m3/s]",
    1198              :                                                  tmpEvapVolFlowRate);
    1199              :                 }
    1200              :             } else {
    1201            0 :                 if (this->EvapVolFlowRate > 0.0 && tmpEvapVolFlowRate > 0.0) {
    1202            0 :                     EvapVolFlowRateUser = this->EvapVolFlowRate;
    1203            0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1204            0 :                         BaseSizer::reportSizerOutput(state,
    1205              :                                                      "ChillerHeater:Absorption:DoubleEffect",
    1206              :                                                      this->Name,
    1207              :                                                      "Design Size Design Chilled Water Flow Rate [m3/s]",
    1208              :                                                      tmpEvapVolFlowRate,
    1209              :                                                      "User-Specified Design Chilled Water Flow Rate [m3/s]",
    1210              :                                                      EvapVolFlowRateUser);
    1211            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1212            0 :                             if ((std::abs(tmpEvapVolFlowRate - EvapVolFlowRateUser) / EvapVolFlowRateUser) >
    1213            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1214            0 :                                 ShowMessage(state,
    1215            0 :                                             format("SizeChillerAbsorptionDoubleEffect: Potential issue with equipment sizing for {}", this->Name));
    1216            0 :                                 ShowContinueError(state,
    1217            0 :                                                   format("User-Specified Design Chilled Water Flow Rate of {:.5R} [m3/s]", EvapVolFlowRateUser));
    1218            0 :                                 ShowContinueError(
    1219            0 :                                     state, format("differs from Design Size Design Chilled Water Flow Rate of {:.5R} [m3/s]", tmpEvapVolFlowRate));
    1220            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1221            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1222              :                             }
    1223              :                         }
    1224              :                     }
    1225            0 :                     tmpEvapVolFlowRate = EvapVolFlowRateUser;
    1226              :                 }
    1227              :             }
    1228              :         }
    1229              :     } else {
    1230            0 :         if (this->EvapVolFlowRateWasAutoSized) {
    1231            0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1232            0 :                 ShowSevereError(state, format("SizeExhaustAbsorber: ChillerHeater:Absorption:DoubleEffect=\"{}\", autosize error.", this->Name));
    1233            0 :                 ShowContinueError(state, "Autosizing of Exhaust Fired Absorption Chiller evap flow rate requires");
    1234            0 :                 ShowContinueError(state, "a cooling loop Sizing:Plant object.");
    1235            0 :                 ErrorsFound = true;
    1236              :             }
    1237              :         } else {
    1238            0 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1239            0 :                 if (this->EvapVolFlowRate > 0.0) {
    1240            0 :                     BaseSizer::reportSizerOutput(state,
    1241              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1242              :                                                  this->Name,
    1243              :                                                  "User-Specified Design Chilled Water Flow Rate [m3/s]",
    1244              :                                                  this->EvapVolFlowRate);
    1245              :                 }
    1246              :             }
    1247              :         }
    1248              :     }
    1249              : 
    1250            0 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->ChillReturnNodeNum, tmpEvapVolFlowRate);
    1251              : 
    1252            0 :     if (PltSizHeatNum > 0) {
    1253            0 :         if (state.dataSize->PlantSizData(PltSizHeatNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1254            0 :             tmpHeatRecVolFlowRate = state.dataSize->PlantSizData(PltSizHeatNum).DesVolFlowRate * this->SizFac;
    1255            0 :             if (!this->HeatVolFlowRateWasAutoSized) {
    1256            0 :                 tmpHeatRecVolFlowRate = this->HeatVolFlowRate;
    1257              :             }
    1258              : 
    1259              :         } else {
    1260            0 :             if (this->HeatVolFlowRateWasAutoSized) {
    1261            0 :                 tmpHeatRecVolFlowRate = 0.0;
    1262              :             }
    1263              :         }
    1264            0 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1265            0 :             if (this->HeatVolFlowRateWasAutoSized) {
    1266            0 :                 this->HeatVolFlowRate = tmpHeatRecVolFlowRate;
    1267            0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1268            0 :                     BaseSizer::reportSizerOutput(state,
    1269              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1270              :                                                  this->Name,
    1271              :                                                  "Design Size Design Hot Water Flow Rate [m3/s]",
    1272              :                                                  tmpHeatRecVolFlowRate);
    1273              :                 }
    1274            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1275            0 :                     BaseSizer::reportSizerOutput(state,
    1276              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1277              :                                                  this->Name,
    1278              :                                                  "Initial Design Size Design Hot Water Flow Rate [m3/s]",
    1279              :                                                  tmpHeatRecVolFlowRate);
    1280              :                 }
    1281              :             } else {
    1282            0 :                 if (this->HeatVolFlowRate > 0.0 && tmpHeatRecVolFlowRate > 0.0) {
    1283            0 :                     HeatRecVolFlowRateUser = this->HeatVolFlowRate;
    1284            0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1285            0 :                         BaseSizer::reportSizerOutput(state,
    1286              :                                                      "ChillerHeater:Absorption:DoubleEffect",
    1287              :                                                      this->Name,
    1288              :                                                      "Design Size Design Hot Water Flow Rate [m3/s]",
    1289              :                                                      tmpHeatRecVolFlowRate,
    1290              :                                                      "User-Specified Design Hot Water Flow Rate [m3/s]",
    1291              :                                                      HeatRecVolFlowRateUser);
    1292            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1293            0 :                             if ((std::abs(tmpHeatRecVolFlowRate - HeatRecVolFlowRateUser) / HeatRecVolFlowRateUser) >
    1294            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1295            0 :                                 ShowMessage(
    1296              :                                     state,
    1297            0 :                                     format("SizeChillerHeaterAbsorptionDoubleEffect: Potential issue with equipment sizing for {}", this->Name));
    1298            0 :                                 ShowContinueError(state,
    1299            0 :                                                   format("User-Specified Design Hot Water Flow Rate of {:.5R} [m3/s]", HeatRecVolFlowRateUser));
    1300            0 :                                 ShowContinueError(
    1301            0 :                                     state, format("differs from Design Size Design Hot Water Flow Rate of {:.5R} [m3/s]", tmpHeatRecVolFlowRate));
    1302            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1303            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1304              :                             }
    1305              :                         }
    1306              :                     }
    1307            0 :                     tmpHeatRecVolFlowRate = HeatRecVolFlowRateUser;
    1308              :                 }
    1309              :             }
    1310              :         }
    1311              :     } else {
    1312            0 :         if (this->HeatVolFlowRateWasAutoSized) {
    1313            0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1314            0 :                 ShowSevereError(state, format("SizeExhaustAbsorber: ChillerHeater:Absorption:DoubleEffect=\"{}\", autosize error.", this->Name));
    1315            0 :                 ShowContinueError(state, "Autosizing of Exhaust Fired Absorption Chiller hot water flow rate requires");
    1316            0 :                 ShowContinueError(state, "a heating loop Sizing:Plant object.");
    1317            0 :                 ErrorsFound = true;
    1318              :             }
    1319              :         } else {
    1320            0 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1321            0 :                 if (this->HeatVolFlowRate > 0.0) {
    1322            0 :                     BaseSizer::reportSizerOutput(state,
    1323              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1324              :                                                  this->Name,
    1325              :                                                  "User-Specified Design Hot Water Flow Rate [m3/s]",
    1326              :                                                  this->HeatVolFlowRate);
    1327              :                 }
    1328              :             }
    1329              :         }
    1330              :     }
    1331              : 
    1332            0 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->HeatReturnNodeNum, tmpHeatRecVolFlowRate);
    1333              : 
    1334            0 :     if (PltSizCondNum > 0 && PltSizCoolNum > 0) {
    1335            0 :         if (state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow && tmpNomCap > 0.0) {
    1336              : 
    1337            0 :             Cp = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).glycol->getSpecificHeat(state, this->TempDesCondReturn, RoutineName);
    1338            0 :             rho = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).glycol->getDensity(state, this->TempDesCondReturn, RoutineName);
    1339            0 :             tmpCondVolFlowRate = tmpNomCap * (1.0 + this->ThermalEnergyCoolRatio) / (state.dataSize->PlantSizData(PltSizCondNum).DeltaT * Cp * rho);
    1340            0 :             if (!this->CondVolFlowRateWasAutoSized) {
    1341            0 :                 tmpCondVolFlowRate = this->CondVolFlowRate;
    1342              :             }
    1343              : 
    1344              :         } else {
    1345            0 :             if (this->CondVolFlowRateWasAutoSized) {
    1346            0 :                 tmpCondVolFlowRate = 0.0;
    1347              :             }
    1348              :         }
    1349            0 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1350            0 :             if (this->CondVolFlowRateWasAutoSized) {
    1351            0 :                 this->CondVolFlowRate = tmpCondVolFlowRate;
    1352            0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1353            0 :                     BaseSizer::reportSizerOutput(state,
    1354              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1355              :                                                  this->Name,
    1356              :                                                  "Design Size Design Condenser Water Flow Rate [m3/s]",
    1357              :                                                  tmpCondVolFlowRate);
    1358              :                 }
    1359            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1360            0 :                     BaseSizer::reportSizerOutput(state,
    1361              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1362              :                                                  this->Name,
    1363              :                                                  "Initial Design Size Design Condenser Water Flow Rate [m3/s]",
    1364              :                                                  tmpCondVolFlowRate);
    1365              :                 }
    1366              :             } else {
    1367            0 :                 if (this->CondVolFlowRate > 0.0 && tmpCondVolFlowRate > 0.0) {
    1368            0 :                     CondVolFlowRateUser = this->CondVolFlowRate;
    1369            0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1370            0 :                         BaseSizer::reportSizerOutput(state,
    1371              :                                                      "ChillerHeater:Absorption:DoubleEffect",
    1372              :                                                      this->Name,
    1373              :                                                      "Design Size Design Condenser Water Flow Rate [m3/s]",
    1374              :                                                      tmpCondVolFlowRate,
    1375              :                                                      "User-Specified Design Condenser Water Flow Rate [m3/s]",
    1376              :                                                      CondVolFlowRateUser);
    1377            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1378            0 :                             if ((std::abs(tmpCondVolFlowRate - CondVolFlowRateUser) / CondVolFlowRateUser) >
    1379            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1380            0 :                                 ShowMessage(state,
    1381            0 :                                             format("SizeChillerAbsorptionDoubleEffect: Potential issue with equipment sizing for {}", this->Name));
    1382            0 :                                 ShowContinueError(state,
    1383            0 :                                                   format("User-Specified Design Condenser Water Flow Rate of {:.5R} [m3/s]", CondVolFlowRateUser));
    1384            0 :                                 ShowContinueError(
    1385            0 :                                     state, format("differs from Design Size Design Condenser Water Flow Rate of {:.5R} [m3/s]", tmpCondVolFlowRate));
    1386            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1387            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1388              :                             }
    1389              :                         }
    1390              :                     }
    1391            0 :                     tmpCondVolFlowRate = CondVolFlowRateUser;
    1392              :                 }
    1393              :             }
    1394              :         }
    1395              :     } else {
    1396            0 :         if (this->CondVolFlowRateWasAutoSized) {
    1397            0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1398            0 :                 ShowSevereError(state, format("SizeExhaustAbsorber: ChillerHeater:Absorption:DoubleEffect=\"{}\", autosize error.", this->Name));
    1399            0 :                 ShowContinueError(state, "Autosizing of Exhaust Fired Absorption Chiller condenser flow rate requires a condenser");
    1400            0 :                 ShowContinueError(state, "loop Sizing:Plant object.");
    1401            0 :                 ErrorsFound = true;
    1402              :             }
    1403              :         } else {
    1404            0 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1405            0 :                 if (this->CondVolFlowRate > 0.0) {
    1406            0 :                     BaseSizer::reportSizerOutput(state,
    1407              :                                                  "ChillerHeater:Absorption:DoubleEffect",
    1408              :                                                  this->Name,
    1409              :                                                  "User-Specified Design Condenser Water Flow Rate [m3/s]",
    1410              :                                                  this->CondVolFlowRate);
    1411              :                 }
    1412              :             }
    1413              :         }
    1414              :     }
    1415              : 
    1416              :     // save the design condenser water volumetric flow rate for use by the condenser water loop sizing algorithms
    1417            0 :     if (this->isWaterCooled) {
    1418            0 :         PlantUtilities::RegisterPlantCompDesignFlow(state, this->CondReturnNodeNum, tmpCondVolFlowRate);
    1419              :     }
    1420              : 
    1421            0 :     if (ErrorsFound) {
    1422            0 :         ShowFatalError(state, "Preceding sizing errors cause program termination");
    1423              :     }
    1424              : 
    1425            0 :     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1426              :         // create predefined report
    1427            0 :         OutputReportPredefined::PreDefTableEntry(
    1428            0 :             state, state.dataOutRptPredefined->pdchMechType, this->Name, "ChillerHeater:Absorption:DoubleEffect");
    1429            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomEff, this->Name, this->ThermalEnergyCoolRatio);
    1430            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, this->Name, this->NomCoolingCap);
    1431              : 
    1432              :         // std 229 new Chillers table
    1433            0 :         OutputReportPredefined::PreDefTableEntry(
    1434            0 :             state, state.dataOutRptPredefined->pdchChillerType, this->Name, "ChillerHeater:Absorption:DoubleEffect");
    1435            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefCap, this->Name, this->NomCoolingCap);
    1436            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefEff, this->Name, this->ThermalEnergyCoolRatio);
    1437            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRatedCap, this->Name, this->NomCoolingCap);
    1438            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRatedEff, this->Name, this->ThermalEnergyCoolRatio);
    1439            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerIPLVinSI, this->Name, "N/A");
    1440            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerIPLVinIP, this->Name, "N/A");
    1441            0 :         OutputReportPredefined::PreDefTableEntry(state,
    1442            0 :                                                  state.dataOutRptPredefined->pdchChillerPlantloopName,
    1443              :                                                  this->Name,
    1444            0 :                                                  this->CWPlantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).Name : "N/A");
    1445            0 :         OutputReportPredefined::PreDefTableEntry(
    1446              :             state,
    1447            0 :             state.dataOutRptPredefined->pdchChillerPlantloopBranchName,
    1448              :             this->Name,
    1449            0 :             this->CWPlantLoc.loopNum > 0
    1450            0 :                 ? state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).LoopSide(this->CWPlantLoc.loopSideNum).Branch(this->CWPlantLoc.branchNum).Name
    1451              :                 : "N/A");
    1452            0 :         OutputReportPredefined::PreDefTableEntry(state,
    1453            0 :                                                  state.dataOutRptPredefined->pdchChillerCondLoopName,
    1454              :                                                  this->Name,
    1455            0 :                                                  this->CDPlantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).Name : "N/A");
    1456            0 :         OutputReportPredefined::PreDefTableEntry(
    1457              :             state,
    1458            0 :             state.dataOutRptPredefined->pdchChillerCondLoopBranchName,
    1459              :             this->Name,
    1460            0 :             this->CDPlantLoc.loopNum > 0
    1461            0 :                 ? state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).LoopSide(this->CDPlantLoc.loopSideNum).Branch(this->CDPlantLoc.branchNum).Name
    1462              :                 : "N/A");
    1463            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerMinPLR, this->Name, this->MinPartLoadRat);
    1464            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerFuelType, this->Name, this->ExhaustSourceName);
    1465            0 :         OutputReportPredefined::PreDefTableEntry(
    1466            0 :             state, state.dataOutRptPredefined->pdchChillerRatedEntCondTemp, this->Name, this->TempDesCondReturn); // Rated==Ref?
    1467            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRatedLevEvapTemp, this->Name, "N/A");
    1468            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefEntCondTemp, this->Name, this->TempDesCondReturn);
    1469            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefLevEvapTemp, this->Name, "N/A");
    1470              : 
    1471            0 :         OutputReportPredefined::PreDefTableEntry(
    1472            0 :             state, state.dataOutRptPredefined->pdchChillerDesSizeRefCHWFlowRate, this->Name, this->DesEvapMassFlowRate);
    1473            0 :         OutputReportPredefined::PreDefTableEntry(
    1474            0 :             state, state.dataOutRptPredefined->pdchChillerDesSizeRefCondFluidFlowRate, this->Name, this->DesCondMassFlowRate);
    1475            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerHeatRecPlantloopName, this->Name, "N/A");
    1476            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerHeatRecPlantloopBranchName, this->Name, "N/A");
    1477            0 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRecRelCapFrac, this->Name, "N/A");
    1478              :     }
    1479            0 : }
    1480              : 
    1481            2 : void ExhaustAbsorberSpecs::calcChiller(EnergyPlusData &state, Real64 &MyLoad)
    1482              : {
    1483              : 
    1484              :     // SUBROUTINE INFORMATION:
    1485              :     //       AUTHOR         Jason Glazer
    1486              :     //       DATE WRITTEN   March 2001
    1487              :     //       MODIFIED       Mahabir Bhandari, ORNL, Aug 2011, modified to accommodate exhaust fired chiller
    1488              : 
    1489              :     // PURPOSE OF THIS SUBROUTINE:
    1490              :     // Simulate a Exhaust fired (Exhaust consuming) absorption chiller using
    1491              :     // curves and inputs similar to DOE-2.1e
    1492              : 
    1493              :     // METHODOLOGY EMPLOYED:
    1494              :     // Curve fit of performance data
    1495              : 
    1496              :     // REFERENCES:
    1497              :     // 1.  DOE-2.1e Supplement and source code
    1498              :     // 2.  CoolTools GasMod work
    1499              : 
    1500              :     // FlowLock = 0  if mass flow rates may be changed by loop components
    1501              :     // FlowLock = 1  if mass flow rates may not be changed by loop components
    1502              : 
    1503              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1504            2 :     Real64 constexpr AbsLeavingTemp(176.667); // C - Minimum temperature leaving the Chiller absorber (350 F)
    1505              :     static constexpr std::string_view RoutineName("CalcExhaustAbsorberChillerModel");
    1506              : 
    1507              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1508              :     // Local copies of ExhaustAbsorberSpecs Type
    1509              :     // all variables that are local copies of data structure
    1510              :     // variables are prefaced with an "l" for local.
    1511              :     // Local copies of ExhaustAbsorberReportVars Type
    1512            2 :     Real64 lCoolingLoad(0.0);              // cooling load on the chiller (previously called QEvap)
    1513            2 :     Real64 lTowerLoad(0.0);                // load on the cooling tower/condenser (previously called QCond)
    1514            2 :     Real64 lCoolThermalEnergyUseRate(0.0); // instantaneous use of exhaust for period for cooling
    1515            2 :     Real64 lCoolElectricPower(0.0);        // parasitic electric power used  for cooling
    1516            2 :     Real64 lChillSupplyTemp(0.0);          // reporting: evaporator outlet temperature (was EvapOutletTemp)
    1517            2 :     Real64 lCondSupplyTemp(0.0);           // reporting: condenser outlet temperature (was CondOutletTemp)
    1518            2 :     Real64 lCondWaterMassFlowRate(0.0);    // reporting: condenser mass flow rate (was Condmdot)
    1519            2 :     Real64 lCoolPartLoadRatio(0.0);        // operating part load ratio (load/capacity for cooling)
    1520            2 :     Real64 lAvailableCoolingCapacity(0.0); // current capacity after temperature adjustment
    1521            2 :     Real64 lFractionOfPeriodRunning(0.0);
    1522            2 :     Real64 PartLoadRat(0.0);                // actual operating part load ratio of unit (ranges from minplr to 1)
    1523            2 :     Real64 lChillWaterMassflowratemax(0.0); // Maximum flow rate through the evaporator
    1524            2 :     Real64 lExhHeatRecPotentialCool(0.0);   // Exhaust heat recovery potential during cooling
    1525              :     // other local variables
    1526            2 :     Real64 ChillSupplySetPointTemp(0.0);
    1527              :     Real64 calcCondTemp; // the condenser temperature used for curve calculation
    1528              :     // either return or supply depending on user input
    1529              :     Real64 revisedEstimateAvailCap; // final estimate of available capacity if using leaving
    1530              :     // condenser water temperature
    1531              :     Real64 errorAvailCap; // error fraction on final estimate of AvailableCoolingCapacity
    1532              :     DataPlant::LoopSideLocation LoopSideNum;
    1533            2 :     Real64 Cp_CD = -1; // local fluid specific heat for condenser water -- initializing to negative to ensure it isn't used uninitialized
    1534              :     Real64 CpAir;      // specific heat of exhaust air
    1535              : 
    1536              :     // set node values to data structure values for nodes
    1537            2 :     int lChillReturnNodeNum = this->ChillReturnNodeNum;         // Node number on the inlet side of the plant
    1538            2 :     int lChillSupplyNodeNum = this->ChillSupplyNodeNum;         // Node number on the outlet side of the plant
    1539            2 :     int lCondReturnNodeNum = this->CondReturnNodeNum;           // Node number on the inlet side of the condenser
    1540            2 :     int lExhaustAirInletNodeNum = this->ExhaustAirInletNodeNum; // Combustion Air Inlet Node number
    1541              : 
    1542              :     // set local copies of data from rest of input structure
    1543            2 :     Real64 lNomCoolingCap = this->NomCoolingCap;                   // W - design nominal capacity of Absorber
    1544            2 :     Real64 lThermalEnergyCoolRatio = this->ThermalEnergyCoolRatio; // ratio of ThermalEnergy input to cooling output
    1545            2 :     Real64 lThermalEnergyHeatRatio = this->ThermalEnergyHeatRatio; // ratio of ThermalEnergy input to heating output
    1546            2 :     Real64 lElecCoolRatio = this->ElecCoolRatio;                   // ratio of electricity input to cooling output
    1547            2 :     Real64 lMinPartLoadRat = this->MinPartLoadRat;                 // min allowed operating frac full load
    1548            2 :     Real64 lMaxPartLoadRat = this->MaxPartLoadRat;                 // max allowed operating frac full load
    1549            2 :     bool lIsEnterCondensTemp = this->isEnterCondensTemp;           // if using entering condenser water temperature is TRUE, exiting is FALSE
    1550            2 :     bool lIsWaterCooled = this->isWaterCooled;                     // if water cooled it is TRUE
    1551            2 :     Real64 lCHWLowLimitTemp = this->CHWLowLimitTemp;
    1552            2 :     Real64 lHeatElectricPower = this->HeatElectricPower;               // parasitic electric power used  for heating
    1553            2 :     Real64 lHeatThermalEnergyUseRate = this->HeatThermalEnergyUseRate; // instantaneous use of exhaust for period for heating
    1554            2 :     Real64 lHeatPartLoadRatio = this->HeatPartLoadRatio;               // operating part load ratio (load/capacity for heating)
    1555              : 
    1556              :     // initialize entering conditions
    1557            2 :     Real64 lChillReturnTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
    1558            2 :     Real64 lChillWaterMassFlowRate = state.dataLoopNodes->Node(lChillReturnNodeNum).MassFlowRate;
    1559            2 :     Real64 lCondReturnTemp = state.dataLoopNodes->Node(lCondReturnNodeNum).Temp;
    1560            2 :     switch (state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).LoopDemandCalcScheme) {
    1561            2 :     case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1562            2 :         ChillSupplySetPointTemp = state.dataLoopNodes->Node(lChillSupplyNodeNum).TempSetPoint;
    1563            2 :     } break;
    1564            0 :     case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1565            0 :         ChillSupplySetPointTemp = state.dataLoopNodes->Node(lChillSupplyNodeNum).TempSetPointHi;
    1566            0 :     } break;
    1567            0 :     default: {
    1568            0 :         assert(false);
    1569              :     } break;
    1570              :     }
    1571            2 :     Real64 ChillDeltaTemp = std::abs(lChillReturnTemp - ChillSupplySetPointTemp);
    1572            2 :     Real64 lExhaustInTemp = state.dataLoopNodes->Node(lExhaustAirInletNodeNum).Temp;
    1573            2 :     Real64 lExhaustInFlow = state.dataLoopNodes->Node(lExhaustAirInletNodeNum).MassFlowRate;
    1574            2 :     Real64 lExhaustAirHumRat = state.dataLoopNodes->Node(lExhaustAirInletNodeNum).HumRat;
    1575              : 
    1576            2 :     Real64 Cp_CW = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getSpecificHeat(state, lChillReturnTemp, RoutineName);
    1577            2 :     if (this->CDPlantLoc.loopNum > 0) {
    1578            0 :         Cp_CD = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).glycol->getSpecificHeat(state, lChillReturnTemp, RoutineName);
    1579              :     }
    1580              : 
    1581              :     // If no loop demand or Absorber OFF, return
    1582              :     // will need to modify when absorber can act as a boiler
    1583            2 :     if (MyLoad >= 0 || !((this->InHeatingMode) || (this->InCoolingMode))) {
    1584              :         // set node temperatures
    1585            0 :         lChillSupplyTemp = lChillReturnTemp;
    1586            0 :         lCondSupplyTemp = lCondReturnTemp;
    1587            0 :         lCondWaterMassFlowRate = 0.0;
    1588            0 :         if (lIsWaterCooled) {
    1589            0 :             PlantUtilities::SetComponentFlowRate(state, lCondWaterMassFlowRate, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDPlantLoc);
    1590              :         }
    1591            0 :         lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, lCoolPartLoadRatio) / lMinPartLoadRat);
    1592              : 
    1593              :     } else {
    1594              : 
    1595              :         // if water cooled use the input node otherwise just use outside air temperature
    1596            2 :         if (lIsWaterCooled) {
    1597              :             // most manufacturers rate have tables of entering condenser water temperature
    1598              :             // but a few use leaving condenser water temperature so we have a flag
    1599              :             // when leaving is used it uses the previous iterations value of the value
    1600            2 :             lCondReturnTemp = state.dataLoopNodes->Node(lCondReturnNodeNum).Temp;
    1601            2 :             if (lIsEnterCondensTemp) {
    1602            2 :                 calcCondTemp = lCondReturnTemp;
    1603              :             } else {
    1604            0 :                 if (this->oldCondSupplyTemp == 0) {
    1605            0 :                     this->oldCondSupplyTemp = lCondReturnTemp + 8.0; // if not previously estimated assume 8C greater than return
    1606              :                 }
    1607            0 :                 calcCondTemp = this->oldCondSupplyTemp;
    1608              :             }
    1609              :             // Set mass flow rates
    1610            2 :             lCondWaterMassFlowRate = this->DesCondMassFlowRate;
    1611            2 :             PlantUtilities::SetComponentFlowRate(state, lCondWaterMassFlowRate, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDPlantLoc);
    1612              :         } else {
    1613              :             // air cooled
    1614            0 :             state.dataLoopNodes->Node(lCondReturnNodeNum).Temp = state.dataLoopNodes->Node(lCondReturnNodeNum).OutAirDryBulb;
    1615            0 :             calcCondTemp = state.dataLoopNodes->Node(lCondReturnNodeNum).OutAirDryBulb;
    1616            0 :             lCondReturnTemp = state.dataLoopNodes->Node(lCondReturnNodeNum).Temp;
    1617            0 :             lCondWaterMassFlowRate = 0.0;
    1618            0 :             if (this->CDPlantLoc.loopNum > 0) {
    1619            0 :                 PlantUtilities::SetComponentFlowRate(
    1620            0 :                     state, lCondWaterMassFlowRate, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDPlantLoc);
    1621              :             }
    1622              :         }
    1623              : 
    1624              :         // Determine available cooling capacity using the setpoint temperature
    1625            2 :         lAvailableCoolingCapacity = lNomCoolingCap * this->CoolCapFTCurve->value(state, ChillSupplySetPointTemp, calcCondTemp);
    1626              : 
    1627              :         // Calculate current load for cooling
    1628            2 :         MyLoad = sign(max(std::abs(MyLoad), lAvailableCoolingCapacity * lMinPartLoadRat), MyLoad);
    1629            2 :         MyLoad = sign(min(std::abs(MyLoad), lAvailableCoolingCapacity * lMaxPartLoadRat), MyLoad);
    1630              : 
    1631              :         // Determine the following variables depending on if the flow has been set in
    1632              :         // the nodes (flowlock=1 to 2) or if the amount of load is still be determined (flowlock=0)
    1633              :         //    chilled water flow,
    1634              :         //    cooling load taken by the chiller, and
    1635              :         //    supply temperature
    1636            2 :         lChillWaterMassflowratemax = this->DesEvapMassFlowRate;
    1637              : 
    1638            2 :         int LoopNum = this->CWPlantLoc.loopNum;
    1639            2 :         LoopSideNum = this->CWPlantLoc.loopSideNum;
    1640            2 :         switch (state.dataPlnt->PlantLoop(LoopNum).LoopSide(LoopSideNum).FlowLock) {
    1641            0 :         case DataPlant::FlowLock::Unlocked: { // mass flow rates may be changed by loop components
    1642            0 :             this->PossibleSubcooling = false;
    1643            0 :             lCoolingLoad = std::abs(MyLoad);
    1644            0 :             if (ChillDeltaTemp != 0.0) {
    1645            0 :                 lChillWaterMassFlowRate = std::abs(lCoolingLoad / (Cp_CW * ChillDeltaTemp));
    1646            0 :                 if (lChillWaterMassFlowRate - lChillWaterMassflowratemax > DataBranchAirLoopPlant::MassFlowTolerance) {
    1647            0 :                     this->PossibleSubcooling = true;
    1648              :                 }
    1649              : 
    1650            0 :                 PlantUtilities::SetComponentFlowRate(
    1651            0 :                     state, lChillWaterMassFlowRate, this->ChillReturnNodeNum, this->ChillSupplyNodeNum, this->CWPlantLoc);
    1652              :             } else {
    1653            0 :                 lChillWaterMassFlowRate = 0.0;
    1654            0 :                 ShowRecurringWarningErrorAtEnd(state,
    1655            0 :                                                "ExhaustAbsorberChillerModel:Cooling\"" + this->Name + "\", DeltaTemp = 0 in mass flow calculation",
    1656            0 :                                                this->DeltaTempCoolErrCount);
    1657              :             }
    1658            0 :             lChillSupplyTemp = ChillSupplySetPointTemp;
    1659            0 :         } break;
    1660            2 :         case DataPlant::FlowLock::Locked: { // mass flow rates may not be changed by loop components
    1661            2 :             lChillWaterMassFlowRate = state.dataLoopNodes->Node(lChillReturnNodeNum).MassFlowRate;
    1662            2 :             if (this->PossibleSubcooling) {
    1663            0 :                 lCoolingLoad = std::abs(MyLoad);
    1664              : 
    1665            0 :                 ChillDeltaTemp = lCoolingLoad / lChillWaterMassFlowRate / Cp_CW;
    1666            0 :                 lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - ChillDeltaTemp;
    1667              :             } else {
    1668              : 
    1669            2 :                 ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - ChillSupplySetPointTemp;
    1670            2 :                 lCoolingLoad = std::abs(lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp);
    1671            2 :                 lChillSupplyTemp = ChillSupplySetPointTemp;
    1672              :             }
    1673              :             // Check that the Chiller Supply outlet temp honors both plant loop temp low limit and also the chiller low limit
    1674            2 :             if (lChillSupplyTemp < lCHWLowLimitTemp) {
    1675            2 :                 if ((state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lCHWLowLimitTemp) > DataPlant::DeltaTempTol) {
    1676            0 :                     lChillSupplyTemp = lCHWLowLimitTemp;
    1677            0 :                     ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
    1678            0 :                     lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
    1679              :                 } else {
    1680            2 :                     lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
    1681            2 :                     ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
    1682            2 :                     lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
    1683              :                 }
    1684              :             }
    1685            2 :             if (lChillSupplyTemp < state.dataLoopNodes->Node(lChillSupplyNodeNum).TempMin) {
    1686            0 :                 if ((state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - state.dataLoopNodes->Node(lChillSupplyNodeNum).TempMin) >
    1687              :                     DataPlant::DeltaTempTol) {
    1688            0 :                     lChillSupplyTemp = state.dataLoopNodes->Node(lChillSupplyNodeNum).TempMin;
    1689            0 :                     ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
    1690            0 :                     lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
    1691              :                 } else {
    1692            0 :                     lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
    1693            0 :                     ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
    1694            0 :                     lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
    1695              :                 }
    1696              :             }
    1697              : 
    1698              :             // Checks Coolingload on the basis of the machine limits.
    1699            2 :             if (lCoolingLoad > std::abs(MyLoad)) {
    1700            0 :                 if (lChillWaterMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
    1701            0 :                     lCoolingLoad = std::abs(MyLoad);
    1702            0 :                     ChillDeltaTemp = lCoolingLoad / lChillWaterMassFlowRate / Cp_CW;
    1703            0 :                     lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - ChillDeltaTemp;
    1704              :                 } else {
    1705            0 :                     lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
    1706            0 :                     ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
    1707            0 :                     lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
    1708              :                 }
    1709              :             }
    1710            2 :         } break;
    1711            0 :         default:
    1712            0 :             break;
    1713              :         }
    1714              : 
    1715              :         // Calculate operating part load ratio for cooling
    1716            2 :         PartLoadRat = min(std::abs(MyLoad) / lAvailableCoolingCapacity, lMaxPartLoadRat);
    1717            2 :         PartLoadRat = max(lMinPartLoadRat, PartLoadRat);
    1718              : 
    1719            2 :         if (lAvailableCoolingCapacity > 0.0) {
    1720            2 :             if (std::abs(MyLoad) / lAvailableCoolingCapacity < lMinPartLoadRat) {
    1721            0 :                 lCoolPartLoadRatio = MyLoad / lAvailableCoolingCapacity;
    1722              :             } else {
    1723            2 :                 lCoolPartLoadRatio = PartLoadRat;
    1724              :             }
    1725              :         } else { // Else if AvailableCoolingCapacity < 0.0
    1726            0 :             lCoolPartLoadRatio = 0.0;
    1727              :         }
    1728              : 
    1729              :         // calculate the fraction of the time period that the chiller would be running
    1730              :         // use maximum from heating and cooling sides
    1731            2 :         if (lCoolPartLoadRatio < lMinPartLoadRat || lHeatPartLoadRatio < lMinPartLoadRat) {
    1732            2 :             lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, lCoolPartLoadRatio) / lMinPartLoadRat);
    1733              :         } else {
    1734            0 :             lFractionOfPeriodRunning = 1.0;
    1735              :         }
    1736              : 
    1737              :         // Calculate thermal energy consumption for cooling
    1738              :         // Thermal Energy used for cooling availCap * TeFIR * TeFIR-FT * TeFIR-FPLR
    1739            6 :         lCoolThermalEnergyUseRate = lAvailableCoolingCapacity * lThermalEnergyCoolRatio *
    1740            2 :                                     this->ThermalEnergyCoolFTCurve->value(state, lChillSupplyTemp, calcCondTemp) *
    1741            2 :                                     this->ThermalEnergyCoolFPLRCurve->value(state, lCoolPartLoadRatio) * lFractionOfPeriodRunning;
    1742              : 
    1743              :         // Calculate electric parasitics used
    1744              :         // based on nominal capacity, not available capacity,
    1745              :         // electric used for cooling nomCap * %OP * EIR * EIR-FT * EIR-FPLR
    1746            6 :         lCoolElectricPower = lNomCoolingCap * lElecCoolRatio * lFractionOfPeriodRunning *
    1747            2 :                              this->ElecCoolFTCurve->value(state, lChillSupplyTemp, calcCondTemp) *
    1748            2 :                              this->ElecCoolFPLRCurve->value(state, lCoolPartLoadRatio);
    1749              : 
    1750              :         // determine condenser load which is cooling load plus the
    1751              :         // ThermalEnergy used for cooling plus
    1752              :         // the electricity used
    1753            2 :         lTowerLoad = lCoolingLoad + lCoolThermalEnergyUseRate / lThermalEnergyHeatRatio + lCoolElectricPower;
    1754              : 
    1755            2 :         lExhaustInTemp = state.dataLoopNodes->Node(lExhaustAirInletNodeNum).Temp;
    1756            2 :         lExhaustInFlow = state.dataLoopNodes->Node(lExhaustAirInletNodeNum).MassFlowRate;
    1757            2 :         CpAir = Psychrometrics::PsyCpAirFnW(lExhaustAirHumRat);
    1758            2 :         lExhHeatRecPotentialCool = lExhaustInFlow * CpAir * (lExhaustInTemp - AbsLeavingTemp);
    1759              :         // If Microturbine Exhaust temperature and flow rate is not sufficient to run the chiller, then chiller will not run
    1760              :         // lCoolThermalEnergyUseRate , lTowerLoad and  lCoolElectricPower will be set to 0.0
    1761              : 
    1762            2 :         if (lExhHeatRecPotentialCool < lCoolThermalEnergyUseRate) {
    1763            0 :             if (this->ExhTempLTAbsLeavingTempIndex == 0) {
    1764            0 :                 ShowWarningError(state, format("ChillerHeater:Absorption:DoubleEffect \"{}\"", this->Name));
    1765            0 :                 ShowContinueError(state,
    1766              :                                   "...Exhaust temperature and flow input from Micro Turbine is not sufficient during cooling to run the chiller ");
    1767            0 :                 ShowContinueError(state, format("...Value of Exhaust air inlet temp ={:.4T} C.", lExhaustInTemp));
    1768            0 :                 ShowContinueError(state, format("... and Exhaust air flow rate of {:.2T} kg/s.", lExhaustInFlow));
    1769            0 :                 ShowContinueError(state, format("...Value of minimum absorber leaving temp ={:.4T} C.", AbsLeavingTemp));
    1770            0 :                 ShowContinueError(state,
    1771              :                                   "...Either increase the Exhaust temperature (min required = 350 C )  or flow or both of Micro Turbine to meet "
    1772              :                                   "the min available potential criteria.");
    1773            0 :                 ShowContinueErrorTimeStamp(state, "... Simulation will continue.");
    1774              :             }
    1775            0 :             ShowRecurringWarningErrorAtEnd(
    1776              :                 state,
    1777            0 :                 "ChillerHeater:Absorption:DoubleEffect \"" + this->Name +
    1778              :                     "\": Exhaust temperature from Micro Turbine is not sufficient to run the chiller during cooling warning continues...",
    1779            0 :                 this->ExhTempLTAbsLeavingTempIndex,
    1780              :                 lExhaustInTemp,
    1781              :                 AbsLeavingTemp);
    1782              :             // If exhaust is not available, it means the available thermal energy is 0.0 and Chiller is not available
    1783            0 :             lCoolThermalEnergyUseRate = 0.0;
    1784            0 :             lTowerLoad = 0.0;
    1785            0 :             lCoolElectricPower = 0.0;
    1786            0 :             lChillSupplyTemp = lChillReturnTemp;
    1787            0 :             lCondSupplyTemp = lCondReturnTemp;
    1788            0 :             lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, lCoolPartLoadRatio) / lMinPartLoadRat);
    1789              :         }
    1790              :         // for water cooled condenser make sure enough flow rate
    1791              :         // for air cooled condenser just set supply to return temperature
    1792            2 :         if (lIsWaterCooled) {
    1793            2 :             if (lCondWaterMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
    1794            0 :                 lCondSupplyTemp = lCondReturnTemp + lTowerLoad / (lCondWaterMassFlowRate * Cp_CD);
    1795              :             } else {
    1796            2 :                 if (this->lCondWaterMassFlowRate_Index == 0) {
    1797            2 :                     ShowSevereError(state,
    1798            2 :                                     format("CalcExhaustAbsorberChillerModel: Condenser flow = 0, for Exhaust Absorber Chiller={}", this->Name));
    1799            3 :                     ShowContinueErrorTimeStamp(state, "");
    1800              :                     // ShowFatalError(state, "Program Terminates due to previous error condition.");
    1801              :                 }
    1802           16 :                 ShowRecurringSevereErrorAtEnd(state,
    1803            4 :                                               format("CalcExhaustAbsorberChillerModel: Condenser flow = 0, for Exhaust Absorber Chiller={}: "
    1804              :                                                      "Condenser flow rate = 0 severe error warning continues...",
    1805            2 :                                                      this->Name),                // Message automatically written to "error file" at end of simulation
    1806            2 :                                               this->lCondWaterMassFlowRate_Index // Recurring message index, if zero, next available index is assigned
    1807              :                 );
    1808              :             }
    1809              :         } else {
    1810            0 :             lCondSupplyTemp = lCondReturnTemp; // if air cooled condenser just set supply and return to same temperature
    1811              :         }
    1812              : 
    1813              :         // save the condenser water supply temperature for next iteration if that is used in lookup
    1814              :         // and if capacity is large enough error than report problem
    1815            2 :         this->oldCondSupplyTemp = lCondSupplyTemp;
    1816            2 :         if (!lIsEnterCondensTemp) {
    1817              :             // calculate the fraction of the estimated error between the capacity based on the previous
    1818              :             // iteration's value of condenser supply temperature and the actual calculated condenser supply
    1819              :             // temperature.  If this becomes too common then may need to iterate a solution instead of
    1820              :             // relying on previous iteration method.
    1821            0 :             revisedEstimateAvailCap = lNomCoolingCap * this->CoolCapFTCurve->value(state, ChillSupplySetPointTemp, lCondSupplyTemp);
    1822            0 :             if (revisedEstimateAvailCap > 0.0) {
    1823            0 :                 errorAvailCap = std::abs((revisedEstimateAvailCap - lAvailableCoolingCapacity) / revisedEstimateAvailCap);
    1824            0 :                 if (errorAvailCap > 0.05) { // if more than 5% error in estimate
    1825            0 :                     ShowRecurringWarningErrorAtEnd(state,
    1826            0 :                                                    "ExhaustAbsorberChillerModel:\"" + this->Name + "\", poor Condenser Supply Estimate",
    1827            0 :                                                    this->CondErrCount,
    1828              :                                                    errorAvailCap,
    1829              :                                                    errorAvailCap);
    1830              :                 }
    1831              :             }
    1832              :         }
    1833              :     } // IF(MyLoad>=0 .OR. .NOT. RunFlag)
    1834              :     // Write into the Report Variables except for nodes
    1835            2 :     this->CoolingLoad = lCoolingLoad;
    1836            2 :     this->TowerLoad = lTowerLoad;
    1837            2 :     this->CoolThermalEnergyUseRate = lCoolThermalEnergyUseRate;
    1838            2 :     this->CoolElectricPower = lCoolElectricPower;
    1839            2 :     this->CondReturnTemp = lCondReturnTemp;
    1840            2 :     this->ChillReturnTemp = lChillReturnTemp;
    1841            2 :     this->CondSupplyTemp = lCondSupplyTemp;
    1842            2 :     this->ChillSupplyTemp = lChillSupplyTemp;
    1843            2 :     this->ChillWaterFlowRate = lChillWaterMassFlowRate;
    1844            2 :     this->CondWaterFlowRate = lCondWaterMassFlowRate;
    1845            2 :     this->CoolPartLoadRatio = lCoolPartLoadRatio;
    1846            2 :     this->CoolingCapacity = lAvailableCoolingCapacity;
    1847            2 :     this->FractionOfPeriodRunning = lFractionOfPeriodRunning;
    1848            2 :     this->ExhaustInTemp = lExhaustInTemp;
    1849            2 :     this->ExhaustInFlow = lExhaustInFlow;
    1850            2 :     this->ExhHeatRecPotentialCool = lExhHeatRecPotentialCool;
    1851              : 
    1852              :     // write the combined heating and cooling ThermalEnergy used and electric used
    1853            2 :     this->ThermalEnergyUseRate = lCoolThermalEnergyUseRate + lHeatThermalEnergyUseRate;
    1854            2 :     this->ElectricPower = lCoolElectricPower + lHeatElectricPower;
    1855            2 : }
    1856              : 
    1857            1 : void ExhaustAbsorberSpecs::calcHeater(EnergyPlusData &state, Real64 &MyLoad, bool RunFlag)
    1858              : {
    1859              : 
    1860              :     // SUBROUTINE INFORMATION:
    1861              :     //       AUTHOR         Jason Glazer and Michael J. Witte
    1862              :     //       DATE WRITTEN   March 2001
    1863              :     //       MODIFIED       Mahabir Bhandari, ORNL, Aug 2011, modified to accommodate exhaust fired double effect absorption chiller
    1864              : 
    1865              :     // PURPOSE OF THIS SUBROUTINE:
    1866              :     // Simulate a Exhaust fired (Exhaust consuming) absorption chiller using
    1867              :     // curves and inputs similar to DOE-2.1e
    1868              : 
    1869              :     // METHODOLOGY EMPLOYED:
    1870              :     // Curve fit of performance data
    1871              : 
    1872              :     // REFERENCES:
    1873              :     // 1.  DOE-2.1e Supplement and source code
    1874              :     // 2.  CoolTools GasMod work
    1875              : 
    1876              :     // Locals
    1877              :     // SUBROUTINE ARGUMENT DEFINITIONS:
    1878              :     // FlowLock = 0  if mass flow rates may be changed by loop components
    1879              :     // FlowLock = 1  if mass flow rates may not be changed by loop components
    1880              :     // FlowLock = 2  if overloaded and mass flow rates has changed to a small amount and Tout drops
    1881              :     //                 below Setpoint
    1882              : 
    1883              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1884            1 :     Real64 constexpr AbsLeavingTemp(176.667); // C - Minimum temperature leaving the Chiller absorber (350 F)
    1885              :     static constexpr std::string_view RoutineName("CalcExhaustAbsorberHeaterModel");
    1886              : 
    1887              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1888              :     // Local copies of ExhaustAbsorberSpecs Type
    1889              :     // all variables that are local copies of data structure
    1890              :     // variables are prefaced with an "l" for local.
    1891              :     // Local copies of ExhaustAbsorberReportVars Type
    1892            1 :     Real64 lHeatingLoad(0.0);              // heating load on the chiller
    1893            1 :     Real64 lHeatThermalEnergyUseRate(0.0); // instantaneous use of thermal energy for period for heating
    1894            1 :     Real64 lHeatElectricPower(0.0);        // parasitic electric power used  for heating
    1895            1 :     Real64 lHotWaterSupplyTemp(0.0);       // reporting: hot water supply (outlet) temperature
    1896            1 :     Real64 lHeatPartLoadRatio(0.0);        // operating part load ratio (load/capacity for heating)
    1897            1 :     Real64 lAvailableHeatingCapacity(0.0); // current heating capacity
    1898            1 :     Real64 lFractionOfPeriodRunning(0.0);
    1899            1 :     Real64 lExhaustInTemp(0.0);           // Exhaust inlet temperature
    1900            1 :     Real64 lExhaustInFlow(0.0);           // Exhaust inlet flow rate
    1901            1 :     Real64 lExhHeatRecPotentialHeat(0.0); // Exhaust heat recovery potential
    1902              : 
    1903              :     // initialize entering conditions
    1904            1 :     auto &hwPlantLoop = state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum);
    1905            0 :     const Real64 HeatSupplySetPointTemp = [this, &hwPlantLoop, &state]() {
    1906            1 :         switch (hwPlantLoop.LoopDemandCalcScheme) {
    1907            1 :         case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1908            1 :             return state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPoint;
    1909              :         }
    1910            0 :         case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1911            0 :             return state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPointLo;
    1912              :         }
    1913            0 :         default: {
    1914            0 :             assert(false);
    1915              :             return 0.0;
    1916              :         }
    1917              :         }
    1918            1 :     }();
    1919              : 
    1920            1 :     auto const &heatReturnNode = state.dataLoopNodes->Node(this->HeatReturnNodeNum);
    1921            1 :     Real64 const HeatDeltaTemp = std::abs(heatReturnNode.Temp - HeatSupplySetPointTemp);
    1922              :     // reporting: hot water mass flow rate
    1923            1 :     Real64 lHotWaterMassFlowRate = heatReturnNode.MassFlowRate;
    1924              : 
    1925              :     // If no loop demand or Absorber OFF, return
    1926              :     // will need to modify when absorber can act as a boiler
    1927            1 :     if (MyLoad <= 0 || !RunFlag) {
    1928              :         // set node temperatures
    1929            0 :         lHotWaterSupplyTemp = heatReturnNode.Temp;
    1930            0 :         lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, this->CoolPartLoadRatio) / this->MinPartLoadRat);
    1931              :     } else {
    1932              : 
    1933            1 :         Real64 const Cp_HW = hwPlantLoop.glycol->getSpecificHeat(state, heatReturnNode.Temp, RoutineName);
    1934              : 
    1935              :         // Determine available heating capacity using the current cooling load
    1936            1 :         lAvailableHeatingCapacity =
    1937            1 :             this->NomHeatCoolRatio * this->NomCoolingCap * this->HeatCapFCoolCurve->value(state, (this->CoolingLoad / this->NomCoolingCap));
    1938              : 
    1939              :         // Calculate current load for heating
    1940            1 :         MyLoad = sign(max(std::abs(MyLoad), this->HeatingCapacity * this->MinPartLoadRat), MyLoad);
    1941            1 :         MyLoad = sign(min(std::abs(MyLoad), this->HeatingCapacity * this->MaxPartLoadRat), MyLoad);
    1942              : 
    1943              :         // Determine the following variables depending on if the flow has been set in
    1944              :         // the nodes (flowlock=1 to 2) or if the amount of load is still be determined (flowlock=0)
    1945              :         //    chilled water flow,
    1946              :         //    cooling load taken by the chiller, and
    1947              :         //    supply temperature
    1948            1 :         switch (hwPlantLoop.LoopSide(this->HWPlantLoc.loopSideNum).FlowLock) {
    1949            0 :         case DataPlant::FlowLock::Unlocked: { // mass flow rates may be changed by loop components
    1950            0 :             lHeatingLoad = std::abs(MyLoad);
    1951            0 :             if (HeatDeltaTemp != 0) {
    1952            0 :                 lHotWaterMassFlowRate = std::abs(lHeatingLoad / (Cp_HW * HeatDeltaTemp));
    1953              : 
    1954            0 :                 PlantUtilities::SetComponentFlowRate(
    1955            0 :                     state, lHotWaterMassFlowRate, this->HeatReturnNodeNum, this->HeatSupplyNodeNum, this->HWPlantLoc);
    1956              : 
    1957              :             } else {
    1958            0 :                 lHotWaterMassFlowRate = 0.0;
    1959            0 :                 ShowRecurringWarningErrorAtEnd(
    1960              :                     state,
    1961            0 :                     format("ExhaustAbsorberChillerModel:Heating\"{}\", DeltaTemp = 0 in mass flow calculation", this->Name),
    1962            0 :                     this->DeltaTempHeatErrCount);
    1963              :             }
    1964            0 :             lHotWaterSupplyTemp = HeatSupplySetPointTemp;
    1965            0 :         } break;
    1966            1 :         case DataPlant::FlowLock::Locked: { // mass flow rates may not be changed by loop components
    1967            1 :             lHotWaterSupplyTemp = HeatSupplySetPointTemp;
    1968            1 :             lHeatingLoad = std::abs(lHotWaterMassFlowRate * Cp_HW * HeatDeltaTemp);
    1969            1 :         } break;
    1970            0 :         default:
    1971            0 :             break;
    1972              :         }
    1973              : 
    1974              :         // Calculate operating part load ratio for cooling
    1975            1 :         if (lAvailableHeatingCapacity <= 0.0) {
    1976            1 :             lAvailableHeatingCapacity = 0.0;
    1977            1 :             lHeatPartLoadRatio = 0.0;
    1978              :         } else {
    1979            0 :             lHeatPartLoadRatio = lHeatingLoad / lAvailableHeatingCapacity;
    1980              :         }
    1981              : 
    1982              :         // Calculate ThermalEnergy consumption for heating
    1983              :         // ThermalEnergy used for heating availCap * HIR * HIR-FT * HIR-FPLR
    1984            1 :         lHeatThermalEnergyUseRate =
    1985            1 :             lAvailableHeatingCapacity * this->ThermalEnergyHeatRatio * this->ThermalEnergyHeatFHPLRCurve->value(state, lHeatPartLoadRatio);
    1986              : 
    1987              :         // calculate the fraction of the time period that the chiller would be running
    1988              :         // use maximum from heating and cooling sides
    1989            1 :         lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, this->CoolPartLoadRatio) / this->MinPartLoadRat);
    1990              : 
    1991              :         // Calculate electric parasitics used
    1992              :         // for heating based on nominal capacity not available capacity
    1993            1 :         lHeatElectricPower = this->NomCoolingCap * this->NomHeatCoolRatio * this->ElecHeatRatio * lFractionOfPeriodRunning;
    1994              :         // Coordinate electric parasitics for heating and cooling to avoid double counting
    1995              :         // Total electric is the max of heating electric or cooling electric
    1996              :         // If heating electric is greater, leave cooling electric and subtract if off of heating elec
    1997              :         // If cooling electric is greater, set heating electric to zero
    1998              : 
    1999            1 :         lExhaustInTemp = state.dataLoopNodes->Node(this->ExhaustAirInletNodeNum).Temp;
    2000            1 :         lExhaustInFlow = state.dataLoopNodes->Node(this->ExhaustAirInletNodeNum).MassFlowRate;
    2001            1 :         Real64 const lExhaustAirHumRat = state.dataLoopNodes->Node(this->ExhaustAirInletNodeNum).HumRat;
    2002            1 :         Real64 const CpAir = Psychrometrics::PsyCpAirFnW(lExhaustAirHumRat);
    2003            1 :         lExhHeatRecPotentialHeat = lExhaustInFlow * CpAir * (lExhaustInTemp - AbsLeavingTemp);
    2004            1 :         if (lExhHeatRecPotentialHeat < lHeatThermalEnergyUseRate) {
    2005            0 :             if (this->ExhTempLTAbsLeavingHeatingTempIndex == 0) {
    2006            0 :                 ShowWarningError(state, format("ChillerHeater:Absorption:DoubleEffect \"{}\"", this->Name));
    2007            0 :                 ShowContinueError(state,
    2008              :                                   "...Exhaust temperature and flow input from Micro Turbine is not sufficient to run the chiller during heating .");
    2009            0 :                 ShowContinueError(state, format("...Value of Exhaust air inlet temp ={:.4T} C.", lExhaustInTemp));
    2010            0 :                 ShowContinueError(state, format("... and Exhaust air flow rate of {:.2T} kg/s.", lExhaustInFlow));
    2011            0 :                 ShowContinueError(state, format("...Value of minimum absorber leaving temp ={:.4T} C.", AbsLeavingTemp));
    2012            0 :                 ShowContinueError(state,
    2013              :                                   "...Either increase the Exhaust temperature (min required = 350 C) or flow or both of Micro Turbine to meet "
    2014              :                                   "the min available potential criteria.");
    2015            0 :                 ShowContinueErrorTimeStamp(state, "... Simulation will continue.");
    2016              :             }
    2017            0 :             ShowRecurringWarningErrorAtEnd(state,
    2018            0 :                                            format("ChillerHeater:Absorption:DoubleEffect \"{}\": Exhaust temperature from Micro Turbine is not "
    2019              :                                                   "sufficient to run the chiller during heating warning continues...",
    2020            0 :                                                   this->Name),
    2021            0 :                                            this->ExhTempLTAbsLeavingHeatingTempIndex,
    2022              :                                            lExhaustInTemp,
    2023              :                                            AbsLeavingTemp);
    2024              :             // If exhaust is not available, it means the available thermal energy is 0.0 and Chiller is not available
    2025            0 :             lHeatThermalEnergyUseRate = 0.0;
    2026            0 :             lHeatElectricPower = 0.0;
    2027            0 :             lHotWaterSupplyTemp = heatReturnNode.Temp;
    2028            0 :             lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, this->CoolPartLoadRatio) / this->MinPartLoadRat);
    2029              :         }
    2030              : 
    2031            1 :         if (lHeatElectricPower <= this->CoolElectricPower) {
    2032            0 :             lHeatElectricPower = 0.0;
    2033              :         } else {
    2034            1 :             lHeatElectricPower -= this->CoolElectricPower;
    2035              :         }
    2036              : 
    2037              :     } // IF(MyLoad==0 .OR. .NOT. RunFlag)
    2038              :     // Write into the Report Variables except for nodes
    2039            1 :     this->HeatingLoad = lHeatingLoad;
    2040            1 :     this->HeatThermalEnergyUseRate = lHeatThermalEnergyUseRate;
    2041            1 :     this->HeatElectricPower = lHeatElectricPower;
    2042            1 :     this->HotWaterReturnTemp = heatReturnNode.Temp;
    2043            1 :     this->HotWaterSupplyTemp = lHotWaterSupplyTemp;
    2044            1 :     this->HotWaterFlowRate = lHotWaterMassFlowRate;
    2045            1 :     this->HeatPartLoadRatio = lHeatPartLoadRatio;
    2046            1 :     this->HeatingCapacity = lAvailableHeatingCapacity;
    2047            1 :     this->FractionOfPeriodRunning = lFractionOfPeriodRunning;
    2048              : 
    2049              :     // write the combined heating and cooling ThermalEnergy used and electric used
    2050            1 :     this->ThermalEnergyUseRate = this->CoolThermalEnergyUseRate + lHeatThermalEnergyUseRate;
    2051            1 :     this->ElectricPower = this->CoolElectricPower + lHeatElectricPower;
    2052            1 :     this->ExhaustInTemp = lExhaustInTemp;
    2053            1 :     this->ExhaustInFlow = lExhaustInFlow;
    2054            1 :     this->ExhHeatRecPotentialHeat = lExhHeatRecPotentialHeat;
    2055            1 : }
    2056              : 
    2057            0 : void ExhaustAbsorberSpecs::updateCoolRecords(EnergyPlusData &state, Real64 MyLoad, bool RunFlag)
    2058              : {
    2059              : 
    2060              :     // SUBROUTINE INFORMATION:
    2061              :     //       AUTHOR         Jason Glazer
    2062              :     //       DATE WRITTEN   March 2001
    2063              : 
    2064            0 :     if (MyLoad == 0 || !RunFlag) {
    2065            0 :         state.dataLoopNodes->Node(this->ChillSupplyNodeNum).Temp = state.dataLoopNodes->Node(this->ChillReturnNodeNum).Temp;
    2066            0 :         if (this->isWaterCooled) {
    2067            0 :             state.dataLoopNodes->Node(this->CondSupplyNodeNum).Temp = state.dataLoopNodes->Node(this->CondReturnNodeNum).Temp;
    2068              :         }
    2069            0 :         state.dataLoopNodes->Node(this->ExhaustAirInletNodeNum).Temp = state.dataLoopNodes->Node(this->ExhaustAirInletNodeNum).Temp;
    2070            0 :         state.dataLoopNodes->Node(this->ExhaustAirInletNodeNum).MassFlowRate = this->ExhaustInFlow;
    2071              :     } else {
    2072            0 :         state.dataLoopNodes->Node(this->ChillSupplyNodeNum).Temp = this->ChillSupplyTemp;
    2073            0 :         if (this->isWaterCooled) {
    2074            0 :             state.dataLoopNodes->Node(this->CondSupplyNodeNum).Temp = this->CondSupplyTemp;
    2075              :         }
    2076            0 :         state.dataLoopNodes->Node(this->ExhaustAirInletNodeNum).Temp = this->ExhaustInTemp;
    2077            0 :         state.dataLoopNodes->Node(this->ExhaustAirInletNodeNum).MassFlowRate = this->ExhaustInFlow;
    2078              :     }
    2079              : 
    2080              :     // convert power to energy and instantaneous use to use over the time step
    2081            0 :     Real64 RptConstant = state.dataHVACGlobal->TimeStepSysSec;
    2082            0 :     this->CoolingEnergy = this->CoolingLoad * RptConstant;
    2083            0 :     this->TowerEnergy = this->TowerLoad * RptConstant;
    2084            0 :     this->ThermalEnergy = this->ThermalEnergyUseRate * RptConstant;
    2085            0 :     this->CoolThermalEnergy = this->CoolThermalEnergyUseRate * RptConstant;
    2086            0 :     this->ElectricEnergy = this->ElectricPower * RptConstant;
    2087            0 :     this->CoolElectricEnergy = this->CoolElectricPower * RptConstant;
    2088            0 :     if (this->CoolThermalEnergyUseRate != 0.0) {
    2089            0 :         this->ThermalEnergyCOP = this->CoolingLoad / this->CoolThermalEnergyUseRate;
    2090              :     } else {
    2091            0 :         this->ThermalEnergyCOP = 0.0;
    2092              :     }
    2093            0 : }
    2094              : 
    2095            0 : void ExhaustAbsorberSpecs::updateHeatRecords(EnergyPlusData &state, Real64 MyLoad, bool RunFlag)
    2096              : {
    2097              : 
    2098              :     // SUBROUTINE INFORMATION:
    2099              :     //       AUTHOR         Jason Glazer
    2100              :     //       DATE WRITTEN   March 2001
    2101              : 
    2102            0 :     if (MyLoad == 0 || !RunFlag) {
    2103            0 :         state.dataLoopNodes->Node(this->HeatSupplyNodeNum).Temp = state.dataLoopNodes->Node(this->HeatReturnNodeNum).Temp;
    2104              :     } else {
    2105            0 :         state.dataLoopNodes->Node(this->HeatSupplyNodeNum).Temp = this->HotWaterSupplyTemp;
    2106              :     }
    2107              : 
    2108              :     // convert power to energy and instantaneous use to use over the time step
    2109            0 :     Real64 RptConstant = state.dataHVACGlobal->TimeStepSysSec;
    2110            0 :     this->HeatingEnergy = this->HeatingLoad * RptConstant;
    2111            0 :     this->ThermalEnergy = this->ThermalEnergyUseRate * RptConstant;
    2112            0 :     this->HeatThermalEnergy = this->HeatThermalEnergyUseRate * RptConstant;
    2113            0 :     this->ElectricEnergy = this->ElectricPower * RptConstant;
    2114            0 :     this->HeatElectricEnergy = this->HeatElectricPower * RptConstant;
    2115            0 : }
    2116              : 
    2117            0 : void ExhaustAbsorberSpecs::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
    2118              : {
    2119            0 : }
    2120              : 
    2121              : } // namespace EnergyPlus::ChillerExhaustAbsorption
        

Generated by: LCOV version 2.0-1