LCOV - code coverage report
Current view: top level - EnergyPlus - ICEngineElectricGenerator.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 15.8 % 354 56
Test Date: 2025-05-22 16:09:37 Functions: 10.0 % 10 1

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <cmath>
      50              : 
      51              : // ObjexxFCL Headers
      52              : #include <ObjexxFCL/Array.functions.hh>
      53              : #include <ObjexxFCL/Fmath.hh>
      54              : 
      55              : // EnergyPlus Headers
      56              : #include <EnergyPlus/BranchNodeConnections.hh>
      57              : #include <EnergyPlus/CurveManager.hh>
      58              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      59              : #include <EnergyPlus/DataGlobalConstants.hh>
      60              : #include <EnergyPlus/DataHVACGlobals.hh>
      61              : #include <EnergyPlus/DataIPShortCuts.hh>
      62              : #include <EnergyPlus/DataLoopNode.hh>
      63              : #include <EnergyPlus/FluidProperties.hh>
      64              : #include <EnergyPlus/General.hh>
      65              : #include <EnergyPlus/ICEngineElectricGenerator.hh>
      66              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      67              : #include <EnergyPlus/NodeInputManager.hh>
      68              : #include <EnergyPlus/OutputProcessor.hh>
      69              : #include <EnergyPlus/Plant/DataPlant.hh>
      70              : #include <EnergyPlus/PlantUtilities.hh>
      71              : #include <EnergyPlus/UtilityRoutines.hh>
      72              : 
      73              : namespace EnergyPlus {
      74              : 
      75              : namespace ICEngineElectricGenerator {
      76              : 
      77              :     // MODULE INFORMATION:
      78              :     //       AUTHOR         Dan Fisher
      79              :     //       DATE WRITTEN   Sept. 2000
      80              :     //       MODIFIED       na
      81              :     //       RE-ENGINEERED  na
      82              : 
      83              :     // PURPOSE OF THIS MODULE:
      84              :     // This module simulates the operation of IC ENGINE Generators.
      85              : 
      86              :     // METHODOLOGY EMPLOYED:
      87              :     // Once the ElectricPowerManager determines that the IC ENGINE Generator
      88              :     // is available to meet an electric load demand, it calls SimICEngineGenerator
      89              :     // which in turn calls the ICEngine Generator model.
      90              : 
      91            0 :     PlantComponent *ICEngineGeneratorSpecs::factory(EnergyPlusData &state, std::string const &objectName)
      92              :     {
      93              :         // Process the input data for ICEGen if it hasn't been done already
      94            0 :         if (state.dataICEngElectGen->getICEInput) {
      95            0 :             GetICEngineGeneratorInput(state);
      96            0 :             state.dataICEngElectGen->getICEInput = false;
      97              :         }
      98              : 
      99              :         // Now look for this particular generator in the list
     100            0 :         for (auto &thisICE : state.dataICEngElectGen->ICEngineGenerator) {
     101            0 :             if (thisICE.Name == objectName) {
     102            0 :                 return &thisICE;
     103              :             }
     104              :         }
     105              :         // If we didn't find it, fatal
     106            0 :         ShowFatalError(state,
     107            0 :                        format("LocalICEngineGeneratorFactory: Error getting inputs for internal combustion engine generator named: {}",
     108              :                               objectName)); // LCOV_EXCL_LINE
     109              :         // Shut up the compiler
     110              :         return nullptr; // LCOV_EXCL_LINE
     111              :     }
     112              : 
     113            1 :     void GetICEngineGeneratorInput(EnergyPlusData &state)
     114              :     {
     115              :         // SUBROUTINE INFORMATION:
     116              :         //       AUTHOR:          Dan Fisher
     117              :         //       DATE WRITTEN:    Sept. 2000
     118              : 
     119              :         // PURPOSE OF THIS SUBROUTINE:
     120              :         // This routine will get the input
     121              :         // required by the IC ENGINE Generator models.
     122              :         static constexpr std::string_view routineName = "GetICEngineGeneratorInput";
     123              : 
     124              :         int genNum;                   // Generator counter
     125              :         int NumAlphas;                // Number of elements in the alpha array
     126              :         int NumNums;                  // Number of elements in the numeric array
     127              :         int IOStat;                   // IO Status when calling get input subroutine
     128            1 :         Array1D_string AlphArray(10); // character string data
     129            1 :         Array1D<Real64> NumArray(11); // numeric data
     130            1 :         bool ErrorsFound(false);      // error flag
     131              : 
     132            1 :         auto &s_ipsc = state.dataIPShortCut;
     133              : 
     134            1 :         auto &ICEngineGenerator(state.dataICEngElectGen->ICEngineGenerator);
     135              : 
     136            1 :         s_ipsc->cCurrentModuleObject = "Generator:InternalCombustionEngine";
     137            2 :         state.dataICEngElectGen->NumICEngineGenerators =
     138            1 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, s_ipsc->cCurrentModuleObject);
     139              : 
     140            1 :         if (state.dataICEngElectGen->NumICEngineGenerators <= 0) {
     141            0 :             ShowSevereError(state, format("No {} equipment specified in input file", s_ipsc->cCurrentModuleObject));
     142            0 :             ErrorsFound = true;
     143              :         }
     144              : 
     145              :         // ALLOCATE ARRAYS
     146            1 :         ICEngineGenerator.allocate(state.dataICEngElectGen->NumICEngineGenerators);
     147              : 
     148              :         // LOAD ARRAYS WITH IC ENGINE Generator CURVE FIT  DATA
     149            2 :         for (genNum = 1; genNum <= state.dataICEngElectGen->NumICEngineGenerators; ++genNum) {
     150            3 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     151            1 :                                                                      s_ipsc->cCurrentModuleObject,
     152              :                                                                      genNum,
     153              :                                                                      AlphArray,
     154              :                                                                      NumAlphas,
     155              :                                                                      NumArray,
     156              :                                                                      NumNums,
     157              :                                                                      IOStat,
     158              :                                                                      _,
     159            1 :                                                                      s_ipsc->lAlphaFieldBlanks,
     160            1 :                                                                      s_ipsc->cAlphaFieldNames,
     161            1 :                                                                      s_ipsc->cNumericFieldNames);
     162              : 
     163            1 :             ErrorObjectHeader eoh{routineName, s_ipsc->cCurrentModuleObject, AlphArray(1)};
     164              : 
     165            1 :             auto &iceGen = state.dataICEngElectGen->ICEngineGenerator(genNum);
     166              : 
     167            1 :             iceGen.Name = AlphArray(1);
     168              : 
     169            1 :             iceGen.RatedPowerOutput = NumArray(1);
     170            1 :             if (NumArray(1) == 0.0) {
     171            0 :                 ShowSevereError(state, format("Invalid {}={:.2R}", s_ipsc->cNumericFieldNames(1), NumArray(1)));
     172            0 :                 ShowContinueError(state, format("Entered in {}={}", s_ipsc->cCurrentModuleObject, AlphArray(1)));
     173            0 :                 ErrorsFound = true;
     174              :             }
     175              : 
     176              :             // Not sure what to do with electric nodes, so do not use optional arguments
     177            1 :             iceGen.ElectricCircuitNode = NodeInputManager::GetOnlySingleNode(state,
     178            1 :                                                                              AlphArray(2),
     179              :                                                                              ErrorsFound,
     180              :                                                                              DataLoopNode::ConnectionObjectType::GeneratorInternalCombustionEngine,
     181            1 :                                                                              AlphArray(1),
     182              :                                                                              DataLoopNode::NodeFluidType::Electric,
     183              :                                                                              DataLoopNode::ConnectionType::Electric,
     184              :                                                                              NodeInputManager::CompFluidStream::Primary,
     185              :                                                                              DataLoopNode::ObjectIsNotParent);
     186              : 
     187            1 :             iceGen.MinPartLoadRat = NumArray(2);
     188            1 :             iceGen.MaxPartLoadRat = NumArray(3);
     189            1 :             iceGen.OptPartLoadRat = NumArray(4);
     190              : 
     191              :             // Load Special IC ENGINE Generator Curve Fit Inputs
     192            1 :             if (s_ipsc->lAlphaFieldBlanks(3)) {
     193            0 :                 ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(3));
     194            0 :                 ErrorsFound = true;
     195            1 :             } else if ((iceGen.ElecOutputFuelCurve = Curve::GetCurve(state, AlphArray(3))) == nullptr) {
     196            0 :                 ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(3), AlphArray(3));
     197            0 :                 ErrorsFound = true;
     198              :             }
     199              : 
     200            1 :             if (s_ipsc->lAlphaFieldBlanks(4)) {
     201            0 :                 ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(4));
     202            0 :                 ErrorsFound = true;
     203            1 :             } else if ((iceGen.RecJacHeattoFuelCurve = Curve::GetCurve(state, AlphArray(4))) == nullptr) {
     204            0 :                 ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(4), AlphArray(4));
     205            0 :                 ErrorsFound = true;
     206              :             }
     207              : 
     208            1 :             if (s_ipsc->lAlphaFieldBlanks(5)) {
     209            0 :                 ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(5));
     210            0 :                 ErrorsFound = true;
     211            1 :             } else if ((iceGen.RecLubeHeattoFuelCurve = Curve::GetCurve(state, AlphArray(5))) == nullptr) {
     212            0 :                 ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(5), AlphArray(5));
     213            0 :                 ErrorsFound = true;
     214              :             }
     215              : 
     216            1 :             if (s_ipsc->lAlphaFieldBlanks(6)) {
     217            0 :                 ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(6));
     218            0 :                 ErrorsFound = true;
     219            1 :             } else if ((iceGen.TotExhausttoFuelCurve = Curve::GetCurve(state, AlphArray(6))) == nullptr) {
     220            0 :                 ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(6), AlphArray(6));
     221            0 :                 ErrorsFound = true;
     222              :             }
     223              : 
     224            1 :             if (s_ipsc->lAlphaFieldBlanks(7)) {
     225            0 :                 ShowSevereEmptyField(state, eoh, s_ipsc->cAlphaFieldNames(7));
     226            0 :                 ErrorsFound = true;
     227            1 :             } else if ((iceGen.ExhaustTempCurve = Curve::GetCurve(state, AlphArray(7))) == nullptr) {
     228            0 :                 ShowSevereItemNotFound(state, eoh, s_ipsc->cAlphaFieldNames(7), AlphArray(7));
     229            0 :                 ErrorsFound = true;
     230              :             } else {
     231            1 :                 Real64 xValue = iceGen.ExhaustTempCurve->value(state, 1.0);
     232            1 :                 if (xValue < ReferenceTemp) {
     233            0 :                     ShowSevereError(state, format("GetICEngineGeneratorInput: {} output has very low value.", s_ipsc->cAlphaFieldNames(7)));
     234            0 :                     ShowContinueError(state, format("...curve generates [{:.3R} C] at PLR=1.0", xValue));
     235            0 :                     ShowContinueError(state,
     236            0 :                                       format("...this is less than the Reference Temperature [{:.2R} C] and may cause errors.", ReferenceTemp));
     237              :                 }
     238              :             }
     239              : 
     240            1 :             iceGen.UACoef(1) = NumArray(5);
     241            1 :             iceGen.UACoef(2) = NumArray(6);
     242              : 
     243            1 :             iceGen.MaxExhaustperPowerOutput = NumArray(7);
     244            1 :             iceGen.DesignMinExitGasTemp = NumArray(8);
     245            1 :             iceGen.FuelHeatingValue = NumArray(9);
     246            1 :             iceGen.DesignHeatRecVolFlowRate = NumArray(10);
     247            1 :             if (iceGen.DesignHeatRecVolFlowRate > 0.0) {
     248            0 :                 iceGen.HeatRecActive = true;
     249            0 :                 iceGen.HeatRecInletNodeNum =
     250            0 :                     NodeInputManager::GetOnlySingleNode(state,
     251            0 :                                                         AlphArray(8),
     252              :                                                         ErrorsFound,
     253              :                                                         DataLoopNode::ConnectionObjectType::GeneratorInternalCombustionEngine,
     254            0 :                                                         AlphArray(1),
     255              :                                                         DataLoopNode::NodeFluidType::Water,
     256              :                                                         DataLoopNode::ConnectionType::Inlet,
     257              :                                                         NodeInputManager::CompFluidStream::Primary,
     258              :                                                         DataLoopNode::ObjectIsNotParent);
     259            0 :                 if (iceGen.HeatRecInletNodeNum == 0) {
     260            0 :                     ShowSevereError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(8), AlphArray(8)));
     261            0 :                     ShowContinueError(state, format("Entered in {}={}", s_ipsc->cCurrentModuleObject, AlphArray(1)));
     262            0 :                     ErrorsFound = true;
     263              :                 }
     264            0 :                 iceGen.HeatRecOutletNodeNum =
     265            0 :                     NodeInputManager::GetOnlySingleNode(state,
     266            0 :                                                         AlphArray(9),
     267              :                                                         ErrorsFound,
     268              :                                                         DataLoopNode::ConnectionObjectType::GeneratorInternalCombustionEngine,
     269            0 :                                                         AlphArray(1),
     270              :                                                         DataLoopNode::NodeFluidType::Water,
     271              :                                                         DataLoopNode::ConnectionType::Outlet,
     272              :                                                         NodeInputManager::CompFluidStream::Primary,
     273              :                                                         DataLoopNode::ObjectIsNotParent);
     274            0 :                 if (iceGen.HeatRecOutletNodeNum == 0) {
     275            0 :                     ShowSevereError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(9), AlphArray(9)));
     276            0 :                     ShowContinueError(state, format("Entered in {}={}", s_ipsc->cCurrentModuleObject, AlphArray(1)));
     277            0 :                     ErrorsFound = true;
     278              :                 }
     279            0 :                 BranchNodeConnections::TestCompSet(
     280            0 :                     state, s_ipsc->cCurrentModuleObject, AlphArray(1), AlphArray(8), AlphArray(9), "Heat Recovery Nodes");
     281            0 :                 PlantUtilities::RegisterPlantCompDesignFlow(state, iceGen.HeatRecInletNodeNum, iceGen.DesignHeatRecVolFlowRate);
     282              :             } else {
     283            1 :                 iceGen.HeatRecActive = false;
     284            1 :                 iceGen.HeatRecInletNodeNum = 0;
     285            1 :                 iceGen.HeatRecOutletNodeNum = 0;
     286            1 :                 if (!s_ipsc->lAlphaFieldBlanks(8) || !s_ipsc->lAlphaFieldBlanks(9)) {
     287            0 :                     ShowWarningError(
     288              :                         state,
     289            0 :                         format("Since Design Heat Flow Rate = 0.0, Heat Recovery inactive for {}={}", s_ipsc->cCurrentModuleObject, AlphArray(1)));
     290            0 :                     ShowContinueError(state, "However, Node names were specified for Heat Recovery inlet or outlet nodes");
     291              :                 }
     292              :             }
     293              : 
     294              :             // Validate fuel type input
     295            1 :             iceGen.FuelType = static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, AlphArray(10)));
     296            1 :             if (iceGen.FuelType == Constant::eFuel::Invalid) {
     297            0 :                 ShowSevereError(state, format("Invalid {}={}", s_ipsc->cAlphaFieldNames(10), AlphArray(10)));
     298            0 :                 ShowContinueError(state, format("Entered in {}={}", s_ipsc->cCurrentModuleObject, AlphArray(1)));
     299            0 :                 ErrorsFound = true;
     300              :             }
     301              : 
     302            1 :             iceGen.HeatRecMaxTemp = NumArray(11);
     303              :         }
     304              : 
     305            1 :         if (ErrorsFound) {
     306            0 :             ShowFatalError(state, format("Errors found in processing input for {}", s_ipsc->cCurrentModuleObject));
     307              :         }
     308            1 :     }
     309              : 
     310            0 :     void ICEngineGeneratorSpecs::setupOutputVars(EnergyPlusData &state)
     311              :     {
     312            0 :         std::string_view const sFuelType = Constant::eFuelNames[static_cast<int>(this->FuelType)];
     313            0 :         SetupOutputVariable(state,
     314              :                             "Generator Produced AC Electricity Rate",
     315              :                             Constant::Units::W,
     316            0 :                             this->ElecPowerGenerated,
     317              :                             OutputProcessor::TimeStepType::System,
     318              :                             OutputProcessor::StoreType::Average,
     319            0 :                             this->Name);
     320              : 
     321            0 :         SetupOutputVariable(state,
     322              :                             "Generator Produced AC Electricity Energy",
     323              :                             Constant::Units::J,
     324            0 :                             this->ElecEnergyGenerated,
     325              :                             OutputProcessor::TimeStepType::System,
     326              :                             OutputProcessor::StoreType::Sum,
     327            0 :                             this->Name,
     328              :                             Constant::eResource::ElectricityProduced,
     329              :                             OutputProcessor::Group::Plant,
     330              :                             OutputProcessor::EndUseCat::Cogeneration);
     331              : 
     332            0 :         SetupOutputVariable(state,
     333            0 :                             format("Generator {} Rate", sFuelType),
     334              :                             Constant::Units::W,
     335            0 :                             this->FuelEnergyUseRate,
     336              :                             OutputProcessor::TimeStepType::System,
     337              :                             OutputProcessor::StoreType::Average,
     338            0 :                             this->Name);
     339              : 
     340            0 :         SetupOutputVariable(state,
     341            0 :                             format("Generator {} Energy", sFuelType),
     342              :                             Constant::Units::J,
     343            0 :                             this->FuelEnergy,
     344              :                             OutputProcessor::TimeStepType::System,
     345              :                             OutputProcessor::StoreType::Sum,
     346            0 :                             this->Name,
     347            0 :                             Constant::eFuel2eResource[(int)this->FuelType],
     348              :                             OutputProcessor::Group::Plant,
     349              :                             OutputProcessor::EndUseCat::Cogeneration);
     350              : 
     351              :         //    general fuel use report to match other generators.
     352            0 :         SetupOutputVariable(state,
     353              :                             "Generator Fuel HHV Basis Rate",
     354              :                             Constant::Units::W,
     355            0 :                             this->FuelEnergyUseRate,
     356              :                             OutputProcessor::TimeStepType::System,
     357              :                             OutputProcessor::StoreType::Average,
     358            0 :                             this->Name);
     359              : 
     360            0 :         SetupOutputVariable(state,
     361              :                             "Generator Fuel HHV Basis Energy",
     362              :                             Constant::Units::J,
     363            0 :                             this->FuelEnergy,
     364              :                             OutputProcessor::TimeStepType::System,
     365              :                             OutputProcessor::StoreType::Sum,
     366            0 :                             this->Name);
     367              : 
     368            0 :         SetupOutputVariable(state,
     369            0 :                             format("Generator {} Mass Flow Rate", sFuelType),
     370              :                             Constant::Units::kg_s,
     371            0 :                             this->FuelMdot,
     372              :                             OutputProcessor::TimeStepType::System,
     373              :                             OutputProcessor::StoreType::Average,
     374            0 :                             this->Name);
     375              : 
     376            0 :         SetupOutputVariable(state,
     377              :                             "Generator Exhaust Air Temperature",
     378              :                             Constant::Units::C,
     379            0 :                             this->ExhaustStackTemp,
     380              :                             OutputProcessor::TimeStepType::System,
     381              :                             OutputProcessor::StoreType::Average,
     382            0 :                             this->Name);
     383              : 
     384            0 :         if (this->HeatRecActive) {
     385            0 :             SetupOutputVariable(state,
     386              :                                 "Generator Heat Recovery Mass Flow Rate",
     387              :                                 Constant::Units::kg_s,
     388            0 :                                 this->HeatRecMdotActual,
     389              :                                 OutputProcessor::TimeStepType::System,
     390              :                                 OutputProcessor::StoreType::Average,
     391            0 :                                 this->Name);
     392              : 
     393            0 :             SetupOutputVariable(state,
     394              :                                 "Generator Jacket Heat Recovery Rate",
     395              :                                 Constant::Units::W,
     396            0 :                                 this->QJacketRecovered,
     397              :                                 OutputProcessor::TimeStepType::System,
     398              :                                 OutputProcessor::StoreType::Average,
     399            0 :                                 this->Name);
     400              : 
     401            0 :             SetupOutputVariable(state,
     402              :                                 "Generator Jacket Heat Recovery Energy",
     403              :                                 Constant::Units::J,
     404            0 :                                 this->JacketEnergyRec,
     405              :                                 OutputProcessor::TimeStepType::System,
     406              :                                 OutputProcessor::StoreType::Sum,
     407            0 :                                 this->Name,
     408              :                                 Constant::eResource::EnergyTransfer,
     409              :                                 OutputProcessor::Group::Plant,
     410              :                                 OutputProcessor::EndUseCat::HeatRecovery);
     411              : 
     412            0 :             SetupOutputVariable(state,
     413              :                                 "Generator Lube Heat Recovery Rate",
     414              :                                 Constant::Units::W,
     415            0 :                                 this->QLubeOilRecovered,
     416              :                                 OutputProcessor::TimeStepType::System,
     417              :                                 OutputProcessor::StoreType::Average,
     418            0 :                                 this->Name);
     419              : 
     420            0 :             SetupOutputVariable(state,
     421              :                                 "Generator Lube Heat Recovery Energy",
     422              :                                 Constant::Units::J,
     423            0 :                                 this->LubeOilEnergyRec,
     424              :                                 OutputProcessor::TimeStepType::System,
     425              :                                 OutputProcessor::StoreType::Sum,
     426            0 :                                 this->Name,
     427              :                                 Constant::eResource::EnergyTransfer,
     428              :                                 OutputProcessor::Group::Plant,
     429              :                                 OutputProcessor::EndUseCat::HeatRecovery);
     430              : 
     431            0 :             SetupOutputVariable(state,
     432              :                                 "Generator Exhaust Heat Recovery Rate",
     433              :                                 Constant::Units::W,
     434            0 :                                 this->QExhaustRecovered,
     435              :                                 OutputProcessor::TimeStepType::System,
     436              :                                 OutputProcessor::StoreType::Average,
     437            0 :                                 this->Name);
     438              : 
     439            0 :             SetupOutputVariable(state,
     440              :                                 "Generator Exhaust Heat Recovery Energy",
     441              :                                 Constant::Units::J,
     442            0 :                                 this->ExhaustEnergyRec,
     443              :                                 OutputProcessor::TimeStepType::System,
     444              :                                 OutputProcessor::StoreType::Sum,
     445            0 :                                 this->Name,
     446              :                                 Constant::eResource::EnergyTransfer,
     447              :                                 OutputProcessor::Group::Plant,
     448              :                                 OutputProcessor::EndUseCat::HeatRecovery);
     449              : 
     450            0 :             SetupOutputVariable(state,
     451              :                                 "Generator Produced Thermal Rate",
     452              :                                 Constant::Units::W,
     453            0 :                                 this->QTotalHeatRecovered,
     454              :                                 OutputProcessor::TimeStepType::System,
     455              :                                 OutputProcessor::StoreType::Average,
     456            0 :                                 this->Name);
     457              : 
     458            0 :             SetupOutputVariable(state,
     459              :                                 "Generator Produced Thermal Energy",
     460              :                                 Constant::Units::J,
     461            0 :                                 this->TotalHeatEnergyRec,
     462              :                                 OutputProcessor::TimeStepType::System,
     463              :                                 OutputProcessor::StoreType::Sum,
     464            0 :                                 this->Name);
     465              : 
     466            0 :             SetupOutputVariable(state,
     467              :                                 "Generator Heat Recovery Inlet Temperature",
     468              :                                 Constant::Units::C,
     469            0 :                                 this->HeatRecInletTemp,
     470              :                                 OutputProcessor::TimeStepType::System,
     471              :                                 OutputProcessor::StoreType::Average,
     472            0 :                                 this->Name);
     473              : 
     474            0 :             SetupOutputVariable(state,
     475              :                                 "Generator Heat Recovery Outlet Temperature",
     476              :                                 Constant::Units::C,
     477            0 :                                 this->HeatRecOutletTemp,
     478              :                                 OutputProcessor::TimeStepType::System,
     479              :                                 OutputProcessor::StoreType::Average,
     480            0 :                                 this->Name);
     481              :         }
     482            0 :     }
     483              : 
     484            0 :     void ICEngineGeneratorSpecs::getDesignCapacities(
     485              :         [[maybe_unused]] EnergyPlusData &state, const EnergyPlus::PlantLocation &, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
     486              :     {
     487            0 :         MaxLoad = 0.0;
     488            0 :         MinLoad = 0.0;
     489            0 :         OptLoad = 0.0;
     490            0 :     }
     491              : 
     492            0 :     void ICEngineGeneratorSpecs::simulate(EnergyPlusData &state,
     493              :                                           [[maybe_unused]] const EnergyPlus::PlantLocation &calledFromLocation,
     494              :                                           bool FirstHVACIteration,
     495              :                                           [[maybe_unused]] Real64 &CurLoad,
     496              :                                           [[maybe_unused]] bool RunFlag)
     497              :     {
     498              :         // empty function to emulate current behavior as of conversion to using the PlantComponent calling structure.
     499              :         // calls from the plant side only update the plant nodes.
     500              :         // calls from the ElectricPowerServiceManger call the init, calc, and update worker functions directly.
     501              : 
     502            0 :         PlantUtilities::UpdateComponentHeatRecoverySide(state,
     503              :                                                         this->HRPlantLoc.loopNum,
     504              :                                                         this->HRPlantLoc.loopSideNum,
     505              :                                                         DataPlant::PlantEquipmentType::Generator_ICEngine,
     506              :                                                         this->HeatRecInletNodeNum,
     507              :                                                         this->HeatRecOutletNodeNum,
     508              :                                                         this->QTotalHeatRecovered,
     509              :                                                         this->HeatRecInletTemp,
     510              :                                                         this->HeatRecOutletTemp,
     511              :                                                         this->HeatRecMdotActual,
     512              :                                                         FirstHVACIteration);
     513            0 :     }
     514              : 
     515            0 :     void ICEngineGeneratorSpecs::CalcICEngineGeneratorModel(EnergyPlusData &state, bool const RunFlag, Real64 const MyLoad)
     516              :     {
     517              :         // SUBROUTINE INFORMATION:
     518              :         //       AUTHOR         Dan Fisher
     519              :         //       DATE WRITTEN   Sept. 2000
     520              :         //       MODIFIED     na
     521              :         //       RE-ENGINEERED
     522              : 
     523              :         // PURPOSE OF THIS SUBROUTINE:
     524              :         // simulate a IC ENGINE generator using the BLAST model
     525              : 
     526              :         // METHODOLOGY EMPLOYED:
     527              :         // curve fit of performance data:
     528              : 
     529            0 :         constexpr Real64 ExhaustCP(1.047); // Exhaust Gas Specific Heat (J/kg-K)
     530            0 :         constexpr Real64 KJtoJ(1000.0);    // convert Kjoules to joules
     531              : 
     532              :         // Heat Recovery Fluid Mass FlowRate (kg/s)
     533              :         Real64 HeatRecMdot;
     534              : 
     535              :         // Heat Recovery Fluid Inlet Temperature (C)
     536              :         Real64 HeatRecInTemp;
     537              : 
     538            0 :         if (this->HeatRecActive) {
     539            0 :             int HeatRecInNode = this->HeatRecInletNodeNum;
     540            0 :             HeatRecInTemp = state.dataLoopNodes->Node(HeatRecInNode).Temp;
     541            0 :             HeatRecMdot = state.dataLoopNodes->Node(HeatRecInNode).MassFlowRate;
     542              : 
     543              :         } else {
     544            0 :             HeatRecInTemp = 0.0;
     545            0 :             HeatRecMdot = 0.0;
     546              :         }
     547              : 
     548              :         // If no loop demand or Generator OFF, return
     549            0 :         if (!RunFlag) {
     550            0 :             this->ElecPowerGenerated = 0.0;
     551            0 :             this->ElecEnergyGenerated = 0.0;
     552            0 :             this->HeatRecInletTemp = HeatRecInTemp;
     553            0 :             this->HeatRecOutletTemp = HeatRecInTemp;
     554            0 :             this->HeatRecMdotActual = 0.0;
     555            0 :             this->QJacketRecovered = 0.0;
     556            0 :             this->QExhaustRecovered = 0.0;
     557            0 :             this->QLubeOilRecovered = 0.0;
     558            0 :             this->QTotalHeatRecovered = 0.0;
     559            0 :             this->JacketEnergyRec = 0.0;
     560            0 :             this->ExhaustEnergyRec = 0.0;
     561            0 :             this->LubeOilEnergyRec = 0.0;
     562            0 :             this->TotalHeatEnergyRec = 0.0;
     563            0 :             this->FuelEnergyUseRate = 0.0;
     564            0 :             this->FuelEnergy = 0.0;
     565            0 :             this->FuelMdot = 0.0;
     566            0 :             this->ExhaustStackTemp = 0.0;
     567              : 
     568            0 :             return;
     569              :         }
     570              : 
     571              :         // Generator output (W)
     572            0 :         Real64 elecPowerGenerated = min(MyLoad, this->RatedPowerOutput);
     573            0 :         elecPowerGenerated = max(elecPowerGenerated, 0.0);
     574              : 
     575              :         // Generator operating part load ratio
     576            0 :         Real64 PLR = min(elecPowerGenerated / this->RatedPowerOutput, this->MaxPartLoadRat);
     577            0 :         PLR = max(PLR, this->MinPartLoadRat);
     578            0 :         elecPowerGenerated = PLR * this->RatedPowerOutput;
     579              : 
     580              :         // DETERMINE FUEL CONSUMED AND AVAILABLE WASTE HEAT
     581              : 
     582              :         // Use Curve fit to determine Fuel Energy Input.  For electric power generated in Watts, the fuel
     583              :         // energy input is calculated in J/s.  The PLBasedFuelInputCurve selects ratio of fuel flow (J/s)/power generated (J/s).
     584              :         Real64 fuelEnergyUseRate; // IC ENGINE fuel use rate (W)
     585            0 :         if (PLR > 0.0) {
     586              :             // (RELDC) Ratio of generator output to Fuel Energy Input
     587            0 :             Real64 elecOutputFuelRat = this->ElecOutputFuelCurve->value(state, PLR);
     588            0 :             fuelEnergyUseRate = elecPowerGenerated / elecOutputFuelRat;
     589              :         } else {
     590            0 :             fuelEnergyUseRate = 0.0;
     591              :         }
     592              : 
     593              :         // Use Curve fit to determine heat recovered in the water jacket.  This curve calculates the water jacket heat recovered (J/s) by
     594              :         // multiplying the total fuel input (J/s) by the fraction of that power that could be recovered in the water jacket at that
     595              :         // particular part load.
     596              : 
     597              :         // (RJACDC) Ratio of Recoverable Jacket Heat to Fuel Energy Input
     598            0 :         Real64 recJacHeattoFuelRat = this->RecJacHeattoFuelCurve->value(state, PLR);
     599              : 
     600              :         // water jacket heat recovered (W)
     601            0 :         Real64 QJacketRec = fuelEnergyUseRate * recJacHeattoFuelRat;
     602              : 
     603              :         // Use Curve fit to determine Heat Recovered Lubricant heat.  This curve calculates the lube heat recovered (J/s) by
     604              :         // multiplying the total fuel input (J/s) by the fraction of that power that could be recovered in the lube oil at that
     605              :         // particular part load.
     606              :         // (RLUBDC) Ratio of Recoverable Lube Oil Heat to Fuel Energy Input
     607            0 :         Real64 recLubeHeattoFuelRat = this->RecLubeHeattoFuelCurve->value(state, PLR);
     608              : 
     609              :         // lube oil cooler heat recovered (W)
     610            0 :         Real64 QLubeOilRec = fuelEnergyUseRate * recLubeHeattoFuelRat;
     611              : 
     612              :         // Use Curve fit to determine Heat Recovered from the exhaust.  This curve calculates the  heat recovered (J/s) by
     613              :         // multiplying the total fuel input (J/s) by the fraction of that power that could be recovered in the exhaust at that
     614              :         // particular part load.
     615              : 
     616              :         // (REXDC) Total Exhaust Energy Input to Fuel Energy Input
     617            0 :         Real64 totExhausttoFuelRat = this->TotExhausttoFuelCurve->value(state, PLR);
     618              : 
     619              :         // total engine exhaust heat (W)
     620            0 :         Real64 QExhaustTotal = fuelEnergyUseRate * totExhausttoFuelRat;
     621              : 
     622              :         // exhaust gas heat recovered (W)
     623              :         Real64 QExhaustRec;
     624              : 
     625              :         // engine stack temp. (C)
     626            0 :         Real64 exhaustStackTemp = 0.0;
     627              : 
     628              :         // Use Curve fit to determine Exhaust Temperature in C.  The temperature is simply a curve fit
     629              :         // of the exhaust temperature in C to the part load ratio.
     630            0 :         if (PLR > 0.0) {
     631              :             // (TEX) Exhaust Gas Temp
     632            0 :             Real64 exhaustTemp = this->ExhaustTempCurve->value(state, PLR);
     633              : 
     634            0 :             if (exhaustTemp > ReferenceTemp) {
     635              : 
     636              :                 // exhaust gas mass flow rate (kg/s)
     637            0 :                 Real64 ExhaustGasFlow = QExhaustTotal / (ExhaustCP * (exhaustTemp - ReferenceTemp));
     638              : 
     639              :                 // Use Curve fit to determine stack exhaustTemp after heat recovery
     640              :                 // (UACDC) exhaust gas Heat Exchanger UA
     641            0 :                 Real64 UA_loc = this->UACoef(1) * std::pow(this->RatedPowerOutput, this->UACoef(2));
     642              : 
     643              :                 // design engine stact saturated steam exhaustTemp. (C)
     644            0 :                 Real64 designMinExitGasTemp = this->DesignMinExitGasTemp;
     645              : 
     646            0 :                 exhaustStackTemp = designMinExitGasTemp +
     647            0 :                                    (exhaustTemp - designMinExitGasTemp) /
     648            0 :                                        std::exp(UA_loc / (max(ExhaustGasFlow, this->MaxExhaustperPowerOutput * this->RatedPowerOutput) * ExhaustCP));
     649              : 
     650            0 :                 QExhaustRec = max(ExhaustGasFlow * ExhaustCP * (exhaustTemp - exhaustStackTemp), 0.0);
     651              :             } else {
     652            0 :                 if (this->ErrExhaustTempIndex == 0) {
     653            0 :                     ShowWarningMessage(
     654            0 :                         state, format("CalcICEngineGeneratorModel: {}=\"{}\" low Exhaust Temperature from Curve Value", this->TypeOf, this->Name));
     655            0 :                     ShowContinueError(state, format("...curve generated temperature=[{:.3R} C], PLR=[{:.3R}].", exhaustTemp, PLR));
     656            0 :                     ShowContinueError(state, "...simulation will continue with exhaust heat reclaim set to 0.");
     657              :                 }
     658            0 :                 ShowRecurringWarningErrorAtEnd(state,
     659            0 :                                                "CalcICEngineGeneratorModel: " + this->TypeOf + "=\"" + this->Name +
     660              :                                                    "\" low Exhaust Temperature continues...",
     661            0 :                                                this->ErrExhaustTempIndex,
     662              :                                                exhaustTemp,
     663              :                                                exhaustTemp,
     664              :                                                _,
     665              :                                                "[C]",
     666              :                                                "[C]");
     667            0 :                 QExhaustRec = 0.0;
     668            0 :                 exhaustStackTemp = this->DesignMinExitGasTemp;
     669              :             }
     670              :         } else {
     671            0 :             QExhaustRec = 0.0;
     672              :             // Bug exhaustStackTemp not set but used below
     673              :         }
     674              : 
     675            0 :         Real64 qTotalHeatRecovered = QExhaustRec + QLubeOilRec + QJacketRec;
     676              : 
     677              :         // When Max Temp is reached the amount of recovered heat has to be reduced.
     678              :         Real64 HRecRatio;
     679              : 
     680            0 :         if (this->HeatRecActive) {
     681            0 :             this->CalcICEngineGenHeatRecovery(state, qTotalHeatRecovered, HeatRecMdot, HRecRatio);
     682            0 :             QExhaustRec *= HRecRatio;
     683            0 :             QLubeOilRec *= HRecRatio;
     684            0 :             QJacketRec *= HRecRatio;
     685            0 :             qTotalHeatRecovered *= HRecRatio;
     686              :         } else {
     687            0 :             this->HeatRecInletTemp = HeatRecInTemp;
     688            0 :             this->HeatRecOutletTemp = HeatRecInTemp;
     689            0 :             this->HeatRecMdotActual = HeatRecMdot;
     690              :         }
     691              : 
     692              :         // Calculate Energy
     693              :         // Generator output (J)
     694            0 :         Real64 ElectricEnergyGen = elecPowerGenerated * state.dataHVACGlobal->TimeStepSysSec;
     695              : 
     696              :         // IC ENGINE fuel use (J)
     697            0 :         Real64 FuelEnergyUsed = fuelEnergyUseRate * state.dataHVACGlobal->TimeStepSysSec;
     698              : 
     699              :         // water jacket heat recovered (J)
     700            0 :         Real64 jacketEnergyRec = QJacketRec * state.dataHVACGlobal->TimeStepSysSec;
     701              : 
     702              :         // lube oil cooler heat recovered (J)
     703            0 :         Real64 lubeOilEnergyRec = QLubeOilRec * state.dataHVACGlobal->TimeStepSysSec;
     704              : 
     705              :         // exhaust gas heat recovered (J)
     706            0 :         Real64 exhaustEnergyRec = QExhaustRec * state.dataHVACGlobal->TimeStepSysSec;
     707            0 :         this->ElecPowerGenerated = elecPowerGenerated;
     708            0 :         this->ElecEnergyGenerated = ElectricEnergyGen;
     709            0 :         this->QJacketRecovered = QJacketRec;
     710            0 :         this->QLubeOilRecovered = QLubeOilRec;
     711            0 :         this->QExhaustRecovered = QExhaustRec;
     712            0 :         this->QTotalHeatRecovered = qTotalHeatRecovered;
     713            0 :         this->JacketEnergyRec = jacketEnergyRec;
     714            0 :         this->LubeOilEnergyRec = lubeOilEnergyRec;
     715            0 :         this->ExhaustEnergyRec = exhaustEnergyRec;
     716            0 :         this->QTotalHeatRecovered = (QExhaustRec + QLubeOilRec + QJacketRec);
     717            0 :         this->TotalHeatEnergyRec = (exhaustEnergyRec + lubeOilEnergyRec + jacketEnergyRec);
     718            0 :         this->FuelEnergyUseRate = std::abs(fuelEnergyUseRate);
     719            0 :         this->FuelEnergy = std::abs(FuelEnergyUsed);
     720              : 
     721              :         // Heating Value of Fuel in kJ/kg
     722            0 :         Real64 fuelHeatingValue = this->FuelHeatingValue;
     723              : 
     724            0 :         this->FuelMdot = std::abs(fuelEnergyUseRate) / (fuelHeatingValue * KJtoJ);
     725            0 :         this->ExhaustStackTemp = exhaustStackTemp;
     726              :     }
     727              : 
     728            0 :     void ICEngineGeneratorSpecs::CalcICEngineGenHeatRecovery(EnergyPlusData &state,
     729              :                                                              Real64 const EnergyRecovered,
     730              :                                                              Real64 const HeatRecMdot,
     731              :                                                              Real64 &HRecRatio)
     732              :     {
     733              :         // SUBROUTINE INFORMATION:
     734              :         //       AUTHOR:          Brandon Anderson
     735              :         //       DATE WRITTEN:    November 2000
     736              : 
     737              :         // PURPOSE OF THIS SUBROUTINE:
     738              :         // To perform heat recovery calculations and node updates
     739              : 
     740              :         // METHODOLOGY EMPLOYED: This routine is required for the heat recovery loop.
     741              :         // It works in conjunction with the Heat Recovery Manager, and the PlantWaterHeater.
     742              :         // The chiller sets the flow on the loop first by the input design flow rate and then
     743              :         // performs a check to verify that
     744              : 
     745              :         static constexpr std::string_view RoutineName("CalcICEngineGeneratorModel");
     746              : 
     747              :         // Need to set the HeatRecRatio to 1.0 if it is not modified
     748            0 :         HRecRatio = 1.0;
     749              : 
     750            0 :         Real64 HeatRecInTemp = state.dataLoopNodes->Node(this->HeatRecInletNodeNum).Temp;
     751            0 :         Real64 HeatRecCp = state.dataPlnt->PlantLoop(this->HRPlantLoc.loopNum).glycol->getSpecificHeat(state, HeatRecInTemp, RoutineName);
     752              : 
     753              :         // Don't divide by zero - Note This also results in no heat recovery when
     754              :         //  design Mdot for Heat Recovery - Specified on Chiller Input - is zero
     755              :         //  In order to see what minimum heat recovery flow rate is for the design temperature
     756              :         //  The design heat recovery flow rate can be set very small, but greater than zero.
     757              : 
     758              :         Real64 HeatRecOutTemp;
     759              : 
     760            0 :         if ((HeatRecMdot > 0) && (HeatRecCp > 0)) {
     761            0 :             HeatRecOutTemp = (EnergyRecovered) / (HeatRecMdot * HeatRecCp) + HeatRecInTemp;
     762              :         } else {
     763            0 :             HeatRecOutTemp = HeatRecInTemp;
     764              :         }
     765              : 
     766              :         // Note: check to make sure the Max Temperature was not exceeded
     767            0 :         if (HeatRecOutTemp > this->HeatRecMaxTemp) {
     768              :             Real64 MinHeatRecMdot;
     769            0 :             if (this->HeatRecMaxTemp != HeatRecInTemp) {
     770            0 :                 MinHeatRecMdot = (EnergyRecovered) / (HeatRecCp * (this->HeatRecMaxTemp - HeatRecInTemp));
     771            0 :                 if (MinHeatRecMdot < 0.0) MinHeatRecMdot = 0.0;
     772              :             } else {
     773            0 :                 MinHeatRecMdot = 0.0;
     774              :             }
     775              : 
     776              :             // Recalculate Outlet Temperature, with adjusted flowrate
     777            0 :             if ((MinHeatRecMdot > 0.0) && (HeatRecCp > 0.0)) {
     778            0 :                 HeatRecOutTemp = (EnergyRecovered) / (MinHeatRecMdot * HeatRecCp) + HeatRecInTemp;
     779            0 :                 HRecRatio = HeatRecMdot / MinHeatRecMdot;
     780              :             } else {
     781            0 :                 HeatRecOutTemp = HeatRecInTemp;
     782            0 :                 HRecRatio = 0.0;
     783              :             }
     784              :         }
     785              : 
     786              :         // Update global variables for reporting later
     787            0 :         this->HeatRecInletTemp = HeatRecInTemp;
     788            0 :         this->HeatRecOutletTemp = HeatRecOutTemp;
     789            0 :         this->HeatRecMdotActual = HeatRecMdot;
     790            0 :     }
     791              : 
     792            0 :     void ICEngineGeneratorSpecs::InitICEngineGenerators(EnergyPlusData &state, bool const RunFlag, bool const FirstHVACIteration)
     793              :     {
     794              : 
     795              :         // SUBROUTINE INFORMATION:
     796              :         //       AUTHOR         Dan Fisher
     797              :         //       DATE WRITTEN   Oct 2000
     798              :         //       MODIFIED       na
     799              :         //       RE-ENGINEERED  Brent Griffith, Sept 2010, plant upgrades, generalize fluid props
     800              : 
     801              :         // PURPOSE OF THIS SUBROUTINE:
     802              :         // This subroutine is for initializations of the IC ENGINE generators.
     803              : 
     804              :         // METHODOLOGY EMPLOYED:
     805              :         // Uses the status flags to trigger initializations.
     806              : 
     807            0 :         this->oneTimeInit(state); // end one time inits
     808              : 
     809              :         // Do the Begin Environment initializations
     810            0 :         if (state.dataGlobal->BeginEnvrnFlag && this->MyEnvrnFlag && this->HeatRecActive) {
     811            0 :             int HeatRecInletNode = this->HeatRecInletNodeNum;
     812            0 :             int HeatRecOutletNode = this->HeatRecOutletNodeNum;
     813              :             // set the node Temperature, assuming freeze control
     814            0 :             state.dataLoopNodes->Node(HeatRecInletNode).Temp = 20.0;
     815            0 :             state.dataLoopNodes->Node(HeatRecOutletNode).Temp = 20.0;
     816              :             // set the node max and min mass flow rates
     817            0 :             PlantUtilities::InitComponentNodes(state, 0.0, this->DesignHeatRecMassFlowRate, HeatRecInletNode, HeatRecOutletNode);
     818              : 
     819            0 :             this->MyEnvrnFlag = false;
     820              :         } // end environmental inits
     821              : 
     822            0 :         if (!state.dataGlobal->BeginEnvrnFlag) {
     823            0 :             this->MyEnvrnFlag = true;
     824              :         }
     825              : 
     826            0 :         if (this->HeatRecActive) {
     827            0 :             if (FirstHVACIteration) {
     828              :                 Real64 mdot;
     829            0 :                 if (RunFlag) {
     830            0 :                     mdot = this->DesignHeatRecMassFlowRate;
     831              :                 } else {
     832            0 :                     mdot = 0.0;
     833              :                 }
     834            0 :                 PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum, this->HRPlantLoc);
     835              : 
     836              :             } else {
     837            0 :                 PlantUtilities::SetComponentFlowRate(
     838            0 :                     state, this->HeatRecMdotActual, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum, this->HRPlantLoc);
     839              :             }
     840              :         }
     841            0 :     }
     842              : 
     843            0 :     void ICEngineGeneratorSpecs::update(EnergyPlusData &state)
     844              :     {
     845            0 :         if (this->HeatRecActive) {
     846            0 :             int HeatRecOutletNode = this->HeatRecOutletNodeNum;
     847            0 :             state.dataLoopNodes->Node(HeatRecOutletNode).Temp = this->HeatRecOutletTemp;
     848              :         }
     849            0 :     }
     850            0 :     void ICEngineGeneratorSpecs::oneTimeInit(EnergyPlusData &state)
     851              :     {
     852              :         static constexpr std::string_view RoutineName("InitICEngineGenerators");
     853              : 
     854              :         bool errFlag;
     855              : 
     856            0 :         if (this->myFlag) {
     857            0 :             this->setupOutputVars(state);
     858            0 :             this->myFlag = false;
     859              :         }
     860              : 
     861            0 :         if (this->MyPlantScanFlag && allocated(state.dataPlnt->PlantLoop) && this->HeatRecActive) {
     862            0 :             errFlag = false;
     863            0 :             PlantUtilities::ScanPlantLoopsForObject(
     864            0 :                 state, this->Name, DataPlant::PlantEquipmentType::Generator_ICEngine, this->HRPlantLoc, errFlag, _, _, _, _, _);
     865            0 :             if (errFlag) {
     866            0 :                 ShowFatalError(state, "InitICEngineGenerators: Program terminated due to previous condition(s).");
     867              :             }
     868              : 
     869            0 :             this->MyPlantScanFlag = false;
     870              :         }
     871              : 
     872            0 :         if (this->MySizeAndNodeInitFlag && (!this->MyPlantScanFlag) && this->HeatRecActive) {
     873              : 
     874              :             // size mass flow rate
     875            0 :             Real64 rho = state.dataPlnt->PlantLoop(this->HRPlantLoc.loopNum).glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
     876              : 
     877            0 :             this->DesignHeatRecMassFlowRate = rho * this->DesignHeatRecVolFlowRate;
     878            0 :             this->HeatRecMdotDesign = this->DesignHeatRecMassFlowRate;
     879              : 
     880            0 :             PlantUtilities::InitComponentNodes(state, 0.0, this->DesignHeatRecMassFlowRate, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum);
     881              : 
     882            0 :             this->MySizeAndNodeInitFlag = false;
     883              :         }
     884            0 :     }
     885              : 
     886              : } // namespace ICEngineElectricGenerator
     887              : 
     888              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1