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

Generated by: LCOV version 2.0-1