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 <cassert>
50 : #include <cmath>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Array.functions.hh>
54 : #include <ObjexxFCL/Fmath.hh>
55 :
56 : // EnergyPlus Headers
57 : #include <EnergyPlus/Autosizing/Base.hh>
58 : #include <EnergyPlus/BranchNodeConnections.hh>
59 : #include <EnergyPlus/ChillerGasAbsorption.hh>
60 : #include <EnergyPlus/CurveManager.hh>
61 : #include <EnergyPlus/Data/EnergyPlusData.hh>
62 : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
63 : #include <EnergyPlus/DataEnvironment.hh>
64 : #include <EnergyPlus/DataHVACGlobals.hh>
65 : #include <EnergyPlus/DataIPShortCuts.hh>
66 : #include <EnergyPlus/DataLoopNode.hh>
67 : #include <EnergyPlus/DataSizing.hh>
68 : #include <EnergyPlus/EMSManager.hh>
69 : #include <EnergyPlus/FluidProperties.hh>
70 : #include <EnergyPlus/GlobalNames.hh>
71 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
72 : #include <EnergyPlus/NodeInputManager.hh>
73 : #include <EnergyPlus/OutAirNodeManager.hh>
74 : #include <EnergyPlus/OutputProcessor.hh>
75 : #include <EnergyPlus/OutputReportPredefined.hh>
76 : #include <EnergyPlus/Plant/DataPlant.hh>
77 : #include <EnergyPlus/PlantUtilities.hh>
78 : #include <EnergyPlus/Psychrometrics.hh>
79 : #include <EnergyPlus/UtilityRoutines.hh>
80 :
81 : namespace EnergyPlus::ChillerGasAbsorption {
82 :
83 : // MODULE INFORMATION:
84 : // AUTHOR Jason Glazer of GARD Analytics, Inc.
85 : // for Gas Research Institute
86 : // DATE WRITTEN March 2001
87 : // MODIFIED Brent Griffith, Nov 2010 plant upgrades, generalize fluid properties
88 : // RE-ENGINEERED na
89 : // PURPOSE OF THIS MODULE:
90 : // This module simulates the performance of the direct fired
91 : // absorption chiller.
92 : // METHODOLOGY EMPLOYED:
93 : // Once the PlantLoopManager determines that the absorber chiller
94 : // is available to meet a loop cooling demand, it calls SimGasAbsorption
95 : // which in turn calls the appropriate Absorption Chiller model.
96 : // REFERENCES:
97 : // DOE-2.1e Supplement
98 : // PG&E CoolTools GasMod
99 : // OTHER NOTES:
100 : // The curves on this model follow the DOE-2 approach of using
101 : // electric and heat input ratios. In addition, the temperature
102 : // correction curve has two independent variables for the
103 : // chilled water temperature and either the entering or leaving
104 : // condenser water temperature.
105 : // The code was originally adopted from the ChillerAbsorption
106 : // routine but has been extensively modified.
107 : // Development of this module was funded by the Gas Research Institute.
108 : // (Please see copyright and disclaimer information at end of module)
109 :
110 3 : PlantComponent *GasAbsorberSpecs::factory(EnergyPlusData &state, std::string const &objectName)
111 : {
112 : // Process the input data if it hasn't been done already
113 3 : if (state.dataChillerGasAbsorption->getGasAbsorberInputs) {
114 1 : GetGasAbsorberInput(state);
115 1 : state.dataChillerGasAbsorption->getGasAbsorberInputs = false;
116 : }
117 : // Now look for this particular pipe in the list
118 3 : for (auto &comp : state.dataChillerGasAbsorption->GasAbsorber) {
119 3 : if (comp.Name == objectName) {
120 3 : return ∁
121 : }
122 : }
123 : // If we didn't find it, fatal
124 : ShowFatalError(state, "LocalGasAbsorberFactory: Error getting inputs for comp named: " + objectName); // LCOV_EXCL_LINE
125 : // Shut up the compiler
126 : return nullptr; // LCOV_EXCL_LINE
127 : }
128 :
129 63639 : void GasAbsorberSpecs::simulate(
130 : EnergyPlusData &state, const PlantLocation &calledFromLocation, bool FirstHVACIteration, Real64 &CurLoad, bool RunFlag)
131 : {
132 63639 : DataPlant::BrLoopType brIdentity(DataPlant::BrLoopType::NoMatch);
133 :
134 63639 : int branchTotalComp = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
135 63639 : .LoopSide(calledFromLocation.loopSideNum)
136 63639 : .Branch(calledFromLocation.branchNum)
137 63639 : .TotalComponents;
138 :
139 63639 : for (int iComp = 1; iComp <= branchTotalComp; iComp++) {
140 : // kind of a hacky way to find the location of this, but it's what plantloopequip was doing
141 63639 : int compInletNodeNum = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
142 63639 : .LoopSide(calledFromLocation.loopSideNum)
143 63639 : .Branch(calledFromLocation.branchNum)
144 63639 : .Comp(iComp)
145 63639 : .NodeNumIn;
146 : // Match inlet node name of calling branch to determine if this call is for heating or cooling
147 63639 : if (compInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller
148 21213 : brIdentity = DataPlant::BrLoopType::Chiller;
149 21213 : break;
150 42426 : } else if (compInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater
151 21213 : brIdentity = DataPlant::BrLoopType::Heater;
152 21213 : break;
153 21213 : } else if (compInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop
154 21213 : brIdentity = DataPlant::BrLoopType::Condenser;
155 21213 : break;
156 : } else {
157 0 : brIdentity = DataPlant::BrLoopType::NoMatch;
158 : }
159 : }
160 :
161 63639 : if (brIdentity == DataPlant::BrLoopType::Chiller) {
162 : // Calculate Node Values
163 : // Calculate Equipment and Update Variables
164 21213 : this->InCoolingMode = RunFlag != 0;
165 21213 : this->initialize(state);
166 21213 : this->calculateChiller(state, CurLoad);
167 21213 : this->updateCoolRecords(state, CurLoad, RunFlag);
168 42426 : } else if (brIdentity == DataPlant::BrLoopType::Heater) {
169 : // Calculate Node Values
170 : // Calculate Equipment and Update Variables
171 21213 : this->InHeatingMode = RunFlag != 0;
172 21213 : this->initialize(state);
173 21213 : this->calculateHeater(state, CurLoad, RunFlag);
174 21213 : this->updateHeatRecords(state, CurLoad, RunFlag);
175 21213 : } else if (brIdentity == DataPlant::BrLoopType::Condenser) {
176 21213 : if (this->CDplantLoc.loopNum > 0) {
177 21213 : PlantUtilities::UpdateChillerComponentCondenserSide(state,
178 : this->CDplantLoc.loopNum,
179 : this->CDplantLoc.loopSideNum,
180 : DataPlant::PlantEquipmentType::Chiller_DFAbsorption,
181 : this->CondReturnNodeNum,
182 : this->CondSupplyNodeNum,
183 : this->TowerLoad,
184 : this->CondReturnTemp,
185 : this->CondSupplyTemp,
186 : this->CondWaterFlowRate,
187 : FirstHVACIteration);
188 : }
189 : } else {
190 : // Error, nodes do not match
191 0 : ShowSevereError(state, "Invalid call to Gas Absorber Chiller " + this->Name);
192 0 : ShowContinueError(state, "Node connections in branch are not consistent with object nodes.");
193 0 : ShowFatalError(state, "Preceding conditions cause termination.");
194 : }
195 63639 : }
196 :
197 15 : void GasAbsorberSpecs::getDesignCapacities(
198 : EnergyPlusData &state, const PlantLocation &calledFromLocation, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
199 : {
200 15 : bool matchfound(false);
201 :
202 15 : int branchTotalComp = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
203 15 : .LoopSide(calledFromLocation.loopSideNum)
204 15 : .Branch(calledFromLocation.branchNum)
205 15 : .TotalComponents;
206 :
207 15 : for (int iComp = 1; iComp <= branchTotalComp; iComp++) {
208 : // kind of a hacky way to find the location of this, but it's what plantloopequip was doing
209 15 : int compInletNodeNum = state.dataPlnt->PlantLoop(calledFromLocation.loopNum)
210 15 : .LoopSide(calledFromLocation.loopSideNum)
211 15 : .Branch(calledFromLocation.branchNum)
212 15 : .Comp(iComp)
213 15 : .NodeNumIn;
214 :
215 15 : if (compInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller
216 5 : MinLoad = this->NomCoolingCap * this->MinPartLoadRat;
217 5 : MaxLoad = this->NomCoolingCap * this->MaxPartLoadRat;
218 5 : OptLoad = this->NomCoolingCap * this->OptPartLoadRat;
219 5 : matchfound = true;
220 5 : break;
221 10 : } else if (compInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater
222 5 : Real64 Sim_HeatCap = this->NomCoolingCap * this->NomHeatCoolRatio;
223 5 : MinLoad = Sim_HeatCap * this->MinPartLoadRat;
224 5 : MaxLoad = Sim_HeatCap * this->MaxPartLoadRat;
225 5 : OptLoad = Sim_HeatCap * this->OptPartLoadRat;
226 5 : matchfound = true;
227 5 : break;
228 5 : } else if (compInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop
229 5 : MinLoad = 0.0;
230 5 : MaxLoad = 0.0;
231 5 : OptLoad = 0.0;
232 5 : matchfound = true;
233 5 : break;
234 : } else {
235 0 : matchfound = false;
236 : }
237 : }
238 :
239 15 : if (!matchfound) {
240 : // Error, nodes do not match
241 0 : ShowSevereError(state, "SimGasAbsorber: Invalid call to Gas Absorbtion Chiller-Heater " + this->Name);
242 0 : ShowContinueError(state, "Node connections in branch are not consistent with object nodes.");
243 0 : ShowFatalError(state, "Preceding conditions cause termination.");
244 : } // Operate as Chiller or Heater
245 15 : }
246 :
247 3 : void GasAbsorberSpecs::getSizingFactor(Real64 &_SizFac)
248 : {
249 3 : _SizFac = this->SizFac;
250 3 : }
251 :
252 15 : void GasAbsorberSpecs::onInitLoopEquip(EnergyPlusData &state, const PlantLocation &calledFromLocation)
253 : {
254 15 : this->initialize(state);
255 :
256 : // kind of a hacky way to find the location of this, but it's what plantloopequip was doing
257 : int BranchInletNodeNum =
258 15 : state.dataPlnt->PlantLoop(calledFromLocation.loopNum).LoopSide(calledFromLocation.loopSideNum).Branch(calledFromLocation.branchNum).NodeNumIn;
259 :
260 15 : if (BranchInletNodeNum == this->ChillReturnNodeNum) { // Operate as chiller
261 5 : this->size(state); // only call from chilled water loop
262 10 : } else if (BranchInletNodeNum == this->HeatReturnNodeNum) { // Operate as heater
263 : // don't do anything here
264 5 : } else if (BranchInletNodeNum == this->CondReturnNodeNum) { // called from condenser loop
265 : // don't do anything here
266 : } else { // Error, nodes do not match
267 0 : ShowSevereError(state, "SimGasAbsorber: Invalid call to Gas Absorbtion Chiller-Heater " + this->Name);
268 0 : ShowContinueError(state, "Node connections in branch are not consistent with object nodes.");
269 0 : ShowFatalError(state, "Preceding conditions cause termination.");
270 : } // Operate as Chiller or Heater
271 15 : }
272 :
273 15 : void GasAbsorberSpecs::getDesignTemperatures(Real64 &TempCondInDesign, Real64 &TempEvapOutDesign)
274 : {
275 15 : TempEvapOutDesign = this->TempDesCHWSupply;
276 15 : TempCondInDesign = this->TempDesCondReturn;
277 15 : }
278 :
279 1 : void GetGasAbsorberInput(EnergyPlusData &state)
280 : {
281 : // AUTHOR: Jason Glazer
282 : // DATE WRITTEN: March 2001
283 : // This routine will get the input
284 : // required by the Direct Fired Absorption chiller model in the object ChillerHeater:Absorption:DirectFired
285 :
286 : using BranchNodeConnections::TestCompSet;
287 : using Curve::GetCurveCheck;
288 : using DataSizing::AutoSize;
289 : using GlobalNames::VerifyUniqueChillerName;
290 : using NodeInputManager::GetOnlySingleNode;
291 : using OutAirNodeManager::CheckAndAddAirNodeNumber;
292 :
293 : int AbsorberNum; // Absorber counter
294 : int NumAlphas; // Number of elements in the alpha array
295 : int NumNums; // Number of elements in the numeric array
296 : int IOStat; // IO Status when calling get input subroutine
297 2 : std::string ChillerName;
298 : bool Okay;
299 1 : bool Get_ErrorsFound(false);
300 1 : int NumGasAbsorbers(0); // number of Absorption Chillers specified in input
301 1 : auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
302 :
303 1 : state.dataIPShortCut->cCurrentModuleObject = "ChillerHeater:Absorption:DirectFired";
304 1 : NumGasAbsorbers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
305 :
306 1 : if (NumGasAbsorbers <= 0) {
307 0 : ShowSevereError(state, "No " + cCurrentModuleObject + " equipment found in input file");
308 0 : Get_ErrorsFound = true;
309 : }
310 :
311 1 : if (allocated(state.dataChillerGasAbsorption->GasAbsorber)) return;
312 :
313 : // ALLOCATE ARRAYS
314 1 : state.dataChillerGasAbsorption->GasAbsorber.allocate(NumGasAbsorbers);
315 :
316 : // LOAD ARRAYS
317 :
318 2 : for (AbsorberNum = 1; AbsorberNum <= NumGasAbsorbers; ++AbsorberNum) {
319 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
320 : cCurrentModuleObject,
321 : AbsorberNum,
322 1 : state.dataIPShortCut->cAlphaArgs,
323 : NumAlphas,
324 1 : state.dataIPShortCut->rNumericArgs,
325 : NumNums,
326 : IOStat,
327 : _,
328 1 : state.dataIPShortCut->lAlphaFieldBlanks,
329 1 : state.dataIPShortCut->cAlphaFieldNames,
330 1 : state.dataIPShortCut->cNumericFieldNames);
331 1 : UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, Get_ErrorsFound);
332 :
333 : // Get_ErrorsFound will be set to True if problem was found, left untouched otherwise
334 1 : VerifyUniqueChillerName(state, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1), Get_ErrorsFound, cCurrentModuleObject + " Name");
335 :
336 1 : auto &thisChiller = state.dataChillerGasAbsorption->GasAbsorber(AbsorberNum);
337 1 : thisChiller.Name = state.dataIPShortCut->cAlphaArgs(1);
338 1 : ChillerName = cCurrentModuleObject + " Named " + thisChiller.Name;
339 :
340 : // Assign capacities
341 1 : thisChiller.NomCoolingCap = state.dataIPShortCut->rNumericArgs(1);
342 1 : if (thisChiller.NomCoolingCap == AutoSize) {
343 0 : thisChiller.NomCoolingCapWasAutoSized = true;
344 : }
345 1 : thisChiller.NomHeatCoolRatio = state.dataIPShortCut->rNumericArgs(2);
346 : // Assign efficiencies
347 1 : thisChiller.FuelCoolRatio = state.dataIPShortCut->rNumericArgs(3);
348 1 : thisChiller.FuelHeatRatio = state.dataIPShortCut->rNumericArgs(4);
349 1 : thisChiller.ElecCoolRatio = state.dataIPShortCut->rNumericArgs(5);
350 1 : thisChiller.ElecHeatRatio = state.dataIPShortCut->rNumericArgs(6);
351 :
352 : // Assign Node Numbers to specified nodes
353 1 : thisChiller.ChillReturnNodeNum = GetOnlySingleNode(state,
354 1 : state.dataIPShortCut->cAlphaArgs(2),
355 : Get_ErrorsFound,
356 : DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDirectFired,
357 1 : state.dataIPShortCut->cAlphaArgs(1),
358 : DataLoopNode::NodeFluidType::Water,
359 : DataLoopNode::ConnectionType::Inlet,
360 : NodeInputManager::CompFluidStream::Primary,
361 1 : DataLoopNode::ObjectIsNotParent);
362 1 : thisChiller.ChillSupplyNodeNum = GetOnlySingleNode(state,
363 1 : state.dataIPShortCut->cAlphaArgs(3),
364 : Get_ErrorsFound,
365 : DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDirectFired,
366 1 : state.dataIPShortCut->cAlphaArgs(1),
367 : DataLoopNode::NodeFluidType::Water,
368 : DataLoopNode::ConnectionType::Outlet,
369 : NodeInputManager::CompFluidStream::Primary,
370 1 : DataLoopNode::ObjectIsNotParent);
371 2 : TestCompSet(state,
372 : cCurrentModuleObject,
373 1 : state.dataIPShortCut->cAlphaArgs(1),
374 1 : state.dataIPShortCut->cAlphaArgs(2),
375 1 : state.dataIPShortCut->cAlphaArgs(3),
376 : "Chilled Water Nodes");
377 : // Condenser node processing depends on condenser type, see below
378 1 : thisChiller.HeatReturnNodeNum = GetOnlySingleNode(state,
379 1 : state.dataIPShortCut->cAlphaArgs(6),
380 : Get_ErrorsFound,
381 : DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDirectFired,
382 1 : state.dataIPShortCut->cAlphaArgs(1),
383 : DataLoopNode::NodeFluidType::Water,
384 : DataLoopNode::ConnectionType::Inlet,
385 : NodeInputManager::CompFluidStream::Tertiary,
386 1 : DataLoopNode::ObjectIsNotParent);
387 1 : thisChiller.HeatSupplyNodeNum = GetOnlySingleNode(state,
388 1 : state.dataIPShortCut->cAlphaArgs(7),
389 : Get_ErrorsFound,
390 : DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDirectFired,
391 1 : state.dataIPShortCut->cAlphaArgs(1),
392 : DataLoopNode::NodeFluidType::Water,
393 : DataLoopNode::ConnectionType::Outlet,
394 : NodeInputManager::CompFluidStream::Tertiary,
395 1 : DataLoopNode::ObjectIsNotParent);
396 2 : TestCompSet(state,
397 : cCurrentModuleObject,
398 1 : state.dataIPShortCut->cAlphaArgs(1),
399 1 : state.dataIPShortCut->cAlphaArgs(6),
400 1 : state.dataIPShortCut->cAlphaArgs(7),
401 : "Hot Water Nodes");
402 1 : if (Get_ErrorsFound) {
403 0 : ShowFatalError(state, "Errors found in processing node input for " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
404 0 : Get_ErrorsFound = false;
405 : }
406 :
407 : // Assign Part Load Ratios
408 1 : thisChiller.MinPartLoadRat = state.dataIPShortCut->rNumericArgs(7);
409 1 : thisChiller.MaxPartLoadRat = state.dataIPShortCut->rNumericArgs(8);
410 1 : thisChiller.OptPartLoadRat = state.dataIPShortCut->rNumericArgs(9);
411 : // Assign Design Conditions
412 1 : thisChiller.TempDesCondReturn = state.dataIPShortCut->rNumericArgs(10);
413 1 : thisChiller.TempDesCHWSupply = state.dataIPShortCut->rNumericArgs(11);
414 1 : thisChiller.EvapVolFlowRate = state.dataIPShortCut->rNumericArgs(12);
415 1 : if (thisChiller.EvapVolFlowRate == AutoSize) {
416 0 : thisChiller.EvapVolFlowRateWasAutoSized = true;
417 : }
418 1 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(16), "AirCooled")) {
419 0 : thisChiller.CondVolFlowRate = 0.0011; // Condenser flow rate not used for this cond type
420 : } else {
421 1 : thisChiller.CondVolFlowRate = state.dataIPShortCut->rNumericArgs(13);
422 1 : if (thisChiller.CondVolFlowRate == AutoSize) {
423 0 : thisChiller.CondVolFlowRateWasAutoSized = true;
424 : }
425 : }
426 1 : thisChiller.HeatVolFlowRate = state.dataIPShortCut->rNumericArgs(14);
427 1 : if (thisChiller.HeatVolFlowRate == AutoSize) {
428 0 : thisChiller.HeatVolFlowRateWasAutoSized = true;
429 : }
430 : // Assign Curve Numbers
431 1 : thisChiller.CoolCapFTCurve = GetCurveCheck(state, state.dataIPShortCut->cAlphaArgs(8), Get_ErrorsFound, ChillerName);
432 1 : thisChiller.FuelCoolFTCurve = GetCurveCheck(state, state.dataIPShortCut->cAlphaArgs(9), Get_ErrorsFound, ChillerName);
433 1 : thisChiller.FuelCoolFPLRCurve = GetCurveCheck(state, state.dataIPShortCut->cAlphaArgs(10), Get_ErrorsFound, ChillerName);
434 1 : thisChiller.ElecCoolFTCurve = GetCurveCheck(state, state.dataIPShortCut->cAlphaArgs(11), Get_ErrorsFound, ChillerName);
435 1 : thisChiller.ElecCoolFPLRCurve = GetCurveCheck(state, state.dataIPShortCut->cAlphaArgs(12), Get_ErrorsFound, ChillerName);
436 1 : thisChiller.HeatCapFCoolCurve = GetCurveCheck(state, state.dataIPShortCut->cAlphaArgs(13), Get_ErrorsFound, ChillerName);
437 1 : thisChiller.FuelHeatFHPLRCurve = GetCurveCheck(state, state.dataIPShortCut->cAlphaArgs(14), Get_ErrorsFound, ChillerName);
438 1 : if (Get_ErrorsFound) {
439 0 : ShowFatalError(state, "Errors found in processing curve input for " + cCurrentModuleObject + '=' + state.dataIPShortCut->cAlphaArgs(1));
440 0 : Get_ErrorsFound = false;
441 : }
442 1 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(15), "LeavingCondenser")) {
443 0 : thisChiller.isEnterCondensTemp = false;
444 1 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(15), "EnteringCondenser")) {
445 1 : thisChiller.isEnterCondensTemp = true;
446 : } else {
447 0 : thisChiller.isEnterCondensTemp = true;
448 0 : ShowWarningError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid value");
449 0 : ShowContinueError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(15) + "=\"" + state.dataIPShortCut->cAlphaArgs(15) + "\"");
450 0 : ShowContinueError(state, "resetting to EnteringCondenser, simulation continues");
451 : }
452 : // Assign Other Parameters
453 1 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(16), "AirCooled")) {
454 0 : thisChiller.isWaterCooled = false;
455 1 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(16), "WaterCooled")) {
456 1 : thisChiller.isWaterCooled = true;
457 : } else {
458 0 : thisChiller.isWaterCooled = true;
459 0 : ShowWarningError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid value");
460 0 : ShowContinueError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(16) + '=' + state.dataIPShortCut->cAlphaArgs(16));
461 0 : ShowContinueError(state, "resetting to WaterCooled, simulation continues");
462 : }
463 1 : if (!thisChiller.isEnterCondensTemp && !thisChiller.isWaterCooled) {
464 0 : thisChiller.isEnterCondensTemp = true;
465 0 : ShowWarningError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid value");
466 0 : ShowContinueError(state, "Invalid to have both LeavingCondenser and AirCooled.");
467 0 : ShowContinueError(state, "resetting to EnteringCondenser, simulation continues");
468 : }
469 1 : if (thisChiller.isWaterCooled) {
470 1 : if (state.dataIPShortCut->lAlphaFieldBlanks(5)) {
471 0 : ShowSevereError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid value");
472 0 : ShowContinueError(state, "For WaterCooled chiller the condenser outlet node is required.");
473 0 : Get_ErrorsFound = true;
474 : }
475 1 : thisChiller.CondReturnNodeNum = GetOnlySingleNode(state,
476 1 : state.dataIPShortCut->cAlphaArgs(4),
477 : Get_ErrorsFound,
478 : DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDirectFired,
479 1 : state.dataIPShortCut->cAlphaArgs(1),
480 : DataLoopNode::NodeFluidType::Water,
481 : DataLoopNode::ConnectionType::Inlet,
482 : NodeInputManager::CompFluidStream::Secondary,
483 1 : DataLoopNode::ObjectIsNotParent);
484 1 : thisChiller.CondSupplyNodeNum = GetOnlySingleNode(state,
485 1 : state.dataIPShortCut->cAlphaArgs(5),
486 : Get_ErrorsFound,
487 : DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDirectFired,
488 1 : state.dataIPShortCut->cAlphaArgs(1),
489 : DataLoopNode::NodeFluidType::Water,
490 : DataLoopNode::ConnectionType::Outlet,
491 : NodeInputManager::CompFluidStream::Secondary,
492 1 : DataLoopNode::ObjectIsNotParent);
493 2 : TestCompSet(state,
494 : cCurrentModuleObject,
495 1 : state.dataIPShortCut->cAlphaArgs(1),
496 1 : state.dataIPShortCut->cAlphaArgs(4),
497 1 : state.dataIPShortCut->cAlphaArgs(5),
498 : "Condenser Water Nodes");
499 : } else {
500 0 : thisChiller.CondReturnNodeNum = GetOnlySingleNode(state,
501 0 : state.dataIPShortCut->cAlphaArgs(4),
502 : Get_ErrorsFound,
503 : DataLoopNode::ConnectionObjectType::ChillerHeaterAbsorptionDirectFired,
504 0 : state.dataIPShortCut->cAlphaArgs(1),
505 : DataLoopNode::NodeFluidType::Air,
506 : DataLoopNode::ConnectionType::OutsideAirReference,
507 : NodeInputManager::CompFluidStream::Secondary,
508 0 : DataLoopNode::ObjectIsNotParent);
509 : // Condenser outlet node not used for air or evap cooled condenser so ignore cAlphaArgs( 5 )
510 : // Connection not required for air or evap cooled condenser so no call to TestCompSet here
511 0 : CheckAndAddAirNodeNumber(state, thisChiller.CondReturnNodeNum, Okay);
512 0 : if (!Okay) {
513 0 : ShowWarningError(state, cCurrentModuleObject + ", Adding OutdoorAir:Node=" + state.dataIPShortCut->cAlphaArgs(4));
514 : }
515 : }
516 1 : thisChiller.CHWLowLimitTemp = state.dataIPShortCut->rNumericArgs(15);
517 1 : thisChiller.FuelHeatingValue = state.dataIPShortCut->rNumericArgs(16);
518 1 : thisChiller.SizFac = state.dataIPShortCut->rNumericArgs(17);
519 :
520 : // Validate fuel type input
521 1 : bool FuelTypeError(false);
522 1 : UtilityRoutines::ValidateFuelType(state, state.dataIPShortCut->cAlphaArgs(17), thisChiller.FuelType, FuelTypeError);
523 1 : if (FuelTypeError) {
524 0 : ShowSevereError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid value");
525 0 : ShowContinueError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(17) + '=' + state.dataIPShortCut->cAlphaArgs(17));
526 0 : ShowContinueError(
527 : state, "Valid choices are Electricity, NaturalGas, Propane, Diesel, Gasoline, FuelOilNo1, FuelOilNo2,OtherFuel1 or OtherFuel2");
528 0 : Get_ErrorsFound = true;
529 0 : FuelTypeError = false;
530 : }
531 : }
532 :
533 1 : if (Get_ErrorsFound) {
534 0 : ShowFatalError(state, "Errors found in processing input for " + cCurrentModuleObject);
535 : }
536 : }
537 :
538 1 : void GasAbsorberSpecs::setupOutputVariables(EnergyPlusData &state)
539 : {
540 1 : std::string &ChillerName = this->Name;
541 :
542 2 : SetupOutputVariable(state,
543 : "Chiller Heater Evaporator Cooling Rate",
544 : OutputProcessor::Unit::W,
545 : this->CoolingLoad,
546 : OutputProcessor::SOVTimeStepType::System,
547 : OutputProcessor::SOVStoreType::Average,
548 1 : ChillerName);
549 2 : SetupOutputVariable(state,
550 : "Chiller Heater Evaporator Cooling Energy",
551 : OutputProcessor::Unit::J,
552 : this->CoolingEnergy,
553 : OutputProcessor::SOVTimeStepType::System,
554 : OutputProcessor::SOVStoreType::Summed,
555 : ChillerName,
556 : _,
557 : "ENERGYTRANSFER",
558 : "CHILLERS",
559 : _,
560 1 : "Plant");
561 :
562 2 : SetupOutputVariable(state,
563 : "Chiller Heater Heating Rate",
564 : OutputProcessor::Unit::W,
565 : this->HeatingLoad,
566 : OutputProcessor::SOVTimeStepType::System,
567 : OutputProcessor::SOVStoreType::Average,
568 1 : ChillerName);
569 2 : SetupOutputVariable(state,
570 : "Chiller Heater Heating Energy",
571 : OutputProcessor::Unit::J,
572 : this->HeatingEnergy,
573 : OutputProcessor::SOVTimeStepType::System,
574 : OutputProcessor::SOVStoreType::Summed,
575 : ChillerName,
576 : _,
577 : "ENERGYTRANSFER",
578 : "BOILERS",
579 : _,
580 1 : "Plant");
581 :
582 2 : SetupOutputVariable(state,
583 : "Chiller Heater Condenser Heat Transfer Rate",
584 : OutputProcessor::Unit::W,
585 : this->TowerLoad,
586 : OutputProcessor::SOVTimeStepType::System,
587 : OutputProcessor::SOVStoreType::Average,
588 1 : ChillerName);
589 2 : SetupOutputVariable(state,
590 : "Chiller Heater Condenser Heat Transfer Energy",
591 : OutputProcessor::Unit::J,
592 : this->TowerEnergy,
593 : OutputProcessor::SOVTimeStepType::System,
594 : OutputProcessor::SOVStoreType::Summed,
595 : ChillerName,
596 : _,
597 : "ENERGYTRANSFER",
598 : "HEATREJECTION",
599 : _,
600 1 : "Plant");
601 :
602 3 : SetupOutputVariable(state,
603 2 : "Chiller Heater " + this->FuelType + " Rate",
604 : OutputProcessor::Unit::W,
605 : this->FuelUseRate,
606 : OutputProcessor::SOVTimeStepType::System,
607 : OutputProcessor::SOVStoreType::Average,
608 : ChillerName);
609 : // Do not include this on meters, this would duplicate the cool fuel and heat fuel
610 3 : SetupOutputVariable(state,
611 2 : "Chiller Heater " + this->FuelType + " Energy",
612 : OutputProcessor::Unit::J,
613 : this->FuelEnergy,
614 : OutputProcessor::SOVTimeStepType::System,
615 : OutputProcessor::SOVStoreType::Summed,
616 : ChillerName);
617 :
618 3 : SetupOutputVariable(state,
619 2 : "Chiller Heater Cooling " + this->FuelType + " Rate",
620 : OutputProcessor::Unit::W,
621 : this->CoolFuelUseRate,
622 : OutputProcessor::SOVTimeStepType::System,
623 : OutputProcessor::SOVStoreType::Average,
624 : ChillerName);
625 3 : SetupOutputVariable(state,
626 2 : "Chiller Heater Cooling " + this->FuelType + " Energy",
627 : OutputProcessor::Unit::J,
628 : this->CoolFuelEnergy,
629 : OutputProcessor::SOVTimeStepType::System,
630 : OutputProcessor::SOVStoreType::Summed,
631 : ChillerName,
632 : _,
633 : this->FuelType,
634 : "Cooling",
635 : _,
636 : "Plant");
637 :
638 2 : SetupOutputVariable(state,
639 : "Chiller Heater Cooling COP",
640 : OutputProcessor::Unit::W_W,
641 : this->FuelCOP,
642 : OutputProcessor::SOVTimeStepType::System,
643 : OutputProcessor::SOVStoreType::Average,
644 1 : ChillerName);
645 :
646 3 : SetupOutputVariable(state,
647 2 : "Chiller Heater Heating " + this->FuelType + " Rate",
648 : OutputProcessor::Unit::W,
649 : this->HeatFuelUseRate,
650 : OutputProcessor::SOVTimeStepType::System,
651 : OutputProcessor::SOVStoreType::Average,
652 : ChillerName);
653 3 : SetupOutputVariable(state,
654 2 : "Chiller Heater Heating " + this->FuelType + " Energy",
655 : OutputProcessor::Unit::J,
656 : this->HeatFuelEnergy,
657 : OutputProcessor::SOVTimeStepType::System,
658 : OutputProcessor::SOVStoreType::Summed,
659 : ChillerName,
660 : _,
661 : this->FuelType,
662 : "Heating",
663 : _,
664 : "Plant");
665 :
666 2 : SetupOutputVariable(state,
667 : "Chiller Heater Electricity Rate",
668 : OutputProcessor::Unit::W,
669 : this->ElectricPower,
670 : OutputProcessor::SOVTimeStepType::System,
671 : OutputProcessor::SOVStoreType::Average,
672 1 : ChillerName);
673 : // Do not include this on meters, this would duplicate the cool electric and heat electric
674 2 : SetupOutputVariable(state,
675 : "Chiller Heater Electricity Energy",
676 : OutputProcessor::Unit::J,
677 : this->ElectricEnergy,
678 : OutputProcessor::SOVTimeStepType::System,
679 : OutputProcessor::SOVStoreType::Summed,
680 1 : ChillerName);
681 :
682 2 : SetupOutputVariable(state,
683 : "Chiller Heater Cooling Electricity Rate",
684 : OutputProcessor::Unit::W,
685 : this->CoolElectricPower,
686 : OutputProcessor::SOVTimeStepType::System,
687 : OutputProcessor::SOVStoreType::Average,
688 1 : ChillerName);
689 2 : SetupOutputVariable(state,
690 : "Chiller Heater Cooling Electricity Energy",
691 : OutputProcessor::Unit::J,
692 : this->CoolElectricEnergy,
693 : OutputProcessor::SOVTimeStepType::System,
694 : OutputProcessor::SOVStoreType::Summed,
695 : ChillerName,
696 : _,
697 : "Electricity",
698 : "Cooling",
699 : _,
700 1 : "Plant");
701 :
702 2 : SetupOutputVariable(state,
703 : "Chiller Heater Heating Electricity Rate",
704 : OutputProcessor::Unit::W,
705 : this->HeatElectricPower,
706 : OutputProcessor::SOVTimeStepType::System,
707 : OutputProcessor::SOVStoreType::Average,
708 1 : ChillerName);
709 2 : SetupOutputVariable(state,
710 : "Chiller Heater Heating Electricity Energy",
711 : OutputProcessor::Unit::J,
712 : this->HeatElectricEnergy,
713 : OutputProcessor::SOVTimeStepType::System,
714 : OutputProcessor::SOVStoreType::Summed,
715 : ChillerName,
716 : _,
717 : "Electricity",
718 : "Heating",
719 : _,
720 1 : "Plant");
721 :
722 2 : SetupOutputVariable(state,
723 : "Chiller Heater Evaporator Inlet Temperature",
724 : OutputProcessor::Unit::C,
725 : this->ChillReturnTemp,
726 : OutputProcessor::SOVTimeStepType::System,
727 : OutputProcessor::SOVStoreType::Average,
728 1 : ChillerName);
729 2 : SetupOutputVariable(state,
730 : "Chiller Heater Evaporator Outlet Temperature",
731 : OutputProcessor::Unit::C,
732 : this->ChillSupplyTemp,
733 : OutputProcessor::SOVTimeStepType::System,
734 : OutputProcessor::SOVStoreType::Average,
735 1 : ChillerName);
736 2 : SetupOutputVariable(state,
737 : "Chiller Heater Evaporator Mass Flow Rate",
738 : OutputProcessor::Unit::kg_s,
739 : this->ChillWaterFlowRate,
740 : OutputProcessor::SOVTimeStepType::System,
741 : OutputProcessor::SOVStoreType::Average,
742 1 : ChillerName);
743 :
744 1 : if (this->isWaterCooled) {
745 2 : SetupOutputVariable(state,
746 : "Chiller Heater Condenser Inlet Temperature",
747 : OutputProcessor::Unit::C,
748 : this->CondReturnTemp,
749 : OutputProcessor::SOVTimeStepType::System,
750 : OutputProcessor::SOVStoreType::Average,
751 1 : ChillerName);
752 2 : SetupOutputVariable(state,
753 : "Chiller Heater Condenser Outlet Temperature",
754 : OutputProcessor::Unit::C,
755 : this->CondSupplyTemp,
756 : OutputProcessor::SOVTimeStepType::System,
757 : OutputProcessor::SOVStoreType::Average,
758 1 : ChillerName);
759 2 : SetupOutputVariable(state,
760 : "Chiller Heater Condenser Mass Flow Rate",
761 : OutputProcessor::Unit::kg_s,
762 : this->CondWaterFlowRate,
763 : OutputProcessor::SOVTimeStepType::System,
764 : OutputProcessor::SOVStoreType::Average,
765 1 : ChillerName);
766 : } else {
767 0 : SetupOutputVariable(state,
768 : "Chiller Heater Condenser Inlet Temperature",
769 : OutputProcessor::Unit::C,
770 : this->CondReturnTemp,
771 : OutputProcessor::SOVTimeStepType::System,
772 : OutputProcessor::SOVStoreType::Average,
773 0 : ChillerName);
774 : }
775 :
776 2 : SetupOutputVariable(state,
777 : "Chiller Heater Heating Inlet Temperature",
778 : OutputProcessor::Unit::C,
779 : this->HotWaterReturnTemp,
780 : OutputProcessor::SOVTimeStepType::System,
781 : OutputProcessor::SOVStoreType::Average,
782 1 : ChillerName);
783 2 : SetupOutputVariable(state,
784 : "Chiller Heater Heating Outlet Temperature",
785 : OutputProcessor::Unit::C,
786 : this->HotWaterSupplyTemp,
787 : OutputProcessor::SOVTimeStepType::System,
788 : OutputProcessor::SOVStoreType::Average,
789 1 : ChillerName);
790 2 : SetupOutputVariable(state,
791 : "Chiller Heater Heating Mass Flow Rate",
792 : OutputProcessor::Unit::kg_s,
793 : this->HotWaterFlowRate,
794 : OutputProcessor::SOVTimeStepType::System,
795 : OutputProcessor::SOVStoreType::Average,
796 1 : ChillerName);
797 :
798 2 : SetupOutputVariable(state,
799 : "Chiller Heater Cooling Part Load Ratio",
800 : OutputProcessor::Unit::None,
801 : this->CoolPartLoadRatio,
802 : OutputProcessor::SOVTimeStepType::System,
803 : OutputProcessor::SOVStoreType::Average,
804 1 : ChillerName);
805 2 : SetupOutputVariable(state,
806 : "Chiller Heater Maximum Cooling Rate",
807 : OutputProcessor::Unit::W,
808 : this->CoolingCapacity,
809 : OutputProcessor::SOVTimeStepType::System,
810 : OutputProcessor::SOVStoreType::Average,
811 1 : ChillerName);
812 2 : SetupOutputVariable(state,
813 : "Chiller Heater Heating Part Load Ratio",
814 : OutputProcessor::Unit::None,
815 : this->HeatPartLoadRatio,
816 : OutputProcessor::SOVTimeStepType::System,
817 : OutputProcessor::SOVStoreType::Average,
818 1 : ChillerName);
819 2 : SetupOutputVariable(state,
820 : "Chiller Heater Maximum Heating Rate",
821 : OutputProcessor::Unit::W,
822 : this->HeatingCapacity,
823 : OutputProcessor::SOVTimeStepType::System,
824 : OutputProcessor::SOVStoreType::Average,
825 1 : ChillerName);
826 :
827 2 : SetupOutputVariable(state,
828 : "Chiller Heater Runtime Fraction",
829 : OutputProcessor::Unit::None,
830 : this->FractionOfPeriodRunning,
831 : OutputProcessor::SOVTimeStepType::System,
832 : OutputProcessor::SOVStoreType::Average,
833 1 : ChillerName);
834 1 : }
835 :
836 1 : void GasAbsorberSpecs::oneTimeInit_new(EnergyPlusData &state)
837 : {
838 :
839 1 : this->setupOutputVariables(state);
840 :
841 : // Locate the chillers on the plant loops for later usage
842 1 : bool errFlag = false;
843 1 : PlantUtilities::ScanPlantLoopsForObject(state,
844 : this->Name,
845 : DataPlant::PlantEquipmentType::Chiller_DFAbsorption,
846 : this->CWplantLoc,
847 : errFlag,
848 : this->CHWLowLimitTemp,
849 : _,
850 : _,
851 : this->ChillReturnNodeNum,
852 : _);
853 1 : if (errFlag) {
854 0 : ShowFatalError(state, "InitGasAbsorber: Program terminated due to previous condition(s).");
855 : }
856 :
857 1 : PlantUtilities::ScanPlantLoopsForObject(
858 : state, this->Name, DataPlant::PlantEquipmentType::Chiller_DFAbsorption, this->HWplantLoc, errFlag, _, _, _, this->HeatReturnNodeNum, _);
859 1 : if (errFlag) {
860 0 : ShowFatalError(state, "InitGasAbsorber: Program terminated due to previous condition(s).");
861 : }
862 :
863 1 : if (this->isWaterCooled) {
864 1 : PlantUtilities::ScanPlantLoopsForObject(
865 : state, this->Name, DataPlant::PlantEquipmentType::Chiller_DFAbsorption, this->CDplantLoc, errFlag, _, _, _, this->CondReturnNodeNum, _);
866 1 : if (errFlag) {
867 0 : ShowFatalError(state, "InitGasAbsorber: Program terminated due to previous condition(s).");
868 : }
869 1 : PlantUtilities::InterConnectTwoPlantLoopSides(
870 : state, this->CWplantLoc, this->CDplantLoc, DataPlant::PlantEquipmentType::Chiller_DFAbsorption, true);
871 1 : PlantUtilities::InterConnectTwoPlantLoopSides(
872 : state, this->HWplantLoc, this->CDplantLoc, DataPlant::PlantEquipmentType::Chiller_DFAbsorption, true);
873 : }
874 :
875 1 : PlantUtilities::InterConnectTwoPlantLoopSides(
876 : state, this->CWplantLoc, this->HWplantLoc, DataPlant::PlantEquipmentType::Chiller_DFAbsorption, true);
877 :
878 : // check if outlet node of chilled water side has a setpoint.
879 1 : if ((state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) &&
880 0 : (state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPointHi == DataLoopNode::SensedNodeFlagValue)) {
881 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
882 0 : if (!this->ChillSetPointErrDone) {
883 0 : ShowWarningError(state, "Missing temperature setpoint on cool side for chiller heater named " + this->Name);
884 0 : ShowContinueError(state, " A temperature setpoint is needed at the outlet node of this chiller, use a SetpointManager");
885 0 : ShowContinueError(state, " The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
886 0 : this->ChillSetPointErrDone = true;
887 : }
888 : } else {
889 : // need call to EMS to check node
890 0 : errFlag = false; // but not really fatal yet, but should be.
891 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->ChillSupplyNodeNum, EMSManager::SPControlType::TemperatureSetPoint, errFlag);
892 0 : state.dataLoopNodes->NodeSetpointCheck(this->ChillSupplyNodeNum).needsSetpointChecking = false;
893 0 : if (errFlag) {
894 0 : if (!this->ChillSetPointErrDone) {
895 0 : ShowWarningError(state, "Missing temperature setpoint on cool side for chiller heater named " + this->Name);
896 0 : ShowContinueError(state, " A temperature setpoint is needed at the outlet node of this chiller evaporator ");
897 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the chiller evaporator outlet node ");
898 0 : ShowContinueError(state, " or use an EMS actuator to establish a setpoint at the outlet node ");
899 0 : ShowContinueError(state, " The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
900 0 : this->ChillSetPointErrDone = true;
901 : }
902 : }
903 : }
904 0 : this->ChillSetPointSetToLoop = true;
905 0 : state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPoint =
906 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
907 0 : state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPointHi =
908 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
909 : }
910 : // check if outlet node of hot water side has a setpoint.
911 1 : if ((state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPoint == DataLoopNode::SensedNodeFlagValue) &&
912 0 : (state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPointLo == DataLoopNode::SensedNodeFlagValue)) {
913 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
914 0 : if (!this->HeatSetPointErrDone) {
915 0 : ShowWarningError(state, "Missing temperature setpoint on heat side for chiller heater named " + this->Name);
916 0 : ShowContinueError(state, " A temperature setpoint is needed at the outlet node of this chiller, use a SetpointManager");
917 0 : ShowContinueError(state, " The overall loop setpoint will be assumed for chiller. The simulation continues ... ");
918 0 : this->HeatSetPointErrDone = true;
919 : }
920 : } else {
921 : // need call to EMS to check node
922 0 : errFlag = false; // but not really fatal yet, but should be.
923 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, this->HeatSupplyNodeNum, EMSManager::SPControlType::TemperatureSetPoint, errFlag);
924 0 : state.dataLoopNodes->NodeSetpointCheck(this->HeatSupplyNodeNum).needsSetpointChecking = false;
925 0 : if (errFlag) {
926 0 : if (!this->HeatSetPointErrDone) {
927 0 : ShowWarningError(state, "Missing temperature setpoint on heat side for chiller heater named " + this->Name);
928 0 : ShowContinueError(state, " A temperature setpoint is needed at the outlet node of this chiller heater ");
929 0 : ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the heater side outlet node ");
930 0 : ShowContinueError(state, " or use an EMS actuator to establish a setpoint at the outlet node ");
931 0 : ShowContinueError(state, " The overall loop setpoint will be assumed for heater side. The simulation continues ... ");
932 0 : this->HeatSetPointErrDone = true;
933 : }
934 : }
935 : }
936 0 : this->HeatSetPointSetToLoop = true;
937 0 : state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPoint =
938 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
939 0 : state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPointLo =
940 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).TempSetPointNodeNum).TempSetPointLo;
941 : }
942 1 : }
943 :
944 42441 : void GasAbsorberSpecs::initialize(EnergyPlusData &state)
945 : {
946 : // AUTHOR Fred Buhl
947 : // DATE WRITTEN June 2003
948 :
949 : // This subroutine is for initializations of direct fired absorption chiller
950 : // components.
951 :
952 : // Uses the status flags to trigger initializations.
953 :
954 : static constexpr std::string_view RoutineName("InitGasAbsorber");
955 :
956 42441 : Real64 rho = 0.0; // local fluid density
957 42441 : Real64 mdot = 0.0; // lcoal fluid mass flow rate
958 :
959 : // Init more variables
960 :
961 42441 : int CondInletNode = this->CondReturnNodeNum;
962 42441 : int CondOutletNode = this->CondSupplyNodeNum;
963 42441 : int HeatInletNode = this->HeatReturnNodeNum;
964 42441 : int HeatOutletNode = this->HeatSupplyNodeNum;
965 :
966 42441 : if (this->envrnFlag && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
967 :
968 4 : if (this->isWaterCooled) {
969 : // init max available condenser water flow rate
970 4 : if (this->CDplantLoc.loopNum > 0) {
971 8 : rho = FluidProperties::GetDensityGlycol(state,
972 4 : state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).FluidName,
973 : DataGlobalConstants::CWInitConvTemp,
974 4 : state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).FluidIndex,
975 : RoutineName);
976 : } else {
977 0 : rho = Psychrometrics::RhoH2O(DataGlobalConstants::InitConvTemp);
978 : }
979 :
980 4 : this->DesCondMassFlowRate = rho * this->CondVolFlowRate;
981 4 : PlantUtilities::InitComponentNodes(state, 0.0, this->DesCondMassFlowRate, CondInletNode, CondOutletNode);
982 : }
983 :
984 4 : if (this->HWplantLoc.loopNum > 0) {
985 8 : rho = FluidProperties::GetDensityGlycol(state,
986 4 : state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).FluidName,
987 : DataGlobalConstants::HWInitConvTemp,
988 4 : state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).FluidIndex,
989 : RoutineName);
990 : } else {
991 0 : rho = Psychrometrics::RhoH2O(DataGlobalConstants::InitConvTemp);
992 : }
993 4 : this->DesHeatMassFlowRate = rho * this->HeatVolFlowRate;
994 : // init available hot water flow rate
995 4 : PlantUtilities::InitComponentNodes(state, 0.0, this->DesHeatMassFlowRate, HeatInletNode, HeatOutletNode);
996 :
997 4 : if (this->CWplantLoc.loopNum > 0) {
998 8 : rho = FluidProperties::GetDensityGlycol(state,
999 4 : state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).FluidName,
1000 : DataGlobalConstants::CWInitConvTemp,
1001 4 : state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).FluidIndex,
1002 : RoutineName);
1003 : } else {
1004 0 : rho = Psychrometrics::RhoH2O(DataGlobalConstants::InitConvTemp);
1005 : }
1006 4 : this->DesEvapMassFlowRate = rho * this->EvapVolFlowRate;
1007 : // init available hot water flow rate
1008 4 : PlantUtilities::InitComponentNodes(state, 0.0, this->DesEvapMassFlowRate, this->ChillReturnNodeNum, this->ChillSupplyNodeNum);
1009 :
1010 4 : this->envrnFlag = false;
1011 : }
1012 :
1013 42441 : if (!state.dataGlobal->BeginEnvrnFlag) {
1014 42240 : this->envrnFlag = true;
1015 : }
1016 :
1017 : // this component model works off setpoints on the leaving node
1018 : // fill from plant if needed
1019 42441 : if (this->ChillSetPointSetToLoop) {
1020 0 : state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPoint =
1021 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
1022 0 : state.dataLoopNodes->Node(this->ChillSupplyNodeNum).TempSetPointHi =
1023 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).TempSetPointNodeNum).TempSetPointHi;
1024 : }
1025 :
1026 42441 : if (this->HeatSetPointSetToLoop) {
1027 0 : state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPoint =
1028 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).TempSetPointNodeNum).TempSetPoint;
1029 0 : state.dataLoopNodes->Node(this->HeatSupplyNodeNum).TempSetPointLo =
1030 0 : state.dataLoopNodes->Node(state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).TempSetPointNodeNum).TempSetPointLo;
1031 : }
1032 :
1033 42441 : if ((this->isWaterCooled) && ((this->InHeatingMode) || (this->InCoolingMode))) {
1034 27304 : mdot = this->DesCondMassFlowRate;
1035 :
1036 27304 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDplantLoc);
1037 :
1038 : } else {
1039 15137 : mdot = 0.0;
1040 15137 : if (this->CDplantLoc.loopNum > 0 && this->isWaterCooled) {
1041 15137 : PlantUtilities::SetComponentFlowRate(state, mdot, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDplantLoc);
1042 : }
1043 : }
1044 42441 : }
1045 :
1046 5 : void GasAbsorberSpecs::size(EnergyPlusData &state)
1047 : {
1048 : // AUTHOR Fred Buhl
1049 : // DATE WRITTEN June 2003
1050 : // MODIFIED November 2013 Daeho Kang, add component sizing table entries
1051 :
1052 : // This subroutine is for sizing direct fired gas absorption chiller components for which
1053 : // capacities and flow rates have not been specified in the input.
1054 :
1055 : // METHODOLOGY EMPLOYED:
1056 : // Obtains evaporator flow rate from the plant sizing array. Calculates nominal capacity from
1057 : // the evaporator flow rate and the chilled water loop design delta T. The condenser flow rate
1058 : // is calculated from the nominal capacity, the COP, and the condenser loop design delta T.
1059 :
1060 : static constexpr std::string_view RoutineName("SizeGasAbsorber");
1061 :
1062 10 : std::string equipName;
1063 : Real64 Cp; // local fluid specific heat
1064 : Real64 rho; // local fluid density
1065 : Real64 tmpNomCap; // local nominal capacity cooling power
1066 : Real64 tmpEvapVolFlowRate; // local evaporator design volume flow rate
1067 : Real64 tmpCondVolFlowRate; // local condenser design volume flow rate
1068 : Real64 tmpHeatRecVolFlowRate; // local heat recovery design volume flow rate
1069 : Real64 NomCapUser; // Hardsized nominal capacity for reporting
1070 : Real64 EvapVolFlowRateUser; // Hardsized evaporator volume flow rate for reporting
1071 : Real64 CondVolFlowRateUser; // Hardsized condenser flow rate for reporting
1072 : Real64 HeatRecVolFlowRateUser; // Hardsized generator flow rate for reporting
1073 :
1074 5 : bool ErrorsFound = false;
1075 5 : tmpNomCap = this->NomCoolingCap;
1076 5 : tmpEvapVolFlowRate = this->EvapVolFlowRate;
1077 5 : tmpCondVolFlowRate = this->CondVolFlowRate;
1078 5 : tmpHeatRecVolFlowRate = this->HeatVolFlowRate;
1079 : // Commenting this could cause diffs - NomCapUser = 0.0;
1080 : // Commenting this could cause diffs - EvapVolFlowRateUser = 0.0;
1081 : // Commenting this could cause diffs - CondVolFlowRateUser = 0.0;
1082 : // Commenting this could cause diffs - HeatRecVolFlowRateUser = 0.0;
1083 :
1084 5 : int PltSizCondNum = 0; // Plant Sizing index for condenser loop
1085 5 : if (this->isWaterCooled) PltSizCondNum = state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).PlantSizNum;
1086 5 : int PltSizHeatNum = state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).PlantSizNum;
1087 5 : int PltSizCoolNum = state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).PlantSizNum;
1088 :
1089 5 : if (PltSizCoolNum > 0) {
1090 0 : if (state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
1091 0 : Cp = FluidProperties::GetSpecificHeatGlycol(state,
1092 0 : state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).FluidName,
1093 : DataGlobalConstants::CWInitConvTemp,
1094 0 : state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).FluidIndex,
1095 : RoutineName);
1096 0 : rho = FluidProperties::GetDensityGlycol(state,
1097 0 : state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).FluidName,
1098 : DataGlobalConstants::CWInitConvTemp,
1099 0 : state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).FluidIndex,
1100 : RoutineName);
1101 0 : tmpNomCap = Cp * rho * state.dataSize->PlantSizData(PltSizCoolNum).DeltaT * state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate *
1102 0 : this->SizFac;
1103 0 : if (!this->NomCoolingCapWasAutoSized) tmpNomCap = this->NomCoolingCap;
1104 : } else {
1105 0 : if (this->NomCoolingCapWasAutoSized) tmpNomCap = 0.0;
1106 : }
1107 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1108 0 : if (this->NomCoolingCapWasAutoSized) {
1109 0 : this->NomCoolingCap = tmpNomCap;
1110 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1111 0 : BaseSizer::reportSizerOutput(
1112 0 : state, "ChillerHeater:Absorption:DirectFired", this->Name, "Design Size Nominal Cooling Capacity [W]", tmpNomCap);
1113 : }
1114 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1115 0 : BaseSizer::reportSizerOutput(
1116 0 : state, "ChillerHeater:Absorption:DirectFired", this->Name, "Initial Design Size Nominal Cooling Capacity [W]", tmpNomCap);
1117 : }
1118 : } else {
1119 0 : if (this->NomCoolingCap > 0.0 && tmpNomCap > 0.0) {
1120 0 : NomCapUser = this->NomCoolingCap;
1121 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1122 0 : BaseSizer::reportSizerOutput(state,
1123 : "ChillerHeater:Absorption:DirectFired",
1124 : this->Name,
1125 : "Design Size Nominal Cooling Capacity [W]",
1126 : tmpNomCap,
1127 : "User-Specified Nominal Cooling Capacity [W]",
1128 0 : NomCapUser);
1129 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1130 0 : if ((std::abs(tmpNomCap - NomCapUser) / NomCapUser) > state.dataSize->AutoVsHardSizingThreshold) {
1131 0 : ShowMessage(state, "SizeChillerHeaterAbsorptionDirectFired: Potential issue with equipment sizing for " + this->Name);
1132 0 : ShowContinueError(state, format("User-Specified Nominal Capacity of {:.2R} [W]", NomCapUser));
1133 0 : ShowContinueError(state, format("differs from Design Size Nominal Capacity of {:.2R} [W]", tmpNomCap));
1134 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1135 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1136 : }
1137 : }
1138 : }
1139 0 : tmpNomCap = NomCapUser;
1140 : }
1141 : }
1142 : }
1143 : } else {
1144 5 : if (this->NomCoolingCapWasAutoSized) {
1145 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1146 0 : ShowSevereError(state, "SizeGasAbsorber: ChillerHeater:Absorption:DirectFired=\"" + this->Name + "\", autosize error.");
1147 0 : ShowContinueError(state, "Autosizing of Direct Fired Absorption Chiller nominal cooling capacity requires");
1148 0 : ShowContinueError(state, "a cooling loop Sizing:Plant object.");
1149 0 : ErrorsFound = true;
1150 : }
1151 : } else {
1152 5 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1153 1 : if (this->NomCoolingCap > 0.0) {
1154 3 : BaseSizer::reportSizerOutput(
1155 2 : state, "ChillerHeater:Absorption:DirectFired", this->Name, "User-Specified Nominal Capacity [W]", this->NomCoolingCap);
1156 : }
1157 : }
1158 : }
1159 : }
1160 :
1161 5 : if (PltSizCoolNum > 0) {
1162 0 : if (state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
1163 0 : tmpEvapVolFlowRate = state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate * this->SizFac;
1164 0 : if (!this->EvapVolFlowRateWasAutoSized) tmpEvapVolFlowRate = this->EvapVolFlowRate;
1165 : } else {
1166 0 : if (this->EvapVolFlowRateWasAutoSized) tmpEvapVolFlowRate = 0.0;
1167 : }
1168 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1169 0 : if (this->EvapVolFlowRateWasAutoSized) {
1170 0 : this->EvapVolFlowRate = tmpEvapVolFlowRate;
1171 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1172 0 : BaseSizer::reportSizerOutput(state,
1173 : "ChillerHeater:Absorption:DirectFired",
1174 : this->Name,
1175 : "Design Size Design Chilled Water Flow Rate [m3/s]",
1176 0 : tmpEvapVolFlowRate);
1177 : }
1178 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1179 0 : BaseSizer::reportSizerOutput(state,
1180 : "ChillerHeater:Absorption:DirectFired",
1181 : this->Name,
1182 : "Initial Design Size Design Chilled Water Flow Rate [m3/s]",
1183 0 : tmpEvapVolFlowRate);
1184 : }
1185 : } else {
1186 0 : if (this->EvapVolFlowRate > 0.0 && tmpEvapVolFlowRate > 0.0) {
1187 0 : EvapVolFlowRateUser = this->EvapVolFlowRate;
1188 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1189 0 : BaseSizer::reportSizerOutput(state,
1190 : "ChillerHeater:Absorption:DirectFired",
1191 : this->Name,
1192 : "Design Size Design Chilled Water Flow Rate [m3/s]",
1193 : tmpEvapVolFlowRate,
1194 : "User-Specified Design Chilled Water Flow Rate [m3/s]",
1195 0 : EvapVolFlowRateUser);
1196 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1197 0 : if ((std::abs(tmpEvapVolFlowRate - EvapVolFlowRateUser) / EvapVolFlowRateUser) >
1198 0 : state.dataSize->AutoVsHardSizingThreshold) {
1199 0 : ShowMessage(state, "SizeChillerAbsorptionDirectFired: Potential issue with equipment sizing for " + this->Name);
1200 0 : ShowContinueError(state,
1201 0 : format("User-Specified Design Chilled Water Flow Rate of {:.5R} [m3/s]", EvapVolFlowRateUser));
1202 0 : ShowContinueError(
1203 0 : state, format("differs from Design Size Design Chilled Water Flow Rate of {:.5R} [m3/s]", tmpEvapVolFlowRate));
1204 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1205 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1206 : }
1207 : }
1208 : }
1209 0 : tmpEvapVolFlowRate = EvapVolFlowRateUser;
1210 : }
1211 : }
1212 : }
1213 : } else {
1214 5 : if (this->EvapVolFlowRateWasAutoSized) {
1215 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1216 0 : ShowSevereError(state, "SizeGasAbsorber: ChillerHeater:Absorption:DirectFired=\"" + this->Name + "\", autosize error.");
1217 0 : ShowContinueError(state, "Autosizing of Direct Fired Absorption Chiller evap flow rate requires");
1218 0 : ShowContinueError(state, "a cooling loop Sizing:Plant object.");
1219 0 : ErrorsFound = true;
1220 : }
1221 : } else {
1222 5 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1223 1 : if (this->EvapVolFlowRate > 0.0) {
1224 3 : BaseSizer::reportSizerOutput(state,
1225 : "ChillerHeater:Absorption:DirectFired",
1226 : this->Name,
1227 : "User-Specified Design Chilled Water Flow Rate [m3/s]",
1228 2 : this->EvapVolFlowRate);
1229 : }
1230 : }
1231 : }
1232 : }
1233 :
1234 5 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->ChillReturnNodeNum, tmpEvapVolFlowRate);
1235 :
1236 5 : if (PltSizHeatNum > 0) {
1237 0 : if (state.dataSize->PlantSizData(PltSizHeatNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
1238 0 : tmpHeatRecVolFlowRate = state.dataSize->PlantSizData(PltSizHeatNum).DesVolFlowRate * this->SizFac;
1239 0 : if (!this->HeatVolFlowRateWasAutoSized) tmpHeatRecVolFlowRate = this->HeatVolFlowRate;
1240 :
1241 : } else {
1242 0 : if (this->HeatVolFlowRateWasAutoSized) tmpHeatRecVolFlowRate = 0.0;
1243 : }
1244 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1245 0 : if (this->HeatVolFlowRateWasAutoSized) {
1246 0 : this->HeatVolFlowRate = tmpHeatRecVolFlowRate;
1247 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1248 0 : BaseSizer::reportSizerOutput(state,
1249 : "ChillerHeater:Absorption:DirectFired",
1250 : this->Name,
1251 : "Design Size Design Hot Water Flow Rate [m3/s]",
1252 0 : tmpHeatRecVolFlowRate);
1253 : }
1254 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1255 0 : BaseSizer::reportSizerOutput(state,
1256 : "ChillerHeater:Absorption:DirectFired",
1257 : this->Name,
1258 : "Initial Design Size Design Hot Water Flow Rate [m3/s]",
1259 0 : tmpHeatRecVolFlowRate);
1260 : }
1261 : } else {
1262 0 : if (this->HeatVolFlowRate > 0.0 && tmpHeatRecVolFlowRate > 0.0) {
1263 0 : HeatRecVolFlowRateUser = this->HeatVolFlowRate;
1264 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1265 0 : BaseSizer::reportSizerOutput(state,
1266 : "ChillerHeater:Absorption:DirectFired",
1267 : this->Name,
1268 : "Design Size Design Hot Water Flow Rate [m3/s]",
1269 : tmpHeatRecVolFlowRate,
1270 : "User-Specified Design Hot Water Flow Rate [m3/s]",
1271 0 : HeatRecVolFlowRateUser);
1272 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1273 0 : if ((std::abs(tmpHeatRecVolFlowRate - HeatRecVolFlowRateUser) / HeatRecVolFlowRateUser) >
1274 0 : state.dataSize->AutoVsHardSizingThreshold) {
1275 0 : ShowMessage(state, "SizeChillerHeaterAbsorptionDirectFired: Potential issue with equipment sizing for " + this->Name);
1276 0 : ShowContinueError(state,
1277 0 : format("User-Specified Design Hot Water Flow Rate of {:.5R} [m3/s]", HeatRecVolFlowRateUser));
1278 0 : ShowContinueError(
1279 0 : state, format("differs from Design Size Design Hot Water Flow Rate of {:.5R} [m3/s]", tmpHeatRecVolFlowRate));
1280 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1281 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1282 : }
1283 : }
1284 : }
1285 0 : tmpHeatRecVolFlowRate = HeatRecVolFlowRateUser;
1286 : }
1287 : }
1288 : }
1289 : } else {
1290 5 : if (this->HeatVolFlowRateWasAutoSized) {
1291 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1292 0 : ShowSevereError(state, "SizeGasAbsorber: ChillerHeater:Absorption:DirectFired=\"" + this->Name + "\", autosize error.");
1293 0 : ShowContinueError(state, "Autosizing of Direct Fired Absorption Chiller hot water flow rate requires");
1294 0 : ShowContinueError(state, "a heating loop Sizing:Plant object.");
1295 0 : ErrorsFound = true;
1296 : }
1297 : } else {
1298 5 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1299 1 : if (this->HeatVolFlowRate > 0.0) {
1300 3 : BaseSizer::reportSizerOutput(state,
1301 : "ChillerHeater:Absorption:DirectFired",
1302 : this->Name,
1303 : "User-Specified Design Hot Water Flow Rate [m3/s]",
1304 2 : this->HeatVolFlowRate);
1305 : }
1306 : }
1307 : }
1308 : }
1309 :
1310 5 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->HeatReturnNodeNum, tmpHeatRecVolFlowRate);
1311 :
1312 5 : if (PltSizCondNum > 0 && PltSizCoolNum > 0) {
1313 0 : if (state.dataSize->PlantSizData(PltSizCoolNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow && tmpNomCap > 0.0) {
1314 :
1315 0 : Cp = FluidProperties::GetSpecificHeatGlycol(state,
1316 0 : state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).FluidName,
1317 : this->TempDesCondReturn,
1318 0 : state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).FluidIndex,
1319 : RoutineName);
1320 0 : rho = FluidProperties::GetDensityGlycol(state,
1321 0 : state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).FluidName,
1322 : this->TempDesCondReturn,
1323 0 : state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).FluidIndex,
1324 : RoutineName);
1325 0 : tmpCondVolFlowRate = tmpNomCap * (1.0 + this->FuelCoolRatio) / (state.dataSize->PlantSizData(PltSizCondNum).DeltaT * Cp * rho);
1326 0 : if (!this->CondVolFlowRateWasAutoSized) tmpCondVolFlowRate = this->CondVolFlowRate;
1327 : // IF (PlantFirstSizesOkayToFinalize) GasAbsorber(ChillNum)%CondVolFlowRate = tmpCondVolFlowRate
1328 : } else {
1329 0 : if (this->CondVolFlowRateWasAutoSized) tmpCondVolFlowRate = 0.0;
1330 : // IF (PlantFirstSizesOkayToFinalize) GasAbsorber(ChillNum)%CondVolFlowRate = tmpCondVolFlowRate
1331 : }
1332 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1333 0 : if (this->CondVolFlowRateWasAutoSized) {
1334 0 : this->CondVolFlowRate = tmpCondVolFlowRate;
1335 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1336 0 : BaseSizer::reportSizerOutput(state,
1337 : "ChillerHeater:Absorption:DirectFired",
1338 : this->Name,
1339 : "Design Size Design Condenser Water Flow Rate [m3/s]",
1340 0 : tmpCondVolFlowRate);
1341 : }
1342 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1343 0 : BaseSizer::reportSizerOutput(state,
1344 : "ChillerHeater:Absorption:DirectFired",
1345 : this->Name,
1346 : "Initial Design Size Design Condenser Water Flow Rate [m3/s]",
1347 0 : tmpCondVolFlowRate);
1348 : }
1349 : } else {
1350 0 : if (this->CondVolFlowRate > 0.0 && tmpCondVolFlowRate > 0.0) {
1351 0 : CondVolFlowRateUser = this->CondVolFlowRate;
1352 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1353 0 : BaseSizer::reportSizerOutput(state,
1354 : "ChillerHeater:Absorption:DirectFired",
1355 : this->Name,
1356 : "Design Size Design Condenser Water Flow Rate [m3/s]",
1357 : tmpCondVolFlowRate,
1358 : "User-Specified Design Condenser Water Flow Rate [m3/s]",
1359 0 : CondVolFlowRateUser);
1360 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1361 0 : if ((std::abs(tmpCondVolFlowRate - CondVolFlowRateUser) / CondVolFlowRateUser) >
1362 0 : state.dataSize->AutoVsHardSizingThreshold) {
1363 0 : ShowMessage(state, "SizeChillerAbsorptionDirectFired: Potential issue with equipment sizing for " + this->Name);
1364 0 : ShowContinueError(state,
1365 0 : format("User-Specified Design Condenser Water Flow Rate of {:.5R} [m3/s]", CondVolFlowRateUser));
1366 0 : ShowContinueError(
1367 0 : state, format("differs from Design Size Design Condenser Water Flow Rate of {:.5R} [m3/s]", tmpCondVolFlowRate));
1368 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1369 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1370 : }
1371 : }
1372 : }
1373 0 : tmpCondVolFlowRate = CondVolFlowRateUser;
1374 : }
1375 : }
1376 : }
1377 : } else {
1378 5 : if (this->CondVolFlowRateWasAutoSized) {
1379 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1380 0 : ShowSevereError(state, "SizeGasAbsorber: ChillerHeater:Absorption:DirectFired=\"" + this->Name + "\", autosize error.");
1381 0 : ShowContinueError(state, "Autosizing of Direct Fired Absorption Chiller condenser flow rate requires a condenser");
1382 0 : ShowContinueError(state, "loop Sizing:Plant object.");
1383 0 : ErrorsFound = true;
1384 : }
1385 : } else {
1386 5 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1387 1 : if (this->CondVolFlowRate > 0.0) {
1388 3 : BaseSizer::reportSizerOutput(state,
1389 : "ChillerHeater:Absorption:DirectFired",
1390 : this->Name,
1391 : "User-Specified Design Condenser Water Flow Rate [m3/s]",
1392 2 : this->CondVolFlowRate);
1393 : }
1394 : }
1395 : }
1396 : }
1397 :
1398 : // save the design condenser water volumetric flow rate for use by the condenser water loop sizing algorithms
1399 5 : if (this->isWaterCooled) PlantUtilities::RegisterPlantCompDesignFlow(state, this->CondReturnNodeNum, tmpCondVolFlowRate);
1400 :
1401 5 : if (ErrorsFound) {
1402 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
1403 : }
1404 :
1405 5 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1406 : // create predefined report
1407 1 : equipName = this->Name;
1408 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechType, equipName, "ChillerHeater:Absorption:DirectFired");
1409 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomEff, equipName, this->FuelCoolRatio);
1410 1 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechNomCap, equipName, this->NomCoolingCap);
1411 : }
1412 5 : }
1413 :
1414 21213 : void GasAbsorberSpecs::calculateChiller(EnergyPlusData &state, Real64 &MyLoad)
1415 : {
1416 : // AUTHOR Jason Glazer
1417 : // DATE WRITTEN March 2001
1418 :
1419 : // Simulate a direct fired (gas consuming) absorption chiller using
1420 : // curves and inputs similar to DOE-2.1e
1421 :
1422 : // METHODOLOGY EMPLOYED:
1423 : // Curve fit of performance data
1424 :
1425 : // REFERENCES:
1426 : // 1. DOE-2.1e Supplement and source code
1427 : // 2. CoolTools GasMod work
1428 :
1429 : // FlowLock = 0 if mass flow rates may be changed by loop components
1430 : // FlowLock = 1 if mass flow rates may not be changed by loop components
1431 :
1432 : static constexpr std::string_view RoutineName("CalcGasAbsorberChillerModel");
1433 :
1434 : // Local copies of GasAbsorberSpecs Type
1435 : // all variables that are local copies of data structure
1436 : // variables are prefaced with an "l" for local.
1437 : Real64 lNomCoolingCap; // W - design nominal capacity of Absorber
1438 : Real64 lFuelCoolRatio; // ratio of fuel input to cooling output
1439 : Real64 lFuelHeatRatio; // ratio of fuel input to heating output
1440 : Real64 lElecCoolRatio; // ratio of electricity input to cooling output
1441 : int lChillReturnNodeNum; // Node number on the inlet side of the plant
1442 : int lChillSupplyNodeNum; // Node number on the outlet side of the plant
1443 : int lCondReturnNodeNum; // Node number on the inlet side of the condenser
1444 : Real64 lMinPartLoadRat; // min allowed operating frac full load
1445 : Real64 lMaxPartLoadRat; // max allowed operating frac full load
1446 : int lCoolCapFTCurve; // cooling capacity as a function of temperature curve
1447 : int lFuelCoolFTCurve; // Fuel-Input-to cooling output Ratio Function of Temperature Curve
1448 : int lFuelCoolFPLRCurve; // Fuel-Input-to cooling output Ratio Function of Part Load Ratio Curve
1449 : int lElecCoolFTCurve; // Electric-Input-to cooling output Ratio Function of Temperature Curve
1450 : int lElecCoolFPLRCurve; // Electric-Input-to cooling output Ratio Function of Part Load Ratio Curve
1451 : bool lIsEnterCondensTemp; // if using entering conderser water temperature is TRUE, exiting is FALSE
1452 : bool lIsWaterCooled; // if water cooled it is TRUE
1453 : Real64 lCHWLowLimitTemp; // Chilled Water Lower Limit Temperature
1454 : // Local copies of GasAbsorberReportVars Type
1455 21213 : Real64 lCoolingLoad(0.0); // cooling load on the chiller (previously called QEvap)
1456 21213 : Real64 lTowerLoad(0.0); // load on the cooling tower/condenser (previously called QCond)
1457 21213 : Real64 lCoolFuelUseRate(0.0); // instantaneous use of gas for period for cooling
1458 21213 : Real64 lHeatFuelUseRate(0.0); // instantaneous use of gas for period for heating
1459 21213 : Real64 lCoolElectricPower(0.0); // parasitic electric power used for cooling
1460 21213 : Real64 lHeatElectricPower(0.0); // parasitic electric power used for heating
1461 21213 : Real64 lChillReturnTemp(0.0); // reporting: evaporator inlet temperature (was EvapInletTemp)
1462 21213 : Real64 lChillSupplyTemp(0.0); // reporting: evaporator outlet temperature (was EvapOutletTemp)
1463 21213 : Real64 lChillWaterMassFlowRate(0.0); // reporting: evaporator mass flow rate (was Evapmdot)
1464 21213 : Real64 lCondReturnTemp(0.0); // reporting: condenser inlet temperature (was CondInletTemp)
1465 21213 : Real64 lCondSupplyTemp(0.0); // reporting: condenser outlet temperature (was CondOutletTemp)
1466 21213 : Real64 lCondWaterMassFlowRate(0.0); // reporting: condenser mass flow rate (was Condmdot)
1467 21213 : Real64 lCoolPartLoadRatio(0.0); // operating part load ratio (load/capacity for cooling)
1468 21213 : Real64 lHeatPartLoadRatio(0.0); // operating part load ratio (load/capacity for heating)
1469 21213 : Real64 lAvailableCoolingCapacity(0.0); // current capacity after temperature adjustment
1470 21213 : Real64 lFractionOfPeriodRunning(0.0);
1471 21213 : Real64 PartLoadRat(0.0); // actual operating part load ratio of unit (ranges from minplr to 1)
1472 : Real64 lChillWaterMassflowratemax; // Maximum flow rate through the evaporator
1473 :
1474 : // other local variables
1475 : Real64 ChillDeltaTemp; // chilled water temperature difference
1476 21213 : Real64 ChillSupplySetPointTemp(0.0);
1477 :
1478 : Real64 calcCondTemp; // the condenser temperature used for curve calculation
1479 : // either return or supply depending on user input
1480 : Real64 revisedEstimateAvailCap; // final estimate of available capacity if using leaving
1481 : // condenser water temperature
1482 : Real64 errorAvailCap; // error fraction on final estimate of AvailableCoolingCapacity
1483 : int LoopNum;
1484 : DataPlant::LoopSideLocation LoopSideNum;
1485 : Real64 Cp_CW; // local fluid specific heat for chilled water
1486 : Real64 Cp_CD; // local fluid specific heat for condenser water
1487 :
1488 : // set node values to data structure values for nodes
1489 :
1490 21213 : lChillReturnNodeNum = this->ChillReturnNodeNum;
1491 21213 : lChillSupplyNodeNum = this->ChillSupplyNodeNum;
1492 21213 : lCondReturnNodeNum = this->CondReturnNodeNum;
1493 :
1494 : // set local copies of data from rest of input structure
1495 :
1496 21213 : lNomCoolingCap = this->NomCoolingCap;
1497 21213 : lFuelCoolRatio = this->FuelCoolRatio;
1498 21213 : lFuelHeatRatio = this->FuelHeatRatio;
1499 21213 : lElecCoolRatio = this->ElecCoolRatio;
1500 21213 : lMinPartLoadRat = this->MinPartLoadRat;
1501 21213 : lMaxPartLoadRat = this->MaxPartLoadRat;
1502 21213 : lCoolCapFTCurve = this->CoolCapFTCurve;
1503 21213 : lFuelCoolFTCurve = this->FuelCoolFTCurve;
1504 21213 : lFuelCoolFPLRCurve = this->FuelCoolFPLRCurve;
1505 21213 : lElecCoolFTCurve = this->ElecCoolFTCurve;
1506 21213 : lElecCoolFPLRCurve = this->ElecCoolFPLRCurve;
1507 21213 : lIsEnterCondensTemp = this->isEnterCondensTemp;
1508 21213 : lIsWaterCooled = this->isWaterCooled;
1509 21213 : lCHWLowLimitTemp = this->CHWLowLimitTemp;
1510 :
1511 21213 : lHeatElectricPower = this->HeatElectricPower;
1512 21213 : lHeatFuelUseRate = this->HeatFuelUseRate;
1513 21213 : lHeatPartLoadRatio = this->HeatPartLoadRatio;
1514 :
1515 : // initialize entering conditions
1516 21213 : lChillReturnTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
1517 21213 : lChillWaterMassFlowRate = state.dataLoopNodes->Node(lChillReturnNodeNum).MassFlowRate;
1518 21213 : lCondReturnTemp = state.dataLoopNodes->Node(lCondReturnNodeNum).Temp;
1519 : // Commenting this could be cause of diffs - lCondWaterMassFlowRate = Node(lCondReturnNodeNum).MassFlowRate;
1520 21213 : switch (state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).LoopDemandCalcScheme) {
1521 21213 : case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
1522 21213 : ChillSupplySetPointTemp = state.dataLoopNodes->Node(lChillSupplyNodeNum).TempSetPoint;
1523 21213 : } break;
1524 0 : case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
1525 0 : ChillSupplySetPointTemp = state.dataLoopNodes->Node(lChillSupplyNodeNum).TempSetPointHi;
1526 0 : } break;
1527 0 : default: {
1528 0 : assert(false);
1529 : } break;
1530 : }
1531 21213 : ChillDeltaTemp = std::abs(lChillReturnTemp - ChillSupplySetPointTemp);
1532 :
1533 42426 : Cp_CW = FluidProperties::GetSpecificHeatGlycol(state,
1534 21213 : state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).FluidName,
1535 : lChillReturnTemp,
1536 21213 : state.dataPlnt->PlantLoop(this->CWplantLoc.loopNum).FluidIndex,
1537 : RoutineName);
1538 21213 : Cp_CD = 0; // putting this here as a dummy initialization to hush the compiler warning, in real runs this value should never be used
1539 21213 : if (this->CDplantLoc.loopNum > 0) {
1540 42426 : Cp_CD = FluidProperties::GetSpecificHeatGlycol(state,
1541 21213 : state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).FluidName,
1542 : lChillReturnTemp,
1543 21213 : state.dataPlnt->PlantLoop(this->CDplantLoc.loopNum).FluidIndex,
1544 : RoutineName);
1545 : }
1546 :
1547 : // If no loop demand or Absorber OFF, return
1548 : // will need to modify when absorber can act as a boiler
1549 21213 : if (MyLoad >= 0 || !((this->InHeatingMode) || (this->InCoolingMode))) {
1550 : // set node temperatures
1551 16709 : lChillSupplyTemp = lChillReturnTemp;
1552 16709 : lCondSupplyTemp = lCondReturnTemp;
1553 16709 : lCondWaterMassFlowRate = 0.0;
1554 16709 : if (lIsWaterCooled) {
1555 16709 : PlantUtilities::SetComponentFlowRate(state, lCondWaterMassFlowRate, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDplantLoc);
1556 : }
1557 : // Commenting this could cause diffs - ChillDeltaTemp = 0.0;
1558 16709 : lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, lCoolPartLoadRatio) / lMinPartLoadRat);
1559 : } else {
1560 :
1561 : // if water cooled use the input node otherwise just use outside air temperature
1562 4504 : if (lIsWaterCooled) {
1563 : // most manufacturers rate have tables of entering condenser water temperature
1564 : // but a few use leaving condenser water temperature so we have a flag
1565 : // when leaving is used it uses the previous iterations value of the value
1566 4504 : lCondReturnTemp = state.dataLoopNodes->Node(lCondReturnNodeNum).Temp;
1567 4504 : if (lIsEnterCondensTemp) {
1568 4504 : calcCondTemp = lCondReturnTemp;
1569 : } else {
1570 0 : if (this->oldCondSupplyTemp == 0) {
1571 0 : this->oldCondSupplyTemp = lCondReturnTemp + 8.0; // if not previously estimated assume 8C greater than return
1572 : }
1573 0 : calcCondTemp = this->oldCondSupplyTemp;
1574 : }
1575 : // Set mass flow rates
1576 4504 : lCondWaterMassFlowRate = this->DesCondMassFlowRate;
1577 4504 : PlantUtilities::SetComponentFlowRate(state, lCondWaterMassFlowRate, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDplantLoc);
1578 : } else {
1579 : // air cooled
1580 0 : state.dataLoopNodes->Node(lCondReturnNodeNum).Temp = state.dataLoopNodes->Node(lCondReturnNodeNum).OutAirDryBulb;
1581 0 : calcCondTemp = state.dataLoopNodes->Node(lCondReturnNodeNum).OutAirDryBulb;
1582 0 : lCondReturnTemp = state.dataLoopNodes->Node(lCondReturnNodeNum).Temp;
1583 0 : lCondWaterMassFlowRate = 0.0;
1584 0 : if (this->CDplantLoc.loopNum > 0) {
1585 0 : PlantUtilities::SetComponentFlowRate(
1586 : state, lCondWaterMassFlowRate, this->CondReturnNodeNum, this->CondSupplyNodeNum, this->CDplantLoc);
1587 : }
1588 : }
1589 :
1590 : // Determine available cooling capacity using the setpoint temperature
1591 4504 : lAvailableCoolingCapacity = lNomCoolingCap * Curve::CurveValue(state, lCoolCapFTCurve, ChillSupplySetPointTemp, calcCondTemp);
1592 :
1593 : // Calculate current load for cooling
1594 4504 : MyLoad = sign(max(std::abs(MyLoad), lAvailableCoolingCapacity * lMinPartLoadRat), MyLoad);
1595 4504 : MyLoad = sign(min(std::abs(MyLoad), lAvailableCoolingCapacity * lMaxPartLoadRat), MyLoad);
1596 :
1597 : // Determine the following variables depending on if the flow has been set in
1598 : // the nodes (flowlock=1 to 2) or if the amount of load is still be determined (flowlock=0)
1599 : // chilled water flow,
1600 : // cooling load taken by the chiller, and
1601 : // supply temperature
1602 4504 : lChillWaterMassflowratemax = this->DesEvapMassFlowRate;
1603 :
1604 4504 : LoopNum = this->CWplantLoc.loopNum;
1605 4504 : LoopSideNum = this->CWplantLoc.loopSideNum;
1606 4504 : switch (state.dataPlnt->PlantLoop(LoopNum).LoopSide(LoopSideNum).FlowLock) {
1607 2252 : case DataPlant::FlowLock::Unlocked: { // mass flow rates may be changed by loop components
1608 2252 : this->PossibleSubcooling = false;
1609 2252 : lCoolingLoad = std::abs(MyLoad);
1610 2252 : if (ChillDeltaTemp != 0.0) {
1611 2252 : lChillWaterMassFlowRate = std::abs(lCoolingLoad / (Cp_CW * ChillDeltaTemp));
1612 2252 : if (lChillWaterMassFlowRate - lChillWaterMassflowratemax > DataBranchAirLoopPlant::MassFlowTolerance) this->PossibleSubcooling = true;
1613 :
1614 2252 : PlantUtilities::SetComponentFlowRate(
1615 : state, lChillWaterMassFlowRate, this->ChillReturnNodeNum, this->ChillSupplyNodeNum, this->CWplantLoc);
1616 : // Commenting this could cause diffs - lChillSupplyTemp = ChillSupplySetPointTemp;
1617 : } else {
1618 0 : lChillWaterMassFlowRate = 0.0;
1619 0 : ShowRecurringWarningErrorAtEnd(state,
1620 0 : "GasAbsorberChillerModel:Cooling\"" + this->Name + "\", DeltaTemp = 0 in mass flow calculation",
1621 : this->DeltaTempCoolErrCount);
1622 : }
1623 2252 : lChillSupplyTemp = ChillSupplySetPointTemp;
1624 2252 : } break;
1625 2252 : case DataPlant::FlowLock::Locked: { // mass flow rates may not be changed by loop components
1626 2252 : lChillWaterMassFlowRate = state.dataLoopNodes->Node(lChillReturnNodeNum).MassFlowRate;
1627 2252 : if (this->PossibleSubcooling) {
1628 0 : lCoolingLoad = std::abs(MyLoad);
1629 :
1630 0 : ChillDeltaTemp = lCoolingLoad / lChillWaterMassFlowRate / Cp_CW;
1631 0 : lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - ChillDeltaTemp;
1632 : } else {
1633 2252 : ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - ChillSupplySetPointTemp;
1634 2252 : lCoolingLoad = std::abs(lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp);
1635 2252 : lChillSupplyTemp = ChillSupplySetPointTemp;
1636 : }
1637 : // Check that the Chiller Supply outlet temp honors both plant loop temp low limit and also the chiller low limit
1638 2252 : if (lChillSupplyTemp < lCHWLowLimitTemp) {
1639 0 : if ((state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lCHWLowLimitTemp) > DataPlant::DeltaTempTol) {
1640 0 : lChillSupplyTemp = lCHWLowLimitTemp;
1641 0 : ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
1642 0 : lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
1643 : } else {
1644 0 : lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
1645 0 : ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
1646 0 : lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
1647 : }
1648 : }
1649 2252 : if (lChillSupplyTemp < state.dataLoopNodes->Node(lChillSupplyNodeNum).TempMin) {
1650 0 : if ((state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - state.dataLoopNodes->Node(lChillSupplyNodeNum).TempMin) >
1651 : DataPlant::DeltaTempTol) {
1652 0 : lChillSupplyTemp = state.dataLoopNodes->Node(lChillSupplyNodeNum).TempMin;
1653 0 : ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
1654 0 : lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
1655 : } else {
1656 0 : lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
1657 0 : ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
1658 0 : lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
1659 : }
1660 : }
1661 :
1662 : // Checks Coolingload on the basis of the machine limits.
1663 2252 : if (lCoolingLoad > std::abs(MyLoad)) {
1664 45 : if (lChillWaterMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
1665 45 : lCoolingLoad = std::abs(MyLoad);
1666 45 : ChillDeltaTemp = lCoolingLoad / lChillWaterMassFlowRate / Cp_CW;
1667 45 : lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - ChillDeltaTemp;
1668 : } else {
1669 0 : lChillSupplyTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
1670 0 : ChillDeltaTemp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp - lChillSupplyTemp;
1671 0 : lCoolingLoad = lChillWaterMassFlowRate * Cp_CW * ChillDeltaTemp;
1672 : }
1673 : }
1674 2252 : } break;
1675 0 : default:
1676 0 : break;
1677 : }
1678 :
1679 : // Calculate operating part load ratio for cooling
1680 4504 : PartLoadRat = min(std::abs(MyLoad) / lAvailableCoolingCapacity, lMaxPartLoadRat);
1681 4504 : PartLoadRat = max(lMinPartLoadRat, PartLoadRat);
1682 :
1683 4504 : if (lAvailableCoolingCapacity > 0.0) {
1684 4504 : if (std::abs(MyLoad) / lAvailableCoolingCapacity < lMinPartLoadRat) {
1685 0 : lCoolPartLoadRatio = MyLoad / lAvailableCoolingCapacity;
1686 : } else {
1687 4504 : lCoolPartLoadRatio = PartLoadRat;
1688 : }
1689 : } else { // Else if AvailableCoolingCapacity < 0.0
1690 0 : lCoolPartLoadRatio = 0.0;
1691 : }
1692 :
1693 : // calculate the fraction of the time period that the chiller would be running
1694 : // use maximum from heating and cooling sides
1695 4504 : if (lCoolPartLoadRatio < lMinPartLoadRat || lHeatPartLoadRatio < lMinPartLoadRat) {
1696 4504 : lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, lCoolPartLoadRatio) / lMinPartLoadRat);
1697 : } else {
1698 0 : lFractionOfPeriodRunning = 1.0;
1699 : }
1700 :
1701 : // Calculate fuel consumption for cooling
1702 : // fuel used for cooling availCap * HIR * HIR-FT * HIR-FPLR
1703 13512 : lCoolFuelUseRate = lAvailableCoolingCapacity * lFuelCoolRatio * Curve::CurveValue(state, lFuelCoolFTCurve, lChillSupplyTemp, calcCondTemp) *
1704 9008 : Curve::CurveValue(state, lFuelCoolFPLRCurve, lCoolPartLoadRatio) * lFractionOfPeriodRunning;
1705 :
1706 : // Calculate electric parasitics used
1707 : // based on nominal capacity, not available capacity,
1708 : // electric used for cooling nomCap * %OP * EIR * EIR-FT * EIR-FPLR
1709 13512 : lCoolElectricPower = lNomCoolingCap * lElecCoolRatio * lFractionOfPeriodRunning *
1710 9008 : Curve::CurveValue(state, lElecCoolFTCurve, lChillSupplyTemp, calcCondTemp) *
1711 9008 : Curve::CurveValue(state, lElecCoolFPLRCurve, lCoolPartLoadRatio);
1712 :
1713 : // determine conderser load which is cooling load plus the
1714 : // fuel used for cooling times the burner efficiency plus
1715 : // the electricity used
1716 4504 : lTowerLoad = lCoolingLoad + lCoolFuelUseRate / lFuelHeatRatio + lCoolElectricPower;
1717 :
1718 : // for water cooled condenser make sure enough flow rate
1719 : // for air cooled condenser just set supply to return temperature
1720 4504 : if (lIsWaterCooled) {
1721 4504 : if (lCondWaterMassFlowRate > DataBranchAirLoopPlant::MassFlowTolerance) {
1722 4504 : lCondSupplyTemp = lCondReturnTemp + lTowerLoad / (lCondWaterMassFlowRate * Cp_CD);
1723 : } else {
1724 0 : if (this->lCondWaterMassFlowRate_Index == 0) {
1725 0 : ShowSevereError(state, format("CalcGasAbsorberChillerModel: Condenser flow = 0, for Gas Absorber Chiller={}", this->Name));
1726 0 : ShowContinueErrorTimeStamp(state, "");
1727 : // ShowFatalError(state, "Program Terminates due to previous error condition.");
1728 : }
1729 0 : ShowRecurringSevereErrorAtEnd(state,
1730 0 : format("CalcGasAbsorberChillerModel: Condenser flow = 0, for Gas Absorber Chiller={}: Condenser flow "
1731 : "rate = 0 severe error warning continues...",
1732 0 : this->Name), // Message automatically written to "error file" at end of simulation
1733 : this->lCondWaterMassFlowRate_Index // Recurring message index, if zero, next available index is assigned
1734 : );
1735 : }
1736 : } else {
1737 0 : lCondSupplyTemp = lCondReturnTemp; // if air cooled condenser just set supply and return to same temperature
1738 : }
1739 :
1740 : // save the condenser water supply temperature for next iteration if that is used in lookup
1741 : // and if capacity is large enough error than report problem
1742 4504 : this->oldCondSupplyTemp = lCondSupplyTemp;
1743 4504 : if (!lIsEnterCondensTemp) {
1744 : // calculate the fraction of the estimated error between the capacity based on the previous
1745 : // iteration's value of condenser supply temperature and the actual calculated condenser supply
1746 : // temperature. If this becomes too common then may need to iterate a solution instead of
1747 : // relying on previous iteration method.
1748 0 : revisedEstimateAvailCap = lNomCoolingCap * Curve::CurveValue(state, lCoolCapFTCurve, ChillSupplySetPointTemp, lCondSupplyTemp);
1749 0 : if (revisedEstimateAvailCap > 0.0) {
1750 0 : errorAvailCap = std::abs((revisedEstimateAvailCap - lAvailableCoolingCapacity) / revisedEstimateAvailCap);
1751 0 : if (errorAvailCap > 0.05) { // if more than 5% error in estimate
1752 0 : ShowRecurringWarningErrorAtEnd(state,
1753 0 : "GasAbsorberChillerModel:\"" + this->Name + "\", poor Condenser Supply Estimate",
1754 : this->CondErrCount,
1755 : errorAvailCap,
1756 : errorAvailCap);
1757 : }
1758 : }
1759 : }
1760 : } // IF(MyLoad>=0 .OR. .NOT. RunFlag)
1761 : // Write into the Report Variables except for nodes
1762 21213 : this->CoolingLoad = lCoolingLoad;
1763 21213 : this->TowerLoad = lTowerLoad;
1764 21213 : this->CoolFuelUseRate = lCoolFuelUseRate;
1765 21213 : this->CoolElectricPower = lCoolElectricPower;
1766 21213 : this->CondReturnTemp = lCondReturnTemp;
1767 21213 : this->ChillReturnTemp = lChillReturnTemp;
1768 21213 : this->CondSupplyTemp = lCondSupplyTemp;
1769 21213 : this->ChillSupplyTemp = lChillSupplyTemp;
1770 21213 : this->ChillWaterFlowRate = lChillWaterMassFlowRate;
1771 21213 : this->CondWaterFlowRate = lCondWaterMassFlowRate;
1772 21213 : this->CoolPartLoadRatio = lCoolPartLoadRatio;
1773 21213 : this->CoolingCapacity = lAvailableCoolingCapacity;
1774 21213 : this->FractionOfPeriodRunning = lFractionOfPeriodRunning;
1775 :
1776 : // write the combined heating and cooling fuel used and electric used
1777 21213 : this->FuelUseRate = lCoolFuelUseRate + lHeatFuelUseRate;
1778 21213 : this->ElectricPower = lCoolElectricPower + lHeatElectricPower;
1779 21213 : }
1780 :
1781 21213 : void GasAbsorberSpecs::calculateHeater(EnergyPlusData &state, Real64 &MyLoad, bool const RunFlag)
1782 : {
1783 : // AUTHOR Jason Glazer and Michael J. Witte
1784 : // DATE WRITTEN March 2001
1785 : // Simulate a direct fired (gas consuming) absorption chiller using
1786 : // curves and inputs similar to DOE-2.1e
1787 :
1788 : // METHODOLOGY EMPLOYED:
1789 : // Curve fit of performance data
1790 :
1791 : // REFERENCES:
1792 : // 1. DOE-2.1e Supplement and source code
1793 : // 2. CoolTools GasMod work
1794 :
1795 : // FlowLock = 0 if mass flow rates may be changed by loop components
1796 : // FlowLock = 1 if mass flow rates may not be changed by loop components
1797 : // FlowLock = 2 if overloaded and mass flow rates has changed to a small amount and Tout drops
1798 : // below Setpoint
1799 :
1800 : // SUBROUTINE PARAMETER DEFINITIONS:
1801 : static constexpr std::string_view RoutineName("CalcGasAbsorberHeaterModel");
1802 :
1803 : // Local copies of GasAbsorberSpecs Type
1804 : // all variables that are local copies of data structure
1805 : // variables are prefaced with an "l" for local.
1806 : Real64 lNomCoolingCap; // W - design nominal capacity of Absorber
1807 : Real64 lNomHeatCoolRatio; // ratio of heating to cooling capacity
1808 : Real64 lFuelHeatRatio; // ratio of fuel input to heating output
1809 : Real64 lElecHeatRatio; // ratio of electricity input to heating output
1810 : int lHeatReturnNodeNum; // absorber steam inlet node number, water side
1811 : int lHeatSupplyNodeNum; // absorber steam outlet node number, water side
1812 : Real64 lMinPartLoadRat; // min allowed operating frac full load
1813 : Real64 lMaxPartLoadRat; // max allowed operating frac full load
1814 : int lHeatCapFCoolCurve; // Heating Capacity Function of Cooling Capacity Curve
1815 : int lFuelHeatFHPLRCurve; // Fuel Input to heat output ratio during heating only function
1816 : // Local copies of GasAbsorberReportVars Type
1817 21213 : Real64 lHeatingLoad(0.0); // heating load on the chiller
1818 21213 : Real64 lCoolFuelUseRate(0.0); // instantaneous use of gas for period for cooling
1819 21213 : Real64 lHeatFuelUseRate(0.0); // instantaneous use of gas for period for heating
1820 21213 : Real64 lCoolElectricPower(0.0); // parasitic electric power used for cooling
1821 21213 : Real64 lHeatElectricPower(0.0); // parasitic electric power used for heating
1822 21213 : Real64 lHotWaterReturnTemp(0.0); // reporting: hot water return (inlet) temperature
1823 21213 : Real64 lHotWaterSupplyTemp(0.0); // reporting: hot water supply (outlet) temperature
1824 21213 : Real64 lHotWaterMassFlowRate(0.0); // reporting: hot water mass flow rate
1825 21213 : Real64 lCoolPartLoadRatio(0.0); // operating part load ratio (load/capacity for cooling)
1826 21213 : Real64 lHeatPartLoadRatio(0.0); // operating part load ratio (load/capacity for heating)
1827 21213 : Real64 lAvailableHeatingCapacity(0.0); // current heating capacity
1828 21213 : Real64 lFractionOfPeriodRunning(0.0);
1829 : // other local variables
1830 21213 : Real64 HeatDeltaTemp(0.0); // hot water temperature difference
1831 21213 : Real64 HeatSupplySetPointTemp(0.0);
1832 : int LoopNum;
1833 : DataPlant::LoopSideLocation LoopSideNum;
1834 : Real64 Cp_HW; // local fluid specific heat for hot water
1835 :
1836 : // set node values to data structure values for nodes
1837 :
1838 21213 : lHeatReturnNodeNum = this->HeatReturnNodeNum;
1839 21213 : lHeatSupplyNodeNum = this->HeatSupplyNodeNum;
1840 :
1841 : // set local copies of data from rest of input structure
1842 :
1843 21213 : lNomCoolingCap = this->NomCoolingCap;
1844 21213 : lNomHeatCoolRatio = this->NomHeatCoolRatio;
1845 21213 : lFuelHeatRatio = this->FuelHeatRatio;
1846 21213 : lElecHeatRatio = this->ElecHeatRatio;
1847 21213 : lMinPartLoadRat = this->MinPartLoadRat;
1848 21213 : lMaxPartLoadRat = this->MaxPartLoadRat;
1849 21213 : lHeatCapFCoolCurve = this->HeatCapFCoolCurve;
1850 21213 : lFuelHeatFHPLRCurve = this->FuelHeatFHPLRCurve;
1851 21213 : LoopNum = this->HWplantLoc.loopNum;
1852 21213 : LoopSideNum = this->HWplantLoc.loopSideNum;
1853 :
1854 42426 : Cp_HW = FluidProperties::GetSpecificHeatGlycol(
1855 42426 : state, state.dataPlnt->PlantLoop(LoopNum).FluidName, lHotWaterReturnTemp, state.dataPlnt->PlantLoop(LoopNum).FluidIndex, RoutineName);
1856 :
1857 21213 : lCoolElectricPower = this->CoolElectricPower;
1858 21213 : lCoolFuelUseRate = this->CoolFuelUseRate;
1859 21213 : lCoolPartLoadRatio = this->CoolPartLoadRatio;
1860 :
1861 : // initialize entering conditions
1862 21213 : lHotWaterReturnTemp = state.dataLoopNodes->Node(lHeatReturnNodeNum).Temp;
1863 21213 : lHotWaterMassFlowRate = state.dataLoopNodes->Node(lHeatReturnNodeNum).MassFlowRate;
1864 21213 : switch (state.dataPlnt->PlantLoop(LoopNum).LoopDemandCalcScheme) {
1865 21213 : case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
1866 21213 : HeatSupplySetPointTemp = state.dataLoopNodes->Node(lHeatSupplyNodeNum).TempSetPoint;
1867 21213 : } break;
1868 0 : case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
1869 0 : HeatSupplySetPointTemp = state.dataLoopNodes->Node(lHeatSupplyNodeNum).TempSetPointLo;
1870 0 : } break;
1871 0 : default: {
1872 0 : assert(false);
1873 : } break;
1874 : }
1875 21213 : HeatDeltaTemp = std::abs(lHotWaterReturnTemp - HeatSupplySetPointTemp);
1876 :
1877 : // If no loop demand or Absorber OFF, return
1878 : // will need to modify when absorber can act as a boiler
1879 21213 : if (MyLoad <= 0 || !RunFlag) {
1880 : // set node temperatures
1881 12065 : lHotWaterSupplyTemp = lHotWaterReturnTemp;
1882 : // Commenting this could cause diffs - HeatDeltaTemp = 0.0;
1883 12065 : lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, lCoolPartLoadRatio) / lMinPartLoadRat);
1884 : } else {
1885 :
1886 : // Determine available heating capacity using the current cooling load
1887 9148 : lAvailableHeatingCapacity =
1888 18296 : this->NomHeatCoolRatio * this->NomCoolingCap * Curve::CurveValue(state, lHeatCapFCoolCurve, (this->CoolingLoad / this->NomCoolingCap));
1889 :
1890 : // Calculate current load for heating
1891 9148 : MyLoad = sign(max(std::abs(MyLoad), this->HeatingCapacity * lMinPartLoadRat), MyLoad);
1892 9148 : MyLoad = sign(min(std::abs(MyLoad), this->HeatingCapacity * lMaxPartLoadRat), MyLoad);
1893 :
1894 : // Determine the following variables depending on if the flow has been set in
1895 : // the nodes (flowlock=1 to 2) or if the amount of load is still be determined (flowlock=0)
1896 : // chilled water flow,
1897 : // cooling load taken by the chiller, and
1898 : // supply temperature
1899 9148 : switch (state.dataPlnt->PlantLoop(LoopNum).LoopSide(LoopSideNum).FlowLock) {
1900 4574 : case DataPlant::FlowLock::Unlocked: { // mass flow rates may be changed by loop components
1901 4574 : lHeatingLoad = std::abs(MyLoad);
1902 4574 : if (HeatDeltaTemp != 0) {
1903 4574 : lHotWaterMassFlowRate = std::abs(lHeatingLoad / (Cp_HW * HeatDeltaTemp));
1904 :
1905 4574 : PlantUtilities::SetComponentFlowRate(
1906 : state, lHotWaterMassFlowRate, this->HeatReturnNodeNum, this->HeatSupplyNodeNum, this->HWplantLoc);
1907 :
1908 : } else {
1909 0 : lHotWaterMassFlowRate = 0.0;
1910 0 : ShowRecurringWarningErrorAtEnd(state,
1911 0 : "GasAbsorberChillerModel:Heating\"" + this->Name + "\", DeltaTemp = 0 in mass flow calculation",
1912 : this->DeltaTempHeatErrCount);
1913 : }
1914 4574 : lHotWaterSupplyTemp = HeatSupplySetPointTemp;
1915 4574 : } break;
1916 4574 : case DataPlant::FlowLock::Locked: { // mass flow rates may not be changed by loop components
1917 4574 : lHotWaterSupplyTemp = HeatSupplySetPointTemp;
1918 4574 : lHeatingLoad = std::abs(lHotWaterMassFlowRate * Cp_HW * HeatDeltaTemp);
1919 4574 : } break;
1920 0 : default:
1921 0 : break;
1922 : }
1923 :
1924 : // Calculate operating part load ratio for cooling
1925 9148 : if (lAvailableHeatingCapacity <= 0.0) {
1926 0 : lAvailableHeatingCapacity = 0.0;
1927 0 : lHeatPartLoadRatio = 0.0;
1928 : } else {
1929 9148 : lHeatPartLoadRatio = lHeatingLoad / lAvailableHeatingCapacity;
1930 : }
1931 :
1932 : // Calculate fuel consumption for cooling
1933 : // fuel used for cooling availCap * HIR * HIR-FT * HIR-FPLR
1934 :
1935 9148 : lHeatFuelUseRate = lAvailableHeatingCapacity * lFuelHeatRatio * Curve::CurveValue(state, lFuelHeatFHPLRCurve, lHeatPartLoadRatio);
1936 :
1937 : // calculate the fraction of the time period that the chiller would be running
1938 : // use maximum from heating and cooling sides
1939 9148 : lFractionOfPeriodRunning = min(1.0, max(lHeatPartLoadRatio, lCoolPartLoadRatio) / lMinPartLoadRat);
1940 :
1941 : // Calculate electric parasitics used
1942 : // for heating based on nominal capacity not available capacity
1943 9148 : lHeatElectricPower = lNomCoolingCap * lNomHeatCoolRatio * lElecHeatRatio * lFractionOfPeriodRunning;
1944 : // Coodinate electric parasitics for heating and cooling to avoid double counting
1945 : // Total electric is the max of heating electric or cooling electric
1946 : // If heating electric is greater, leave cooling electric and subtract if off of heating elec
1947 : // If cooling electric is greater, set heating electric to zero
1948 9148 : if (lHeatElectricPower <= lCoolElectricPower) {
1949 18 : lHeatElectricPower = 0.0;
1950 : } else {
1951 9130 : lHeatElectricPower -= lCoolElectricPower;
1952 : }
1953 :
1954 : } // IF(MyLoad==0 .OR. .NOT. RunFlag)
1955 : // Write into the Report Variables except for nodes
1956 21213 : this->HeatingLoad = lHeatingLoad;
1957 21213 : this->HeatFuelUseRate = lHeatFuelUseRate;
1958 21213 : this->HeatElectricPower = lHeatElectricPower;
1959 21213 : this->HotWaterReturnTemp = lHotWaterReturnTemp;
1960 21213 : this->HotWaterSupplyTemp = lHotWaterSupplyTemp;
1961 21213 : this->HotWaterFlowRate = lHotWaterMassFlowRate;
1962 21213 : this->HeatPartLoadRatio = lHeatPartLoadRatio;
1963 21213 : this->HeatingCapacity = lAvailableHeatingCapacity;
1964 21213 : this->FractionOfPeriodRunning = lFractionOfPeriodRunning;
1965 :
1966 : // write the combined heating and cooling fuel used and electric used
1967 21213 : this->FuelUseRate = lCoolFuelUseRate + lHeatFuelUseRate;
1968 21213 : this->ElectricPower = lCoolElectricPower + lHeatElectricPower;
1969 21213 : }
1970 :
1971 21213 : void GasAbsorberSpecs::updateCoolRecords(EnergyPlusData &state,
1972 : Real64 const MyLoad, // current load
1973 : bool const RunFlag // TRUE if Absorber operating
1974 : )
1975 : {
1976 : // AUTHOR Jason Glazer
1977 : // DATE WRITTEN March 2001
1978 :
1979 21213 : int lChillReturnNodeNum = this->ChillReturnNodeNum;
1980 21213 : int lChillSupplyNodeNum = this->ChillSupplyNodeNum;
1981 21213 : int lCondReturnNodeNum = this->CondReturnNodeNum;
1982 21213 : int lCondSupplyNodeNum = this->CondSupplyNodeNum;
1983 :
1984 21213 : if (MyLoad == 0 || !RunFlag) {
1985 16709 : state.dataLoopNodes->Node(lChillSupplyNodeNum).Temp = state.dataLoopNodes->Node(lChillReturnNodeNum).Temp;
1986 33418 : if (this->isWaterCooled) {
1987 16709 : state.dataLoopNodes->Node(lCondSupplyNodeNum).Temp = state.dataLoopNodes->Node(lCondReturnNodeNum).Temp;
1988 : }
1989 : } else {
1990 4504 : state.dataLoopNodes->Node(lChillSupplyNodeNum).Temp = this->ChillSupplyTemp;
1991 4504 : if (this->isWaterCooled) {
1992 4504 : state.dataLoopNodes->Node(lCondSupplyNodeNum).Temp = this->CondSupplyTemp;
1993 : }
1994 : }
1995 :
1996 : // convert power to energy and instantaneous use to use over the time step
1997 21213 : this->CoolingEnergy = this->CoolingLoad * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
1998 21213 : this->TowerEnergy = this->TowerLoad * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
1999 21213 : this->FuelEnergy = this->FuelUseRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2000 21213 : this->CoolFuelEnergy = this->CoolFuelUseRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2001 21213 : this->ElectricEnergy = this->ElectricPower * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2002 21213 : this->CoolElectricEnergy = this->CoolElectricPower * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2003 21213 : if (this->CoolFuelUseRate != 0.0) {
2004 4504 : this->FuelCOP = this->CoolingLoad / this->CoolFuelUseRate;
2005 : } else {
2006 16709 : this->FuelCOP = 0.0;
2007 : }
2008 21213 : }
2009 :
2010 21213 : void GasAbsorberSpecs::updateHeatRecords(EnergyPlusData &state,
2011 : Real64 const MyLoad, // current load
2012 : bool const RunFlag // TRUE if Absorber operating
2013 : )
2014 : {
2015 : // AUTHOR Jason Glazer
2016 : // DATE WRITTEN March 2001
2017 :
2018 21213 : int lHeatReturnNodeNum = this->HeatReturnNodeNum;
2019 21213 : int lHeatSupplyNodeNum = this->HeatSupplyNodeNum;
2020 :
2021 21213 : if (MyLoad == 0 || !RunFlag) {
2022 12074 : state.dataLoopNodes->Node(lHeatSupplyNodeNum).Temp = state.dataLoopNodes->Node(lHeatReturnNodeNum).Temp;
2023 : } else {
2024 9139 : state.dataLoopNodes->Node(lHeatSupplyNodeNum).Temp = this->HotWaterSupplyTemp;
2025 : }
2026 :
2027 : // convert power to energy and instantaneous use to use over the time step
2028 21213 : this->HeatingEnergy = this->HeatingLoad * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2029 21213 : this->FuelEnergy = this->FuelUseRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2030 21213 : this->HeatFuelEnergy = this->HeatFuelUseRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2031 21213 : this->ElectricEnergy = this->ElectricPower * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2032 21213 : this->HeatElectricEnergy = this->HeatElectricPower * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2033 21213 : }
2034 :
2035 0 : void GasAbsorberSpecs::oneTimeInit([[maybe_unused]] EnergyPlusData &state)
2036 : {
2037 0 : }
2038 :
2039 2313 : } // namespace EnergyPlus::ChillerGasAbsorption
|