LCOV - code coverage report
Current view: top level - EnergyPlus - ChillerAbsorption.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 48.0 % 922 443
Test Date: 2025-06-02 07:23:51 Functions: 100.0 % 15 15

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cassert>
      50              : #include <cmath>
      51              : 
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Array.functions.hh>
      54              : #include <ObjexxFCL/Fmath.hh>
      55              : 
      56              : // EnergyPlus Headers
      57              : #include <EnergyPlus/Autosizing/Base.hh>
      58              : #include <EnergyPlus/BranchNodeConnections.hh>
      59              : #include <EnergyPlus/ChillerAbsorption.hh>
      60              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      61              : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
      62              : #include <EnergyPlus/DataHVACGlobals.hh>
      63              : #include <EnergyPlus/DataIPShortCuts.hh>
      64              : #include <EnergyPlus/DataLoopNode.hh>
      65              : #include <EnergyPlus/DataSizing.hh>
      66              : #include <EnergyPlus/EMSManager.hh>
      67              : #include <EnergyPlus/FaultsManager.hh>
      68              : #include <EnergyPlus/FluidProperties.hh>
      69              : #include <EnergyPlus/GlobalNames.hh>
      70              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      71              : #include <EnergyPlus/NodeInputManager.hh>
      72              : #include <EnergyPlus/OutputProcessor.hh>
      73              : #include <EnergyPlus/OutputReportPredefined.hh>
      74              : #include <EnergyPlus/Plant/DataPlant.hh>
      75              : #include <EnergyPlus/Plant/PlantLocation.hh>
      76              : #include <EnergyPlus/PlantUtilities.hh>
      77              : #include <EnergyPlus/UtilityRoutines.hh>
      78              : 
      79              : namespace EnergyPlus::ChillerAbsorption {
      80              : 
      81              : // MODULE INFORMATION:
      82              : //       AUTHOR         Dan Fisher
      83              : //       DATE WRITTEN   Nov. 2000
      84              : 
      85              : // PURPOSE OF THIS MODULE:
      86              : // This module simulates the performance of the BLAST absorbers.
      87              : 
      88              : // METHODOLOGY EMPLOYED:
      89              : // Once the PlantLoopManager determines that the BLAST absorber
      90              : // is available to meet a loop cooling demand, it calls SimBLAST
      91              : // absorber which in turn calls the appropriate Absorption Chiller model.
      92              : // All Absorption Chiller models are based on a polynomial fit of Absorber
      93              : // performance data.
      94              : 
      95              : // REFERENCES:
      96              : // 1. BLAST Users Manual
      97              : 
      98              : // OTHER NOTES:
      99              : // The Absorber program from the BLAST family of software can be used
     100              : // to generate the coefficients for the model.
     101              : 
     102              : const char *calcChillerAbsorption("CALC Chiller:Absorption ");
     103              : const char *moduleObjectType("Chiller:Absorption");
     104              : 
     105            4 : BLASTAbsorberSpecs *BLASTAbsorberSpecs::factory(EnergyPlusData &state, std::string const &objectName)
     106              : {
     107              :     // Process the input data
     108            4 :     if (state.dataChillerAbsorber->getInput) {
     109            2 :         GetBLASTAbsorberInput(state);
     110            2 :         state.dataChillerAbsorber->getInput = false;
     111              :     }
     112              :     // Now look for this particular object
     113            4 :     auto thisAbs = std::find_if(state.dataChillerAbsorber->absorptionChillers.begin(),
     114            4 :                                 state.dataChillerAbsorber->absorptionChillers.end(),
     115            4 :                                 [&objectName](const BLASTAbsorberSpecs &myAbs) { return myAbs.Name == objectName; });
     116            4 :     if (thisAbs != state.dataChillerAbsorber->absorptionChillers.end()) {
     117            4 :         return thisAbs;
     118              :     }
     119              :     // If we didn't find it, fatal
     120              :     ShowFatalError(state, format("LocalBlastAbsorberFactory: Error getting inputs for object named: {}", objectName)); // LCOV_EXCL_LINE
     121              :     // Shut up the compiler
     122              :     return nullptr; // LCOV_EXCL_LINE
     123              : }
     124              : 
     125        77796 : void BLASTAbsorberSpecs::simulate(
     126              :     EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag)
     127              : {
     128              : 
     129        77796 :     this->EquipFlowCtrl = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
     130        77796 :                               .LoopSide(calledFromLocation.loopSideNum)
     131        77796 :                               .Branch(calledFromLocation.branchNum)
     132        77796 :                               .Comp(calledFromLocation.compNum)
     133        77796 :                               .FlowCtrl;
     134              : 
     135        77796 :     if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) {
     136              :         // called from dominant chilled water connection loop side
     137              : 
     138              :         // Calculate Load
     139        38898 :         this->initialize(state, RunFlag, CurLoad);
     140        38898 :         this->calculate(state, CurLoad, RunFlag);
     141        38898 :         this->updateRecords(state, CurLoad, RunFlag);
     142              : 
     143        38898 :     } else if (calledFromLocation.loopNum == this->CDPlantLoc.loopNum) {
     144              :         // Called from non-dominant condenser water connection loop side
     145        38898 :         PlantUtilities::UpdateChillerComponentCondenserSide(state,
     146        38898 :                                                             calledFromLocation.loopNum,
     147        38898 :                                                             calledFromLocation.loopSideNum,
     148              :                                                             DataPlant::PlantEquipmentType::Chiller_Absorption,
     149              :                                                             this->CondInletNodeNum,
     150              :                                                             this->CondOutletNodeNum,
     151              :                                                             this->Report.QCond,
     152              :                                                             this->Report.CondInletTemp,
     153              :                                                             this->Report.CondOutletTemp,
     154              :                                                             this->Report.Condmdot,
     155              :                                                             FirstHVACIteration);
     156              : 
     157            0 :     } else if (calledFromLocation.loopNum == this->GenPlantLoc.loopNum) {
     158              :         // Called from non-dominant generator hot water or steam connection loop side
     159            0 :         PlantUtilities::UpdateAbsorberChillerComponentGeneratorSide(state,
     160            0 :                                                                     calledFromLocation.loopNum,
     161            0 :                                                                     calledFromLocation.loopSideNum,
     162              :                                                                     DataPlant::PlantEquipmentType::Chiller_Absorption,
     163              :                                                                     this->GeneratorInletNodeNum,
     164              :                                                                     this->GeneratorOutletNodeNum,
     165              :                                                                     this->GenHeatSourceType,
     166              :                                                                     this->Report.QGenerator,
     167              :                                                                     this->Report.SteamMdot,
     168              :                                                                     FirstHVACIteration);
     169              : 
     170              :     } else {
     171            0 :         ShowFatalError(state,
     172            0 :                        format("SimBLASTAbsorber: Invalid LoopNum passed={}, Unit name={}, stored chilled water loop={}, stored condenser water "
     173              :                               "loop={}, stored generator loop={}",
     174            0 :                               calledFromLocation.loopNum,
     175            0 :                               this->Name,
     176            0 :                               this->CWPlantLoc.loopNum,
     177            0 :                               this->CDPlantLoc.loopNum,
     178            0 :                               this->GenPlantLoc.loopNum));
     179              :     }
     180        77796 : }
     181              : 
     182           20 : void BLASTAbsorberSpecs::onInitLoopEquip(EnergyPlusData &state, const PlantLocation &calledFromLocation)
     183              : {
     184           20 :     bool runFlag = true;
     185           20 :     Real64 myLoad = 0.0;
     186              : 
     187           20 :     this->initialize(state, runFlag, myLoad);
     188              : 
     189           20 :     if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) {
     190           10 :         this->sizeChiller(state);
     191              :     }
     192           20 : }
     193              : 
     194           20 : void BLASTAbsorberSpecs::getDesignCapacities(
     195              :     EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
     196              : {
     197           20 :     if (calledFromLocation.loopNum == this->CWPlantLoc.loopNum) {
     198           10 :         this->sizeChiller(state);
     199           10 :         MinLoad = this->NomCap * this->MinPartLoadRat;
     200           10 :         MaxLoad = this->NomCap * this->MaxPartLoadRat;
     201           10 :         OptLoad = this->NomCap * this->OptPartLoadRat;
     202              :     } else {
     203           10 :         MinLoad = 0.0;
     204           10 :         MaxLoad = 0.0;
     205           10 :         OptLoad = 0.0;
     206              :     }
     207           20 : }
     208              : 
     209            4 : void BLASTAbsorberSpecs::getSizingFactor(Real64 &sizFac)
     210              : {
     211            4 :     sizFac = this->SizFac;
     212            4 : }
     213              : 
     214           20 : void BLASTAbsorberSpecs::getDesignTemperatures(Real64 &tempDesCondIn, [[maybe_unused]] Real64 &TempDesEvapOut)
     215              : {
     216           20 :     tempDesCondIn = this->TempDesCondIn;
     217           20 : }
     218              : 
     219            2 : void GetBLASTAbsorberInput(EnergyPlusData &state)
     220              : {
     221              :     // SUBROUTINE INFORMATION:
     222              :     //       AUTHOR:          Dan Fisher
     223              :     //       DATE WRITTEN:    April 1998
     224              :     //       MODIFIED:        R. Raustad May 2008 - added generator nodes
     225              : 
     226              :     // PURPOSE OF THIS SUBROUTINE:
     227              :     // This routine will get the input
     228              :     // required by the BLAST Absorption chiller models as shown below:
     229              : 
     230              :     // METHODOLOGY EMPLOYED:
     231              :     // EnergyPlus input processor
     232              : 
     233            2 :     constexpr const char *RoutineName("GetBLASTAbsorberInput: "); // include trailing blank space
     234              : 
     235            2 :     int NumAlphas = 0; // Number of elements in the alpha array
     236            2 :     int NumNums = 0;   // Number of elements in the numeric array
     237            2 :     int IOStat = 0;    // IO Status when calling get input subroutine
     238            2 :     bool ErrorsFound(false);
     239              : 
     240            2 :     state.dataIPShortCut->cCurrentModuleObject = moduleObjectType;
     241              : 
     242            2 :     int numAbsorbers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
     243              : 
     244            2 :     if (numAbsorbers <= 0) {
     245            0 :         ShowSevereError(state, format("No {} equipment specified in input file", state.dataIPShortCut->cCurrentModuleObject));
     246              :         // See if load distribution manager has already gotten the input
     247            0 :         ErrorsFound = true;
     248              :     }
     249              : 
     250            2 :     if (allocated(state.dataChillerAbsorber->absorptionChillers)) {
     251            0 :         return;
     252              :     }
     253              : 
     254            2 :     state.dataChillerAbsorber->absorptionChillers.allocate(numAbsorbers);
     255              : 
     256              :     // LOAD ARRAYS WITH BLAST CURVE FIT Absorber DATA
     257            4 :     for (int AbsorberNum = 1; AbsorberNum <= numAbsorbers; ++AbsorberNum) {
     258            6 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     259            2 :                                                                  state.dataIPShortCut->cCurrentModuleObject,
     260              :                                                                  AbsorberNum,
     261            2 :                                                                  state.dataIPShortCut->cAlphaArgs,
     262              :                                                                  NumAlphas,
     263            2 :                                                                  state.dataIPShortCut->rNumericArgs,
     264              :                                                                  NumNums,
     265              :                                                                  IOStat,
     266              :                                                                  _,
     267            2 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     268            2 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     269            2 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     270              : 
     271              :         // ErrorsFound will be set to True if problem was found, left untouched otherwise
     272            2 :         GlobalNames::VerifyUniqueChillerName(state,
     273            2 :                                              state.dataIPShortCut->cCurrentModuleObject,
     274            2 :                                              state.dataIPShortCut->cAlphaArgs(1),
     275              :                                              ErrorsFound,
     276            4 :                                              state.dataIPShortCut->cCurrentModuleObject + " Name");
     277              : 
     278            2 :         auto &thisChiller = state.dataChillerAbsorber->absorptionChillers(AbsorberNum);
     279            2 :         thisChiller.Name = state.dataIPShortCut->cAlphaArgs(1);
     280            2 :         thisChiller.NomCap = state.dataIPShortCut->rNumericArgs(1);
     281            2 :         if (thisChiller.NomCap == DataSizing::AutoSize) {
     282            0 :             thisChiller.NomCapWasAutoSized = true;
     283              :         }
     284            2 :         thisChiller.NomPumpPower = state.dataIPShortCut->rNumericArgs(2);
     285            2 :         if (thisChiller.NomPumpPower == DataSizing::AutoSize) {
     286            0 :             thisChiller.NomPumpPowerWasAutoSized = true;
     287              :         }
     288            2 :         if (state.dataIPShortCut->rNumericArgs(1) == 0.0) {
     289            0 :             ShowSevereError(state, format("Invalid {}={:.2R}", state.dataIPShortCut->cNumericFieldNames(1), state.dataIPShortCut->rNumericArgs(1)));
     290            0 :             ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     291            0 :             ErrorsFound = true;
     292              :         }
     293              :         // Assign Node Numbers to specified nodes
     294            2 :         thisChiller.EvapInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     295            2 :                                                                            state.dataIPShortCut->cAlphaArgs(2),
     296              :                                                                            ErrorsFound,
     297              :                                                                            DataLoopNode::ConnectionObjectType::ChillerAbsorption,
     298            2 :                                                                            state.dataIPShortCut->cAlphaArgs(1),
     299              :                                                                            DataLoopNode::NodeFluidType::Water,
     300              :                                                                            DataLoopNode::ConnectionType::Inlet,
     301              :                                                                            NodeInputManager::CompFluidStream::Primary,
     302              :                                                                            DataLoopNode::ObjectIsNotParent);
     303            4 :         thisChiller.EvapOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     304            2 :                                                                             state.dataIPShortCut->cAlphaArgs(3),
     305              :                                                                             ErrorsFound,
     306              :                                                                             DataLoopNode::ConnectionObjectType::ChillerAbsorption,
     307            2 :                                                                             state.dataIPShortCut->cAlphaArgs(1),
     308              :                                                                             DataLoopNode::NodeFluidType::Water,
     309              :                                                                             DataLoopNode::ConnectionType::Outlet,
     310              :                                                                             NodeInputManager::CompFluidStream::Primary,
     311              :                                                                             DataLoopNode::ObjectIsNotParent);
     312            4 :         BranchNodeConnections::TestCompSet(state,
     313            2 :                                            state.dataIPShortCut->cCurrentModuleObject,
     314            2 :                                            state.dataIPShortCut->cAlphaArgs(1),
     315            2 :                                            state.dataIPShortCut->cAlphaArgs(2),
     316            2 :                                            state.dataIPShortCut->cAlphaArgs(3),
     317              :                                            "Chilled Water Nodes");
     318              : 
     319            2 :         thisChiller.CondInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     320            2 :                                                                            state.dataIPShortCut->cAlphaArgs(4),
     321              :                                                                            ErrorsFound,
     322              :                                                                            DataLoopNode::ConnectionObjectType::ChillerAbsorption,
     323            2 :                                                                            state.dataIPShortCut->cAlphaArgs(1),
     324              :                                                                            DataLoopNode::NodeFluidType::Water,
     325              :                                                                            DataLoopNode::ConnectionType::Inlet,
     326              :                                                                            NodeInputManager::CompFluidStream::Secondary,
     327              :                                                                            DataLoopNode::ObjectIsNotParent);
     328            4 :         thisChiller.CondOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     329            2 :                                                                             state.dataIPShortCut->cAlphaArgs(5),
     330              :                                                                             ErrorsFound,
     331              :                                                                             DataLoopNode::ConnectionObjectType::ChillerAbsorption,
     332            2 :                                                                             state.dataIPShortCut->cAlphaArgs(1),
     333              :                                                                             DataLoopNode::NodeFluidType::Water,
     334              :                                                                             DataLoopNode::ConnectionType::Outlet,
     335              :                                                                             NodeInputManager::CompFluidStream::Secondary,
     336              :                                                                             DataLoopNode::ObjectIsNotParent);
     337            4 :         BranchNodeConnections::TestCompSet(state,
     338            2 :                                            state.dataIPShortCut->cCurrentModuleObject,
     339            2 :                                            state.dataIPShortCut->cAlphaArgs(1),
     340            2 :                                            state.dataIPShortCut->cAlphaArgs(4),
     341            2 :                                            state.dataIPShortCut->cAlphaArgs(5),
     342              :                                            "Condenser (not tested) Nodes");
     343              : 
     344            2 :         if (NumAlphas > 8) {
     345            0 :             if (Util::SameString(state.dataIPShortCut->cAlphaArgs(9), "HotWater") ||
     346            0 :                 Util::SameString(state.dataIPShortCut->cAlphaArgs(9), "HotWater")) {
     347            0 :                 thisChiller.GenHeatSourceType = DataLoopNode::NodeFluidType::Water;
     348            0 :             } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(9), "STEAM") || state.dataIPShortCut->cAlphaArgs(9).empty()) {
     349            0 :                 thisChiller.GenHeatSourceType = DataLoopNode::NodeFluidType::Steam;
     350              :             } else {
     351            0 :                 ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(9), state.dataIPShortCut->cAlphaArgs(9)));
     352            0 :                 ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     353            0 :                 ShowContinueError(state, "...Generator heat source type must be Steam or Hot Water.");
     354            0 :                 ErrorsFound = true;
     355              :             }
     356              :         } else {
     357            2 :             thisChiller.GenHeatSourceType = DataLoopNode::NodeFluidType::Steam;
     358              :         }
     359              : 
     360            2 :         if (!state.dataIPShortCut->lAlphaFieldBlanks(6) && !state.dataIPShortCut->lAlphaFieldBlanks(7)) {
     361            0 :             thisChiller.GenInputOutputNodesUsed = true;
     362            0 :             if (thisChiller.GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
     363            0 :                 thisChiller.GeneratorInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     364            0 :                                                                                         state.dataIPShortCut->cAlphaArgs(6),
     365              :                                                                                         ErrorsFound,
     366              :                                                                                         DataLoopNode::ConnectionObjectType::ChillerAbsorption,
     367            0 :                                                                                         state.dataIPShortCut->cAlphaArgs(1),
     368              :                                                                                         DataLoopNode::NodeFluidType::Water,
     369              :                                                                                         DataLoopNode::ConnectionType::Inlet,
     370              :                                                                                         NodeInputManager::CompFluidStream::Tertiary,
     371              :                                                                                         DataLoopNode::ObjectIsNotParent);
     372            0 :                 thisChiller.GeneratorOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     373            0 :                                                                                          state.dataIPShortCut->cAlphaArgs(7),
     374              :                                                                                          ErrorsFound,
     375              :                                                                                          DataLoopNode::ConnectionObjectType::ChillerAbsorption,
     376            0 :                                                                                          state.dataIPShortCut->cAlphaArgs(1),
     377              :                                                                                          DataLoopNode::NodeFluidType::Water,
     378              :                                                                                          DataLoopNode::ConnectionType::Outlet,
     379              :                                                                                          NodeInputManager::CompFluidStream::Tertiary,
     380              :                                                                                          DataLoopNode::ObjectIsNotParent);
     381            0 :                 BranchNodeConnections::TestCompSet(state,
     382            0 :                                                    state.dataIPShortCut->cCurrentModuleObject,
     383            0 :                                                    state.dataIPShortCut->cAlphaArgs(1),
     384            0 :                                                    state.dataIPShortCut->cAlphaArgs(6),
     385            0 :                                                    state.dataIPShortCut->cAlphaArgs(7),
     386              :                                                    "Hot Water Nodes");
     387              :             } else {
     388            0 :                 thisChiller.steam = Fluid::GetSteam(state);
     389            0 :                 thisChiller.GeneratorInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     390            0 :                                                                                         state.dataIPShortCut->cAlphaArgs(6),
     391              :                                                                                         ErrorsFound,
     392              :                                                                                         DataLoopNode::ConnectionObjectType::ChillerAbsorption,
     393            0 :                                                                                         state.dataIPShortCut->cAlphaArgs(1),
     394              :                                                                                         DataLoopNode::NodeFluidType::Steam,
     395              :                                                                                         DataLoopNode::ConnectionType::Inlet,
     396              :                                                                                         NodeInputManager::CompFluidStream::Tertiary,
     397              :                                                                                         DataLoopNode::ObjectIsNotParent);
     398            0 :                 thisChiller.GeneratorOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     399            0 :                                                                                          state.dataIPShortCut->cAlphaArgs(7),
     400              :                                                                                          ErrorsFound,
     401              :                                                                                          DataLoopNode::ConnectionObjectType::ChillerAbsorption,
     402            0 :                                                                                          state.dataIPShortCut->cAlphaArgs(1),
     403              :                                                                                          DataLoopNode::NodeFluidType::Steam,
     404              :                                                                                          DataLoopNode::ConnectionType::Outlet,
     405              :                                                                                          NodeInputManager::CompFluidStream::Tertiary,
     406              :                                                                                          DataLoopNode::ObjectIsNotParent);
     407            0 :                 BranchNodeConnections::TestCompSet(state,
     408            0 :                                                    state.dataIPShortCut->cCurrentModuleObject,
     409            0 :                                                    state.dataIPShortCut->cAlphaArgs(1),
     410            0 :                                                    state.dataIPShortCut->cAlphaArgs(6),
     411            0 :                                                    state.dataIPShortCut->cAlphaArgs(7),
     412              :                                                    "Steam Nodes");
     413              :             }
     414            4 :         } else if ((state.dataIPShortCut->lAlphaFieldBlanks(6) && !state.dataIPShortCut->lAlphaFieldBlanks(7)) ||
     415            2 :                    (!state.dataIPShortCut->lAlphaFieldBlanks(6) && state.dataIPShortCut->lAlphaFieldBlanks(7))) {
     416            0 :             ShowSevereError(state, format("{}, Name={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     417            0 :             ShowContinueError(state, "...Generator fluid nodes must both be entered (or both left blank).");
     418            0 :             ShowContinueError(state, format("...{} = {}", state.dataIPShortCut->cAlphaFieldNames(6), state.dataIPShortCut->cAlphaArgs(6)));
     419            0 :             ShowContinueError(state, format("...{} = {}", state.dataIPShortCut->cAlphaFieldNames(7), state.dataIPShortCut->cAlphaArgs(7)));
     420            0 :             ErrorsFound = true;
     421              :         } else {
     422            2 :             if (thisChiller.GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
     423            0 :                 ShowWarningError(state, format("{}, Name={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     424            0 :                 ShowContinueError(state, "...Generator fluid type must be Steam if generator inlet/outlet nodes are blank.");
     425            0 :                 ShowContinueError(state, "...Generator fluid type is set to Steam and the simulation continues.");
     426            0 :                 thisChiller.GenHeatSourceType = DataLoopNode::NodeFluidType::Steam;
     427              :             }
     428              :         }
     429              : 
     430              :         // Get remaining data
     431            2 :         thisChiller.MinPartLoadRat = state.dataIPShortCut->rNumericArgs(3);
     432            2 :         thisChiller.MaxPartLoadRat = state.dataIPShortCut->rNumericArgs(4);
     433            2 :         thisChiller.OptPartLoadRat = state.dataIPShortCut->rNumericArgs(5);
     434            2 :         thisChiller.TempDesCondIn = state.dataIPShortCut->rNumericArgs(6);
     435            2 :         thisChiller.EvapVolFlowRate = state.dataIPShortCut->rNumericArgs(7);
     436            2 :         if (thisChiller.EvapVolFlowRate == DataSizing::AutoSize) {
     437            0 :             thisChiller.EvapVolFlowRateWasAutoSized = true;
     438              :         }
     439            2 :         thisChiller.CondVolFlowRate = state.dataIPShortCut->rNumericArgs(8);
     440            2 :         if (thisChiller.CondVolFlowRate == DataSizing::AutoSize) {
     441            0 :             thisChiller.CondVolFlowRateWasAutoSized = true;
     442              :         }
     443            2 :         thisChiller.SteamLoadCoef[0] = state.dataIPShortCut->rNumericArgs(9);
     444            2 :         thisChiller.SteamLoadCoef[1] = state.dataIPShortCut->rNumericArgs(10);
     445            2 :         thisChiller.SteamLoadCoef[2] = state.dataIPShortCut->rNumericArgs(11);
     446            2 :         thisChiller.PumpPowerCoef[0] = state.dataIPShortCut->rNumericArgs(12);
     447            2 :         thisChiller.PumpPowerCoef[1] = state.dataIPShortCut->rNumericArgs(13);
     448            2 :         thisChiller.PumpPowerCoef[2] = state.dataIPShortCut->rNumericArgs(14);
     449            2 :         thisChiller.TempLowLimitEvapOut = state.dataIPShortCut->rNumericArgs(15);
     450              : 
     451            2 :         thisChiller.FlowMode = static_cast<DataPlant::FlowMode>(getEnumValue(DataPlant::FlowModeNamesUC, state.dataIPShortCut->cAlphaArgs(8)));
     452            2 :         if (thisChiller.FlowMode == DataPlant::FlowMode::Invalid) {
     453            0 :             ShowSevereError(state,
     454            0 :                             format("{}{}=\"{}\",", RoutineName, state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     455            0 :             ShowContinueError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(8), state.dataIPShortCut->cAlphaArgs(8)));
     456            0 :             ShowContinueError(state, "Available choices are ConstantFlow, NotModulated, or LeavingSetpointModulated");
     457            0 :             ShowContinueError(state, "Flow mode NotModulated is assumed and the simulation continues.");
     458            0 :             thisChiller.FlowMode = DataPlant::FlowMode::NotModulated;
     459              :         };
     460              : 
     461            2 :         if (NumNums > 15) {
     462            0 :             thisChiller.GeneratorVolFlowRate = state.dataIPShortCut->rNumericArgs(16);
     463            0 :             if (thisChiller.GeneratorVolFlowRate == DataSizing::AutoSize) {
     464            0 :                 thisChiller.GeneratorVolFlowRateWasAutoSized = true;
     465              :             }
     466              :         }
     467              : 
     468            2 :         if (thisChiller.GeneratorVolFlowRate == 0.0 && thisChiller.GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
     469            0 :             ShowSevereError(state, format("Invalid {}={:.2R}", state.dataIPShortCut->cNumericFieldNames(16), state.dataIPShortCut->rNumericArgs(16)));
     470            0 :             ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     471            0 :             ShowContinueError(state, "...Generator water flow rate must be greater than 0 when absorber generator fluid type is hot water.");
     472            0 :             ErrorsFound = true;
     473              :         }
     474              : 
     475            2 :         if (NumNums > 16) {
     476            0 :             thisChiller.GeneratorSubcool = state.dataIPShortCut->rNumericArgs(17);
     477              :         } else {
     478            2 :             thisChiller.GeneratorSubcool = 1.0;
     479              :         }
     480              : 
     481            2 :         if (NumNums > 17) {
     482            0 :             thisChiller.SizFac = state.dataIPShortCut->rNumericArgs(18);
     483              :         } else {
     484            2 :             thisChiller.SizFac = 1.0;
     485              :         }
     486              :     }
     487              : 
     488            2 :     if (ErrorsFound) {
     489            0 :         ShowFatalError(state, format("Errors found in processing input for {}", state.dataIPShortCut->cCurrentModuleObject));
     490              :     }
     491              : }
     492              : 
     493            2 : void BLASTAbsorberSpecs::setupOutputVars(EnergyPlusData &state)
     494              : {
     495            4 :     SetupOutputVariable(state,
     496              :                         "Chiller Electricity Rate",
     497              :                         Constant::Units::W,
     498            2 :                         this->Report.PumpingPower,
     499              :                         OutputProcessor::TimeStepType::System,
     500              :                         OutputProcessor::StoreType::Average,
     501            2 :                         this->Name);
     502            4 :     SetupOutputVariable(state,
     503              :                         "Chiller Electricity Energy",
     504              :                         Constant::Units::J,
     505            2 :                         this->Report.PumpingEnergy,
     506              :                         OutputProcessor::TimeStepType::System,
     507              :                         OutputProcessor::StoreType::Sum,
     508            2 :                         this->Name,
     509              :                         Constant::eResource::Electricity,
     510              :                         OutputProcessor::Group::Plant,
     511              :                         OutputProcessor::EndUseCat::Cooling);
     512            4 :     SetupOutputVariable(state,
     513              :                         "Chiller Evaporator Cooling Rate",
     514              :                         Constant::Units::W,
     515            2 :                         this->Report.QEvap,
     516              :                         OutputProcessor::TimeStepType::System,
     517              :                         OutputProcessor::StoreType::Average,
     518            2 :                         this->Name);
     519            4 :     SetupOutputVariable(state,
     520              :                         "Chiller Evaporator Cooling Energy",
     521              :                         Constant::Units::J,
     522            2 :                         this->Report.EvapEnergy,
     523              :                         OutputProcessor::TimeStepType::System,
     524              :                         OutputProcessor::StoreType::Sum,
     525            2 :                         this->Name,
     526              :                         Constant::eResource::EnergyTransfer,
     527              :                         OutputProcessor::Group::Plant,
     528              :                         OutputProcessor::EndUseCat::Chillers);
     529            4 :     SetupOutputVariable(state,
     530              :                         "Chiller Evaporator Inlet Temperature",
     531              :                         Constant::Units::C,
     532            2 :                         this->Report.EvapInletTemp,
     533              :                         OutputProcessor::TimeStepType::System,
     534              :                         OutputProcessor::StoreType::Average,
     535            2 :                         this->Name);
     536            4 :     SetupOutputVariable(state,
     537              :                         "Chiller Evaporator Outlet Temperature",
     538              :                         Constant::Units::C,
     539            2 :                         this->Report.EvapOutletTemp,
     540              :                         OutputProcessor::TimeStepType::System,
     541              :                         OutputProcessor::StoreType::Average,
     542            2 :                         this->Name);
     543            4 :     SetupOutputVariable(state,
     544              :                         "Chiller Evaporator Mass Flow Rate",
     545              :                         Constant::Units::kg_s,
     546            2 :                         this->Report.Evapmdot,
     547              :                         OutputProcessor::TimeStepType::System,
     548              :                         OutputProcessor::StoreType::Average,
     549            2 :                         this->Name);
     550              : 
     551            4 :     SetupOutputVariable(state,
     552              :                         "Chiller Condenser Heat Transfer Rate",
     553              :                         Constant::Units::W,
     554            2 :                         this->Report.QCond,
     555              :                         OutputProcessor::TimeStepType::System,
     556              :                         OutputProcessor::StoreType::Average,
     557            2 :                         this->Name);
     558            4 :     SetupOutputVariable(state,
     559              :                         "Chiller Condenser Heat Transfer Energy",
     560              :                         Constant::Units::J,
     561            2 :                         this->Report.CondEnergy,
     562              :                         OutputProcessor::TimeStepType::System,
     563              :                         OutputProcessor::StoreType::Sum,
     564            2 :                         this->Name,
     565              :                         Constant::eResource::EnergyTransfer,
     566              :                         OutputProcessor::Group::Plant,
     567              :                         OutputProcessor::EndUseCat::HeatRejection);
     568            4 :     SetupOutputVariable(state,
     569              :                         "Chiller Condenser Inlet Temperature",
     570              :                         Constant::Units::C,
     571            2 :                         this->Report.CondInletTemp,
     572              :                         OutputProcessor::TimeStepType::System,
     573              :                         OutputProcessor::StoreType::Average,
     574            2 :                         this->Name);
     575            4 :     SetupOutputVariable(state,
     576              :                         "Chiller Condenser Outlet Temperature",
     577              :                         Constant::Units::C,
     578            2 :                         this->Report.CondOutletTemp,
     579              :                         OutputProcessor::TimeStepType::System,
     580              :                         OutputProcessor::StoreType::Average,
     581            2 :                         this->Name);
     582            4 :     SetupOutputVariable(state,
     583              :                         "Chiller Condenser Mass Flow Rate",
     584              :                         Constant::Units::kg_s,
     585            2 :                         this->Report.Condmdot,
     586              :                         OutputProcessor::TimeStepType::System,
     587              :                         OutputProcessor::StoreType::Average,
     588            2 :                         this->Name);
     589              : 
     590            2 :     if (this->GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
     591            0 :         SetupOutputVariable(state,
     592              :                             "Chiller Hot Water Consumption Rate",
     593              :                             Constant::Units::W,
     594            0 :                             this->Report.QGenerator,
     595              :                             OutputProcessor::TimeStepType::System,
     596              :                             OutputProcessor::StoreType::Average,
     597            0 :                             this->Name);
     598            0 :         SetupOutputVariable(state,
     599              :                             "Chiller Source Hot Water Energy",
     600              :                             Constant::Units::J,
     601            0 :                             this->Report.GeneratorEnergy,
     602              :                             OutputProcessor::TimeStepType::System,
     603              :                             OutputProcessor::StoreType::Sum,
     604            0 :                             this->Name,
     605              :                             Constant::eResource::PlantLoopHeatingDemand,
     606              :                             OutputProcessor::Group::Plant,
     607              :                             OutputProcessor::EndUseCat::Chillers);
     608              :     } else {
     609            2 :         if (this->GenInputOutputNodesUsed) {
     610            0 :             SetupOutputVariable(state,
     611              :                                 "Chiller Source Steam Rate",
     612              :                                 Constant::Units::W,
     613            0 :                                 this->Report.QGenerator,
     614              :                                 OutputProcessor::TimeStepType::System,
     615              :                                 OutputProcessor::StoreType::Average,
     616            0 :                                 this->Name);
     617            0 :             SetupOutputVariable(state,
     618              :                                 "Chiller Source Steam Energy",
     619              :                                 Constant::Units::J,
     620            0 :                                 this->Report.GeneratorEnergy,
     621              :                                 OutputProcessor::TimeStepType::System,
     622              :                                 OutputProcessor::StoreType::Sum,
     623            0 :                                 this->Name,
     624              :                                 Constant::eResource::PlantLoopHeatingDemand,
     625              :                                 OutputProcessor::Group::Plant,
     626              :                                 OutputProcessor::EndUseCat::Chillers);
     627              :         } else {
     628            4 :             SetupOutputVariable(state,
     629              :                                 "Chiller Source Steam Rate",
     630              :                                 Constant::Units::W,
     631            2 :                                 this->Report.QGenerator,
     632              :                                 OutputProcessor::TimeStepType::System,
     633              :                                 OutputProcessor::StoreType::Average,
     634            2 :                                 this->Name);
     635            4 :             SetupOutputVariable(state,
     636              :                                 "Chiller Source Steam Energy",
     637              :                                 Constant::Units::J,
     638            2 :                                 this->Report.GeneratorEnergy,
     639              :                                 OutputProcessor::TimeStepType::System,
     640              :                                 OutputProcessor::StoreType::Sum,
     641            2 :                                 this->Name,
     642              :                                 Constant::eResource::DistrictHeatingSteam,
     643              :                                 OutputProcessor::Group::Plant,
     644              :                                 OutputProcessor::EndUseCat::Cooling);
     645              :         }
     646              :     }
     647              : 
     648            4 :     SetupOutputVariable(state,
     649              :                         "Chiller COP",
     650              :                         Constant::Units::W_W,
     651            2 :                         this->Report.ActualCOP,
     652              :                         OutputProcessor::TimeStepType::System,
     653              :                         OutputProcessor::StoreType::Average,
     654            2 :                         this->Name);
     655              : 
     656            2 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     657            0 :         SetupEMSInternalVariable(state, "Chiller Nominal Capacity", this->Name, "[W]", this->NomCap);
     658              :     }
     659            2 : }
     660              : 
     661            2 : void BLASTAbsorberSpecs::oneTimeInit(EnergyPlusData &state)
     662              : {
     663              : 
     664            2 :     this->setupOutputVars(state);
     665              : 
     666              :     // Locate the chillers on the plant loops for later usage
     667            2 :     bool errFlag = false;
     668            6 :     PlantUtilities::ScanPlantLoopsForObject(state,
     669              :                                             this->Name,
     670              :                                             DataPlant::PlantEquipmentType::Chiller_Absorption,
     671            2 :                                             this->CWPlantLoc,
     672              :                                             errFlag,
     673            2 :                                             this->TempLowLimitEvapOut,
     674              :                                             _,
     675              :                                             _,
     676            2 :                                             this->EvapInletNodeNum,
     677              :                                             _);
     678            2 :     if (this->CondInletNodeNum > 0) {
     679            6 :         PlantUtilities::ScanPlantLoopsForObject(
     680            4 :             state, this->Name, DataPlant::PlantEquipmentType::Chiller_Absorption, this->CDPlantLoc, errFlag, _, _, _, this->CondInletNodeNum, _);
     681            2 :         PlantUtilities::InterConnectTwoPlantLoopSides(
     682            2 :             state, this->CWPlantLoc, this->CDPlantLoc, DataPlant::PlantEquipmentType::Chiller_Absorption, true);
     683              :     }
     684            2 :     if (this->GeneratorInletNodeNum > 0) {
     685            0 :         PlantUtilities::ScanPlantLoopsForObject(state,
     686              :                                                 this->Name,
     687              :                                                 DataPlant::PlantEquipmentType::Chiller_Absorption,
     688            0 :                                                 this->GenPlantLoc,
     689              :                                                 errFlag,
     690              :                                                 _,
     691              :                                                 _,
     692              :                                                 _,
     693            0 :                                                 this->GeneratorInletNodeNum,
     694              :                                                 _);
     695            0 :         PlantUtilities::InterConnectTwoPlantLoopSides(
     696            0 :             state, this->CWPlantLoc, this->GenPlantLoc, DataPlant::PlantEquipmentType::Chiller_Absorption, true);
     697              :     }
     698              : 
     699              :     // Fill in connection data
     700            2 :     if ((this->CondInletNodeNum > 0) && (this->GeneratorInletNodeNum > 0)) {
     701            0 :         PlantUtilities::InterConnectTwoPlantLoopSides(
     702            0 :             state, this->CDPlantLoc, this->GenPlantLoc, DataPlant::PlantEquipmentType::Chiller_Absorption, false);
     703              :     }
     704            2 :     if (errFlag) {
     705            0 :         ShowFatalError(state, "InitBLASTAbsorberModel: Program terminated due to previous condition(s).");
     706              :     }
     707              : 
     708            2 :     if (this->FlowMode == DataPlant::FlowMode::Constant) {
     709            0 :         DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyIfLoopOn;
     710              :     }
     711              : 
     712            2 :     if (this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) {
     713            2 :         DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).FlowPriority = DataPlant::LoopFlowStatus::NeedyIfLoopOn;
     714              : 
     715            2 :         if ((state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) &&
     716            0 :             (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi == DataLoopNode::SensedNodeFlagValue)) {
     717            0 :             if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
     718            0 :                 if (!this->ModulatedFlowErrDone) {
     719            0 :                     ShowWarningError(state, format("Missing temperature setpoint for LeavingSetpointModulated mode chiller named {}", this->Name));
     720            0 :                     ShowContinueError(
     721              :                         state, "  A temperature setpoint is needed at the outlet node of a chiller in variable flow mode, use a SetpointManager");
     722            0 :                     ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
     723            0 :                     this->ModulatedFlowErrDone = true;
     724              :                 }
     725              :             } else {
     726              :                 // need call to EMS to check node
     727            0 :                 bool FatalError = false; // but not really fatal yet, but should be.
     728            0 :                 EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->EvapOutletNodeNum, HVAC::CtrlVarType::Temp, FatalError);
     729            0 :                 state.dataLoopNodes->NodeSetpointCheck(this->EvapOutletNodeNum).needsSetpointChecking = false;
     730            0 :                 if (FatalError) {
     731            0 :                     if (!this->ModulatedFlowErrDone) {
     732            0 :                         ShowWarningError(state,
     733            0 :                                          format("Missing temperature setpoint for LeavingSetpointModulated mode chiller named {}", this->Name));
     734            0 :                         ShowContinueError(state,
     735              :                                           "  A temperature setpoint is needed at the outlet node of a chiller evaporator in variable flow mode");
     736            0 :                         ShowContinueError(state, "  use a Setpoint Manager to establish a setpoint at the chiller evaporator outlet node ");
     737            0 :                         ShowContinueError(state, "  or use an EMS actuator to establish a setpoint at the outlet node ");
     738            0 :                         ShowContinueError(state, "  The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
     739            0 :                         this->ModulatedFlowErrDone = true;
     740              :                     }
     741              :                 }
     742              :             }
     743              : 
     744            0 :             this->ModulatedFlowSetToLoop = true;
     745            0 :             state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint =
     746            0 :                 state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
     747            0 :             state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi =
     748            0 :                 state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
     749              :         }
     750              :     }
     751            2 : }
     752              : 
     753           12 : void BLASTAbsorberSpecs::initEachEnvironment(EnergyPlusData &state)
     754              : {
     755           12 :     constexpr std::string_view RoutineName("BLASTAbsorberSpecs::initEachEnvironment");
     756              : 
     757           12 :     Real64 rho = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
     758              : 
     759           12 :     this->EvapMassFlowRateMax = this->EvapVolFlowRate * rho;
     760              : 
     761           12 :     PlantUtilities::InitComponentNodes(state, 0.0, this->EvapMassFlowRateMax, this->EvapInletNodeNum, this->EvapOutletNodeNum);
     762              : 
     763           12 :     rho = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
     764              : 
     765           12 :     this->CondMassFlowRateMax = rho * this->CondVolFlowRate;
     766              : 
     767           12 :     PlantUtilities::InitComponentNodes(state, 0.0, this->CondMassFlowRateMax, this->CondInletNodeNum, this->CondOutletNodeNum);
     768           12 :     state.dataLoopNodes->Node(this->CondInletNodeNum).Temp = this->TempDesCondIn;
     769              : 
     770           12 :     if (this->GeneratorInletNodeNum > 0) {
     771              : 
     772            0 :         if (this->GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
     773            0 :             rho = state.dataPlnt->PlantLoop(this->GenPlantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
     774              : 
     775            0 :             this->GenMassFlowRateMax = rho * this->GeneratorVolFlowRate;
     776            0 :         } else if (this->GenHeatSourceType == DataLoopNode::NodeFluidType::Steam) {
     777              : 
     778            0 :             this->QGenerator = (this->SteamLoadCoef[0] + this->SteamLoadCoef[1] + this->SteamLoadCoef[2]) * this->NomCap;
     779              : 
     780              :             // dry enthalpy of steam (quality = 1)
     781            0 :             Real64 EnthSteamOutDry = this->steam->getSatEnthalpy(
     782            0 :                 state, state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp, 1.0, calcChillerAbsorption + this->Name);
     783              : 
     784              :             // wet enthalpy of steam (quality = 0)
     785            0 :             Real64 EnthSteamOutWet = this->steam->getSatEnthalpy(
     786            0 :                 state, state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp, 0.0, calcChillerAbsorption + this->Name);
     787            0 :             Real64 SteamDeltaT = this->GeneratorSubcool;
     788            0 :             Real64 SteamOutletTemp = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp - SteamDeltaT;
     789            0 :             Real64 HfgSteam = EnthSteamOutDry - EnthSteamOutWet;
     790            0 :             Real64 CpWater = this->water->getDensity(state, SteamOutletTemp, calcChillerAbsorption + this->Name);
     791            0 :             this->GenMassFlowRateMax = this->QGenerator / (HfgSteam + CpWater * SteamDeltaT);
     792              :         }
     793              : 
     794            0 :         PlantUtilities::InitComponentNodes(state, 0.0, this->GenMassFlowRateMax, this->GeneratorInletNodeNum, this->GeneratorOutletNodeNum);
     795              :     }
     796           12 : }
     797              : 
     798        38918 : void BLASTAbsorberSpecs::initialize(EnergyPlusData &state,
     799              :                                     bool RunFlag, // TRUE when chiller operating
     800              :                                     Real64 MyLoad)
     801              : {
     802              : 
     803              :     // SUBROUTINE INFORMATION:
     804              :     //       AUTHOR         Richard Raustad
     805              :     //       DATE WRITTEN   September 2009
     806              : 
     807              :     // PURPOSE OF THIS SUBROUTINE:
     808              :     // This subroutine is for initializations of the Electric Chiller components
     809              : 
     810              :     // METHODOLOGY EMPLOYED:
     811              :     // Uses the status flags to trigger initializations.
     812              : 
     813              :     // Init more variables
     814        38918 :     if (this->MyOneTimeFlag) {
     815            2 :         this->oneTimeInit(state);
     816            2 :         this->MyOneTimeFlag = false;
     817              :     }
     818              : 
     819        38918 :     if (this->MyEnvrnFlag && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
     820           12 :         this->initEachEnvironment(state);
     821           12 :         this->MyEnvrnFlag = false;
     822              :     }
     823        38918 :     if (!state.dataGlobal->BeginEnvrnFlag) {
     824        38520 :         this->MyEnvrnFlag = true;
     825              :     }
     826              : 
     827              :     // every time inits
     828              : 
     829        38918 :     if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) && this->ModulatedFlowSetToLoop) {
     830              :         // fix for clumsy old input that worked because loop setpoint was spread.
     831              :         //  could be removed with transition, testing , model change, period of being obsolete.
     832            0 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint =
     833            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
     834            0 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi =
     835            0 :             state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
     836              :     }
     837              : 
     838        38918 :     Real64 mdotEvap = 0.0; // local fluid mass flow rate thru evaporator
     839        38918 :     Real64 mdotCond = 0.0; // local fluid mass flow rate thru condenser
     840        38918 :     Real64 mdotGen = 0.0;  // local fluid mass flow rate thru generator
     841              : 
     842        38918 :     if ((MyLoad < 0.0) && RunFlag) {
     843        19216 :         mdotEvap = this->EvapMassFlowRateMax;
     844        19216 :         mdotCond = this->CondMassFlowRateMax;
     845        19216 :         mdotGen = this->GenMassFlowRateMax;
     846              :     }
     847              : 
     848        38918 :     PlantUtilities::SetComponentFlowRate(state, mdotEvap, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
     849              : 
     850        38918 :     PlantUtilities::SetComponentFlowRate(state, mdotCond, this->CondInletNodeNum, this->CondOutletNodeNum, this->CDPlantLoc);
     851              : 
     852        38918 :     if (this->GeneratorInletNodeNum > 0) {
     853              : 
     854            0 :         PlantUtilities::SetComponentFlowRate(state, mdotGen, this->GeneratorInletNodeNum, this->GeneratorOutletNodeNum, this->GenPlantLoc);
     855              :     }
     856        38918 : }
     857              : 
     858           20 : void BLASTAbsorberSpecs::sizeChiller(EnergyPlusData &state)
     859              : {
     860              : 
     861              :     // SUBROUTINE INFORMATION:
     862              :     //       AUTHOR         Fred Buhl
     863              :     //       DATE WRITTEN   March 2008
     864              :     //       MODIFIED:      R. Raustad May 2008 - added generator node sizing
     865              :     //                      November 2013 Daeho Kang, add component sizing table entries
     866              : 
     867              :     // PURPOSE OF THIS SUBROUTINE:
     868              :     // This subroutine is for sizing Constant COP Chiller Components for which capacities and flow rates
     869              :     // have not been specified in the input.
     870              : 
     871              :     // METHODOLOGY EMPLOYED:
     872              :     // Obtains evaporator flow rate from the plant sizing array. Calculates nominal capacity from
     873              :     // the evaporator flow rate and the chilled water loop design delta T. The condenser flow rate
     874              :     // is calculated from the nominal capacity, the COP, and the condenser loop design delta T.
     875              : 
     876              :     //        Real64 SteamMassFlowRate; // steam mass flow rate through generator
     877              : 
     878           20 :     constexpr const char *RoutineName("SizeAbsorpChiller");
     879              : 
     880           20 :     int PltSizSteamNum(0);   // Plant Sizing index for steam heating loop
     881           20 :     int PltSizHeatingNum(0); // Plant Sizing index for how water heating loop
     882           20 :     bool ErrorsFound(false); // If errors detected in input
     883           20 :     bool LoopErrorsFound = false;
     884              : 
     885              :     // nominal energy input ratio (steam or hot water)
     886           20 :     Real64 SteamInputRatNom = this->SteamLoadCoef[0] + this->SteamLoadCoef[1] + this->SteamLoadCoef[2];
     887              :     // init local temporary version in case of partial/mixed autosizing
     888              : 
     889              :     // local nominal capacity cooling power
     890           20 :     Real64 tmpNomCap = this->NomCap;
     891              : 
     892              :     // local evaporator design volume flow rate
     893           20 :     Real64 tmpEvapVolFlowRate = this->EvapVolFlowRate;
     894              : 
     895              :     // local condenser design volume flow rate
     896           20 :     Real64 tmpCondVolFlowRate = this->CondVolFlowRate;
     897              : 
     898              :     // local generator design volume flow rate
     899           20 :     Real64 tmpGeneratorVolFlowRate = this->GeneratorVolFlowRate;
     900              : 
     901              :     // find the appropriate Plant Sizing object
     902           20 :     int PltSizNum = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).PlantSizNum;
     903           20 :     int PltSizCondNum = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).PlantSizNum;
     904              : 
     905           20 :     if (this->GenHeatSourceType == DataLoopNode::NodeFluidType::Steam) {
     906           20 :         if (this->GeneratorInletNodeNum > 0 && this->GeneratorOutletNodeNum > 0) {
     907            0 :             PltSizSteamNum = PlantUtilities::MyPlantSizingIndex(
     908              :                 state, moduleObjectType, this->Name, this->GeneratorInletNodeNum, this->GeneratorOutletNodeNum, LoopErrorsFound);
     909              :         } else {
     910           20 :             for (int PltSizIndex = 1; PltSizIndex <= state.dataSize->NumPltSizInput; ++PltSizIndex) {
     911            0 :                 if (state.dataSize->PlantSizData(PltSizIndex).LoopType == DataSizing::TypeOfPlantLoop::Steam) {
     912            0 :                     PltSizSteamNum = PltSizIndex;
     913              :                 }
     914              :             }
     915              :         }
     916              :     } else {
     917            0 :         if (this->GeneratorInletNodeNum > 0 && this->GeneratorOutletNodeNum > 0) {
     918            0 :             PltSizHeatingNum = PlantUtilities::MyPlantSizingIndex(
     919              :                 state, moduleObjectType, this->Name, this->GeneratorInletNodeNum, this->GeneratorOutletNodeNum, LoopErrorsFound);
     920              :         } else {
     921            0 :             for (int PltSizIndex = 1; PltSizIndex <= state.dataSize->NumPltSizInput; ++PltSizIndex) {
     922            0 :                 if (state.dataSize->PlantSizData(PltSizIndex).LoopType == DataSizing::TypeOfPlantLoop::Heating) {
     923            0 :                     PltSizHeatingNum = PltSizIndex;
     924              :                 }
     925              :             }
     926              :         }
     927              :     }
     928              : 
     929           20 :     if (PltSizNum > 0) {
     930            0 :         if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
     931              : 
     932            0 :             Real64 Cp = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getSpecificHeat(state, Constant::CWInitConvTemp, RoutineName);
     933              : 
     934            0 :             Real64 rho = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
     935            0 :             tmpNomCap =
     936            0 :                 Cp * rho * state.dataSize->PlantSizData(PltSizNum).DeltaT * state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate * this->SizFac;
     937            0 :             if (!this->NomCapWasAutoSized) {
     938            0 :                 tmpNomCap = this->NomCap;
     939              :             }
     940              :         } else {
     941            0 :             if (this->NomCapWasAutoSized) {
     942            0 :                 tmpNomCap = 0.0;
     943              :             }
     944              :         }
     945            0 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     946            0 :             if (this->NomCapWasAutoSized) {
     947            0 :                 this->NomCap = tmpNomCap;
     948            0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     949            0 :                     BaseSizer::reportSizerOutput(state, moduleObjectType, this->Name, "Design Size Nominal Capacity [W]", tmpNomCap);
     950              :                 }
     951            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
     952            0 :                     BaseSizer::reportSizerOutput(state, moduleObjectType, this->Name, "Initial Design Size Nominal Capacity [W]", tmpNomCap);
     953              :                 }
     954              :             } else {
     955            0 :                 if (this->NomCap > 0.0 && tmpNomCap > 0.0) {
     956            0 :                     Real64 NomCapUser = this->NomCap;
     957            0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     958            0 :                         BaseSizer::reportSizerOutput(state,
     959              :                                                      moduleObjectType,
     960              :                                                      this->Name,
     961              :                                                      "Design Size Nominal Capacity [W]",
     962              :                                                      tmpNomCap,
     963              :                                                      "User-Specified Nominal Capacity [W]",
     964              :                                                      NomCapUser);
     965            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
     966            0 :                             if ((std::abs(tmpNomCap - NomCapUser) / NomCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
     967            0 :                                 ShowMessage(state, format("SizeChillerAbsorption: Potential issue with equipment sizing for {}", this->Name));
     968            0 :                                 ShowContinueError(state, format("User-Specified Nominal Capacity of {:.2R} [W]", NomCapUser));
     969            0 :                                 ShowContinueError(state, format("differs from Design Size Nominal Capacity of {:.2R} [W]", tmpNomCap));
     970            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
     971            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
     972              :                             }
     973              :                         }
     974              :                     }
     975            0 :                     tmpNomCap = NomCapUser;
     976              :                 }
     977              :             }
     978              :         }
     979              :     } else {
     980           20 :         if (this->NomCapWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     981            0 :             ShowSevereError(state, "Autosizing of Absorption Chiller nominal capacity requires a loop Sizing:Plant object");
     982            0 :             ShowContinueError(state, format("Occurs in Chiller:Absorption object={}", this->Name));
     983            0 :             ErrorsFound = true;
     984              :         }
     985           20 :         if (!this->NomCapWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && this->NomCap > 0.0) {
     986            4 :             BaseSizer::reportSizerOutput(state, moduleObjectType, this->Name, "User-Specified Nominal Capacity [W]", this->NomCap);
     987              :         }
     988              :     }
     989              : 
     990              :     // local nominal pump power
     991           20 :     Real64 tmpNomPumpPower = 0.0045 * this->NomCap;
     992              : 
     993           20 :     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
     994              :         // the DOE-2 EIR for single stage absorption chiller
     995            4 :         if (this->NomPumpPowerWasAutoSized) {
     996            0 :             this->NomPumpPower = tmpNomPumpPower;
     997            0 :             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
     998            0 :                 BaseSizer::reportSizerOutput(state, moduleObjectType, this->Name, "Design Size Nominal Pumping Power [W]", tmpNomPumpPower);
     999              :             }
    1000            0 :             if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1001            0 :                 BaseSizer::reportSizerOutput(state, moduleObjectType, this->Name, "Initial Design Size Nominal Pumping Power [W]", tmpNomPumpPower);
    1002              :             }
    1003              :         } else {
    1004            4 :             if (this->NomPumpPower > 0.0 && tmpNomPumpPower > 0.0) {
    1005              :                 // Hardsized nominal pump power for reporting
    1006            4 :                 Real64 NomPumpPowerUser = this->NomPumpPower;
    1007              : 
    1008            4 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1009            4 :                     BaseSizer::reportSizerOutput(state,
    1010              :                                                  moduleObjectType,
    1011              :                                                  this->Name,
    1012              :                                                  "Design Size Nominal Pumping Power [W]",
    1013              :                                                  tmpNomPumpPower,
    1014              :                                                  "User-Specified Nominal Pumping Power [W]",
    1015              :                                                  NomPumpPowerUser);
    1016            4 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    1017            0 :                         if ((std::abs(tmpNomPumpPower - NomPumpPowerUser) / NomPumpPowerUser) > state.dataSize->AutoVsHardSizingThreshold) {
    1018            0 :                             ShowMessage(state, format("SizeChillerAbsorption: Potential issue with equipment sizing for {}", this->Name));
    1019            0 :                             ShowContinueError(state, format("User-Specified Nominal Pumping Power of {:.2R} [W]", NomPumpPowerUser));
    1020            0 :                             ShowContinueError(state, format("differs from Design Size Nominal Pumping Power of {:.2R} [W]", tmpNomPumpPower));
    1021            0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1022            0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1023              :                         }
    1024              :                     }
    1025              :                 }
    1026            4 :                 tmpNomPumpPower = NomPumpPowerUser;
    1027              :             }
    1028              :         }
    1029              :     }
    1030              : 
    1031           20 :     if (PltSizNum > 0) {
    1032            0 :         if (state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate >= HVAC::SmallWaterVolFlow) {
    1033            0 :             tmpEvapVolFlowRate = state.dataSize->PlantSizData(PltSizNum).DesVolFlowRate * this->SizFac;
    1034            0 :             if (!this->EvapVolFlowRateWasAutoSized) {
    1035            0 :                 tmpEvapVolFlowRate = this->EvapVolFlowRate;
    1036              :             }
    1037              :         } else {
    1038            0 :             if (this->EvapVolFlowRateWasAutoSized) {
    1039            0 :                 tmpEvapVolFlowRate = 0.0;
    1040              :             }
    1041              :         }
    1042            0 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1043            0 :             if (this->EvapVolFlowRateWasAutoSized) {
    1044            0 :                 this->EvapVolFlowRate = tmpEvapVolFlowRate;
    1045            0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1046            0 :                     BaseSizer::reportSizerOutput(
    1047              :                         state, moduleObjectType, this->Name, "Design Size Design Chilled Water Flow Rate [m3/s]", tmpEvapVolFlowRate);
    1048              :                 }
    1049            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1050            0 :                     BaseSizer::reportSizerOutput(
    1051              :                         state, moduleObjectType, this->Name, "Initial Design Size Design Chilled Water Flow Rate [m3/s]", tmpEvapVolFlowRate);
    1052              :                 }
    1053              :             } else {
    1054            0 :                 if (this->EvapVolFlowRate > 0.0 && tmpEvapVolFlowRate > 0.0) {
    1055              :                     // Hardsized evaporator volume flow rate for reporting
    1056            0 :                     Real64 EvapVolFlowRateUser = this->EvapVolFlowRate;
    1057            0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1058            0 :                         BaseSizer::reportSizerOutput(state,
    1059              :                                                      moduleObjectType,
    1060              :                                                      this->Name,
    1061              :                                                      "Design Size Design Chilled Water Flow Rate [m3/s]",
    1062              :                                                      tmpEvapVolFlowRate,
    1063              :                                                      "User-Specified Design Chilled Water Flow Rate [m3/s]",
    1064              :                                                      EvapVolFlowRateUser);
    1065            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1066            0 :                             if ((std::abs(tmpEvapVolFlowRate - EvapVolFlowRateUser) / EvapVolFlowRateUser) >
    1067            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1068            0 :                                 ShowMessage(state, format("SizeChillerAbsorption: Potential issue with equipment sizing for {}", this->Name));
    1069            0 :                                 ShowContinueError(state,
    1070            0 :                                                   format("User-Specified Design Chilled Water Flow Rate of {:.5R} [m3/s]", EvapVolFlowRateUser));
    1071            0 :                                 ShowContinueError(
    1072            0 :                                     state, format("differs from Design Size Design Chilled Water Flow Rate of {:.5R} [m3/s]", tmpEvapVolFlowRate));
    1073            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1074            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1075              :                             }
    1076              :                         }
    1077              :                     }
    1078            0 :                     tmpEvapVolFlowRate = EvapVolFlowRateUser;
    1079              :                 }
    1080              :             }
    1081              :         }
    1082              :     } else {
    1083           20 :         if (this->EvapVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1084            0 :             ShowSevereError(state, "Autosizing of Absorption Chiller evap flow rate requires a loop Sizing:Plant object");
    1085            0 :             ShowContinueError(state, format("Occurs in CHILLER:ABSORPTION object={}", this->Name));
    1086            0 :             ErrorsFound = true;
    1087              :         }
    1088           20 :         if (!this->EvapVolFlowRateWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && this->EvapVolFlowRate > 0.0) {
    1089            4 :             BaseSizer::reportSizerOutput(
    1090              :                 state, moduleObjectType, this->Name, "User-Specified Design Chilled Water Flow Rate [m3/s]", this->EvapVolFlowRate);
    1091              :         }
    1092              :     }
    1093              : 
    1094           20 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->EvapInletNodeNum, tmpEvapVolFlowRate);
    1095              : 
    1096           20 :     if (PltSizCondNum > 0 && PltSizNum > 0) {
    1097            0 :         if (this->EvapVolFlowRate >= HVAC::SmallWaterVolFlow && tmpNomCap > 0.0) {
    1098              :             //       QCondenser = QEvaporator + QGenerator + PumpingPower
    1099              : 
    1100            0 :             Real64 Cp = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).glycol->getSpecificHeat(state, this->TempDesCondIn, RoutineName);
    1101              : 
    1102            0 :             Real64 rho = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
    1103            0 :             tmpCondVolFlowRate =
    1104            0 :                 tmpNomCap * (1.0 + SteamInputRatNom + tmpNomPumpPower / tmpNomCap) / (state.dataSize->PlantSizData(PltSizCondNum).DeltaT * Cp * rho);
    1105            0 :             if (!this->CondVolFlowRateWasAutoSized) {
    1106            0 :                 tmpCondVolFlowRate = this->CondVolFlowRate;
    1107              :             }
    1108              : 
    1109            0 :         } else {
    1110            0 :             if (this->CondVolFlowRateWasAutoSized) {
    1111            0 :                 tmpCondVolFlowRate = 0.0;
    1112              :             }
    1113              :         }
    1114            0 :         if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1115            0 :             if (this->CondVolFlowRateWasAutoSized) {
    1116            0 :                 this->CondVolFlowRate = tmpCondVolFlowRate;
    1117            0 :                 if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1118            0 :                     BaseSizer::reportSizerOutput(
    1119              :                         state, moduleObjectType, this->Name, "Design Size Design Condenser Water Flow Rate [m3/s]", tmpCondVolFlowRate);
    1120              :                 }
    1121            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1122            0 :                     BaseSizer::reportSizerOutput(
    1123              :                         state, moduleObjectType, this->Name, "Initial Design Size Design Condenser Water Flow Rate [m3/s]", tmpCondVolFlowRate);
    1124              :                 }
    1125              :             } else {
    1126            0 :                 if (this->CondVolFlowRate > 0.0 && tmpCondVolFlowRate > 0.0) {
    1127              :                     // Hardsized condenser flow rate for reporting
    1128            0 :                     Real64 CondVolFlowRateUser = this->CondVolFlowRate;
    1129            0 :                     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1130            0 :                         BaseSizer::reportSizerOutput(state,
    1131              :                                                      moduleObjectType,
    1132              :                                                      this->Name,
    1133              :                                                      "Design Size Design Condenser Water Flow Rate [m3/s]",
    1134              :                                                      tmpCondVolFlowRate,
    1135              :                                                      "User-Specified Design Condenser Water Flow Rate [m3/s]",
    1136              :                                                      CondVolFlowRateUser);
    1137            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1138            0 :                             if ((std::abs(tmpCondVolFlowRate - CondVolFlowRateUser) / CondVolFlowRateUser) >
    1139            0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    1140            0 :                                 ShowMessage(state, format("SizeChillerAbsorption: Potential issue with equipment sizing for {}", this->Name));
    1141            0 :                                 ShowContinueError(state,
    1142            0 :                                                   format("User-Specified Design Condenser Water Flow Rate of {:.5R} [m3/s]", CondVolFlowRateUser));
    1143            0 :                                 ShowContinueError(
    1144            0 :                                     state, format("differs from Design Size Design Condenser Water Flow Rate of {:.5R} [m3/s]", tmpCondVolFlowRate));
    1145            0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1146            0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    1147              :                             }
    1148              :                         }
    1149              :                     }
    1150            0 :                     tmpCondVolFlowRate = CondVolFlowRateUser;
    1151              :                 }
    1152              :             }
    1153              :         }
    1154            0 :     } else {
    1155           20 :         if (this->CondVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1156            0 :             ShowSevereError(state, "Autosizing of Absorption Chiller condenser flow rate requires a condenser");
    1157            0 :             ShowContinueError(state, "loop Sizing:Plant object");
    1158            0 :             ShowContinueError(state, format("Occurs in CHILLER:ABSORPTION object={}", this->Name));
    1159            0 :             ErrorsFound = true;
    1160              :         }
    1161           20 :         if (!this->CondVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize && (this->CondVolFlowRate > 0.0)) {
    1162            4 :             BaseSizer::reportSizerOutput(
    1163              :                 state, moduleObjectType, this->Name, "User-Specified Design Condenser Water Flow Rate [m3/s]", this->CondVolFlowRate);
    1164              :         }
    1165              :     }
    1166              : 
    1167              :     // save the design condenser water volumetric flow rate for use by the condenser water loop sizing algorithms
    1168           20 :     PlantUtilities::RegisterPlantCompDesignFlow(state, this->CondInletNodeNum, tmpCondVolFlowRate);
    1169              : 
    1170           20 :     if ((PltSizSteamNum > 0 && this->GenHeatSourceType == DataLoopNode::NodeFluidType::Steam) ||
    1171            0 :         (PltSizHeatingNum > 0 && this->GenHeatSourceType == DataLoopNode::NodeFluidType::Water)) {
    1172            0 :         if (this->EvapVolFlowRate >= HVAC::SmallWaterVolFlow && tmpNomCap > 0.0) {
    1173            0 :             if (this->GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
    1174            0 :                 Real64 CpWater = state.dataPlnt->PlantLoop(this->GenPlantLoc.loopNum)
    1175            0 :                                      .glycol->getSpecificHeat(state, state.dataSize->PlantSizData(PltSizHeatingNum).ExitTemp, RoutineName);
    1176            0 :                 Real64 SteamDeltaT = max(0.5, state.dataSize->PlantSizData(PltSizHeatingNum).DeltaT);
    1177              :                 Real64 RhoWater =
    1178            0 :                     state.dataPlnt->PlantLoop(this->GenPlantLoc.loopNum)
    1179            0 :                         .glycol->getDensity(state, (state.dataSize->PlantSizData(PltSizHeatingNum).ExitTemp - SteamDeltaT), RoutineName);
    1180            0 :                 tmpGeneratorVolFlowRate = (this->NomCap * SteamInputRatNom) / (CpWater * SteamDeltaT * RhoWater);
    1181            0 :                 if (!this->GeneratorVolFlowRateWasAutoSized) {
    1182            0 :                     tmpGeneratorVolFlowRate = this->GeneratorVolFlowRate;
    1183              :                 }
    1184            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1185            0 :                     if (this->GeneratorVolFlowRateWasAutoSized) {
    1186            0 :                         this->GeneratorVolFlowRate = tmpGeneratorVolFlowRate;
    1187            0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1188            0 :                             BaseSizer::reportSizerOutput(
    1189              :                                 state, moduleObjectType, this->Name, "Design Size Design Generator Fluid Flow Rate [m3/s]", tmpGeneratorVolFlowRate);
    1190              :                         }
    1191            0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1192            0 :                             BaseSizer::reportSizerOutput(state,
    1193              :                                                          moduleObjectType,
    1194              :                                                          this->Name,
    1195              :                                                          "Initial Design Size Design Generator Fluid Flow Rate [m3/s]",
    1196              :                                                          tmpGeneratorVolFlowRate);
    1197              :                         }
    1198              :                     } else {
    1199            0 :                         if (this->GeneratorVolFlowRate > 0.0 && tmpGeneratorVolFlowRate > 0.0) {
    1200              :                             // Hardsized generator flow rate for reporting
    1201            0 :                             Real64 GeneratorVolFlowRateUser = this->GeneratorVolFlowRate;
    1202            0 :                             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1203            0 :                                 BaseSizer::reportSizerOutput(state,
    1204              :                                                              moduleObjectType,
    1205              :                                                              this->Name,
    1206              :                                                              "Design Size Design Generator Fluid Flow Rate [m3/s]",
    1207              :                                                              tmpGeneratorVolFlowRate,
    1208              :                                                              "User-Specified Design Generator Fluid Flow Rate [m3/s]",
    1209              :                                                              GeneratorVolFlowRateUser);
    1210            0 :                                 if (state.dataGlobal->DisplayExtraWarnings) {
    1211            0 :                                     if ((std::abs(tmpGeneratorVolFlowRate - GeneratorVolFlowRateUser) / GeneratorVolFlowRateUser) >
    1212            0 :                                         state.dataSize->AutoVsHardSizingThreshold) {
    1213            0 :                                         ShowMessage(state, format("SizeChillerAbsorption: Potential issue with equipment sizing for {}", this->Name));
    1214            0 :                                         ShowContinueError(
    1215              :                                             state,
    1216            0 :                                             format("User-Specified Design Generator Fluid Flow Rate of {:.5R} [m3/s]", GeneratorVolFlowRateUser));
    1217            0 :                                         ShowContinueError(state,
    1218            0 :                                                           format("differs from Design Size Design Generator Fluid Flow Rate of {:.5R} [m3/s]",
    1219              :                                                                  tmpGeneratorVolFlowRate));
    1220            0 :                                         ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1221            0 :                                         ShowContinueError(state,
    1222              :                                                           "Verify that the value entered is intended and is consistent with other components.");
    1223              :                                     }
    1224              :                                 }
    1225              :                             }
    1226            0 :                             tmpGeneratorVolFlowRate = GeneratorVolFlowRateUser;
    1227              :                         }
    1228              :                     }
    1229              :                 }
    1230              :             } else {
    1231            0 :                 constexpr std::string_view RoutineNameLong("SizeAbsorptionChiller");
    1232            0 :                 Real64 SteamDensity = this->steam->getSatDensity(state, state.dataSize->PlantSizData(PltSizSteamNum).ExitTemp, 1.0, RoutineNameLong);
    1233            0 :                 Real64 SteamDeltaT = state.dataSize->PlantSizData(PltSizSteamNum).DeltaT;
    1234            0 :                 Real64 GeneratorOutletTemp = state.dataSize->PlantSizData(PltSizSteamNum).ExitTemp - SteamDeltaT;
    1235              : 
    1236              :                 Real64 EnthSteamOutDry =
    1237            0 :                     this->steam->getSatEnthalpy(state, state.dataSize->PlantSizData(PltSizSteamNum).ExitTemp, 1.0, moduleObjectType + this->Name);
    1238              :                 Real64 EnthSteamOutWet =
    1239            0 :                     this->steam->getSatEnthalpy(state, state.dataSize->PlantSizData(PltSizSteamNum).ExitTemp, 0.0, moduleObjectType + this->Name);
    1240            0 :                 Real64 CpWater = this->water->getSpecificHeat(state, GeneratorOutletTemp, RoutineName);
    1241            0 :                 Real64 HfgSteam = EnthSteamOutDry - EnthSteamOutWet;
    1242            0 :                 this->SteamMassFlowRate = (this->NomCap * SteamInputRatNom) / ((HfgSteam) + (SteamDeltaT * CpWater));
    1243            0 :                 tmpGeneratorVolFlowRate = this->SteamMassFlowRate / SteamDensity;
    1244              : 
    1245            0 :                 if (!this->GeneratorVolFlowRateWasAutoSized) {
    1246            0 :                     tmpGeneratorVolFlowRate = this->GeneratorVolFlowRate;
    1247              :                 }
    1248            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1249              : 
    1250            0 :                     if (this->GeneratorVolFlowRateWasAutoSized) {
    1251            0 :                         this->GeneratorVolFlowRate = tmpGeneratorVolFlowRate;
    1252            0 :                         if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1253            0 :                             BaseSizer::reportSizerOutput(
    1254              :                                 state, moduleObjectType, this->Name, "Design Size Design Generator Fluid Flow Rate [m3/s]", tmpGeneratorVolFlowRate);
    1255              :                         }
    1256            0 :                         if (state.dataPlnt->PlantFirstSizesOkayToReport) {
    1257            0 :                             BaseSizer::reportSizerOutput(state,
    1258              :                                                          moduleObjectType,
    1259              :                                                          this->Name,
    1260              :                                                          "Initial Design Size Design Generator Fluid Flow Rate [m3/s]",
    1261              :                                                          tmpGeneratorVolFlowRate);
    1262              :                         }
    1263              :                     } else {
    1264            0 :                         if (this->GeneratorVolFlowRate > 0.0 && tmpGeneratorVolFlowRate > 0.0) {
    1265              :                             // Hardsized generator flow rate for reporting
    1266            0 :                             Real64 GeneratorVolFlowRateUser = this->GeneratorVolFlowRate;
    1267            0 :                             if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1268            0 :                                 BaseSizer::reportSizerOutput(state,
    1269              :                                                              moduleObjectType,
    1270              :                                                              this->Name,
    1271              :                                                              "Design Size Design Generator Fluid Flow Rate [m3/s]",
    1272              :                                                              tmpGeneratorVolFlowRate,
    1273              :                                                              "User-Specified Design Generator Fluid Flow Rate [m3/s]",
    1274              :                                                              GeneratorVolFlowRateUser);
    1275            0 :                                 if (state.dataGlobal->DisplayExtraWarnings) {
    1276            0 :                                     if ((std::abs(tmpGeneratorVolFlowRate - GeneratorVolFlowRateUser) / GeneratorVolFlowRateUser) >
    1277            0 :                                         state.dataSize->AutoVsHardSizingThreshold) {
    1278            0 :                                         ShowMessage(state, format("SizeChillerAbsorption: Potential issue with equipment sizing for {}", this->Name));
    1279            0 :                                         ShowContinueError(
    1280              :                                             state,
    1281            0 :                                             format("User-Specified Design Generator Fluid Flow Rate of {:.5R} [m3/s]", GeneratorVolFlowRateUser));
    1282            0 :                                         ShowContinueError(state,
    1283            0 :                                                           format("differs from Design Size Design Generator Fluid Flow Rate of {:.5R} [m3/s]",
    1284              :                                                                  tmpGeneratorVolFlowRate));
    1285            0 :                                         ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    1286            0 :                                         ShowContinueError(state,
    1287              :                                                           "Verify that the value entered is intended and is consistent with other components.");
    1288              :                                     }
    1289              :                                 }
    1290              :                             }
    1291            0 :                             tmpGeneratorVolFlowRate = GeneratorVolFlowRateUser;
    1292              :                         }
    1293              :                     }
    1294              :                 }
    1295              :             }
    1296            0 :         } else {
    1297            0 :             if (this->GeneratorVolFlowRateWasAutoSized) {
    1298            0 :                 if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1299            0 :                     this->GeneratorVolFlowRate = 0.0;
    1300              :                 } else {
    1301            0 :                     tmpGeneratorVolFlowRate = 0.0;
    1302              :                 }
    1303              :             }
    1304              :         }
    1305            0 :     } else {
    1306           20 :         if (this->GeneratorVolFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1307            0 :             ShowSevereError(state, "Autosizing of Absorption Chiller generator flow rate requires a loop Sizing:Plant object.");
    1308            0 :             ShowContinueError(state, " For steam loops, use a steam Sizing:Plant object.");
    1309            0 :             ShowContinueError(state, " For hot water loops, use a heating Sizing:Plant object.");
    1310            0 :             ShowContinueError(state, format("Occurs in Chiller:Absorption object={}", this->Name));
    1311            0 :             ErrorsFound = true;
    1312              :         }
    1313           20 :         if (!this->GeneratorVolFlowRateWasAutoSized && state.dataPlnt->PlantFinalSizesOkayToReport && (this->GeneratorVolFlowRate > 0.0)) {
    1314            0 :             BaseSizer::reportSizerOutput(
    1315              :                 state, moduleObjectType, this->Name, "User-Specified Design Generator Fluid Flow Rate [m3/s]", this->GeneratorVolFlowRate);
    1316              :         }
    1317              :     }
    1318              : 
    1319              :     // save the design steam or hot water volumetric flow rate for use by the steam or hot water loop sizing algorithms
    1320           20 :     if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1321            4 :         PlantUtilities::RegisterPlantCompDesignFlow(state, this->GeneratorInletNodeNum, this->GeneratorVolFlowRate);
    1322              :     } else {
    1323           16 :         PlantUtilities::RegisterPlantCompDesignFlow(state, this->GeneratorInletNodeNum, tmpGeneratorVolFlowRate);
    1324              :     }
    1325              : 
    1326           20 :     if (this->GeneratorDeltaTempWasAutoSized) {
    1327           20 :         if (PltSizHeatingNum > 0 && this->GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
    1328            0 :             this->GeneratorDeltaTemp = max(0.5, state.dataSize->PlantSizData(PltSizHeatingNum).DeltaT);
    1329           20 :         } else if (this->GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
    1330            0 :             if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
    1331              :                 Real64 Cp =
    1332            0 :                     state.dataPlnt->PlantLoop(this->GenPlantLoc.loopNum).glycol->getSpecificHeat(state, Constant::HWInitConvTemp, RoutineName);
    1333            0 :                 Real64 rho = state.dataPlnt->PlantLoop(this->GenPlantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    1334              : 
    1335            0 :                 this->GeneratorDeltaTemp = (SteamInputRatNom * this->NomCap) / (Cp * rho * this->GeneratorVolFlowRate);
    1336              :             }
    1337              :         }
    1338              :     }
    1339              : 
    1340           20 :     if (ErrorsFound) {
    1341            0 :         ShowFatalError(state, "Preceding sizing errors cause program termination");
    1342              :     }
    1343              : 
    1344           20 :     if (state.dataPlnt->PlantFinalSizesOkayToReport) {
    1345              :         // create predefined report
    1346            4 :         std::string equipName = this->Name;
    1347            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechType, equipName, moduleObjectType);
    1348            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomEff, equipName, "n/a");
    1349            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, equipName, this->NomCap);
    1350              : 
    1351              :         // std 229 new Chiller table
    1352            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerType, this->Name, moduleObjectType);
    1353            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefCap, this->Name, this->NomCap);
    1354            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefEff, this->Name, "N/A");
    1355            8 :         OutputReportPredefined::PreDefTableEntry(
    1356            4 :             state, state.dataOutRptPredefined->pdchChillerRatedCap, this->Name, this->NomCap); // did not find rated cap, using Nominal
    1357            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRatedEff, this->Name, "N/A");
    1358            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerIPLVinSI, this->Name, "N/A");
    1359            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerIPLVinIP, this->Name, "N/A");
    1360            8 :         OutputReportPredefined::PreDefTableEntry(state,
    1361            4 :                                                  state.dataOutRptPredefined->pdchChillerPlantloopName,
    1362              :                                                  this->Name,
    1363            8 :                                                  this->CWPlantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).Name : "N/A");
    1364            8 :         OutputReportPredefined::PreDefTableEntry(
    1365              :             state,
    1366            4 :             state.dataOutRptPredefined->pdchChillerPlantloopBranchName,
    1367              :             this->Name,
    1368            4 :             this->CWPlantLoc.loopNum > 0
    1369            8 :                 ? state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).LoopSide(this->CWPlantLoc.loopSideNum).Branch(this->CWPlantLoc.branchNum).Name
    1370              :                 : "N/A");
    1371            8 :         OutputReportPredefined::PreDefTableEntry(state,
    1372            4 :                                                  state.dataOutRptPredefined->pdchChillerCondLoopName,
    1373              :                                                  this->Name,
    1374            8 :                                                  this->CDPlantLoc.loopNum > 0 ? state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).Name : "N/A");
    1375            8 :         OutputReportPredefined::PreDefTableEntry(
    1376              :             state,
    1377            4 :             state.dataOutRptPredefined->pdchChillerCondLoopBranchName,
    1378              :             this->Name,
    1379            4 :             this->CDPlantLoc.loopNum > 0
    1380            8 :                 ? state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum).LoopSide(this->CDPlantLoc.loopSideNum).Branch(this->CDPlantLoc.branchNum).Name
    1381              :                 : "N/A");
    1382            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerMinPLR, this->Name, this->MinPartLoadRat);
    1383            8 :         OutputReportPredefined::PreDefTableEntry(state,
    1384            4 :                                                  state.dataOutRptPredefined->pdchChillerFuelType,
    1385              :                                                  this->Name,
    1386            4 :                                                  DataLoopNode::NodeFluidTypeNames[static_cast<int>(this->GenHeatSourceType)]);
    1387            8 :         OutputReportPredefined::PreDefTableEntry(
    1388            4 :             state, state.dataOutRptPredefined->pdchChillerRatedEntCondTemp, this->Name, this->TempDesCondIn); // Rated==Ref?
    1389            8 :         OutputReportPredefined::PreDefTableEntry(
    1390            4 :             state, state.dataOutRptPredefined->pdchChillerRatedLevEvapTemp, this->Name, this->TempLowLimitEvapOut); // Rated==Ref?
    1391            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefEntCondTemp, this->Name, this->TempDesCondIn);
    1392            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRefLevEvapTemp, this->Name, this->TempLowLimitEvapOut);
    1393              : 
    1394            8 :         OutputReportPredefined::PreDefTableEntry(state,
    1395            4 :                                                  state.dataOutRptPredefined->pdchChillerDesSizeRefCHWFlowRate,
    1396              :                                                  this->Name,
    1397              :                                                  this->EvapMassFlowRateMax); // flowrate Max==DesignSizeRef flowrate?
    1398            8 :         OutputReportPredefined::PreDefTableEntry(state,
    1399            4 :                                                  state.dataOutRptPredefined->pdchChillerDesSizeRefCondFluidFlowRate,
    1400              :                                                  this->Name,
    1401              :                                                  this->CondMassFlowRateMax); // Cond flowrate Max==DesignSizeRef Cond flowrate?
    1402            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerHeatRecPlantloopName, this->Name, "N/A");
    1403            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerHeatRecPlantloopBranchName, this->Name, "N/A");
    1404            4 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchChillerRecRelCapFrac, this->Name, "N/A");
    1405            4 :     }
    1406           20 : }
    1407              : 
    1408        38898 : void BLASTAbsorberSpecs::calculate(EnergyPlusData &state, Real64 &MyLoad, bool RunFlag)
    1409              : {
    1410              :     // SUBROUTINE INFORMATION:
    1411              :     //       AUTHOR         Dan Fisher
    1412              :     //       DATE WRITTEN   Sept. 1998
    1413              :     //       MODIFIED       Apr. 1999, May 2000- Taecheol Kim
    1414              :     //                      May. 2008, R. Raustad, Added generator nodes
    1415              :     //                      Jun. 2016, Rongpeng Zhang, Applied the chiller supply water temperature sensor fault model
    1416              : 
    1417              :     // PURPOSE OF THIS SUBROUTINE:
    1418              :     // simulate a vapor compression Absorber using the BLAST model
    1419              : 
    1420              :     // METHODOLOGY EMPLOYED:
    1421              :     // curve fit of performance data:
    1422              : 
    1423              :     // REFERENCES:
    1424              :     // 1.  BLAST User Manual
    1425              :     // 2.  Absorber User Manual
    1426              : 
    1427        38898 :     constexpr const char *RoutineName("CalcBLASTAbsorberModel");
    1428              : 
    1429        38898 :     Real64 EvapDeltaTemp(0.0); // C - evaporator temperature difference, water side
    1430              : 
    1431              :     // If no loop demand or Absorber OFF, return
    1432        38898 :     if (MyLoad >= 0.0 || !RunFlag) { // off or heating
    1433        19682 :         if (this->EquipFlowCtrl == DataBranchAirLoopPlant::ControlType::SeriesActive) {
    1434            0 :             this->EvapMassFlowRate = state.dataLoopNodes->Node(this->EvapInletNodeNum).MassFlowRate;
    1435              :         }
    1436        19682 :         return;
    1437              :     }
    1438              : 
    1439              :     // Set the condenser mass flow rates
    1440        19216 :     this->CondMassFlowRate = state.dataLoopNodes->Node(this->CondInletNodeNum).MassFlowRate;
    1441              : 
    1442        19216 :     Real64 TempEvapOut = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;
    1443              : 
    1444        19216 :     Real64 CpFluid = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum)
    1445        19216 :                          .glycol->getSpecificHeat(state, state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp, RoutineName);
    1446              : 
    1447              :     // If there is a fault of Chiller SWT Sensor
    1448        19216 :     if (this->FaultyChillerSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation)) {
    1449            0 :         int FaultIndex = this->FaultyChillerSWTIndex;
    1450            0 :         Real64 EvapOutletTemp_ff = TempEvapOut;
    1451              : 
    1452              :         // calculate the sensor offset using fault information
    1453            0 :         this->FaultyChillerSWTOffset = state.dataFaultsMgr->FaultsChillerSWTSensor(FaultIndex).CalFaultOffsetAct(state);
    1454              :         // update the TempEvapOut
    1455            0 :         TempEvapOut = max(this->TempLowLimitEvapOut,
    1456            0 :                           min(state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp, EvapOutletTemp_ff - this->FaultyChillerSWTOffset));
    1457            0 :         this->FaultyChillerSWTOffset = EvapOutletTemp_ff - TempEvapOut;
    1458              :     }
    1459              : 
    1460              :     // If FlowLock is True, the new resolved mdot is used to update Power, QEvap, Qcond, and
    1461              :     // condenser side outlet temperature.
    1462        19216 :     if (state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).LoopSide(this->CWPlantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked) {
    1463         9608 :         this->PossibleSubcooling = false;
    1464         9608 :         this->QEvaporator = std::abs(MyLoad);
    1465              :         // limit by max capacity
    1466         9608 :         this->QEvaporator = min(this->QEvaporator, (this->MaxPartLoadRat * this->NomCap));
    1467              : 
    1468              :         // Either set the flow to the Constant value or calculate the flow for the variable volume
    1469         9608 :         if ((this->FlowMode == DataPlant::FlowMode::Constant) || (this->FlowMode == DataPlant::FlowMode::NotModulated)) {
    1470            0 :             this->EvapMassFlowRate = state.dataLoopNodes->Node(this->EvapInletNodeNum).MassFlowRate;
    1471              : 
    1472            0 :             if (this->EvapMassFlowRate != 0.0) {
    1473            0 :                 EvapDeltaTemp = this->QEvaporator / this->EvapMassFlowRate / CpFluid;
    1474              :             } else {
    1475            0 :                 EvapDeltaTemp = 0.0;
    1476              :             }
    1477            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - EvapDeltaTemp;
    1478              : 
    1479         9608 :         } else if (this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) {
    1480              :             // Calculate the Delta Temp from the inlet temp to the chiller outlet setpoint
    1481         9608 :             switch (state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).LoopDemandCalcScheme) {
    1482         9608 :             case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1483         9608 :                 EvapDeltaTemp =
    1484         9608 :                     state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    1485         9608 :             } break;
    1486            0 :             case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1487            0 :                 EvapDeltaTemp =
    1488            0 :                     state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    1489            0 :             } break;
    1490            0 :             default: {
    1491            0 :                 assert(false);
    1492              :             } break;
    1493              :             }
    1494         9608 :             if (EvapDeltaTemp != 0) {
    1495              : 
    1496         9608 :                 this->EvapMassFlowRate = std::abs(this->QEvaporator / CpFluid / EvapDeltaTemp);
    1497         9608 :                 if ((this->EvapMassFlowRate - this->EvapMassFlowRateMax) > DataBranchAirLoopPlant::MassFlowTolerance) {
    1498            0 :                     this->PossibleSubcooling = true;
    1499              :                 }
    1500              :                 // Check to see if the Maximum is exceeded, if so set to maximum
    1501         9608 :                 this->EvapMassFlowRate = min(this->EvapMassFlowRateMax, this->EvapMassFlowRate);
    1502         9608 :                 PlantUtilities::SetComponentFlowRate(
    1503         9608 :                     state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    1504         9608 :                 switch (state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).LoopDemandCalcScheme) {
    1505         9608 :                 case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1506         9608 :                     this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    1507         9608 :                 } break;
    1508            0 :                 case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1509            0 :                     this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    1510            0 :                 } break;
    1511            0 :                 default:
    1512            0 :                     break;
    1513              :                 }
    1514              :             } else {
    1515            0 :                 this->EvapMassFlowRate = 0.0;
    1516              : 
    1517            0 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1518              : 
    1519            0 :                 ShowRecurringWarningErrorAtEnd(state,
    1520            0 :                                                "CalcBLASTAbsorberModel: Name=\"" + this->Name +
    1521              :                                                    "\" Evaporative Condenser Delta Temperature = 0 in mass flow calculation.",
    1522            0 :                                                this->ErrCount2);
    1523              :             }
    1524              :         } // End of Constant Variable Flow If Block
    1525              : 
    1526              :         // If there is a fault of Chiller SWT Sensor
    1527            0 :         if (this->FaultyChillerSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    1528         9608 :             (!state.dataGlobal->KickOffSimulation) && (this->EvapMassFlowRate > 0)) {
    1529              :             // calculate directly affected variables at faulty case: EvapOutletTemp, EvapMassFlowRate, QEvaporator
    1530            0 :             int FaultIndex = this->FaultyChillerSWTIndex;
    1531            0 :             bool VarFlowFlag = (this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated);
    1532            0 :             state.dataFaultsMgr->FaultsChillerSWTSensor(FaultIndex)
    1533            0 :                 .CalFaultChillerSWT(VarFlowFlag,
    1534              :                                     this->FaultyChillerSWTOffset,
    1535              :                                     CpFluid,
    1536            0 :                                     state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp,
    1537            0 :                                     this->EvapOutletTemp,
    1538            0 :                                     this->EvapMassFlowRate,
    1539            0 :                                     this->QEvaporator);
    1540              :             // update corresponding variables at faulty case
    1541              :             // PartLoadRat = ( AvailChillerCap > 0.0 ) ? ( QEvaporator / AvailChillerCap ) : 0.0;
    1542              :             // PartLoadRat = max( 0.0, min( PartLoadRat, MaxPartLoadRat ));
    1543              :             // ChillerPartLoadRatio = PartLoadRat;
    1544              :         }
    1545              : 
    1546              :     } else { // If FlowLock is True
    1547              : 
    1548         9608 :         this->EvapMassFlowRate = state.dataLoopNodes->Node(this->EvapInletNodeNum).MassFlowRate;
    1549         9608 :         if (this->PossibleSubcooling) {
    1550            0 :             this->QEvaporator = std::abs(MyLoad);
    1551            0 :             EvapDeltaTemp = this->QEvaporator / this->EvapMassFlowRate / CpFluid;
    1552            0 :             this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - EvapDeltaTemp;
    1553              :         } else {
    1554         9608 :             Real64 TempEvapOutSetPoint{0}; // C - evaporator outlet temperature setpoint
    1555         9608 :             switch (state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).LoopDemandCalcScheme) {
    1556         9608 :             case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
    1557        19216 :                 if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) ||
    1558         9608 :                     (DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).CurOpSchemeType == DataPlant::OpScheme::CompSetPtBased) ||
    1559            0 :                     (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint != DataLoopNode::SensedNodeFlagValue)) {
    1560         9608 :                     TempEvapOutSetPoint = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPoint;
    1561              :                 } else {
    1562            0 :                     TempEvapOutSetPoint =
    1563            0 :                         state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
    1564              :                 }
    1565         9608 :             } break;
    1566            0 :             case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
    1567            0 :                 if ((this->FlowMode == DataPlant::FlowMode::LeavingSetpointModulated) ||
    1568            0 :                     (DataPlant::CompData::getPlantComponent(state, this->CWPlantLoc).CurOpSchemeType == DataPlant::OpScheme::CompSetPtBased) ||
    1569            0 :                     (state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi != DataLoopNode::SensedNodeFlagValue)) {
    1570            0 :                     TempEvapOutSetPoint = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempSetPointHi;
    1571              :                 } else {
    1572            0 :                     TempEvapOutSetPoint =
    1573            0 :                         state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
    1574              :                 }
    1575            0 :             } break;
    1576            0 :             default: {
    1577            0 :                 assert(false);
    1578              :             } break;
    1579              :             }
    1580         9608 :             EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - TempEvapOutSetPoint;
    1581         9608 :             this->QEvaporator = std::abs(this->EvapMassFlowRate * CpFluid * EvapDeltaTemp);
    1582         9608 :             this->EvapOutletTemp = TempEvapOutSetPoint;
    1583              :         }
    1584              :         // Check that the Evap outlet temp honors both plant loop temp low limit and also the chiller low limit
    1585         9608 :         if (this->EvapOutletTemp < this->TempLowLimitEvapOut) {
    1586            0 :             if ((state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->TempLowLimitEvapOut) > DataPlant::DeltaTempTol) {
    1587            0 :                 this->EvapOutletTemp = this->TempLowLimitEvapOut;
    1588            0 :                 EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->EvapOutletTemp;
    1589            0 :                 this->QEvaporator = this->EvapMassFlowRate * CpFluid * EvapDeltaTemp;
    1590              :             } else {
    1591            0 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1592            0 :                 EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->EvapOutletTemp;
    1593            0 :                 this->QEvaporator = this->EvapMassFlowRate * CpFluid * EvapDeltaTemp;
    1594              :             }
    1595              :         }
    1596         9608 :         if (this->EvapOutletTemp < state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempMin) {
    1597            0 :             if ((state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempMin) >
    1598              :                 DataPlant::DeltaTempTol) {
    1599            0 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).TempMin;
    1600            0 :                 EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->EvapOutletTemp;
    1601            0 :                 this->QEvaporator = this->EvapMassFlowRate * CpFluid * EvapDeltaTemp;
    1602              :             } else {
    1603            0 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1604            0 :                 EvapDeltaTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - this->EvapOutletTemp;
    1605            0 :                 this->QEvaporator = this->EvapMassFlowRate * CpFluid * EvapDeltaTemp;
    1606              :             }
    1607              :         }
    1608              : 
    1609              :         // Checks QEvaporator on the basis of the machine limits.
    1610         9608 :         if (this->QEvaporator > std::abs(MyLoad)) {
    1611           38 :             if (this->EvapMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
    1612           38 :                 this->QEvaporator = std::abs(MyLoad);
    1613           38 :                 EvapDeltaTemp = this->QEvaporator / this->EvapMassFlowRate / CpFluid;
    1614           38 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp - EvapDeltaTemp;
    1615              :             } else {
    1616            0 :                 this->QEvaporator = 0.0;
    1617            0 :                 this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1618              :             }
    1619              :         }
    1620              : 
    1621              :         // If there is a fault of Chiller SWT Sensor
    1622            0 :         if (this->FaultyChillerSWTFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
    1623         9608 :             (!state.dataGlobal->KickOffSimulation) && (this->EvapMassFlowRate > 0)) {
    1624              :             // calculate directly affected variables at faulty case: EvapOutletTemp, EvapMassFlowRate, QEvaporator
    1625            0 :             int FaultIndex = this->FaultyChillerSWTIndex;
    1626            0 :             bool VarFlowFlag = false;
    1627            0 :             state.dataFaultsMgr->FaultsChillerSWTSensor(FaultIndex)
    1628            0 :                 .CalFaultChillerSWT(VarFlowFlag,
    1629              :                                     this->FaultyChillerSWTOffset,
    1630              :                                     CpFluid,
    1631            0 :                                     state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp,
    1632            0 :                                     this->EvapOutletTemp,
    1633            0 :                                     this->EvapMassFlowRate,
    1634            0 :                                     this->QEvaporator);
    1635              :             // update corresponding variables at faulty case
    1636              :         }
    1637              : 
    1638              :     } // This is the end of the FlowLock Block
    1639              : 
    1640              :     // Calculate part load ratio for efficiency calcs. If this part load ratio is greater than
    1641              :     // Min PLR it will be used for calculations too.
    1642        19216 :     Real64 PartLoadRat = max(this->MinPartLoadRat, min(this->QEvaporator / this->NomCap, this->MaxPartLoadRat));
    1643              : 
    1644              :     // In case MyLoad is less than the Min PLR load, the power and steam input should be adjusted
    1645              :     // for cycling. The ratios used however are based on MinPLR.
    1646        19216 :     Real64 OperPartLoadRat = this->QEvaporator / this->NomCap;
    1647              : 
    1648        19216 :     Real64 FRAC = 1.0;
    1649        19216 :     if (OperPartLoadRat < PartLoadRat) {
    1650        16480 :         FRAC = min(1.0, OperPartLoadRat / this->MinPartLoadRat);
    1651              :     }
    1652              : 
    1653              :     // Calculate steam input ratio
    1654        19216 :     Real64 SteamInputRat = this->SteamLoadCoef[0] / PartLoadRat + this->SteamLoadCoef[1] + this->SteamLoadCoef[2] * PartLoadRat;
    1655              : 
    1656              :     // Calculate electric input ratio
    1657        19216 :     Real64 ElectricInputRat = this->PumpPowerCoef[0] + this->PumpPowerCoef[1] * PartLoadRat + this->PumpPowerCoef[2] * pow_2(PartLoadRat);
    1658              : 
    1659              :     // Calculate electric energy input
    1660        19216 :     this->PumpingPower = ElectricInputRat * this->NomPumpPower * FRAC;
    1661              : 
    1662              :     // Calculate steam load
    1663        19216 :     this->QGenerator = SteamInputRat * this->QEvaporator * FRAC;
    1664              : 
    1665        19216 :     if (this->EvapMassFlowRate == 0.0) {
    1666            0 :         this->QGenerator = 0.0;
    1667            0 :         this->EvapOutletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1668            0 :         this->PumpingPower = 0.0;
    1669              :     }
    1670              : 
    1671        19216 :     this->QCondenser = this->QEvaporator + this->QGenerator + this->PumpingPower;
    1672              : 
    1673        19216 :     CpFluid = state.dataPlnt->PlantLoop(this->CDPlantLoc.loopNum)
    1674        19216 :                   .glycol->getSpecificHeat(state, state.dataLoopNodes->Node(this->CondInletNodeNum).Temp, RoutineName);
    1675              : 
    1676        19216 :     if (this->CondMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
    1677        19216 :         this->CondOutletTemp = this->QCondenser / this->CondMassFlowRate / CpFluid + state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1678              :     } else {
    1679              : 
    1680            0 :         this->CondOutletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1681            0 :         this->CondMassFlowRate = 0.0;
    1682            0 :         this->QCondenser = 0.0;
    1683            0 :         MyLoad = 0.0;
    1684            0 :         this->EvapMassFlowRate = 0.0;
    1685            0 :         PlantUtilities::SetComponentFlowRate(state, this->EvapMassFlowRate, this->EvapInletNodeNum, this->EvapOutletNodeNum, this->CWPlantLoc);
    1686            0 :         return;
    1687              :         // V7 plant upgrade, no longer fatal here anymore, set some things and return
    1688              :     }
    1689              : 
    1690        19216 :     if (this->GeneratorInletNodeNum > 0) {
    1691            0 :         if (this->GenHeatSourceType == DataLoopNode::NodeFluidType::Water) {
    1692            0 :             Real64 GenMassFlowRate = 0.0;
    1693              :             //  Hot water plant is used for the generator
    1694            0 :             CpFluid = state.dataPlnt->PlantLoop(this->GenPlantLoc.loopNum)
    1695            0 :                           .glycol->getSpecificHeat(state, state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp, RoutineName);
    1696            0 :             if (state.dataPlnt->PlantLoop(this->GenPlantLoc.loopNum).LoopSide(this->GenPlantLoc.loopSideNum).FlowLock ==
    1697              :                 DataPlant::FlowLock::Unlocked) {
    1698            0 :                 if ((this->FlowMode == DataPlant::FlowMode::Constant) || (this->FlowMode == DataPlant::FlowMode::NotModulated)) {
    1699            0 :                     GenMassFlowRate = this->GenMassFlowRateMax;
    1700              :                 } else { // LeavingSetpointModulated
    1701              :                     // since the .FlowMode applies to the chiller evaporator, the generator mass flow rate will be proportional to the evaporator
    1702              :                     // mass flow rate
    1703            0 :                     Real64 GenFlowRatio = this->EvapMassFlowRate / this->EvapMassFlowRateMax;
    1704            0 :                     GenMassFlowRate = min(this->GenMassFlowRateMax, GenFlowRatio * this->GenMassFlowRateMax);
    1705              :                 }
    1706              :             } else { // If FlowLock is True
    1707            0 :                 GenMassFlowRate = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).MassFlowRate;
    1708              :             }
    1709            0 :             PlantUtilities::SetComponentFlowRate(
    1710            0 :                 state, GenMassFlowRate, this->GeneratorInletNodeNum, this->GeneratorOutletNodeNum, this->GenPlantLoc);
    1711              : 
    1712            0 :             if (GenMassFlowRate <= 0.0) {
    1713            0 :                 this->GenOutletTemp = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp;
    1714            0 :                 this->SteamOutletEnthalpy = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Enthalpy;
    1715              :             } else {
    1716            0 :                 this->GenOutletTemp = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp - this->QGenerator / (CpFluid * GenMassFlowRate);
    1717            0 :                 this->SteamOutletEnthalpy = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Enthalpy - this->QGenerator / GenMassFlowRate;
    1718              :             }
    1719            0 :             state.dataLoopNodes->Node(this->GeneratorOutletNodeNum).Temp = this->GenOutletTemp;
    1720            0 :             state.dataLoopNodes->Node(this->GeneratorOutletNodeNum).Enthalpy = this->SteamOutletEnthalpy;
    1721            0 :             state.dataLoopNodes->Node(this->GeneratorOutletNodeNum).MassFlowRate = GenMassFlowRate;
    1722              : 
    1723              :         } else { // using a steam plant for the generator
    1724              : 
    1725              :             // enthalpy of dry steam at generator inlet
    1726            0 :             Real64 EnthSteamOutDry = this->steam->getSatEnthalpy(
    1727            0 :                 state, state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp, 1.0, calcChillerAbsorption + this->Name);
    1728              :             // enthalpy of wet steam at generator inlet
    1729            0 :             Real64 EnthSteamOutWet = this->steam->getSatEnthalpy(
    1730            0 :                 state, state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp, 0.0, calcChillerAbsorption + this->Name);
    1731            0 :             Real64 SteamDeltaT = this->GeneratorSubcool;
    1732            0 :             Real64 SteamOutletTemp = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp - SteamDeltaT;
    1733            0 :             Real64 HfgSteam = EnthSteamOutDry - EnthSteamOutWet;
    1734            0 :             CpFluid = this->water->getSpecificHeat(state, SteamOutletTemp, calcChillerAbsorption + this->Name);
    1735            0 :             this->SteamMassFlowRate = this->QGenerator / (HfgSteam + CpFluid * SteamDeltaT);
    1736            0 :             PlantUtilities::SetComponentFlowRate(
    1737            0 :                 state, this->SteamMassFlowRate, this->GeneratorInletNodeNum, this->GeneratorOutletNodeNum, this->GenPlantLoc);
    1738              : 
    1739            0 :             if (this->SteamMassFlowRate <= 0.0) {
    1740            0 :                 this->GenOutletTemp = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp;
    1741            0 :                 this->SteamOutletEnthalpy = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Enthalpy;
    1742              :             } else {
    1743            0 :                 this->GenOutletTemp = state.dataLoopNodes->Node(this->GeneratorInletNodeNum).Temp - SteamDeltaT;
    1744            0 :                 this->SteamOutletEnthalpy = this->steam->getSatEnthalpy(state, this->GenOutletTemp, 0.0, moduleObjectType + this->Name);
    1745            0 :                 this->SteamOutletEnthalpy -= CpFluid * SteamDeltaT;
    1746              :             }
    1747              :         }
    1748              :     } // IF(GeneratorInletNode .GT. 0)THEN
    1749              : 
    1750              :     // convert power to energy
    1751        19216 :     this->GeneratorEnergy = this->QGenerator * state.dataHVACGlobal->TimeStepSysSec;
    1752        19216 :     this->EvaporatorEnergy = this->QEvaporator * state.dataHVACGlobal->TimeStepSysSec;
    1753        19216 :     this->CondenserEnergy = this->QCondenser * state.dataHVACGlobal->TimeStepSysSec;
    1754        19216 :     this->PumpingEnergy = this->PumpingPower * state.dataHVACGlobal->TimeStepSysSec;
    1755              : }
    1756              : 
    1757        38898 : void BLASTAbsorberSpecs::updateRecords(EnergyPlusData &state, Real64 MyLoad, bool RunFlag)
    1758              : {
    1759              :     // SUBROUTINE INFORMATION:
    1760              :     //       AUTHOR:          Dan Fisher
    1761              :     //       DATE WRITTEN:    October 1998
    1762              : 
    1763              :     // PURPOSE OF THIS SUBROUTINE:
    1764              :     // reporting
    1765              : 
    1766        38898 :     if (MyLoad >= 0 || !RunFlag) {
    1767              :         // set node conditions
    1768        19682 :         PlantUtilities::SafeCopyPlantNode(state, this->EvapInletNodeNum, this->EvapOutletNodeNum);
    1769        19682 :         PlantUtilities::SafeCopyPlantNode(state, this->CondInletNodeNum, this->CondOutletNodeNum);
    1770              : 
    1771        19682 :         this->Report.PumpingPower = 0.0;
    1772        19682 :         this->Report.QEvap = 0.0;
    1773        19682 :         this->Report.QCond = 0.0;
    1774        19682 :         this->Report.QGenerator = 0.0;
    1775        19682 :         this->Report.PumpingEnergy = 0.0;
    1776        19682 :         this->Report.EvapEnergy = 0.0;
    1777        19682 :         this->Report.CondEnergy = 0.0;
    1778        19682 :         this->Report.GeneratorEnergy = 0.0;
    1779        19682 :         this->Report.EvapInletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1780        19682 :         this->Report.CondInletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1781        19682 :         this->Report.CondOutletTemp = state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp;
    1782        19682 :         this->Report.EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;
    1783        19682 :         this->Report.Evapmdot = 0.0;
    1784        19682 :         this->Report.Condmdot = 0.0;
    1785        19682 :         this->Report.Genmdot = 0.0;
    1786        19682 :         this->Report.ActualCOP = 0.0;
    1787              : 
    1788        19682 :         if (this->GeneratorInletNodeNum > 0) {
    1789            0 :             PlantUtilities::SafeCopyPlantNode(state, this->GeneratorInletNodeNum, this->GeneratorOutletNodeNum);
    1790              :         }
    1791              : 
    1792              :     } else {
    1793              :         // set node conditions
    1794        19216 :         PlantUtilities::SafeCopyPlantNode(state, this->EvapInletNodeNum, this->EvapOutletNodeNum);
    1795        19216 :         PlantUtilities::SafeCopyPlantNode(state, this->CondInletNodeNum, this->CondOutletNodeNum);
    1796        19216 :         state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp = this->EvapOutletTemp;
    1797        19216 :         state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp = this->CondOutletTemp;
    1798              : 
    1799        19216 :         this->Report.PumpingPower = this->PumpingPower;
    1800        19216 :         this->Report.QEvap = this->QEvaporator;
    1801        19216 :         this->Report.QCond = this->QCondenser;
    1802        19216 :         this->Report.QGenerator = this->QGenerator;
    1803        19216 :         this->Report.PumpingEnergy = this->PumpingEnergy;
    1804        19216 :         this->Report.EvapEnergy = this->EvaporatorEnergy;
    1805        19216 :         this->Report.CondEnergy = this->CondenserEnergy;
    1806        19216 :         this->Report.GeneratorEnergy = this->GeneratorEnergy;
    1807        19216 :         this->Report.EvapInletTemp = state.dataLoopNodes->Node(this->EvapInletNodeNum).Temp;
    1808        19216 :         this->Report.CondInletTemp = state.dataLoopNodes->Node(this->CondInletNodeNum).Temp;
    1809        19216 :         this->Report.CondOutletTemp = state.dataLoopNodes->Node(this->CondOutletNodeNum).Temp;
    1810        19216 :         this->Report.EvapOutletTemp = state.dataLoopNodes->Node(this->EvapOutletNodeNum).Temp;
    1811        19216 :         this->Report.Evapmdot = this->EvapMassFlowRate;
    1812        19216 :         this->Report.Condmdot = this->CondMassFlowRate;
    1813        19216 :         this->Report.Genmdot = this->SteamMassFlowRate;
    1814        19216 :         if (this->QGenerator != 0.0) {
    1815        19216 :             this->Report.ActualCOP = this->QEvaporator / this->QGenerator;
    1816              :         } else {
    1817            0 :             this->Report.ActualCOP = 0.0;
    1818              :         }
    1819              : 
    1820        19216 :         if (this->GeneratorInletNodeNum > 0) {
    1821            0 :             PlantUtilities::SafeCopyPlantNode(state, this->GeneratorInletNodeNum, this->GeneratorOutletNodeNum);
    1822            0 :             state.dataLoopNodes->Node(this->GeneratorOutletNodeNum).Temp = this->GenOutletTemp;
    1823              :         }
    1824              :     }
    1825        38898 : }
    1826              : 
    1827              : } // namespace EnergyPlus::ChillerAbsorption
        

Generated by: LCOV version 2.0-1