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