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