LCOV - code coverage report
Current view: top level - EnergyPlus - ChillerExhaustAbsorption.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 645 999 64.6 %
Date: 2024-08-23 23:50:59 Functions: 17 18 94.4 %

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

Generated by: LCOV version 1.14