LCOV - code coverage report
Current view: top level - EnergyPlus - ChillerGasAbsorption.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 607 937 64.8 %
Date: 2023-01-17 19:17:23 Functions: 17 18 94.4 %

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

Generated by: LCOV version 1.13