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 <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 44139 : 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 44139 : if (state.dataICEngElectGen->getICEInput) {
95 5 : GetICEngineGeneratorInput(state);
96 5 : state.dataICEngElectGen->getICEInput = false;
97 : }
98 :
99 : // Now look for this particular generator in the list
100 44139 : for (auto &thisICE : state.dataICEngElectGen->ICEngineGenerator) {
101 44139 : if (thisICE.Name == objectName) {
102 44139 : 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 5 : 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 :
123 : int genNum; // Generator counter
124 : int NumAlphas; // Number of elements in the alpha array
125 : int NumNums; // Number of elements in the numeric array
126 : int IOStat; // IO Status when calling get input subroutine
127 5 : Array1D_string AlphArray(10); // character string data
128 5 : Array1D<Real64> NumArray(11); // numeric data
129 5 : bool ErrorsFound(false); // error flag
130 :
131 5 : auto &ICEngineGenerator(state.dataICEngElectGen->ICEngineGenerator);
132 :
133 5 : state.dataIPShortCut->cCurrentModuleObject = "Generator:InternalCombustionEngine";
134 10 : state.dataICEngElectGen->NumICEngineGenerators =
135 5 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
136 :
137 5 : if (state.dataICEngElectGen->NumICEngineGenerators <= 0) {
138 0 : ShowSevereError(state, format("No {} equipment specified in input file", state.dataIPShortCut->cCurrentModuleObject));
139 0 : ErrorsFound = true;
140 : }
141 :
142 : // ALLOCATE ARRAYS
143 5 : ICEngineGenerator.allocate(state.dataICEngElectGen->NumICEngineGenerators);
144 :
145 : // LOAD ARRAYS WITH IC ENGINE Generator CURVE FIT DATA
146 10 : for (genNum = 1; genNum <= state.dataICEngElectGen->NumICEngineGenerators; ++genNum) {
147 15 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
148 5 : state.dataIPShortCut->cCurrentModuleObject,
149 : genNum,
150 : AlphArray,
151 : NumAlphas,
152 : NumArray,
153 : NumNums,
154 : IOStat,
155 : _,
156 5 : state.dataIPShortCut->lAlphaFieldBlanks,
157 5 : state.dataIPShortCut->cAlphaFieldNames,
158 5 : state.dataIPShortCut->cNumericFieldNames);
159 5 : Util::IsNameEmpty(state, AlphArray(1), state.dataIPShortCut->cCurrentModuleObject, ErrorsFound);
160 :
161 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).Name = AlphArray(1);
162 :
163 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).RatedPowerOutput = NumArray(1);
164 5 : if (NumArray(1) == 0.0) {
165 0 : ShowSevereError(state, format("Invalid {}={:.2R}", state.dataIPShortCut->cNumericFieldNames(1), NumArray(1)));
166 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
167 0 : ErrorsFound = true;
168 : }
169 :
170 : // Not sure what to do with electric nodes, so do not use optional arguments
171 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).ElectricCircuitNode =
172 10 : NodeInputManager::GetOnlySingleNode(state,
173 5 : AlphArray(2),
174 : ErrorsFound,
175 : DataLoopNode::ConnectionObjectType::GeneratorInternalCombustionEngine,
176 5 : AlphArray(1),
177 : DataLoopNode::NodeFluidType::Electric,
178 : DataLoopNode::ConnectionType::Electric,
179 : NodeInputManager::CompFluidStream::Primary,
180 : DataLoopNode::ObjectIsNotParent);
181 :
182 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).MinPartLoadRat = NumArray(2);
183 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).MaxPartLoadRat = NumArray(3);
184 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).OptPartLoadRat = NumArray(4);
185 :
186 : // Load Special IC ENGINE Generator Curve Fit Inputs
187 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).ElecOutputFuelCurve =
188 5 : Curve::GetCurveIndex(state, AlphArray(3)); // convert curve name to number
189 5 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).ElecOutputFuelCurve == 0) {
190 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(3), AlphArray(3)));
191 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
192 0 : ErrorsFound = true;
193 : }
194 :
195 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).RecJacHeattoFuelCurve =
196 5 : Curve::GetCurveIndex(state, AlphArray(4)); // convert curve name to number
197 5 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).RecJacHeattoFuelCurve == 0) {
198 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(4), AlphArray(4)));
199 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
200 0 : ErrorsFound = true;
201 : }
202 :
203 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).RecLubeHeattoFuelCurve =
204 5 : Curve::GetCurveIndex(state, AlphArray(5)); // convert curve name to number
205 5 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).RecLubeHeattoFuelCurve == 0) {
206 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(5), AlphArray(5)));
207 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
208 0 : ErrorsFound = true;
209 : }
210 :
211 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).TotExhausttoFuelCurve =
212 5 : Curve::GetCurveIndex(state, AlphArray(6)); // convert curve name to number
213 5 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).TotExhausttoFuelCurve == 0) {
214 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(6), AlphArray(6)));
215 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
216 0 : ErrorsFound = true;
217 : }
218 :
219 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).ExhaustTempCurve =
220 5 : Curve::GetCurveIndex(state, AlphArray(7)); // convert curve name to number
221 5 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).ExhaustTempCurve == 0) {
222 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(7), AlphArray(7)));
223 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
224 0 : ErrorsFound = true;
225 : } else {
226 5 : Real64 xValue = Curve::CurveValue(state, state.dataICEngElectGen->ICEngineGenerator(genNum).ExhaustTempCurve, 1.0);
227 5 : if (xValue < ReferenceTemp) {
228 0 : ShowSevereError(state,
229 0 : format("GetICEngineGeneratorInput: {} output has very low value.", state.dataIPShortCut->cAlphaFieldNames(7)));
230 0 : ShowContinueError(state, format("...curve generates [{:.3R} C] at PLR=1.0", xValue));
231 0 : ShowContinueError(state,
232 0 : format("...this is less than the Reference Temperature [{:.2R} C] and may cause errors.", ReferenceTemp));
233 : }
234 : }
235 :
236 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).UACoef(1) = NumArray(5);
237 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).UACoef(2) = NumArray(6);
238 :
239 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).MaxExhaustperPowerOutput = NumArray(7);
240 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).DesignMinExitGasTemp = NumArray(8);
241 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).FuelHeatingValue = NumArray(9);
242 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).DesignHeatRecVolFlowRate = NumArray(10);
243 5 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).DesignHeatRecVolFlowRate > 0.0) {
244 3 : state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecActive = true;
245 3 : state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecInletNodeNum =
246 6 : NodeInputManager::GetOnlySingleNode(state,
247 3 : AlphArray(8),
248 : ErrorsFound,
249 : DataLoopNode::ConnectionObjectType::GeneratorInternalCombustionEngine,
250 3 : AlphArray(1),
251 : DataLoopNode::NodeFluidType::Water,
252 : DataLoopNode::ConnectionType::Inlet,
253 : NodeInputManager::CompFluidStream::Primary,
254 : DataLoopNode::ObjectIsNotParent);
255 3 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecInletNodeNum == 0) {
256 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(8), AlphArray(8)));
257 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
258 0 : ErrorsFound = true;
259 : }
260 3 : state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecOutletNodeNum =
261 6 : NodeInputManager::GetOnlySingleNode(state,
262 3 : AlphArray(9),
263 : ErrorsFound,
264 : DataLoopNode::ConnectionObjectType::GeneratorInternalCombustionEngine,
265 3 : AlphArray(1),
266 : DataLoopNode::NodeFluidType::Water,
267 : DataLoopNode::ConnectionType::Outlet,
268 : NodeInputManager::CompFluidStream::Primary,
269 : DataLoopNode::ObjectIsNotParent);
270 3 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecOutletNodeNum == 0) {
271 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(9), AlphArray(9)));
272 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
273 0 : ErrorsFound = true;
274 : }
275 6 : BranchNodeConnections::TestCompSet(
276 3 : state, state.dataIPShortCut->cCurrentModuleObject, AlphArray(1), AlphArray(8), AlphArray(9), "Heat Recovery Nodes");
277 6 : PlantUtilities::RegisterPlantCompDesignFlow(state,
278 3 : state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecInletNodeNum,
279 3 : state.dataICEngElectGen->ICEngineGenerator(genNum).DesignHeatRecVolFlowRate);
280 : } else {
281 2 : state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecActive = false;
282 2 : state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecInletNodeNum = 0;
283 2 : state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecOutletNodeNum = 0;
284 2 : if (!state.dataIPShortCut->lAlphaFieldBlanks(8) || !state.dataIPShortCut->lAlphaFieldBlanks(9)) {
285 0 : ShowWarningError(state,
286 0 : format("Since Design Heat Flow Rate = 0.0, Heat Recovery inactive for {}={}",
287 0 : state.dataIPShortCut->cCurrentModuleObject,
288 : AlphArray(1)));
289 0 : ShowContinueError(state, "However, Node names were specified for Heat Recovery inlet or outlet nodes");
290 : }
291 : }
292 :
293 : // Validate fuel type input
294 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).FuelType =
295 5 : static_cast<Constant::eFuel>(getEnumValue(Constant::eFuelNamesUC, AlphArray(10)));
296 5 : if (state.dataICEngElectGen->ICEngineGenerator(genNum).FuelType == Constant::eFuel::Invalid) {
297 0 : ShowSevereError(state, format("Invalid {}={}", state.dataIPShortCut->cAlphaFieldNames(10), AlphArray(10)));
298 0 : ShowContinueError(state, format("Entered in {}={}", state.dataIPShortCut->cCurrentModuleObject, AlphArray(1)));
299 0 : ErrorsFound = true;
300 : }
301 :
302 5 : state.dataICEngElectGen->ICEngineGenerator(genNum).HeatRecMaxTemp = NumArray(11);
303 : }
304 :
305 5 : if (ErrorsFound) {
306 0 : ShowFatalError(state, format("Errors found in processing input for {}", state.dataIPShortCut->cCurrentModuleObject));
307 : }
308 5 : }
309 :
310 5 : void ICEngineGeneratorSpecs::setupOutputVars(EnergyPlusData &state)
311 : {
312 5 : std::string_view const sFuelType = Constant::eFuelNames[static_cast<int>(this->FuelType)];
313 10 : SetupOutputVariable(state,
314 : "Generator Produced AC Electricity Rate",
315 : Constant::Units::W,
316 5 : this->ElecPowerGenerated,
317 : OutputProcessor::TimeStepType::System,
318 : OutputProcessor::StoreType::Average,
319 5 : this->Name);
320 :
321 10 : SetupOutputVariable(state,
322 : "Generator Produced AC Electricity Energy",
323 : Constant::Units::J,
324 5 : this->ElecEnergyGenerated,
325 : OutputProcessor::TimeStepType::System,
326 : OutputProcessor::StoreType::Sum,
327 5 : this->Name,
328 : Constant::eResource::ElectricityProduced,
329 : OutputProcessor::Group::Plant,
330 : OutputProcessor::EndUseCat::Cogeneration);
331 :
332 15 : SetupOutputVariable(state,
333 10 : format("Generator {} Rate", sFuelType),
334 : Constant::Units::W,
335 5 : this->FuelEnergyUseRate,
336 : OutputProcessor::TimeStepType::System,
337 : OutputProcessor::StoreType::Average,
338 5 : this->Name);
339 :
340 15 : SetupOutputVariable(state,
341 10 : format("Generator {} Energy", sFuelType),
342 : Constant::Units::J,
343 5 : this->FuelEnergy,
344 : OutputProcessor::TimeStepType::System,
345 : OutputProcessor::StoreType::Sum,
346 5 : this->Name,
347 5 : Constant::eFuel2eResource[(int)this->FuelType],
348 : OutputProcessor::Group::Plant,
349 : OutputProcessor::EndUseCat::Cogeneration);
350 :
351 : // general fuel use report to match other generators.
352 10 : SetupOutputVariable(state,
353 : "Generator Fuel HHV Basis Rate",
354 : Constant::Units::W,
355 5 : this->FuelEnergyUseRate,
356 : OutputProcessor::TimeStepType::System,
357 : OutputProcessor::StoreType::Average,
358 5 : this->Name);
359 :
360 10 : SetupOutputVariable(state,
361 : "Generator Fuel HHV Basis Energy",
362 : Constant::Units::J,
363 5 : this->FuelEnergy,
364 : OutputProcessor::TimeStepType::System,
365 : OutputProcessor::StoreType::Sum,
366 5 : this->Name);
367 :
368 15 : SetupOutputVariable(state,
369 10 : format("Generator {} Mass Flow Rate", sFuelType),
370 : Constant::Units::kg_s,
371 5 : this->FuelMdot,
372 : OutputProcessor::TimeStepType::System,
373 : OutputProcessor::StoreType::Average,
374 5 : this->Name);
375 :
376 10 : SetupOutputVariable(state,
377 : "Generator Exhaust Air Temperature",
378 : Constant::Units::C,
379 5 : this->ExhaustStackTemp,
380 : OutputProcessor::TimeStepType::System,
381 : OutputProcessor::StoreType::Average,
382 5 : this->Name);
383 :
384 5 : if (this->HeatRecActive) {
385 6 : SetupOutputVariable(state,
386 : "Generator Heat Recovery Mass Flow Rate",
387 : Constant::Units::kg_s,
388 3 : this->HeatRecMdotActual,
389 : OutputProcessor::TimeStepType::System,
390 : OutputProcessor::StoreType::Average,
391 3 : this->Name);
392 :
393 6 : SetupOutputVariable(state,
394 : "Generator Jacket Heat Recovery Rate",
395 : Constant::Units::W,
396 3 : this->QJacketRecovered,
397 : OutputProcessor::TimeStepType::System,
398 : OutputProcessor::StoreType::Average,
399 3 : this->Name);
400 :
401 6 : SetupOutputVariable(state,
402 : "Generator Jacket Heat Recovery Energy",
403 : Constant::Units::J,
404 3 : this->JacketEnergyRec,
405 : OutputProcessor::TimeStepType::System,
406 : OutputProcessor::StoreType::Sum,
407 3 : this->Name,
408 : Constant::eResource::EnergyTransfer,
409 : OutputProcessor::Group::Plant,
410 : OutputProcessor::EndUseCat::HeatRecovery);
411 :
412 6 : SetupOutputVariable(state,
413 : "Generator Lube Heat Recovery Rate",
414 : Constant::Units::W,
415 3 : this->QLubeOilRecovered,
416 : OutputProcessor::TimeStepType::System,
417 : OutputProcessor::StoreType::Average,
418 3 : this->Name);
419 :
420 6 : SetupOutputVariable(state,
421 : "Generator Lube Heat Recovery Energy",
422 : Constant::Units::J,
423 3 : this->LubeOilEnergyRec,
424 : OutputProcessor::TimeStepType::System,
425 : OutputProcessor::StoreType::Sum,
426 3 : this->Name,
427 : Constant::eResource::EnergyTransfer,
428 : OutputProcessor::Group::Plant,
429 : OutputProcessor::EndUseCat::HeatRecovery);
430 :
431 6 : SetupOutputVariable(state,
432 : "Generator Exhaust Heat Recovery Rate",
433 : Constant::Units::W,
434 3 : this->QExhaustRecovered,
435 : OutputProcessor::TimeStepType::System,
436 : OutputProcessor::StoreType::Average,
437 3 : this->Name);
438 :
439 6 : SetupOutputVariable(state,
440 : "Generator Exhaust Heat Recovery Energy",
441 : Constant::Units::J,
442 3 : this->ExhaustEnergyRec,
443 : OutputProcessor::TimeStepType::System,
444 : OutputProcessor::StoreType::Sum,
445 3 : this->Name,
446 : Constant::eResource::EnergyTransfer,
447 : OutputProcessor::Group::Plant,
448 : OutputProcessor::EndUseCat::HeatRecovery);
449 :
450 6 : SetupOutputVariable(state,
451 : "Generator Produced Thermal Rate",
452 : Constant::Units::W,
453 3 : this->QTotalHeatRecovered,
454 : OutputProcessor::TimeStepType::System,
455 : OutputProcessor::StoreType::Average,
456 3 : this->Name);
457 :
458 6 : SetupOutputVariable(state,
459 : "Generator Produced Thermal Energy",
460 : Constant::Units::J,
461 3 : this->TotalHeatEnergyRec,
462 : OutputProcessor::TimeStepType::System,
463 : OutputProcessor::StoreType::Sum,
464 3 : this->Name);
465 :
466 6 : SetupOutputVariable(state,
467 : "Generator Heat Recovery Inlet Temperature",
468 : Constant::Units::C,
469 3 : this->HeatRecInletTemp,
470 : OutputProcessor::TimeStepType::System,
471 : OutputProcessor::StoreType::Average,
472 3 : this->Name);
473 :
474 6 : SetupOutputVariable(state,
475 : "Generator Heat Recovery Outlet Temperature",
476 : Constant::Units::C,
477 3 : this->HeatRecOutletTemp,
478 : OutputProcessor::TimeStepType::System,
479 : OutputProcessor::StoreType::Average,
480 3 : this->Name);
481 : }
482 5 : }
483 :
484 15 : void ICEngineGeneratorSpecs::getDesignCapacities(
485 : [[maybe_unused]] EnergyPlusData &state, const EnergyPlus::PlantLocation &, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
486 : {
487 15 : MaxLoad = 0.0;
488 15 : MinLoad = 0.0;
489 15 : OptLoad = 0.0;
490 15 : }
491 :
492 105647 : 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 105647 : 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 105647 : }
514 :
515 44136 : 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 44136 : constexpr Real64 ExhaustCP(1.047); // Exhaust Gas Specific Heat (J/kg-K)
530 44136 : 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 44136 : if (this->HeatRecActive) {
539 27120 : int HeatRecInNode = this->HeatRecInletNodeNum;
540 27120 : HeatRecInTemp = state.dataLoopNodes->Node(HeatRecInNode).Temp;
541 27120 : HeatRecMdot = state.dataLoopNodes->Node(HeatRecInNode).MassFlowRate;
542 :
543 : } else {
544 17016 : HeatRecInTemp = 0.0;
545 17016 : HeatRecMdot = 0.0;
546 : }
547 :
548 : // If no loop demand or Generator OFF, return
549 44136 : if (!RunFlag) {
550 34639 : this->ElecPowerGenerated = 0.0;
551 34639 : this->ElecEnergyGenerated = 0.0;
552 34639 : this->HeatRecInletTemp = HeatRecInTemp;
553 34639 : this->HeatRecOutletTemp = HeatRecInTemp;
554 34639 : this->HeatRecMdotActual = 0.0;
555 34639 : this->QJacketRecovered = 0.0;
556 34639 : this->QExhaustRecovered = 0.0;
557 34639 : this->QLubeOilRecovered = 0.0;
558 34639 : this->QTotalHeatRecovered = 0.0;
559 34639 : this->JacketEnergyRec = 0.0;
560 34639 : this->ExhaustEnergyRec = 0.0;
561 34639 : this->LubeOilEnergyRec = 0.0;
562 34639 : this->TotalHeatEnergyRec = 0.0;
563 34639 : this->FuelEnergyUseRate = 0.0;
564 34639 : this->FuelEnergy = 0.0;
565 34639 : this->FuelMdot = 0.0;
566 34639 : this->ExhaustStackTemp = 0.0;
567 :
568 34639 : return;
569 : }
570 :
571 : // Generator output (W)
572 9497 : Real64 elecPowerGenerated = min(MyLoad, this->RatedPowerOutput);
573 9497 : elecPowerGenerated = max(elecPowerGenerated, 0.0);
574 :
575 : // Generator operating part load ratio
576 9497 : Real64 PLR = min(elecPowerGenerated / this->RatedPowerOutput, this->MaxPartLoadRat);
577 9497 : PLR = max(PLR, this->MinPartLoadRat);
578 9497 : 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 9497 : if (PLR > 0.0) {
586 : // (RELDC) Ratio of generator output to Fuel Energy Input
587 9497 : Real64 elecOutputFuelRat = Curve::CurveValue(state, this->ElecOutputFuelCurve, PLR);
588 9497 : 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 9497 : Real64 recJacHeattoFuelRat = Curve::CurveValue(state, this->RecJacHeattoFuelCurve, PLR);
599 :
600 : // water jacket heat recovered (W)
601 9497 : 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 9497 : Real64 recLubeHeattoFuelRat = Curve::CurveValue(state, this->RecLubeHeattoFuelCurve, PLR);
608 :
609 : // lube oil cooler heat recovered (W)
610 9497 : 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 9497 : Real64 totExhausttoFuelRat = Curve::CurveValue(state, this->TotExhausttoFuelCurve, PLR);
618 :
619 : // total engine exhaust heat (W)
620 9497 : Real64 QExhaustTotal = fuelEnergyUseRate * totExhausttoFuelRat;
621 :
622 : // exhaust gas heat recovered (W)
623 : Real64 QExhaustRec;
624 :
625 : // engine stack temp. (C)
626 9497 : 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 9497 : if (PLR > 0.0) {
631 : // (TEX) Exhaust Gas Temp
632 9497 : Real64 exhaustTemp = Curve::CurveValue(state, this->ExhaustTempCurve, PLR);
633 :
634 9497 : if (exhaustTemp > ReferenceTemp) {
635 :
636 : // exhaust gas mass flow rate (kg/s)
637 9497 : 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 9497 : Real64 UA_loc = this->UACoef(1) * std::pow(this->RatedPowerOutput, this->UACoef(2));
642 :
643 : // design engine stact saturated steam exhaustTemp. (C)
644 9497 : Real64 designMinExitGasTemp = this->DesignMinExitGasTemp;
645 :
646 9497 : exhaustStackTemp = designMinExitGasTemp +
647 18994 : (exhaustTemp - designMinExitGasTemp) /
648 9497 : std::exp(UA_loc / (max(ExhaustGasFlow, this->MaxExhaustperPowerOutput * this->RatedPowerOutput) * ExhaustCP));
649 :
650 9497 : 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 9497 : 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 9497 : if (this->HeatRecActive) {
681 7135 : this->CalcICEngineGenHeatRecovery(state, qTotalHeatRecovered, HeatRecMdot, HRecRatio);
682 7135 : QExhaustRec *= HRecRatio;
683 7135 : QLubeOilRec *= HRecRatio;
684 7135 : QJacketRec *= HRecRatio;
685 7135 : qTotalHeatRecovered *= HRecRatio;
686 : } else {
687 2362 : this->HeatRecInletTemp = HeatRecInTemp;
688 2362 : this->HeatRecOutletTemp = HeatRecInTemp;
689 2362 : this->HeatRecMdotActual = HeatRecMdot;
690 : }
691 :
692 : // Calculate Energy
693 : // Generator output (J)
694 9497 : Real64 ElectricEnergyGen = elecPowerGenerated * state.dataHVACGlobal->TimeStepSysSec;
695 :
696 : // IC ENGINE fuel use (J)
697 9497 : Real64 FuelEnergyUsed = fuelEnergyUseRate * state.dataHVACGlobal->TimeStepSysSec;
698 :
699 : // water jacket heat recovered (J)
700 9497 : Real64 jacketEnergyRec = QJacketRec * state.dataHVACGlobal->TimeStepSysSec;
701 :
702 : // lube oil cooler heat recovered (J)
703 9497 : Real64 lubeOilEnergyRec = QLubeOilRec * state.dataHVACGlobal->TimeStepSysSec;
704 :
705 : // exhaust gas heat recovered (J)
706 9497 : Real64 exhaustEnergyRec = QExhaustRec * state.dataHVACGlobal->TimeStepSysSec;
707 9497 : this->ElecPowerGenerated = elecPowerGenerated;
708 9497 : this->ElecEnergyGenerated = ElectricEnergyGen;
709 9497 : this->QJacketRecovered = QJacketRec;
710 9497 : this->QLubeOilRecovered = QLubeOilRec;
711 9497 : this->QExhaustRecovered = QExhaustRec;
712 9497 : this->QTotalHeatRecovered = qTotalHeatRecovered;
713 9497 : this->JacketEnergyRec = jacketEnergyRec;
714 9497 : this->LubeOilEnergyRec = lubeOilEnergyRec;
715 9497 : this->ExhaustEnergyRec = exhaustEnergyRec;
716 9497 : this->QTotalHeatRecovered = (QExhaustRec + QLubeOilRec + QJacketRec);
717 9497 : this->TotalHeatEnergyRec = (exhaustEnergyRec + lubeOilEnergyRec + jacketEnergyRec);
718 9497 : this->FuelEnergyUseRate = std::abs(fuelEnergyUseRate);
719 9497 : this->FuelEnergy = std::abs(FuelEnergyUsed);
720 :
721 : // Heating Value of Fuel in kJ/kg
722 9497 : Real64 fuelHeatingValue = this->FuelHeatingValue;
723 :
724 9497 : this->FuelMdot = std::abs(fuelEnergyUseRate) / (fuelHeatingValue * KJtoJ);
725 9497 : this->ExhaustStackTemp = exhaustStackTemp;
726 : }
727 :
728 7135 : 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 7135 : HRecRatio = 1.0;
749 :
750 7135 : Real64 HeatRecInTemp = state.dataLoopNodes->Node(this->HeatRecInletNodeNum).Temp;
751 7135 : Real64 HeatRecCp = FluidProperties::GetSpecificHeatGlycol(state,
752 7135 : state.dataPlnt->PlantLoop(this->HRPlantLoc.loopNum).FluidName,
753 : HeatRecInTemp,
754 7135 : state.dataPlnt->PlantLoop(this->HRPlantLoc.loopNum).FluidIndex,
755 : RoutineName);
756 :
757 : // Don't divide by zero - Note This also results in no heat recovery when
758 : // design Mdot for Heat Recovery - Specified on Chiller Input - is zero
759 : // In order to see what minimum heat recovery flow rate is for the design temperature
760 : // The design heat recovery flow rate can be set very small, but greater than zero.
761 :
762 : Real64 HeatRecOutTemp;
763 :
764 7135 : if ((HeatRecMdot > 0) && (HeatRecCp > 0)) {
765 7135 : HeatRecOutTemp = (EnergyRecovered) / (HeatRecMdot * HeatRecCp) + HeatRecInTemp;
766 : } else {
767 0 : HeatRecOutTemp = HeatRecInTemp;
768 : }
769 :
770 : // Note: check to make sure the Max Temperature was not exceeded
771 7135 : if (HeatRecOutTemp > this->HeatRecMaxTemp) {
772 : Real64 MinHeatRecMdot;
773 2138 : if (this->HeatRecMaxTemp != HeatRecInTemp) {
774 2138 : MinHeatRecMdot = (EnergyRecovered) / (HeatRecCp * (this->HeatRecMaxTemp - HeatRecInTemp));
775 2138 : if (MinHeatRecMdot < 0.0) MinHeatRecMdot = 0.0;
776 : } else {
777 0 : MinHeatRecMdot = 0.0;
778 : }
779 :
780 : // Recalculate Outlet Temperature, with adjusted flowrate
781 2138 : if ((MinHeatRecMdot > 0.0) && (HeatRecCp > 0.0)) {
782 2138 : HeatRecOutTemp = (EnergyRecovered) / (MinHeatRecMdot * HeatRecCp) + HeatRecInTemp;
783 2138 : HRecRatio = HeatRecMdot / MinHeatRecMdot;
784 : } else {
785 0 : HeatRecOutTemp = HeatRecInTemp;
786 0 : HRecRatio = 0.0;
787 : }
788 : }
789 :
790 : // Update global variables for reporting later
791 7135 : this->HeatRecInletTemp = HeatRecInTemp;
792 7135 : this->HeatRecOutletTemp = HeatRecOutTemp;
793 7135 : this->HeatRecMdotActual = HeatRecMdot;
794 7135 : }
795 :
796 44136 : void ICEngineGeneratorSpecs::InitICEngineGenerators(EnergyPlusData &state, bool const RunFlag, bool const FirstHVACIteration)
797 : {
798 :
799 : // SUBROUTINE INFORMATION:
800 : // AUTHOR Dan Fisher
801 : // DATE WRITTEN Oct 2000
802 : // MODIFIED na
803 : // RE-ENGINEERED Brent Griffith, Sept 2010, plant upgrades, generalize fluid props
804 :
805 : // PURPOSE OF THIS SUBROUTINE:
806 : // This subroutine is for initializations of the IC ENGINE generators.
807 :
808 : // METHODOLOGY EMPLOYED:
809 : // Uses the status flags to trigger initializations.
810 :
811 44136 : this->oneTimeInit(state); // end one time inits
812 :
813 : // Do the Begin Environment initializations
814 44136 : if (state.dataGlobal->BeginEnvrnFlag && this->MyEnvrnFlag && this->HeatRecActive) {
815 22 : int HeatRecInletNode = this->HeatRecInletNodeNum;
816 22 : int HeatRecOutletNode = this->HeatRecOutletNodeNum;
817 : // set the node Temperature, assuming freeze control
818 22 : state.dataLoopNodes->Node(HeatRecInletNode).Temp = 20.0;
819 22 : state.dataLoopNodes->Node(HeatRecOutletNode).Temp = 20.0;
820 : // set the node max and min mass flow rates
821 22 : PlantUtilities::InitComponentNodes(state, 0.0, this->DesignHeatRecMassFlowRate, HeatRecInletNode, HeatRecOutletNode);
822 :
823 22 : this->MyEnvrnFlag = false;
824 : } // end environmental inits
825 :
826 44136 : if (!state.dataGlobal->BeginEnvrnFlag) {
827 43715 : this->MyEnvrnFlag = true;
828 : }
829 :
830 44136 : if (this->HeatRecActive) {
831 27120 : if (FirstHVACIteration) {
832 : Real64 mdot;
833 17630 : if (RunFlag) {
834 4646 : mdot = this->DesignHeatRecMassFlowRate;
835 : } else {
836 12984 : mdot = 0.0;
837 : }
838 17630 : PlantUtilities::SetComponentFlowRate(state, mdot, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum, this->HRPlantLoc);
839 :
840 : } else {
841 9490 : PlantUtilities::SetComponentFlowRate(
842 9490 : state, this->HeatRecMdotActual, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum, this->HRPlantLoc);
843 : }
844 : }
845 44136 : }
846 :
847 44136 : void ICEngineGeneratorSpecs::update(EnergyPlusData &state)
848 : {
849 44136 : if (this->HeatRecActive) {
850 27120 : int HeatRecOutletNode = this->HeatRecOutletNodeNum;
851 27120 : state.dataLoopNodes->Node(HeatRecOutletNode).Temp = this->HeatRecOutletTemp;
852 : }
853 44136 : }
854 44136 : void ICEngineGeneratorSpecs::oneTimeInit(EnergyPlusData &state)
855 : {
856 : static constexpr std::string_view RoutineName("InitICEngineGenerators");
857 :
858 : bool errFlag;
859 :
860 44136 : if (this->myFlag) {
861 5 : this->setupOutputVars(state);
862 5 : this->myFlag = false;
863 : }
864 :
865 44136 : if (this->MyPlantScanFlag && allocated(state.dataPlnt->PlantLoop) && this->HeatRecActive) {
866 3 : errFlag = false;
867 6 : PlantUtilities::ScanPlantLoopsForObject(
868 3 : state, this->Name, DataPlant::PlantEquipmentType::Generator_ICEngine, this->HRPlantLoc, errFlag, _, _, _, _, _);
869 3 : if (errFlag) {
870 0 : ShowFatalError(state, "InitICEngineGenerators: Program terminated due to previous condition(s).");
871 : }
872 :
873 3 : this->MyPlantScanFlag = false;
874 : }
875 :
876 44136 : if (this->MySizeAndNodeInitFlag && (!this->MyPlantScanFlag) && this->HeatRecActive) {
877 :
878 : // size mass flow rate
879 3 : Real64 rho = FluidProperties::GetDensityGlycol(state,
880 3 : state.dataPlnt->PlantLoop(this->HRPlantLoc.loopNum).FluidName,
881 : Constant::InitConvTemp,
882 3 : state.dataPlnt->PlantLoop(this->HRPlantLoc.loopNum).FluidIndex,
883 : RoutineName);
884 :
885 3 : this->DesignHeatRecMassFlowRate = rho * this->DesignHeatRecVolFlowRate;
886 3 : this->HeatRecMdotDesign = this->DesignHeatRecMassFlowRate;
887 :
888 3 : PlantUtilities::InitComponentNodes(state, 0.0, this->DesignHeatRecMassFlowRate, this->HeatRecInletNodeNum, this->HeatRecOutletNodeNum);
889 :
890 3 : this->MySizeAndNodeInitFlag = false;
891 : }
892 44136 : }
893 :
894 : } // namespace ICEngineElectricGenerator
895 :
896 : } // namespace EnergyPlus
|