Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Fmath.hh>
53 :
54 : // EnergyPlus Headers
55 : #include <EnergyPlus/CoolTower.hh>
56 : #include <EnergyPlus/Data/EnergyPlusData.hh>
57 : #include <EnergyPlus/DataEnvironment.hh>
58 : #include <EnergyPlus/DataHVACGlobals.hh>
59 : #include <EnergyPlus/DataHeatBalance.hh>
60 : #include <EnergyPlus/DataIPShortCuts.hh>
61 : #include <EnergyPlus/DataWater.hh>
62 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
63 : #include <EnergyPlus/OutputProcessor.hh>
64 : #include <EnergyPlus/Psychrometrics.hh>
65 : #include <EnergyPlus/ScheduleManager.hh>
66 : #include <EnergyPlus/UtilityRoutines.hh>
67 : #include <EnergyPlus/WaterManager.hh>
68 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
69 :
70 : namespace EnergyPlus {
71 :
72 : namespace CoolTower {
73 : // Module containing the data for cooltower system
74 :
75 : // MODULE INFORMATION:
76 : // AUTHOR Daeho Kang
77 : // DATE WRITTEN Aug 2008
78 : // MODIFIED na
79 : // RE-ENGINEERED na
80 :
81 : // PURPOSE OF THIS MODULE:
82 : // To encapsulate the data and algorithms required to manage the cooltower component.
83 :
84 : // REFERENCES:
85 : // Baruch Givoni. 1994. Passive and Low Energy Cooling of Buildings. Chapter 5: Evaporative Cooling Systems.
86 : // John Wiley & Sons, Inc.
87 : // OTHER NOTES: none
88 :
89 : // Using/Aliasing
90 : using namespace DataHeatBalance;
91 :
92 : constexpr std::array<std::string_view, static_cast<int>(FlowCtrl::Num)> FlowCtrlNamesUC{"WATERFLOWSCHEDULE", "WINDDRIVENFLOW"};
93 :
94 3479215 : void ManageCoolTower(EnergyPlusData &state)
95 : {
96 :
97 : // SUBROUTINE INFORMATION:
98 : // AUTHOR Daeho Kang
99 : // DATE WRITTEN Aug 2008
100 : // MODIFIED na
101 : // RE-ENGINEERED na
102 :
103 : // PURPOSE OF THIS SUBROUTINE:
104 : // This subroutine manages the simulation of Cooltower component.
105 : // This driver manages the calls to all of the other drivers and simulation algorithms.
106 :
107 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
108 :
109 : // Obtains and allocates heat balance related parameters from input
110 3479215 : if (state.dataCoolTower->GetInputFlag) {
111 739 : GetCoolTower(state);
112 739 : state.dataCoolTower->GetInputFlag = false;
113 : }
114 :
115 3479215 : if ((int)state.dataCoolTower->CoolTowerSys.size() == 0) return;
116 :
117 3645 : CalcCoolTower(state);
118 :
119 3645 : UpdateCoolTower(state);
120 :
121 3645 : ReportCoolTower(state);
122 : }
123 :
124 739 : void GetCoolTower(EnergyPlusData &state)
125 : {
126 :
127 : // SUBROUTINE INFORMATION:
128 : // AUTHOR Daeho Kang
129 : // DATE WRITTEN Aug 2008
130 : // MODIFIED na
131 : // RE-ENGINEERED na
132 :
133 : // PURPOSE OF THIS SUBROUTINE:
134 : // This subroutine gets input data for cooltower components
135 : // and stores it in the Cooltower data structure.
136 :
137 : // Using/Aliasing
138 :
139 : using ScheduleManager::GetScheduleIndex;
140 : using WaterManager::SetupTankDemandComponent;
141 :
142 : // SUBROUTINE PARAMETER DEFINITIONS:
143 739 : static std::string const CurrentModuleObject("ZoneCoolTower:Shower");
144 739 : Real64 constexpr MaximumWaterFlowRate(0.016667); // Maximum limit of water flow rate in m3/s (1000 l/min)
145 739 : Real64 constexpr MinimumWaterFlowRate(0.0); // Minimum limit of water flow rate
146 739 : Real64 constexpr MaxHeight(30.0); // Maximum effective tower height in m
147 739 : Real64 constexpr MinHeight(1.0); // Minimum effective tower height in m
148 739 : Real64 constexpr MaxValue(100.0); // Maximum limit of outlet area, airflow, and temperature
149 739 : Real64 constexpr MinValue(0.0); // Minimum limit of outlet area, airflow, and temperature
150 739 : Real64 constexpr MaxFrac(1.0); // Maximum fraction
151 739 : Real64 constexpr MinFrac(0.0); // Minimum fraction
152 :
153 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
154 739 : bool ErrorsFound(false); // If errors detected in input
155 : int CoolTowerNum; // Cooltower number
156 : int NumAlphas; // Number of Alphas for each GetobjectItem call
157 : int NumNumbers; // Number of Numbers for each GetobjectItem call
158 : int NumArgs;
159 : int IOStat;
160 1478 : Array1D_string cAlphaArgs; // Alpha input items for object
161 1478 : Array1D_string cAlphaFields; // Alpha field names
162 1478 : Array1D_string cNumericFields; // Numeric field names
163 1478 : Array1D<Real64> rNumericArgs; // Numeric input items for object
164 1478 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
165 1478 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
166 :
167 : // Initializations and allocations
168 739 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumArgs, NumAlphas, NumNumbers);
169 739 : cAlphaArgs.allocate(NumAlphas);
170 739 : cAlphaFields.allocate(NumAlphas);
171 739 : cNumericFields.allocate(NumNumbers);
172 739 : rNumericArgs.dimension(NumNumbers, 0.0);
173 739 : lAlphaBlanks.dimension(NumAlphas, true);
174 739 : lNumericBlanks.dimension(NumNumbers, true);
175 :
176 739 : auto &Zone(state.dataHeatBal->Zone);
177 :
178 739 : int NumCoolTowers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
179 :
180 739 : state.dataCoolTower->CoolTowerSys.allocate(NumCoolTowers);
181 :
182 : // Obtain inputs
183 744 : for (CoolTowerNum = 1; CoolTowerNum <= NumCoolTowers; ++CoolTowerNum) {
184 :
185 15 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
186 : CurrentModuleObject,
187 : CoolTowerNum,
188 5 : state.dataIPShortCut->cAlphaArgs,
189 : NumAlphas,
190 5 : state.dataIPShortCut->rNumericArgs,
191 : NumNumbers,
192 : IOStat,
193 : lNumericBlanks,
194 : lAlphaBlanks,
195 : cAlphaFields,
196 : cNumericFields);
197 5 : UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), CurrentModuleObject, ErrorsFound);
198 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).Name = state.dataIPShortCut->cAlphaArgs(1); // Name of cooltower
199 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).Schedule = state.dataIPShortCut->cAlphaArgs(2); // Get schedule
200 5 : if (lAlphaBlanks(2)) {
201 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
202 : } else {
203 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
204 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr == 0) {
205 0 : ShowSevereError(state, CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\" invalid data");
206 0 : ShowContinueError(state, "Invalid-Schedule not found " + cAlphaFields(2) + "=\"" + state.dataIPShortCut->cAlphaArgs(2) + "\".");
207 0 : ErrorsFound = true;
208 : }
209 : }
210 :
211 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZoneName = state.dataIPShortCut->cAlphaArgs(3); // Name of zone where cooltower is serving
212 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), Zone);
213 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr == 0) {
214 0 : if (lAlphaBlanks(3)) {
215 0 : ShowSevereError(state,
216 0 : CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\" invalid " + cAlphaFields(3) +
217 : " is required but input is blank.");
218 : } else {
219 0 : ShowSevereError(state,
220 0 : CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\" invalid " + cAlphaFields(3) + "=\"" +
221 0 : state.dataIPShortCut->cAlphaArgs(3) + "\" not found.");
222 : }
223 0 : ErrorsFound = true;
224 : }
225 :
226 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyName = state.dataIPShortCut->cAlphaArgs(4); // Name of water storage tank
227 5 : if (lAlphaBlanks(4)) {
228 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode = WaterSupplyMode::FromMains;
229 0 : } else if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromTank) {
230 0 : SetupTankDemandComponent(state,
231 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).Name,
232 : CurrentModuleObject,
233 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyName,
234 : ErrorsFound,
235 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupTankID,
236 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterTankDemandARRID);
237 : }
238 :
239 : {
240 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).FlowCtrlType =
241 10 : static_cast<FlowCtrl>(getEnumerationValue(FlowCtrlNamesUC, state.dataIPShortCut->cAlphaArgs(5))); // Type of flow control
242 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FlowCtrlType == FlowCtrl::Invalid) {
243 0 : ShowSevereError(state,
244 0 : CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\" invalid " + cAlphaFields(5) + "=\"" +
245 0 : state.dataIPShortCut->cAlphaArgs(5) + "\".");
246 0 : ErrorsFound = true;
247 : }
248 : }
249 :
250 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(6));
251 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpSchedPtr == 0) {
252 0 : if (lAlphaBlanks(6)) {
253 0 : ShowSevereError(state,
254 0 : CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\" invalid " + cAlphaFields(6) +
255 : " is required but input is blank.");
256 : } else {
257 0 : ShowSevereError(state,
258 0 : CurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\" invalid " + cAlphaFields(6) + "=\"" +
259 0 : state.dataIPShortCut->cAlphaArgs(6) + "\" not found.");
260 : }
261 0 : ErrorsFound = true;
262 : }
263 :
264 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate = state.dataIPShortCut->rNumericArgs(1); // Maximum limit of water supply
265 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate > MaximumWaterFlowRate) {
266 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate = MaximumWaterFlowRate;
267 0 : ShowWarningError(state,
268 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
269 : CurrentModuleObject,
270 0 : state.dataIPShortCut->cAlphaArgs(1),
271 : cNumericFields(1),
272 0 : state.dataIPShortCut->rNumericArgs(1)));
273 0 : ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaximumWaterFlowRate));
274 : }
275 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate < MinimumWaterFlowRate) {
276 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate = MinimumWaterFlowRate;
277 0 : ShowWarningError(state,
278 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
279 : CurrentModuleObject,
280 0 : state.dataIPShortCut->cAlphaArgs(1),
281 : cNumericFields(1),
282 0 : state.dataIPShortCut->rNumericArgs(1)));
283 0 : ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinimumWaterFlowRate));
284 : }
285 :
286 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight = state.dataIPShortCut->rNumericArgs(2); // Get effctive tower height
287 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight > MaxHeight) {
288 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight = MaxHeight;
289 0 : ShowWarningError(state,
290 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
291 : CurrentModuleObject,
292 0 : state.dataIPShortCut->cAlphaArgs(1),
293 : cNumericFields(2),
294 0 : state.dataIPShortCut->rNumericArgs(2)));
295 0 : ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxHeight));
296 : }
297 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight < MinHeight) {
298 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight = MinHeight;
299 0 : ShowWarningError(state,
300 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
301 : CurrentModuleObject,
302 0 : state.dataIPShortCut->cAlphaArgs(1),
303 : cNumericFields(2),
304 0 : state.dataIPShortCut->rNumericArgs(2)));
305 0 : ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinHeight));
306 : }
307 :
308 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea = state.dataIPShortCut->rNumericArgs(3); // Get outlet area
309 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea > MaxValue) {
310 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea = MaxValue;
311 0 : ShowWarningError(state,
312 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
313 : CurrentModuleObject,
314 0 : state.dataIPShortCut->cAlphaArgs(1),
315 : cNumericFields(3),
316 0 : state.dataIPShortCut->rNumericArgs(3)));
317 0 : ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxValue));
318 : }
319 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea < MinValue) {
320 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea = MinValue;
321 0 : ShowWarningError(state,
322 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
323 : CurrentModuleObject,
324 0 : state.dataIPShortCut->cAlphaArgs(1),
325 : cNumericFields(3),
326 0 : state.dataIPShortCut->rNumericArgs(3)));
327 0 : ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinValue));
328 : }
329 :
330 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate =
331 5 : state.dataIPShortCut->rNumericArgs(4); // Maximum limit of air flow to the space
332 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate > MaxValue) {
333 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate = MaxValue;
334 0 : ShowWarningError(state,
335 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
336 : CurrentModuleObject,
337 0 : state.dataIPShortCut->cAlphaArgs(1),
338 : cNumericFields(4),
339 0 : state.dataIPShortCut->rNumericArgs(4)));
340 0 : ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxValue));
341 : }
342 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate < MinValue) {
343 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate = MinValue;
344 0 : ShowWarningError(state,
345 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
346 : CurrentModuleObject,
347 0 : state.dataIPShortCut->cAlphaArgs(1),
348 : cNumericFields(4),
349 0 : state.dataIPShortCut->rNumericArgs(4)));
350 0 : ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinValue));
351 : }
352 :
353 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp =
354 5 : state.dataIPShortCut->rNumericArgs(5); // Get minimum temp limit which gets this cooltower off
355 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp > MaxValue) {
356 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp = MaxValue;
357 0 : ShowWarningError(state,
358 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
359 : CurrentModuleObject,
360 0 : state.dataIPShortCut->cAlphaArgs(1),
361 : cNumericFields(5),
362 0 : state.dataIPShortCut->rNumericArgs(5)));
363 0 : ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxValue));
364 : }
365 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp < MinValue) {
366 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp = MinValue;
367 0 : ShowWarningError(state,
368 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
369 : CurrentModuleObject,
370 0 : state.dataIPShortCut->cAlphaArgs(1),
371 : cNumericFields(5),
372 0 : state.dataIPShortCut->rNumericArgs(5)));
373 0 : ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinValue));
374 : }
375 :
376 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss = state.dataIPShortCut->rNumericArgs(6); // Fraction of water loss
377 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss > MaxFrac) {
378 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss = MaxFrac;
379 0 : ShowWarningError(state,
380 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
381 : CurrentModuleObject,
382 0 : state.dataIPShortCut->cAlphaArgs(1),
383 : cNumericFields(6),
384 0 : state.dataIPShortCut->rNumericArgs(6)));
385 0 : ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxFrac));
386 : }
387 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss < MinFrac) {
388 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss = MinFrac;
389 0 : ShowWarningError(state,
390 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
391 : CurrentModuleObject,
392 0 : state.dataIPShortCut->cAlphaArgs(1),
393 : cNumericFields(6),
394 0 : state.dataIPShortCut->rNumericArgs(6)));
395 0 : ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinFrac));
396 : }
397 :
398 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched = state.dataIPShortCut->rNumericArgs(7); // Fraction of loss of air flow
399 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched > MaxFrac) {
400 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched = MaxFrac;
401 0 : ShowWarningError(state,
402 0 : format("{}=\"{}\" invalid {}=[{:.2R}].",
403 : CurrentModuleObject,
404 0 : state.dataIPShortCut->cAlphaArgs(1),
405 : cNumericFields(7),
406 0 : state.dataIPShortCut->rNumericArgs(7)));
407 0 : ShowContinueError(state, format("...Maximum Allowable=[{:.2R}].", MaxFrac));
408 : }
409 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched < MinFrac) {
410 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched = MinFrac;
411 0 : ShowWarningError(state,
412 0 : format("{}=\"{}\" invalid {}=[{:.5R}].",
413 : CurrentModuleObject,
414 0 : state.dataIPShortCut->cAlphaArgs(1),
415 : cNumericFields(7),
416 0 : state.dataIPShortCut->rNumericArgs(7)));
417 0 : ShowContinueError(state, format("...Minimum Allowable=[{:.2R}].", MinFrac));
418 : }
419 :
420 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).RatedPumpPower = state.dataIPShortCut->rNumericArgs(8); // Get rated pump power
421 : }
422 :
423 739 : cAlphaArgs.deallocate();
424 739 : cAlphaFields.deallocate();
425 739 : cNumericFields.deallocate();
426 739 : rNumericArgs.deallocate();
427 739 : lAlphaBlanks.deallocate();
428 739 : lNumericBlanks.deallocate();
429 :
430 739 : if (ErrorsFound) ShowFatalError(state, CurrentModuleObject + " errors occurred in input. Program terminates.");
431 :
432 744 : for (CoolTowerNum = 1; CoolTowerNum <= NumCoolTowers; ++CoolTowerNum) {
433 20 : SetupOutputVariable(state,
434 : "Zone Cooltower Sensible Heat Loss Energy",
435 : OutputProcessor::Unit::J,
436 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatLoss,
437 : OutputProcessor::SOVTimeStepType::System,
438 : OutputProcessor::SOVStoreType::Summed,
439 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
440 20 : SetupOutputVariable(state,
441 : "Zone Cooltower Sensible Heat Loss Rate",
442 : OutputProcessor::Unit::W,
443 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower,
444 : OutputProcessor::SOVTimeStepType::System,
445 : OutputProcessor::SOVStoreType::Average,
446 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
447 20 : SetupOutputVariable(state,
448 : "Zone Cooltower Latent Heat Loss Energy",
449 : OutputProcessor::Unit::J,
450 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatLoss,
451 : OutputProcessor::SOVTimeStepType::System,
452 : OutputProcessor::SOVStoreType::Summed,
453 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
454 20 : SetupOutputVariable(state,
455 : "Zone Cooltower Latent Heat Loss Rate",
456 : OutputProcessor::Unit::W,
457 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower,
458 : OutputProcessor::SOVTimeStepType::System,
459 : OutputProcessor::SOVStoreType::Average,
460 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
461 20 : SetupOutputVariable(state,
462 : "Zone Cooltower Air Volume",
463 : OutputProcessor::Unit::m3,
464 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTAirVol,
465 : OutputProcessor::SOVTimeStepType::System,
466 : OutputProcessor::SOVStoreType::Summed,
467 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
468 20 : SetupOutputVariable(state,
469 : "Zone Cooltower Current Density Air Volume Flow Rate",
470 : OutputProcessor::Unit::m3_s,
471 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate,
472 : OutputProcessor::SOVTimeStepType::System,
473 : OutputProcessor::SOVStoreType::Average,
474 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
475 20 : SetupOutputVariable(state,
476 : "Zone Cooltower Standard Density Air Volume Flow Rate",
477 : OutputProcessor::Unit::m3_s,
478 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd,
479 : OutputProcessor::SOVTimeStepType::System,
480 : OutputProcessor::SOVStoreType::Average,
481 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
482 20 : SetupOutputVariable(state,
483 : "Zone Cooltower Air Mass",
484 : OutputProcessor::Unit::kg,
485 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTAirMass,
486 : OutputProcessor::SOVTimeStepType::System,
487 : OutputProcessor::SOVStoreType::Summed,
488 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
489 20 : SetupOutputVariable(state,
490 : "Zone Cooltower Air Mass Flow Rate",
491 : OutputProcessor::Unit::kg_s,
492 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate,
493 : OutputProcessor::SOVTimeStepType::System,
494 : OutputProcessor::SOVStoreType::Average,
495 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
496 20 : SetupOutputVariable(state,
497 : "Zone Cooltower Air Inlet Temperature",
498 : OutputProcessor::Unit::C,
499 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletDBTemp,
500 : OutputProcessor::SOVTimeStepType::System,
501 : OutputProcessor::SOVStoreType::Average,
502 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
503 20 : SetupOutputVariable(state,
504 : "Zone Cooltower Air Inlet Humidity Ratio",
505 : OutputProcessor::Unit::kgWater_kgDryAir,
506 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletHumRat,
507 : OutputProcessor::SOVTimeStepType::System,
508 : OutputProcessor::SOVStoreType::Average,
509 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
510 20 : SetupOutputVariable(state,
511 : "Zone Cooltower Air Outlet Temperature",
512 : OutputProcessor::Unit::C,
513 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletTemp,
514 : OutputProcessor::SOVTimeStepType::System,
515 : OutputProcessor::SOVStoreType::Average,
516 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
517 20 : SetupOutputVariable(state,
518 : "Zone Cooltower Air Outlet Humidity Ratio",
519 : OutputProcessor::Unit::kgWater_kgDryAir,
520 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletHumRat,
521 : OutputProcessor::SOVTimeStepType::System,
522 : OutputProcessor::SOVStoreType::Average,
523 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
524 20 : SetupOutputVariable(state,
525 : "Zone Cooltower Pump Electricity Rate",
526 : OutputProcessor::Unit::W,
527 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower,
528 : OutputProcessor::SOVTimeStepType::System,
529 : OutputProcessor::SOVStoreType::Average,
530 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
531 20 : SetupOutputVariable(state,
532 : "Zone Cooltower Pump Electricity Energy",
533 : OutputProcessor::Unit::J,
534 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecConsump,
535 : OutputProcessor::SOVTimeStepType::System,
536 : OutputProcessor::SOVStoreType::Summed,
537 5 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name,
538 : _,
539 : "Electricity",
540 : "Cooling",
541 : _,
542 5 : "System");
543 5 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromMains) {
544 20 : SetupOutputVariable(state,
545 : "Zone Cooltower Water Volume",
546 : OutputProcessor::Unit::m3,
547 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump,
548 : OutputProcessor::SOVTimeStepType::System,
549 : OutputProcessor::SOVStoreType::Summed,
550 10 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
551 20 : SetupOutputVariable(state,
552 : "Zone Cooltower Mains Water Volume",
553 : OutputProcessor::Unit::m3,
554 5 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump,
555 : OutputProcessor::SOVTimeStepType::System,
556 : OutputProcessor::SOVStoreType::Summed,
557 5 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name,
558 : _,
559 : "MainsWater",
560 : "Cooling",
561 : _,
562 5 : "System");
563 0 : } else if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromTank) {
564 0 : SetupOutputVariable(state,
565 : "Zone Cooltower Water Volume",
566 : OutputProcessor::Unit::m3,
567 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump,
568 : OutputProcessor::SOVTimeStepType::System,
569 : OutputProcessor::SOVStoreType::Summed,
570 0 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
571 0 : SetupOutputVariable(state,
572 : "Zone Cooltower Storage Tank Water Volume",
573 : OutputProcessor::Unit::m3,
574 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump,
575 : OutputProcessor::SOVTimeStepType::System,
576 : OutputProcessor::SOVStoreType::Summed,
577 0 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name);
578 0 : SetupOutputVariable(state,
579 : "Zone Cooltower Starved Mains Water Volume",
580 : OutputProcessor::Unit::m3,
581 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeup,
582 : OutputProcessor::SOVTimeStepType::System,
583 : OutputProcessor::SOVStoreType::Summed,
584 0 : Zone(state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr).Name,
585 : _,
586 : "MainsWater",
587 : "Cooling",
588 : _,
589 0 : "System");
590 : }
591 : }
592 739 : }
593 :
594 3645 : void CalcCoolTower(EnergyPlusData &state)
595 : {
596 :
597 : // SUBROUTINE INFORMATION:
598 : // AUTHOR Daeho Kang
599 : // DATE WRITTEN Aug 2008
600 : // MODIFIED na
601 : // RE-ENGINEERED na
602 :
603 : // REFERENCES:
604 : // Baruch Givoni. 1994. Passive and Low Energy Cooling of Buildings. Chapter 5: Evaporative Cooling Systems.
605 : // John Wiley & Sons, Inc.
606 :
607 : // Using/Aliasing
608 : using Psychrometrics::PsyCpAirFnW;
609 : using Psychrometrics::PsyRhoAirFnPbTdbW;
610 : using Psychrometrics::PsyWFnTdbH;
611 : using Psychrometrics::PsyWFnTdbTwbPb;
612 : using Psychrometrics::RhoH2O;
613 : using ScheduleManager::GetCurrentScheduleValue;
614 :
615 : // SUBROUTINE PARAMETER DEFINITIONS:
616 3645 : Real64 constexpr MinWindSpeed(0.1); // Minimum limit of outdoor air wind speed in m/s
617 3645 : Real64 constexpr MaxWindSpeed(30.0); // Maximum limit of outdoor air wind speed in m/s
618 3645 : Real64 constexpr UCFactor(60000.0); // Unit conversion factor m3/s to l/min
619 :
620 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
621 : int ZoneNum; // Number of zone being served
622 : int CoolTowerNum; // Number of coolter being served
623 : Real64 CVF_ZoneNum; // Design flow rate in m3/s
624 : Real64 AirMassFlowRate; // Actual air mass flow rate in kg/s
625 : Real64 AirSpecHeat; // Specific heat of air
626 : Real64 AirDensity; // Density of air
627 : Real64 RhoWater; // Density of water
628 : Real64 PumpPartLoadRat; // Pump part load ratio (based on user schedule, or 1.0 for no schedule)
629 : Real64 WaterFlowRate; // Calculated water flow rate in m3/s
630 : Real64 AirVolFlowRate; // Calculated air volume flow rate in m3/s
631 : Real64 InletHumRat; // Humidity ratio of outdoor air
632 : Real64 OutletHumRat; // Humidity ratio of air at the cooltower outlet
633 : Real64 OutletTemp; // Dry bulb temperature of air at the cooltower outlet
634 : Real64 IntHumRat; // Humidity ratio of initialized air
635 :
636 3645 : auto &Zone(state.dataHeatBal->Zone);
637 :
638 12742 : for (CoolTowerNum = 1; CoolTowerNum <= (int)state.dataCoolTower->CoolTowerSys.size(); ++CoolTowerNum) {
639 9097 : ZoneNum = state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr;
640 9097 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
641 9097 : thisZoneHB.MCPTC = 0.0;
642 9097 : thisZoneHB.MCPC = 0.0;
643 9097 : thisZoneHB.CTMFL = 0.0;
644 :
645 9097 : if (GetCurrentScheduleValue(state, state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr) > 0.0) {
646 : // check component operation
647 6471 : if (state.dataEnvrn->WindSpeed < MinWindSpeed || state.dataEnvrn->WindSpeed > MaxWindSpeed) continue;
648 6471 : if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT < state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp)
649 2948 : continue;
650 :
651 : // Unit is on and simulate this component
652 : // Determine the temperature and air flow rate at the cooltower outlet
653 3523 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FlowCtrlType == FlowCtrl::WindDriven) {
654 2851 : Real64 const height_sqrt(std::sqrt(state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight));
655 2851 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletVelocity = 0.7 * height_sqrt + 0.47 * (state.dataEnvrn->WindSpeed - 1.0);
656 2851 : AirVolFlowRate =
657 2851 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletArea * state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletVelocity;
658 2851 : AirVolFlowRate = min(AirVolFlowRate, state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate);
659 2851 : WaterFlowRate = (AirVolFlowRate / (0.0125 * height_sqrt));
660 2851 : if (WaterFlowRate > state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate * UCFactor) {
661 2093 : WaterFlowRate = state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate * UCFactor;
662 2093 : AirVolFlowRate = 0.0125 * WaterFlowRate * height_sqrt;
663 2093 : AirVolFlowRate = min(AirVolFlowRate, state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate);
664 : }
665 2851 : WaterFlowRate = min(WaterFlowRate, (state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate * UCFactor));
666 2851 : OutletTemp =
667 5702 : state.dataEnvrn->OutDryBulbTemp - (state.dataEnvrn->OutDryBulbTemp - state.dataEnvrn->OutWetBulbTemp) *
668 5702 : (1.0 - std::exp(-0.8 * state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight)) *
669 2851 : (1.0 - std::exp(-0.15 * WaterFlowRate));
670 672 : } else if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FlowCtrlType == FlowCtrl::FlowSchedule) {
671 672 : WaterFlowRate = state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxWaterFlowRate * UCFactor;
672 672 : AirVolFlowRate = 0.0125 * WaterFlowRate * std::sqrt(state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight);
673 672 : AirVolFlowRate = min(AirVolFlowRate, state.dataCoolTower->CoolTowerSys(CoolTowerNum).MaxAirVolFlowRate);
674 672 : OutletTemp =
675 1344 : state.dataEnvrn->OutDryBulbTemp - (state.dataEnvrn->OutDryBulbTemp - state.dataEnvrn->OutWetBulbTemp) *
676 1344 : (1.0 - std::exp(-0.8 * state.dataCoolTower->CoolTowerSys(CoolTowerNum).TowerHeight)) *
677 672 : (1.0 - std::exp(-0.15 * WaterFlowRate));
678 : }
679 :
680 3523 : if (OutletTemp < state.dataEnvrn->OutWetBulbTemp) {
681 0 : ShowSevereError(state, "Cooltower outlet temperature exceed the outdoor wet bulb temperature reset to input values");
682 0 : ShowContinueError(state, "Occurs in Cooltower =" + state.dataCoolTower->CoolTowerSys(CoolTowerNum).Name);
683 : }
684 :
685 3523 : WaterFlowRate /= UCFactor;
686 : // Determine actual water flow rate
687 3523 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss > 0.0) {
688 2846 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualWaterFlowRate =
689 2846 : WaterFlowRate * (1.0 + state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracWaterLoss);
690 : } else {
691 677 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualWaterFlowRate = WaterFlowRate;
692 : }
693 :
694 : // Determine actual air flow rate
695 3523 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched > 0.0) {
696 2846 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate =
697 2846 : AirVolFlowRate * (1.0 - state.dataCoolTower->CoolTowerSys(CoolTowerNum).FracFlowSched);
698 : } else {
699 677 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate = AirVolFlowRate;
700 : }
701 :
702 : // Determine pump power
703 3523 : if (GetCurrentScheduleValue(state, state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpSchedPtr) > 0) {
704 3523 : PumpPartLoadRat = GetCurrentScheduleValue(state, state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpSchedPtr);
705 : } else {
706 0 : PumpPartLoadRat = 1.0;
707 : }
708 :
709 : // Determine air mass flow rate and volume flow rate
710 3523 : InletHumRat = PsyWFnTdbTwbPb(state, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutWetBulbTemp, state.dataEnvrn->OutBaroPress);
711 : // Assume no pressure drops and no changes in enthalpy between inlet and outlet air
712 3523 : IntHumRat = PsyWFnTdbH(state, OutletTemp, state.dataEnvrn->OutEnthalpy); // Initialized humidity ratio
713 3523 : AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, OutletTemp, IntHumRat);
714 3523 : AirMassFlowRate = AirDensity * state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate;
715 : // From the mass balance W_in*(m_air + m_water) = W_out*m_air
716 3523 : RhoWater = RhoH2O(OutletTemp); // Assume T_water = T_outlet
717 3523 : OutletHumRat = (InletHumRat * (AirMassFlowRate + (state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualWaterFlowRate * RhoWater))) /
718 : AirMassFlowRate;
719 3523 : AirSpecHeat = PsyCpAirFnW(OutletHumRat);
720 3523 : AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, OutletTemp, OutletHumRat); // Outlet air density
721 7046 : CVF_ZoneNum = state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate *
722 3523 : GetCurrentScheduleValue(state, state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr);
723 3523 : thisZoneHB.MCPC = CVF_ZoneNum * AirDensity * AirSpecHeat;
724 3523 : thisZoneHB.MCPTC = thisZoneHB.MCPC * OutletTemp;
725 3523 : thisZoneHB.CTMFL = thisZoneHB.MCPC / AirSpecHeat;
726 :
727 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower = thisZoneHB.MCPC * std::abs(thisZoneHB.ZT - OutletTemp);
728 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower = CVF_ZoneNum * std::abs(thisZoneHB.ZoneAirHumRat - OutletHumRat);
729 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletTemp = OutletTemp;
730 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletHumRat = OutletHumRat;
731 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate = CVF_ZoneNum;
732 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate = thisZoneHB.CTMFL;
733 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd = thisZoneHB.CTMFL / state.dataEnvrn->StdRhoAir;
734 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletDBTemp = Zone(ZoneNum).OutDryBulbTemp;
735 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletWBTemp = Zone(ZoneNum).OutWetBulbTemp;
736 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletHumRat = state.dataEnvrn->OutHumRat;
737 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate =
738 3523 : (std::abs(InletHumRat - OutletHumRat) * thisZoneHB.CTMFL) / RhoWater;
739 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate = 0.0; // initialize -- calc in update
740 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower =
741 3523 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).RatedPumpPower * PumpPartLoadRat;
742 : } else { // Unit is off
743 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower = 0.0;
744 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower = 0.0;
745 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletTemp = 0.0;
746 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletHumRat = 0.0;
747 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate = 0.0;
748 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate = 0.0;
749 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd = 0.0;
750 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletDBTemp = 0.0;
751 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletHumRat = 0.0;
752 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower = 0.0;
753 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate = 0.0;
754 2626 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate = 0.0;
755 : }
756 : }
757 3645 : }
758 :
759 3645 : void UpdateCoolTower(EnergyPlusData &state)
760 : {
761 :
762 : // SUBROUTINE INFORMATION:
763 : // AUTHOR Richard J. Liesen
764 : // DATE WRITTEN October 2000
765 : // MODIFIED Aug 2008 Daeho Kang
766 : // RE-ENGINEERED na
767 :
768 : // Using/Aliasing
769 : using namespace DataWater;
770 :
771 : int CoolTowerNum;
772 : Real64 AvailWaterRate;
773 :
774 12742 : for (CoolTowerNum = 1; CoolTowerNum <= (int)state.dataCoolTower->CoolTowerSys.size(); ++CoolTowerNum) {
775 :
776 : // Set the demand request for supply water from water storage tank (if needed)
777 9097 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromTank) {
778 0 : state.dataWaterData->WaterStorage(state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupTankID)
779 0 : .VdotRequestDemand(state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterTankDemandARRID) =
780 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate;
781 : }
782 :
783 : // check if should be starved by restricted flow from tank
784 9097 : if (state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupplyMode == WaterSupplyMode::FromTank) {
785 0 : AvailWaterRate = state.dataWaterData->WaterStorage(state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterSupTankID)
786 0 : .VdotAvailDemand(state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterTankDemandARRID);
787 0 : if (AvailWaterRate < state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate) {
788 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate =
789 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate - AvailWaterRate;
790 0 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate = AvailWaterRate;
791 : }
792 : }
793 : }
794 3645 : }
795 :
796 3645 : void ReportCoolTower(EnergyPlusData &state)
797 : {
798 :
799 : // SUBROUTINE INFORMATION:
800 : // AUTHOR Daeho Kang
801 : // DATE WRITTEN Aut 2008
802 : // MODIFIED na
803 : // RE-ENGINEERED na
804 :
805 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
806 : int CoolTowerNum;
807 : Real64 TSMult;
808 :
809 3645 : TSMult = state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
810 :
811 12742 : for (CoolTowerNum = 1; CoolTowerNum <= (int)state.dataCoolTower->CoolTowerSys.size(); ++CoolTowerNum) {
812 :
813 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTAirVol = state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate * TSMult;
814 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTAirMass = state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate * TSMult;
815 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatLoss = state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower * TSMult;
816 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatLoss = state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower * TSMult;
817 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecConsump = state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower * TSMult;
818 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsump =
819 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate * TSMult;
820 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeup =
821 9097 : state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate * TSMult;
822 : }
823 3645 : }
824 :
825 : } // namespace CoolTower
826 :
827 2313 : } // namespace EnergyPlus
|