LCOV - code coverage report
Current view: top level - EnergyPlus - ChillerAbsorption.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 450 955 47.1 %
Date: 2024-08-24 18:31:18 Functions: 15 15 100.0 %

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

Generated by: LCOV version 1.14