Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Autosizing/Base.hh>
57 : #include <EnergyPlus/BranchNodeConnections.hh>
58 : #include <EnergyPlus/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataBranchAirLoopPlant.hh>
60 : #include <EnergyPlus/DataEnvironment.hh>
61 : #include <EnergyPlus/DataHVACGlobals.hh>
62 : #include <EnergyPlus/DataIPShortCuts.hh>
63 : #include <EnergyPlus/DataLoopNode.hh>
64 : #include <EnergyPlus/DataSizing.hh>
65 : #include <EnergyPlus/DataWater.hh>
66 : #include <EnergyPlus/EvaporativeFluidCoolers.hh>
67 : #include <EnergyPlus/FluidProperties.hh>
68 : #include <EnergyPlus/General.hh>
69 : #include <EnergyPlus/GlobalNames.hh>
70 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
71 : #include <EnergyPlus/NodeInputManager.hh>
72 : #include <EnergyPlus/OutAirNodeManager.hh>
73 : #include <EnergyPlus/OutputProcessor.hh>
74 : #include <EnergyPlus/OutputReportPredefined.hh>
75 : #include <EnergyPlus/Plant/DataPlant.hh>
76 : #include <EnergyPlus/PlantUtilities.hh>
77 : #include <EnergyPlus/Psychrometrics.hh>
78 : #include <EnergyPlus/ScheduleManager.hh>
79 : #include <EnergyPlus/UtilityRoutines.hh>
80 : #include <EnergyPlus/WaterManager.hh>
81 :
82 : namespace EnergyPlus {
83 :
84 : namespace EvaporativeFluidCoolers {
85 :
86 : // MODULE INFORMATION:
87 : // AUTHOR Chandan Sharma
88 : // DATE WRITTEN May 2009
89 : // MODIFIED na
90 : // RE-ENGINEERED na
91 :
92 : // PURPOSE OF THIS MODULE:
93 : // Model the performance of evaporative fluid coolers
94 :
95 : // METHODOLOGY EMPLOYED:
96 : // Based on cooling tower by Shirey, Raustad: Dec 2000; Shirey, Sept 2002
97 :
98 : constexpr std::string_view cEvapFluidCooler_SingleSpeed("EvaporativeFluidCooler:SingleSpeed");
99 : constexpr std::string_view cEvapFluidCooler_TwoSpeed("EvaporativeFluidCooler:TwoSpeed");
100 : constexpr std::array<std::string_view, static_cast<int>(CapacityControl::Num)> controlNamesUC = {"FANCYCLING", "FLUIDBYPASS"};
101 : constexpr std::array<std::string_view, static_cast<int>(EvapLoss::Num)> evapLossNamesUC = {"LOSSFACTOR", "SATURATEDEXIT"};
102 : constexpr std::array<std::string_view, static_cast<int>(Blowdown::Num)> blowDownNamesUC = {"CONCENTRATIONRATIO", "SCHEDULEDRATE"};
103 :
104 : EvapFluidCoolerSpecs *
105 3 : EvapFluidCoolerSpecs::factory(EnergyPlusData &state, DataPlant::PlantEquipmentType objectType, std::string const &objectName)
106 : {
107 : // Process the input data if it hasn't been done already
108 3 : if (state.dataEvapFluidCoolers->GetEvapFluidCoolerInputFlag) {
109 3 : GetEvapFluidCoolerInput(state);
110 3 : state.dataEvapFluidCoolers->GetEvapFluidCoolerInputFlag = false;
111 : }
112 :
113 : // Now look for this particular object
114 3 : for (auto &thisEFC : state.dataEvapFluidCoolers->SimpleEvapFluidCooler) {
115 3 : if ((thisEFC.Type == objectType) && (thisEFC.Name == objectName)) {
116 3 : return &thisEFC;
117 : }
118 : }
119 : // If we didn't find it, fatal
120 : ShowFatalError(state, "LocalEvapFluidCoolerFactory: Error getting inputs for object named: " + objectName); // LCOV_EXCL_LINE
121 : // Shut up the compiler
122 : return nullptr; // LCOV_EXCL_LINE
123 : }
124 :
125 3 : void GetEvapFluidCoolerInput(EnergyPlusData &state)
126 : {
127 :
128 : // SUBROUTINE INFORMATION:
129 : // AUTHOR: Chandan Sharma
130 : // DATE WRITTEN: May 2009
131 : // MODIFIED Chandan Sharma, April 2010
132 : // RE-ENGINEERED na
133 :
134 : // PURPOSE OF THIS SUBROUTINE:
135 : // Obtains input data for evaporative fluid coolers and stores it in SimpleEvapFluidCooler data structure.
136 :
137 : // METHODOLOGY EMPLOYED:
138 : // Uses "Get" routines to read in the data.
139 :
140 : // REFERENCES:
141 : // Based on GetTowerInput subroutine from Don Shirey, Jan 2001 and Sept/Oct 2002
142 : // B.A. Qureshi and S.M. Zubair , Prediction of evaporation losses in evaporative fluid coolers
143 : // Applied thermal engineering 27 (2007) 520-527
144 :
145 : int NumAlphas; // Number of elements in the alpha array
146 : int NumNums; // Number of elements in the numeric array
147 : int IOStat; // IO Status when calling get input subroutine
148 3 : bool ErrorsFound(false); // Logical flag set .TRUE. if errors found while getting input data
149 6 : Array1D<Real64> NumArray(25); // Numeric input data array
150 6 : Array1D_string AlphArray(13); // Character string input data array
151 :
152 : // Get number of all evaporative fluid coolers specified in the input data file (idf)
153 3 : int NumSingleSpeedEvapFluidCoolers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cEvapFluidCooler_SingleSpeed);
154 3 : int NumTwoSpeedEvapFluidCoolers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cEvapFluidCooler_TwoSpeed);
155 3 : int NumSimpleEvapFluidCoolers = NumSingleSpeedEvapFluidCoolers + NumTwoSpeedEvapFluidCoolers;
156 :
157 3 : if (NumSimpleEvapFluidCoolers <= 0)
158 0 : ShowFatalError(state,
159 : "No evaporative fluid cooler objects found in input, however, a branch object has specified an evaporative fluid cooler. "
160 : "Search the input for evaporative fluid cooler to determine the cause for this error.");
161 :
162 : // Allocate data structures to hold evaporative fluid cooler input data,
163 : // report data and evaporative fluid cooler inlet conditions
164 3 : state.dataEvapFluidCoolers->SimpleEvapFluidCooler.allocate(NumSimpleEvapFluidCoolers);
165 3 : state.dataEvapFluidCoolers->UniqueSimpleEvapFluidCoolerNames.reserve(NumSimpleEvapFluidCoolers);
166 :
167 : // Load data structures with evaporative fluid cooler input data
168 3 : state.dataIPShortCut->cCurrentModuleObject = cEvapFluidCooler_SingleSpeed;
169 4 : for (int SingleSpeedEvapFluidCoolerNumber = 1; SingleSpeedEvapFluidCoolerNumber <= NumSingleSpeedEvapFluidCoolers;
170 : ++SingleSpeedEvapFluidCoolerNumber) {
171 1 : int EvapFluidCoolerNum = SingleSpeedEvapFluidCoolerNumber;
172 5 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
173 1 : state.dataIPShortCut->cCurrentModuleObject,
174 : SingleSpeedEvapFluidCoolerNumber,
175 : AlphArray,
176 : NumAlphas,
177 : NumArray,
178 : NumNums,
179 : IOStat,
180 : _,
181 1 : state.dataIPShortCut->lAlphaFieldBlanks,
182 1 : state.dataIPShortCut->cAlphaFieldNames,
183 1 : state.dataIPShortCut->cNumericFieldNames);
184 3 : GlobalNames::VerifyUniqueInterObjectName(state,
185 1 : state.dataEvapFluidCoolers->UniqueSimpleEvapFluidCoolerNames,
186 1 : AlphArray(1),
187 1 : state.dataIPShortCut->cCurrentModuleObject,
188 1 : state.dataIPShortCut->cAlphaFieldNames(1),
189 : ErrorsFound);
190 :
191 1 : auto &thisEFC = state.dataEvapFluidCoolers->SimpleEvapFluidCooler(EvapFluidCoolerNum);
192 :
193 1 : thisEFC.Name = AlphArray(1);
194 1 : thisEFC.EvapFluidCoolerType = state.dataIPShortCut->cCurrentModuleObject;
195 1 : thisEFC.Type = DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd;
196 1 : thisEFC.EvapFluidCoolerMassFlowRateMultiplier = 2.5;
197 1 : thisEFC.WaterInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
198 1 : AlphArray(2),
199 : ErrorsFound,
200 : DataLoopNode::ConnectionObjectType::EvaporativeFluidCoolerSingleSpeed,
201 1 : AlphArray(1),
202 : DataLoopNode::NodeFluidType::Water,
203 : DataLoopNode::ConnectionType::Inlet,
204 : NodeInputManager::CompFluidStream::Primary,
205 1 : DataLoopNode::ObjectIsNotParent);
206 1 : thisEFC.WaterOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
207 1 : AlphArray(3),
208 : ErrorsFound,
209 : DataLoopNode::ConnectionObjectType::EvaporativeFluidCoolerSingleSpeed,
210 1 : AlphArray(1),
211 : DataLoopNode::NodeFluidType::Water,
212 : DataLoopNode::ConnectionType::Outlet,
213 : NodeInputManager::CompFluidStream::Primary,
214 1 : DataLoopNode::ObjectIsNotParent);
215 3 : BranchNodeConnections::TestCompSet(
216 2 : state, state.dataIPShortCut->cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Chilled Water Nodes");
217 1 : thisEFC.HighSpeedAirFlowRate = NumArray(1);
218 1 : if (thisEFC.HighSpeedAirFlowRate == DataSizing::AutoSize) {
219 0 : thisEFC.HighSpeedAirFlowRateWasAutoSized = true;
220 : }
221 1 : thisEFC.HighSpeedFanPower = NumArray(2);
222 1 : if (thisEFC.HighSpeedFanPower == DataSizing::AutoSize) {
223 0 : thisEFC.HighSpeedFanPowerWasAutoSized = true;
224 : }
225 1 : thisEFC.DesignSprayWaterFlowRate = NumArray(3);
226 1 : thisEFC.HeatRejectCapNomCapSizingRatio = NumArray(4);
227 1 : thisEFC.HighSpeedStandardDesignCapacity = NumArray(5);
228 1 : thisEFC.HighSpeedEvapFluidCoolerUA = NumArray(6);
229 1 : if (thisEFC.HighSpeedEvapFluidCoolerUA == DataSizing::AutoSize) {
230 0 : thisEFC.HighSpeedEvapFluidCoolerUAWasAutoSized = true;
231 : }
232 1 : thisEFC.DesignWaterFlowRate = NumArray(7);
233 1 : if (thisEFC.DesignWaterFlowRate == DataSizing::AutoSize) {
234 0 : thisEFC.DesignWaterFlowRateWasAutoSized = true;
235 : }
236 1 : thisEFC.HighSpeedUserSpecifiedDesignCapacity = NumArray(8);
237 1 : thisEFC.DesignEnteringWaterTemp = NumArray(9);
238 1 : thisEFC.DesignEnteringAirTemp = NumArray(10);
239 1 : thisEFC.DesignEnteringAirWetBulbTemp = NumArray(11);
240 :
241 1 : if (state.dataIPShortCut->lAlphaFieldBlanks(4) || AlphArray(4).empty()) {
242 0 : ShowSevereError(
243 0 : state, state.dataIPShortCut->cCurrentModuleObject + ", \"" + thisEFC.Name + "\" Performance input method is not specified. ");
244 0 : ErrorsFound = true;
245 : } else {
246 1 : thisEFC.PerformanceInputMethod = AlphArray(4);
247 : }
248 :
249 : // outdoor air inlet node
250 1 : if (state.dataIPShortCut->lAlphaFieldBlanks(5)) {
251 1 : thisEFC.OutdoorAirInletNodeNum = 0;
252 : } else {
253 0 : thisEFC.OutdoorAirInletNodeNum =
254 0 : NodeInputManager::GetOnlySingleNode(state,
255 0 : AlphArray(5),
256 : ErrorsFound,
257 : DataLoopNode::ConnectionObjectType::EvaporativeFluidCoolerSingleSpeed,
258 : thisEFC.Name,
259 : DataLoopNode::NodeFluidType::Air,
260 : DataLoopNode::ConnectionType::OutsideAirReference,
261 : NodeInputManager::CompFluidStream::Primary,
262 0 : DataLoopNode::ObjectIsNotParent);
263 0 : if (!OutAirNodeManager::CheckOutAirNodeNumber(state, thisEFC.OutdoorAirInletNodeNum)) {
264 0 : ShowSevereError(state,
265 0 : state.dataIPShortCut->cCurrentModuleObject + ", \"" + thisEFC.Name +
266 0 : "\" Outdoor Air Inlet DataLoopNode::Node Name not valid Outdoor Air DataLoopNode::Node= " + AlphArray(5));
267 0 : ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:DataLoopNode::Node.");
268 0 : ErrorsFound = true;
269 : }
270 : }
271 :
272 : // fluid bypass for single speed evaporative fluid cooler
273 1 : if (state.dataIPShortCut->lAlphaFieldBlanks(6) || AlphArray(6).empty()) {
274 1 : thisEFC.capacityControl = CapacityControl::FanCycling; // FanCycling
275 : } else {
276 0 : thisEFC.capacityControl =
277 0 : static_cast<CapacityControl>(getEnumerationValue(controlNamesUC, UtilityRoutines::MakeUPPERCase(AlphArray(6))));
278 0 : if (thisEFC.capacityControl == CapacityControl::Invalid) {
279 0 : thisEFC.capacityControl = CapacityControl::FanCycling;
280 0 : ShowWarningError(state,
281 0 : state.dataIPShortCut->cCurrentModuleObject + ", \"" + thisEFC.Name +
282 : "\" The Capacity Control is not specified correctly. The default Fan Cycling is used.");
283 : }
284 : }
285 :
286 1 : thisEFC.SizFac = NumArray(12); // N11 \field Sizing Factor
287 1 : if (thisEFC.SizFac <= 0.0) thisEFC.SizFac = 1.0;
288 :
289 1 : if (AlphArray(7).empty()) {
290 1 : thisEFC.EvapLossMode = EvapLoss::ByMoistTheory;
291 : } else {
292 0 : thisEFC.EvapLossMode = static_cast<EvapLoss>(getEnumerationValue(evapLossNamesUC, UtilityRoutines::MakeUPPERCase(AlphArray(7))));
293 0 : if (thisEFC.EvapLossMode == EvapLoss::Invalid) {
294 0 : ShowSevereError(state, "Invalid, " + state.dataIPShortCut->cAlphaFieldNames(7) + " = " + AlphArray(7));
295 0 : ShowContinueError(state, "Entered in " + state.dataIPShortCut->cCurrentModuleObject + " = " + AlphArray(1));
296 0 : ErrorsFound = true;
297 : }
298 : }
299 :
300 1 : thisEFC.UserEvapLossFactor = NumArray(13); // N13 , \field Evaporation Loss Factor
301 1 : if ((NumNums < 13) && (thisEFC.UserEvapLossFactor == 0.0)) {
302 : // assume Evaporation loss factor not entered and should be calculated
303 1 : if ((state.dataEnvrn->OutRelHumValue >= 0.1) && (state.dataEnvrn->OutRelHumValue <= 0.7)) {
304 : // Use correlation by B.A. Qureshi and S.M. Zubair if within these limits
305 0 : thisEFC.UserEvapLossFactor =
306 0 : (113.0 - 8.417 * state.dataEnvrn->OutRelHumValue + 1.6147 * state.dataEnvrn->OutDryBulbTemp) * 1.0e-5;
307 : } else { // Inlet conditions are out of the limit of correlation; An approximate default value of loss factor is used
308 1 : thisEFC.UserEvapLossFactor = 0.2;
309 : }
310 : }
311 :
312 1 : thisEFC.DriftLossFraction = NumArray(14) / 100.0; // N14, \field Drift Loss Percent
313 :
314 1 : if ((NumNums < 13) && (thisEFC.DriftLossFraction == 0.0)) {
315 : // assume Drift loss not entered and should be defaulted
316 1 : thisEFC.DriftLossFraction = 0.008 / 100.0;
317 : }
318 1 : thisEFC.ConcentrationRatio = NumArray(15); // N15, \field Blowdown Concentration Ratio
319 :
320 1 : if (AlphArray(8).empty()) {
321 1 : thisEFC.BlowdownMode = Blowdown::ByConcentration;
322 1 : if ((NumNums < 15) && (thisEFC.ConcentrationRatio == 0.0)) {
323 : // assume Concentration ratio was omitted and should be defaulted
324 1 : thisEFC.ConcentrationRatio = 3.0;
325 : }
326 : } else {
327 0 : thisEFC.BlowdownMode = static_cast<Blowdown>(getEnumerationValue(blowDownNamesUC, UtilityRoutines::MakeUPPERCase(AlphArray(8))));
328 0 : if (thisEFC.BlowdownMode == Blowdown::Invalid) {
329 0 : ShowSevereError(state, "Invalid, " + state.dataIPShortCut->cAlphaFieldNames(8) + " = " + AlphArray(8));
330 0 : ShowContinueError(state, "Entered in " + state.dataIPShortCut->cCurrentModuleObject + " =" + AlphArray(1));
331 0 : ErrorsFound = true;
332 : }
333 : }
334 :
335 1 : thisEFC.SchedIDBlowdown = ScheduleManager::GetScheduleIndex(state, AlphArray(9));
336 1 : if ((thisEFC.SchedIDBlowdown == 0) && (thisEFC.BlowdownMode == Blowdown::BySchedule)) {
337 0 : ShowSevereError(state, "Invalid, " + state.dataIPShortCut->cAlphaFieldNames(9) + " = " + AlphArray(9));
338 0 : ShowContinueError(state, "Entered in " + state.dataIPShortCut->cCurrentModuleObject + " =" + AlphArray(1));
339 0 : ErrorsFound = true;
340 : }
341 :
342 1 : if (AlphArray(10).empty()) {
343 1 : thisEFC.SuppliedByWaterSystem = false;
344 : } else { // water from storage tank
345 0 : WaterManager::SetupTankDemandComponent(state,
346 0 : AlphArray(1),
347 0 : state.dataIPShortCut->cCurrentModuleObject,
348 0 : AlphArray(10),
349 : ErrorsFound,
350 : thisEFC.WaterTankID,
351 : thisEFC.WaterTankDemandARRID);
352 0 : thisEFC.SuppliedByWaterSystem = true;
353 : }
354 :
355 : // Check various inputs to ensure that all the required variables are specified.
356 :
357 1 : if (thisEFC.DesignSprayWaterFlowRate <= 0.0) {
358 0 : ShowSevereError(
359 : state,
360 0 : state.dataIPShortCut->cCurrentModuleObject + " \"" + thisEFC.Name +
361 : "\". Evaporative fluid cooler input requires a design spray water flow rate greater than zero for all performance "
362 : "input methods.");
363 0 : ErrorsFound = true;
364 : }
365 1 : if (thisEFC.HighSpeedAirFlowRate <= 0.0 && thisEFC.HighSpeedAirFlowRate != DataSizing::AutoSize) {
366 0 : ShowSevereError(state,
367 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
368 0 : state.dataIPShortCut->cNumericFieldNames(1) + "\", entered value <= 0.0, but must be > 0 for " +
369 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
370 0 : ErrorsFound = true;
371 : }
372 1 : if (thisEFC.HighSpeedFanPower <= 0.0 && thisEFC.HighSpeedFanPower != DataSizing::AutoSize) {
373 0 : ShowSevereError(state,
374 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
375 0 : state.dataIPShortCut->cNumericFieldNames(2) + "\", entered value <= 0.0, but must be > 0 for " +
376 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
377 0 : ErrorsFound = true;
378 : }
379 :
380 1 : if (UtilityRoutines::SameString(AlphArray(4), "UFACTORTIMESAREAANDDESIGNWATERFLOWRATE")) {
381 0 : thisEFC.PerformanceInputMethod_Num = PIM::UFactor;
382 0 : if (thisEFC.HighSpeedEvapFluidCoolerUA <= 0.0 && thisEFC.HighSpeedEvapFluidCoolerUA != DataSizing::AutoSize) {
383 0 : ShowSevereError(state,
384 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
385 0 : state.dataIPShortCut->cNumericFieldNames(6) + "\", entered value <= 0.0, but must be > 0 for " +
386 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
387 0 : ErrorsFound = true;
388 : }
389 0 : if (thisEFC.DesignWaterFlowRate <= 0.0 && thisEFC.DesignWaterFlowRate != DataSizing::AutoSize) {
390 0 : ShowSevereError(state,
391 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
392 0 : state.dataIPShortCut->cNumericFieldNames(7) + "\", entered value <= 0.0, but must be > 0 for " +
393 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
394 0 : ErrorsFound = true;
395 : }
396 1 : } else if (UtilityRoutines::SameString(AlphArray(4), "STANDARDDESIGNCAPACITY")) {
397 0 : thisEFC.PerformanceInputMethod_Num = PIM::StandardDesignCapacity;
398 0 : if (thisEFC.HighSpeedStandardDesignCapacity <= 0.0) {
399 0 : ShowSevereError(state,
400 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
401 0 : state.dataIPShortCut->cNumericFieldNames(5) + "\", entered value <= 0.0, but must be > 0 for " +
402 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
403 0 : ErrorsFound = true;
404 : }
405 1 : } else if (UtilityRoutines::SameString(AlphArray(4), "USERSPECIFIEDDESIGNCAPACITY")) {
406 1 : thisEFC.PerformanceInputMethod_Num = PIM::UserSpecifiedDesignCapacity;
407 1 : if (thisEFC.DesignWaterFlowRate <= 0.0 && thisEFC.DesignWaterFlowRate != DataSizing::AutoSize) {
408 0 : ShowSevereError(state,
409 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
410 0 : state.dataIPShortCut->cNumericFieldNames(7) + "\", entered value <= 0.0, but must be > 0 for " +
411 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
412 0 : ErrorsFound = true;
413 : }
414 1 : if (thisEFC.HighSpeedUserSpecifiedDesignCapacity <= 0.0) {
415 0 : ShowSevereError(state,
416 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
417 0 : state.dataIPShortCut->cNumericFieldNames(8) + "\", entered value <= 0.0, but must be > 0 for " +
418 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
419 0 : ErrorsFound = true;
420 : }
421 1 : if (thisEFC.DesignEnteringWaterTemp <= 0.0) {
422 0 : ShowSevereError(state,
423 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
424 0 : state.dataIPShortCut->cNumericFieldNames(9) + "\", entered value <= 0.0, but must be >0 for " +
425 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
426 0 : ErrorsFound = true;
427 : }
428 1 : if (thisEFC.DesignEnteringAirTemp <= 0.0) {
429 0 : ShowSevereError(state,
430 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
431 0 : state.dataIPShortCut->cNumericFieldNames(10) + "\", entered value <= 0.0, but must be >0 for " +
432 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
433 0 : ErrorsFound = true;
434 : }
435 1 : if (thisEFC.DesignEnteringAirWetBulbTemp <= 0.0) {
436 0 : ShowSevereError(state,
437 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
438 0 : state.dataIPShortCut->cNumericFieldNames(11) + "\", entered value <= 0.0, but must be >0 for " +
439 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
440 0 : ErrorsFound = true;
441 : }
442 1 : if (thisEFC.DesignEnteringWaterTemp <= thisEFC.DesignEnteringAirWetBulbTemp) {
443 0 : ShowSevereError(state,
444 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", " +
445 0 : state.dataIPShortCut->cNumericFieldNames(9) + " must be greater than " +
446 0 : state.dataIPShortCut->cNumericFieldNames(11) + '.');
447 0 : ErrorsFound = true;
448 : }
449 1 : if (thisEFC.DesignEnteringAirTemp <= thisEFC.DesignEnteringAirWetBulbTemp) {
450 0 : ShowSevereError(state,
451 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", " +
452 0 : state.dataIPShortCut->cNumericFieldNames(10) + " must be greater than " +
453 0 : state.dataIPShortCut->cNumericFieldNames(11) + '.');
454 0 : ErrorsFound = true;
455 : }
456 : } else { // Evaporative fluid cooler performance input method is not specified as a valid "choice"
457 0 : ShowSevereError(state,
458 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
459 : "\". Evaporative fluid cooler Performance Input Method must be \"UFactorTimesAreaAndDesignWaterFlowRate\" or "
460 : "\"StandardDesignCapacity\" or \"UserSpecifiedDesignCapacity\".");
461 0 : ShowContinueError(state, "Evaporative fluid cooler Performance Input Method currently specified as: " + AlphArray(4));
462 0 : ErrorsFound = true;
463 : }
464 :
465 : } // End Single-Speed Evaporative Fluid Cooler Loop
466 :
467 3 : state.dataIPShortCut->cCurrentModuleObject = cEvapFluidCooler_TwoSpeed;
468 5 : for (int TwoSpeedEvapFluidCoolerNumber = 1; TwoSpeedEvapFluidCoolerNumber <= NumTwoSpeedEvapFluidCoolers; ++TwoSpeedEvapFluidCoolerNumber) {
469 2 : int EvapFluidCoolerNum = NumSingleSpeedEvapFluidCoolers + TwoSpeedEvapFluidCoolerNumber;
470 10 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
471 2 : state.dataIPShortCut->cCurrentModuleObject,
472 : TwoSpeedEvapFluidCoolerNumber,
473 : AlphArray,
474 : NumAlphas,
475 : NumArray,
476 : NumNums,
477 : IOStat,
478 : _,
479 2 : state.dataIPShortCut->lAlphaFieldBlanks,
480 2 : state.dataIPShortCut->cAlphaFieldNames,
481 2 : state.dataIPShortCut->cNumericFieldNames);
482 :
483 6 : GlobalNames::VerifyUniqueInterObjectName(state,
484 2 : state.dataEvapFluidCoolers->UniqueSimpleEvapFluidCoolerNames,
485 2 : AlphArray(1),
486 2 : state.dataIPShortCut->cCurrentModuleObject,
487 2 : state.dataIPShortCut->cAlphaFieldNames(1),
488 : ErrorsFound);
489 :
490 2 : auto &thisEFC = state.dataEvapFluidCoolers->SimpleEvapFluidCooler(EvapFluidCoolerNum);
491 :
492 2 : thisEFC.Name = AlphArray(1);
493 2 : thisEFC.EvapFluidCoolerType = state.dataIPShortCut->cCurrentModuleObject;
494 2 : thisEFC.Type = DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd;
495 2 : thisEFC.EvapFluidCoolerMassFlowRateMultiplier = 2.5;
496 2 : thisEFC.WaterInletNodeNum = NodeInputManager::GetOnlySingleNode(state,
497 2 : AlphArray(2),
498 : ErrorsFound,
499 : DataLoopNode::ConnectionObjectType::EvaporativeFluidCoolerTwoSpeed,
500 2 : AlphArray(1),
501 : DataLoopNode::NodeFluidType::Water,
502 : DataLoopNode::ConnectionType::Inlet,
503 : NodeInputManager::CompFluidStream::Primary,
504 2 : DataLoopNode::ObjectIsNotParent);
505 2 : thisEFC.WaterOutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
506 2 : AlphArray(3),
507 : ErrorsFound,
508 : DataLoopNode::ConnectionObjectType::EvaporativeFluidCoolerTwoSpeed,
509 2 : AlphArray(1),
510 : DataLoopNode::NodeFluidType::Water,
511 : DataLoopNode::ConnectionType::Outlet,
512 : NodeInputManager::CompFluidStream::Primary,
513 2 : DataLoopNode::ObjectIsNotParent);
514 6 : BranchNodeConnections::TestCompSet(
515 4 : state, state.dataIPShortCut->cCurrentModuleObject, AlphArray(1), AlphArray(2), AlphArray(3), "Chilled Water Nodes");
516 :
517 2 : thisEFC.HighSpeedAirFlowRate = NumArray(1);
518 2 : if (thisEFC.HighSpeedAirFlowRate == DataSizing::AutoSize) {
519 2 : thisEFC.HighSpeedAirFlowRateWasAutoSized = true;
520 : }
521 2 : thisEFC.HighSpeedFanPower = NumArray(2);
522 2 : if (thisEFC.HighSpeedFanPower == DataSizing::AutoSize) {
523 2 : thisEFC.HighSpeedFanPowerWasAutoSized = true;
524 : }
525 2 : thisEFC.LowSpeedAirFlowRate = NumArray(3);
526 2 : if (thisEFC.LowSpeedAirFlowRate == DataSizing::AutoSize) {
527 2 : thisEFC.LowSpeedAirFlowRateWasAutoSized = true;
528 : }
529 2 : thisEFC.LowSpeedAirFlowRateSizingFactor = NumArray(4);
530 2 : thisEFC.LowSpeedFanPower = NumArray(5);
531 2 : if (thisEFC.LowSpeedFanPower == DataSizing::AutoSize) {
532 2 : thisEFC.LowSpeedFanPowerWasAutoSized = true;
533 : }
534 2 : thisEFC.LowSpeedFanPowerSizingFactor = NumArray(6);
535 2 : thisEFC.DesignSprayWaterFlowRate = NumArray(7);
536 2 : thisEFC.HeatRejectCapNomCapSizingRatio = NumArray(8);
537 2 : thisEFC.HighSpeedStandardDesignCapacity = NumArray(9);
538 2 : thisEFC.LowSpeedStandardDesignCapacity = NumArray(10);
539 2 : thisEFC.HighSpeedEvapFluidCoolerUA = NumArray(12);
540 2 : if (thisEFC.HighSpeedEvapFluidCoolerUA == DataSizing::AutoSize) {
541 2 : thisEFC.HighSpeedEvapFluidCoolerUAWasAutoSized = true;
542 : }
543 2 : thisEFC.LowSpeedEvapFluidCoolerUA = NumArray(13);
544 2 : if (thisEFC.LowSpeedEvapFluidCoolerUA == DataSizing::AutoSize) {
545 2 : thisEFC.LowSpeedEvapFluidCoolerUAWasAutoSized = true;
546 : }
547 2 : thisEFC.LowSpeedEvapFluidCoolerUASizingFactor = NumArray(14);
548 2 : thisEFC.DesignWaterFlowRate = NumArray(15);
549 2 : if (thisEFC.DesignWaterFlowRate == DataSizing::AutoSize) {
550 2 : thisEFC.DesignWaterFlowRateWasAutoSized = true;
551 : }
552 2 : thisEFC.HighSpeedUserSpecifiedDesignCapacity = NumArray(16);
553 2 : thisEFC.LowSpeedUserSpecifiedDesignCapacity = NumArray(17);
554 2 : thisEFC.DesignEnteringWaterTemp = NumArray(19);
555 2 : thisEFC.DesignEnteringAirTemp = NumArray(20);
556 2 : thisEFC.DesignEnteringAirWetBulbTemp = NumArray(21);
557 :
558 2 : if (state.dataIPShortCut->lAlphaFieldBlanks(4)) {
559 0 : ShowSevereError(
560 0 : state, state.dataIPShortCut->cCurrentModuleObject + ", \"" + thisEFC.Name + "\" Performance input method is not specified. ");
561 0 : ErrorsFound = true;
562 : } else {
563 2 : thisEFC.PerformanceInputMethod = AlphArray(4);
564 : }
565 :
566 : // outdoor air inlet node
567 2 : if (state.dataIPShortCut->lAlphaFieldBlanks(5)) {
568 2 : thisEFC.OutdoorAirInletNodeNum = 0;
569 : } else {
570 0 : thisEFC.OutdoorAirInletNodeNum =
571 0 : NodeInputManager::GetOnlySingleNode(state,
572 0 : AlphArray(5),
573 : ErrorsFound,
574 : DataLoopNode::ConnectionObjectType::EvaporativeFluidCoolerTwoSpeed,
575 : thisEFC.Name,
576 : DataLoopNode::NodeFluidType::Air,
577 : DataLoopNode::ConnectionType::OutsideAirReference,
578 : NodeInputManager::CompFluidStream::Primary,
579 0 : DataLoopNode::ObjectIsNotParent);
580 0 : if (!OutAirNodeManager::CheckOutAirNodeNumber(state, thisEFC.OutdoorAirInletNodeNum)) {
581 0 : ShowSevereError(state,
582 0 : state.dataIPShortCut->cCurrentModuleObject + ", \"" + thisEFC.Name +
583 0 : "\" Outdoor Air Inlet DataLoopNode::Node Name not valid Outdoor Air DataLoopNode::Node= " + AlphArray(5));
584 0 : ShowContinueError(state, "...does not appear in an OutdoorAir:NodeList or as an OutdoorAir:DataLoopNode::Node.");
585 0 : ErrorsFound = true;
586 : }
587 : }
588 :
589 2 : thisEFC.SizFac = NumArray(22); // N16 \field Sizing Factor
590 2 : if (thisEFC.SizFac <= 0.0) thisEFC.SizFac = 1.0;
591 :
592 2 : if (state.dataIPShortCut->lAlphaFieldBlanks(6)) {
593 1 : thisEFC.EvapLossMode = EvapLoss::ByMoistTheory;
594 : } else {
595 1 : thisEFC.EvapLossMode = static_cast<EvapLoss>(getEnumerationValue(evapLossNamesUC, UtilityRoutines::MakeUPPERCase(AlphArray(6))));
596 1 : if (thisEFC.EvapLossMode == EvapLoss::Invalid) {
597 0 : ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(6) + " = " + AlphArray(6));
598 0 : ShowContinueError(state, "Entered in " + state.dataIPShortCut->cCurrentModuleObject + " = " + AlphArray(1));
599 0 : ErrorsFound = true;
600 : }
601 : }
602 :
603 2 : thisEFC.UserEvapLossFactor = NumArray(23); // N23 , \field Evaporation Loss Factor
604 2 : if ((NumNums < 23) && (thisEFC.UserEvapLossFactor == 0.0)) {
605 : // assume Evaporation loss factor not entered and should be calculated
606 1 : if ((state.dataEnvrn->OutRelHumValue >= 0.1) && (state.dataEnvrn->OutRelHumValue <= 0.7)) {
607 : // Use correlation by B.A. Qureshi and S.M. Zubair if within these limits
608 0 : thisEFC.UserEvapLossFactor =
609 0 : (113.0 - 8.417 * state.dataEnvrn->OutRelHumValue + 1.6147 * state.dataEnvrn->OutDryBulbTemp) * 1.0e-5;
610 : } else { // Inlet conditions are out of the limit of correlation; An approximate default value of loss factor is used
611 1 : thisEFC.UserEvapLossFactor = 0.2;
612 : }
613 : }
614 2 : thisEFC.DriftLossFraction = NumArray(24) / 100.0; // N24, \field Drift Loss Percent
615 2 : if ((NumNums < 24) && (thisEFC.DriftLossFraction == 0.0)) {
616 : // assume Drift loss not entered and should be defaulted
617 1 : thisEFC.DriftLossFraction = 0.008 / 100.0;
618 : }
619 :
620 2 : thisEFC.ConcentrationRatio = NumArray(25); // N25, \field Blowdown Concentration Ratio
621 :
622 2 : if (state.dataIPShortCut->lAlphaFieldBlanks(7)) {
623 1 : thisEFC.BlowdownMode = Blowdown::ByConcentration;
624 1 : if ((NumNums < 25) && (thisEFC.ConcentrationRatio == 0.0)) {
625 : // assume Concentration ratio was omitted and should be defaulted
626 1 : thisEFC.ConcentrationRatio = 3.0;
627 : }
628 : } else {
629 1 : thisEFC.BlowdownMode = static_cast<Blowdown>(getEnumerationValue(blowDownNamesUC, UtilityRoutines::MakeUPPERCase(AlphArray(7))));
630 1 : if (thisEFC.BlowdownMode == Blowdown::Invalid) {
631 0 : ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(7) + " = " + AlphArray(7));
632 0 : ShowContinueError(state, "Entered in " + state.dataIPShortCut->cCurrentModuleObject + " = " + AlphArray(1));
633 0 : ErrorsFound = true;
634 : }
635 : }
636 :
637 2 : thisEFC.SchedIDBlowdown = ScheduleManager::GetScheduleIndex(state, AlphArray(8));
638 2 : if ((thisEFC.SchedIDBlowdown == 0) && (thisEFC.BlowdownMode == Blowdown::BySchedule)) {
639 0 : ShowSevereError(state, "Invalid " + state.dataIPShortCut->cAlphaFieldNames(8) + " = " + AlphArray(8));
640 0 : ShowContinueError(state, "Entered in " + state.dataIPShortCut->cCurrentModuleObject + " = " + AlphArray(1));
641 0 : ErrorsFound = true;
642 : }
643 :
644 2 : if (state.dataIPShortCut->lAlphaFieldBlanks(9)) {
645 2 : thisEFC.SuppliedByWaterSystem = false;
646 : } else { // water from storage tank
647 0 : WaterManager::SetupTankDemandComponent(state,
648 0 : AlphArray(1),
649 0 : state.dataIPShortCut->cCurrentModuleObject,
650 0 : AlphArray(9),
651 : ErrorsFound,
652 : thisEFC.WaterTankID,
653 : thisEFC.WaterTankDemandARRID);
654 0 : thisEFC.SuppliedByWaterSystem = true;
655 : }
656 :
657 : // Check various inputs to ensure that all the required variables are specified.
658 :
659 2 : if (thisEFC.DesignSprayWaterFlowRate <= 0.0) {
660 0 : ShowSevereError(
661 : state,
662 0 : state.dataIPShortCut->cCurrentModuleObject + " \"" + thisEFC.Name +
663 : "\". Evaporative fluid cooler input requires a design spray water flow rate greater than zero for all performance "
664 : "input methods.");
665 0 : ErrorsFound = true;
666 : }
667 2 : if (thisEFC.HighSpeedAirFlowRate <= 0.0 && thisEFC.HighSpeedAirFlowRate != DataSizing::AutoSize) {
668 0 : ShowSevereError(
669 : state,
670 0 : state.dataIPShortCut->cCurrentModuleObject + "= \"" + thisEFC.Name +
671 : "\". Evaporative fluid cooler input requires design air flow rate at high fan speed to be greater than zero for all "
672 : "performance input methods.");
673 0 : ErrorsFound = true;
674 : }
675 2 : if (thisEFC.LowSpeedAirFlowRate <= 0.0 && thisEFC.LowSpeedAirFlowRate != DataSizing::AutoSize) {
676 0 : ShowSevereError(
677 : state,
678 0 : state.dataIPShortCut->cCurrentModuleObject + "= \"" + thisEFC.Name +
679 : "\". Evaporative fluid cooler input requires design air flow rate at low fan speed to be greater than zero for all "
680 : "performance input methods.");
681 0 : ErrorsFound = true;
682 : }
683 : // High speed air flow rate must be greater than low speed air flow rate.
684 : // Can't tell yet if autosized, check later in InitEvapFluidCooler.
685 2 : if (thisEFC.HighSpeedAirFlowRate <= thisEFC.LowSpeedAirFlowRate && thisEFC.HighSpeedAirFlowRate != DataSizing::AutoSize) {
686 0 : ShowSevereError(
687 : state,
688 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
689 : "\". Evaporative fluid cooler air flow rate at low fan speed must be less than the air flow rate at high fan speed.");
690 0 : ErrorsFound = true;
691 : }
692 2 : if (thisEFC.HighSpeedFanPower <= 0.0 && thisEFC.HighSpeedFanPower != DataSizing::AutoSize) {
693 0 : ShowSevereError(state,
694 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
695 0 : state.dataIPShortCut->cNumericFieldNames(2) + "\", entered value <= 0.0, but must be > 0 for " +
696 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
697 0 : ErrorsFound = true;
698 : }
699 2 : if (thisEFC.LowSpeedFanPower <= 0.0 && thisEFC.LowSpeedFanPower != DataSizing::AutoSize) {
700 0 : ShowSevereError(state,
701 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
702 0 : state.dataIPShortCut->cNumericFieldNames(5) + "\", entered value <= 0.0, but must be > 0 for " +
703 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
704 0 : ErrorsFound = true;
705 : }
706 2 : if (thisEFC.HighSpeedFanPower <= thisEFC.LowSpeedFanPower && thisEFC.HighSpeedFanPower != DataSizing::AutoSize) {
707 0 : ShowSevereError(state,
708 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
709 : "\". Evaporative fluid cooler low speed fan power must be less than the high speed fan power .");
710 0 : ErrorsFound = true;
711 : }
712 :
713 2 : if (UtilityRoutines::SameString(AlphArray(4), "UFACTORTIMESAREAANDDESIGNWATERFLOWRATE")) {
714 2 : thisEFC.PerformanceInputMethod_Num = PIM::UFactor;
715 2 : if (thisEFC.HighSpeedEvapFluidCoolerUA <= 0.0 && thisEFC.HighSpeedEvapFluidCoolerUA != DataSizing::AutoSize) {
716 0 : ShowSevereError(state,
717 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
718 0 : state.dataIPShortCut->cNumericFieldNames(12) + "\", entered value <= 0.0, but must be > 0 for " +
719 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
720 0 : ErrorsFound = true;
721 : }
722 2 : if (thisEFC.LowSpeedEvapFluidCoolerUA <= 0.0 && thisEFC.LowSpeedEvapFluidCoolerUA != DataSizing::AutoSize) {
723 0 : ShowSevereError(state,
724 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
725 0 : state.dataIPShortCut->cNumericFieldNames(13) + "\", entered value <= 0.0, but must be > 0 for " +
726 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
727 0 : ErrorsFound = true;
728 : }
729 4 : if (thisEFC.HighSpeedEvapFluidCoolerUA <= thisEFC.LowSpeedEvapFluidCoolerUA &&
730 2 : thisEFC.HighSpeedEvapFluidCoolerUA != DataSizing::AutoSize) {
731 0 : ShowSevereError(
732 : state,
733 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
734 : "\". Evaporative fluid cooler U-factor Times Area Value at Low Fan Speed must be less than the U-factor Times "
735 : "Area Value at High Fan Speed.");
736 0 : ErrorsFound = true;
737 : }
738 2 : if (thisEFC.DesignWaterFlowRate <= 0.0 && thisEFC.DesignWaterFlowRate != DataSizing::AutoSize) {
739 0 : ShowSevereError(state,
740 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
741 0 : state.dataIPShortCut->cNumericFieldNames(15) + "\", entered value <= 0.0, but must be > 0 for " +
742 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
743 0 : ErrorsFound = true;
744 : }
745 0 : } else if (UtilityRoutines::SameString(AlphArray(4), "STANDARDDESIGNCAPACITY")) {
746 0 : thisEFC.PerformanceInputMethod_Num = PIM::StandardDesignCapacity;
747 0 : if (thisEFC.HighSpeedStandardDesignCapacity <= 0.0) {
748 0 : ShowSevereError(state,
749 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
750 0 : state.dataIPShortCut->cNumericFieldNames(9) + "\", entered value <= 0.0, but must be > 0 for " +
751 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
752 0 : ErrorsFound = true;
753 : }
754 0 : if (thisEFC.LowSpeedStandardDesignCapacity <= 0.0) {
755 0 : ShowSevereError(state,
756 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
757 0 : state.dataIPShortCut->cNumericFieldNames(10) + "\", entered value <= 0.0, but must be > 0 for " +
758 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
759 0 : ErrorsFound = true;
760 : }
761 0 : if (thisEFC.LowSpeedStandardDesignCapacity >= thisEFC.HighSpeedStandardDesignCapacity) {
762 0 : ShowSevereError(state,
763 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
764 : "\". Low-Speed Standard Design Capacity must be less than the High-Speed Standard Design Capacity.");
765 0 : ErrorsFound = true;
766 : }
767 0 : } else if (UtilityRoutines::SameString(AlphArray(4), "USERSPECIFIEDDESIGNCAPACITY")) {
768 0 : thisEFC.PerformanceInputMethod_Num = PIM::UserSpecifiedDesignCapacity;
769 0 : if (thisEFC.DesignWaterFlowRate <= 0.0 && thisEFC.DesignWaterFlowRate != DataSizing::AutoSize) {
770 0 : ShowSevereError(state,
771 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
772 0 : state.dataIPShortCut->cNumericFieldNames(15) + "\", entered value <= 0.0, but must be > 0 for " +
773 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
774 0 : ErrorsFound = true;
775 : }
776 0 : if (thisEFC.HighSpeedUserSpecifiedDesignCapacity <= 0.0) {
777 0 : ShowSevereError(state,
778 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
779 0 : state.dataIPShortCut->cNumericFieldNames(16) + "\", entered value <= 0.0, but must be > 0 for " +
780 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
781 0 : ErrorsFound = true;
782 : }
783 0 : if (thisEFC.LowSpeedUserSpecifiedDesignCapacity <= 0.0) {
784 0 : ShowSevereError(state,
785 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
786 0 : state.dataIPShortCut->cNumericFieldNames(17) + "\", entered value <= 0.0, but must be > 0 for " +
787 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
788 0 : ErrorsFound = true;
789 : }
790 0 : if (thisEFC.HighSpeedEvapFluidCoolerUA != 0.0) {
791 0 : if (thisEFC.HighSpeedEvapFluidCoolerUA > 0.0) {
792 0 : ShowSevereError(
793 : state,
794 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
795 : "\". UserSpecifiedDesignCapacity performance input method and evaporative fluid cooler UA at high fan speed "
796 : "have been specified.");
797 : } else {
798 0 : ShowSevereError(
799 : state,
800 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
801 : "\". UserSpecifiedDesignCapacity performance input method has been specified and evaporative fluid cooler UA "
802 : "at high fan speed is being autosized.");
803 : }
804 0 : ShowContinueError(state,
805 : "Evaporative fluid cooler UA at high fan speed must be left blank when UserSpecifiedDesignCapacity performance "
806 : "input method is used.");
807 0 : ErrorsFound = true;
808 : }
809 0 : if (thisEFC.LowSpeedEvapFluidCoolerUA != 0.0) {
810 0 : if (thisEFC.LowSpeedEvapFluidCoolerUA > 0.0) {
811 0 : ShowSevereError(
812 : state,
813 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
814 : "\". UserSpecifiedDesignCapacity performance input method and evaporative fluid cooler UA at low fan speed "
815 : "have been specified.");
816 : } else {
817 0 : ShowSevereError(
818 : state,
819 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
820 : "\". UserSpecifiedDesignCapacity performance input method has been specified and evaporative fluid cooler UA "
821 : "at low fan speed is being autosized.");
822 : }
823 0 : ShowContinueError(state,
824 : "Evaporative fluid cooler UA at low fan speed must be left blank when UserSpecifiedDesignCapacity performance "
825 : "input method is used.");
826 0 : ErrorsFound = true;
827 : }
828 0 : if (thisEFC.LowSpeedUserSpecifiedDesignCapacity >= thisEFC.HighSpeedUserSpecifiedDesignCapacity) {
829 0 : ShowSevereError(
830 : state,
831 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
832 : "\". Low-Speed User Specified Design Capacity must be less than the High-Speed User Specified Design Dapacity.");
833 0 : ErrorsFound = true;
834 : }
835 0 : if (thisEFC.DesignEnteringWaterTemp <= 0.0) {
836 0 : ShowSevereError(state,
837 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
838 0 : state.dataIPShortCut->cNumericFieldNames(19) + "\", entered value <= 0.0, but must be >0 for " +
839 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
840 0 : ErrorsFound = true;
841 : }
842 0 : if (thisEFC.DesignEnteringAirTemp <= 0.0) {
843 0 : ShowSevereError(state,
844 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
845 0 : state.dataIPShortCut->cNumericFieldNames(20) + "\", entered value <= 0.0, buy must be >0 for " +
846 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
847 0 : ErrorsFound = true;
848 : }
849 0 : if (thisEFC.DesignEnteringAirWetBulbTemp <= 0.0) {
850 0 : ShowSevereError(state,
851 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", invalid data for \"" +
852 0 : state.dataIPShortCut->cNumericFieldNames(21) + "\", entered value <= 0.0, but must be >0 for " +
853 0 : state.dataIPShortCut->cAlphaFieldNames(4) + " = \"" + AlphArray(4) + "\".");
854 0 : ErrorsFound = true;
855 : }
856 0 : if (thisEFC.DesignEnteringWaterTemp <= thisEFC.DesignEnteringAirWetBulbTemp) {
857 0 : ShowSevereError(state,
858 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", " +
859 0 : state.dataIPShortCut->cNumericFieldNames(19) + " must be greater than " +
860 0 : state.dataIPShortCut->cNumericFieldNames(15) + '.');
861 0 : ErrorsFound = true;
862 : }
863 0 : if (thisEFC.DesignEnteringAirTemp <= thisEFC.DesignEnteringAirWetBulbTemp) {
864 0 : ShowSevereError(state,
865 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + AlphArray(1) + "\", " +
866 0 : state.dataIPShortCut->cNumericFieldNames(20) + " must be greater than " +
867 0 : state.dataIPShortCut->cNumericFieldNames(15) + '.');
868 0 : ErrorsFound = true;
869 : }
870 : } else { // Evaporative fluid cooler performance input method is not specified as a valid "choice"
871 0 : ShowSevereError(state,
872 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + thisEFC.Name +
873 : "\". Evaporative fluid cooler Performance Input Method must be \"UFactorTimesAreaAndDesignWaterFlowRate\" or "
874 : "\"StandardDesignCapacity\" or \"UserSpecifiedDesignCapacity\".");
875 0 : ShowContinueError(state, "Evaporative fluid cooler Performanace Input Method currently specified as: " + AlphArray(4));
876 0 : ErrorsFound = true;
877 : }
878 :
879 : } // End Two-Speed Evaporative Fluid Cooler Loop
880 :
881 3 : if (ErrorsFound) {
882 0 : ShowFatalError(state, "Errors found in getting evaporative fluid cooler input.");
883 : }
884 3 : }
885 :
886 3 : void EvapFluidCoolerSpecs::setupOutputVars(EnergyPlusData &state)
887 : {
888 : // Set up output variables
889 : // CurrentModuleObject='EvaporativeFluidCooler:SingleSpeed'
890 3 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd) {
891 :
892 : // Added for fluid bypass
893 2 : SetupOutputVariable(state,
894 : "Cooling Tower Bypass Fraction",
895 : OutputProcessor::Unit::None,
896 : this->BypassFraction,
897 : OutputProcessor::SOVTimeStepType::System,
898 : OutputProcessor::SOVStoreType::Average,
899 1 : this->Name);
900 : }
901 :
902 : // setup common water reporting for all types of evaporative fluid coolers.
903 : // CurrentModuleObject='EvaporativeFluidCooler:*'
904 3 : if (this->SuppliedByWaterSystem) {
905 0 : SetupOutputVariable(state,
906 : "Cooling Tower Make Up Water Volume Flow Rate",
907 : OutputProcessor::Unit::m3_s,
908 : this->MakeUpVdot,
909 : OutputProcessor::SOVTimeStepType::System,
910 : OutputProcessor::SOVStoreType::Average,
911 0 : this->Name);
912 :
913 0 : SetupOutputVariable(state,
914 : "Cooling Tower Make Up Water Volume",
915 : OutputProcessor::Unit::m3,
916 : this->MakeUpVol,
917 : OutputProcessor::SOVTimeStepType::System,
918 : OutputProcessor::SOVStoreType::Summed,
919 0 : this->Name);
920 :
921 0 : SetupOutputVariable(state,
922 : "Cooling Tower Storage Tank Water Volume Flow Rate",
923 : OutputProcessor::Unit::m3_s,
924 : this->TankSupplyVdot,
925 : OutputProcessor::SOVTimeStepType::System,
926 : OutputProcessor::SOVStoreType::Average,
927 0 : this->Name);
928 :
929 0 : SetupOutputVariable(state,
930 : "Cooling Tower Storage Tank Water Volume",
931 : OutputProcessor::Unit::m3,
932 : this->TankSupplyVol,
933 : OutputProcessor::SOVTimeStepType::System,
934 : OutputProcessor::SOVStoreType::Summed,
935 : this->Name,
936 : _,
937 : "Water",
938 : "HeatRejection",
939 : _,
940 0 : "Plant");
941 :
942 0 : SetupOutputVariable(state,
943 : "Cooling Tower Starved Storage Tank Water Volume Flow Rate",
944 : OutputProcessor::Unit::m3_s,
945 : this->StarvedMakeUpVdot,
946 : OutputProcessor::SOVTimeStepType::System,
947 : OutputProcessor::SOVStoreType::Average,
948 0 : this->Name);
949 :
950 0 : SetupOutputVariable(state,
951 : "Cooling Tower Starved Storage Tank Water Volume",
952 : OutputProcessor::Unit::m3,
953 : this->StarvedMakeUpVol,
954 : OutputProcessor::SOVTimeStepType::System,
955 : OutputProcessor::SOVStoreType::Summed,
956 : this->Name,
957 : _,
958 : "Water",
959 : "HeatRejection",
960 : _,
961 0 : "Plant");
962 :
963 0 : SetupOutputVariable(state,
964 : "Cooling Tower Make Up Mains Water Volume",
965 : OutputProcessor::Unit::m3,
966 : this->StarvedMakeUpVol,
967 : OutputProcessor::SOVTimeStepType::System,
968 : OutputProcessor::SOVStoreType::Summed,
969 : this->Name,
970 : _,
971 : "MainsWater",
972 : "HeatRejection",
973 : _,
974 0 : "Plant");
975 :
976 : } else { // Evaporative fluid cooler water from mains and gets metered
977 6 : SetupOutputVariable(state,
978 : "Cooling Tower Make Up Water Volume Flow Rate",
979 : OutputProcessor::Unit::m3_s,
980 : this->MakeUpVdot,
981 : OutputProcessor::SOVTimeStepType::System,
982 : OutputProcessor::SOVStoreType::Average,
983 3 : this->Name);
984 :
985 6 : SetupOutputVariable(state,
986 : "Cooling Tower Make Up Water Volume",
987 : OutputProcessor::Unit::m3,
988 : this->MakeUpVol,
989 : OutputProcessor::SOVTimeStepType::System,
990 : OutputProcessor::SOVStoreType::Summed,
991 : this->Name,
992 : _,
993 : "Water",
994 : "HeatRejection",
995 : _,
996 3 : "Plant");
997 :
998 6 : SetupOutputVariable(state,
999 : "Cooling Tower Make Up Mains Water Volume",
1000 : OutputProcessor::Unit::m3,
1001 : this->MakeUpVol,
1002 : OutputProcessor::SOVTimeStepType::System,
1003 : OutputProcessor::SOVStoreType::Summed,
1004 : this->Name,
1005 : _,
1006 : "MainsWater",
1007 : "HeatRejection",
1008 : _,
1009 3 : "Plant");
1010 : }
1011 :
1012 6 : SetupOutputVariable(state,
1013 : "Cooling Tower Inlet Temperature",
1014 : OutputProcessor::Unit::C,
1015 : this->fluidCoolerInletWaterTemp,
1016 : OutputProcessor::SOVTimeStepType::System,
1017 : OutputProcessor::SOVStoreType::Average,
1018 3 : this->Name);
1019 :
1020 6 : SetupOutputVariable(state,
1021 : "Cooling Tower Outlet Temperature",
1022 : OutputProcessor::Unit::C,
1023 : this->fluidCoolerOutletWaterTemp,
1024 : OutputProcessor::SOVTimeStepType::System,
1025 : OutputProcessor::SOVStoreType::Average,
1026 3 : this->Name);
1027 :
1028 6 : SetupOutputVariable(state,
1029 : "Cooling Tower Mass Flow Rate",
1030 : OutputProcessor::Unit::kg_s,
1031 : this->WaterMassFlowRate,
1032 : OutputProcessor::SOVTimeStepType::System,
1033 : OutputProcessor::SOVStoreType::Average,
1034 3 : this->Name);
1035 :
1036 6 : SetupOutputVariable(state,
1037 : "Cooling Tower Heat Transfer Rate",
1038 : OutputProcessor::Unit::W,
1039 : this->Qactual,
1040 : OutputProcessor::SOVTimeStepType::System,
1041 : OutputProcessor::SOVStoreType::Average,
1042 3 : this->Name);
1043 :
1044 6 : SetupOutputVariable(state,
1045 : "Cooling Tower Fan Electricity Rate",
1046 : OutputProcessor::Unit::W,
1047 : this->FanPower,
1048 : OutputProcessor::SOVTimeStepType::System,
1049 : OutputProcessor::SOVStoreType::Average,
1050 3 : this->Name);
1051 :
1052 6 : SetupOutputVariable(state,
1053 : "Cooling Tower Fan Electricity Energy",
1054 : OutputProcessor::Unit::J,
1055 : this->FanEnergy,
1056 : OutputProcessor::SOVTimeStepType::System,
1057 : OutputProcessor::SOVStoreType::Summed,
1058 : this->Name,
1059 : _,
1060 : "Electricity",
1061 : "HeatRejection",
1062 : _,
1063 3 : "Plant");
1064 :
1065 6 : SetupOutputVariable(state,
1066 : "Cooling Tower Water Evaporation Volume Flow Rate",
1067 : OutputProcessor::Unit::m3_s,
1068 : this->EvaporationVdot,
1069 : OutputProcessor::SOVTimeStepType::System,
1070 : OutputProcessor::SOVStoreType::Average,
1071 3 : this->Name);
1072 :
1073 6 : SetupOutputVariable(state,
1074 : "Cooling Tower Water Evaporation Volume",
1075 : OutputProcessor::Unit::m3,
1076 : this->EvaporationVol,
1077 : OutputProcessor::SOVTimeStepType::System,
1078 : OutputProcessor::SOVStoreType::Summed,
1079 3 : this->Name);
1080 :
1081 6 : SetupOutputVariable(state,
1082 : "Cooling Tower Water Drift Volume Flow Rate",
1083 : OutputProcessor::Unit::m3_s,
1084 : this->DriftVdot,
1085 : OutputProcessor::SOVTimeStepType::System,
1086 : OutputProcessor::SOVStoreType::Average,
1087 3 : this->Name);
1088 :
1089 6 : SetupOutputVariable(state,
1090 : "Cooling Tower Water Drift Volume",
1091 : OutputProcessor::Unit::m3,
1092 : this->DriftVol,
1093 : OutputProcessor::SOVTimeStepType::System,
1094 : OutputProcessor::SOVStoreType::Summed,
1095 3 : this->Name);
1096 :
1097 6 : SetupOutputVariable(state,
1098 : "Cooling Tower Water Blowdown Volume Flow Rate",
1099 : OutputProcessor::Unit::m3_s,
1100 : this->BlowdownVdot,
1101 : OutputProcessor::SOVTimeStepType::System,
1102 : OutputProcessor::SOVStoreType::Average,
1103 3 : this->Name);
1104 :
1105 6 : SetupOutputVariable(state,
1106 : "Cooling Tower Water Blowdown Volume",
1107 : OutputProcessor::Unit::m3,
1108 : this->BlowdownVol,
1109 : OutputProcessor::SOVTimeStepType::System,
1110 : OutputProcessor::SOVStoreType::Summed,
1111 3 : this->Name);
1112 3 : }
1113 :
1114 3 : void EvapFluidCoolerSpecs::getSizingFactor(Real64 &_sizFac)
1115 : {
1116 3 : _sizFac = this->SizFac;
1117 3 : }
1118 :
1119 15 : void EvapFluidCoolerSpecs::onInitLoopEquip(EnergyPlusData &state, [[maybe_unused]] const PlantLocation &calledFromLocation)
1120 : {
1121 15 : this->InitEvapFluidCooler(state);
1122 15 : this->SizeEvapFluidCooler(state);
1123 15 : }
1124 :
1125 15 : void EvapFluidCoolerSpecs::getDesignCapacities(EnergyPlusData &state, const PlantLocation &, Real64 &MaxLoad, Real64 &MinLoad, Real64 &OptLoad)
1126 : {
1127 25 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd ||
1128 10 : this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1129 15 : MinLoad = 0.0; // signifies non-load based model (i.e. forward heat exchanger model)
1130 15 : MaxLoad = this->HighSpeedStandardDesignCapacity * this->HeatRejectCapNomCapSizingRatio;
1131 15 : OptLoad = this->HighSpeedStandardDesignCapacity;
1132 : } else {
1133 0 : ShowFatalError(state, "SimEvapFluidCoolers: Invalid evaporative fluid cooler Type Requested = " + EvapFluidCoolerType);
1134 : }
1135 15 : }
1136 :
1137 68681 : void EvapFluidCoolerSpecs::simulate(EnergyPlusData &state,
1138 : [[maybe_unused]] const PlantLocation &calledFromLocation,
1139 : [[maybe_unused]] bool FirstHVACIteration,
1140 : [[maybe_unused]] Real64 &CurLoad,
1141 : bool RunFlag)
1142 : {
1143 :
1144 : // SUBROUTINE INFORMATION:
1145 : // AUTHOR Chandan Sharma
1146 : // DATE WRITTEN May 2009
1147 : // MODIFIED na
1148 : // RE-ENGINEERED na
1149 :
1150 : // PURPOSE OF THIS SUBROUTINE:
1151 : // Main evaporative fluid cooler driver subroutine. Gets called from
1152 : // PlantCondLoopSupplySideManager.
1153 :
1154 : // REFERENCES:
1155 : // Based on SimTowers subroutine by Fred Buhl, May 2002
1156 :
1157 68681 : this->AirFlowRateRatio = 0.0; // Ratio of air flow rate through VS Evaporative fluid cooler to design air flow rate
1158 :
1159 68681 : this->InitEvapFluidCooler(state);
1160 :
1161 68681 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd) {
1162 23565 : this->CalcSingleSpeedEvapFluidCooler(state);
1163 45116 : } else if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1164 45116 : this->CalcTwoSpeedEvapFluidCooler(state);
1165 : } else {
1166 0 : ShowFatalError(state, "SimEvapFluidCoolers: Invalid evaporative fluid cooler Type Requested = " + EvapFluidCoolerType);
1167 : }
1168 :
1169 68681 : this->CalculateWaterUsage(state);
1170 68681 : this->UpdateEvapFluidCooler(state);
1171 68681 : this->ReportEvapFluidCooler(state, RunFlag);
1172 68681 : }
1173 :
1174 68696 : void EvapFluidCoolerSpecs::InitEvapFluidCooler(EnergyPlusData &state)
1175 : {
1176 :
1177 : // SUBROUTINE INFORMATION:
1178 : // AUTHOR Chandan Sharma
1179 : // DATE WRITTEN May 2009
1180 : // MODIFIED na
1181 : // RE-ENGINEERED na
1182 :
1183 : // PURPOSE OF THIS SUBROUTINE:
1184 : // This subroutine is for initializations of the evaporative fluid cooler components and for
1185 : // final checking of evaporative fluid cooler inputs (post autosizing)
1186 :
1187 : // METHODOLOGY EMPLOYED:
1188 : // Uses the status flags to trigger initializations.
1189 :
1190 : // REFERENCES:
1191 : // Based on InitTower subroutine by Don Shirey Sept/Oct 2002, F Buhl Oct 2002
1192 :
1193 : static constexpr std::string_view RoutineName("InitEvapFluidCooler");
1194 :
1195 68696 : this->oneTimeInit(state);
1196 :
1197 : // Begin environment initializations
1198 68696 : if (this->MyEnvrnFlag && state.dataGlobal->BeginEnvrnFlag && (state.dataPlnt->PlantFirstSizesOkayToFinalize)) {
1199 :
1200 38 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1201 19 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1202 : DataGlobalConstants::InitConvTemp,
1203 19 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1204 19 : RoutineName);
1205 19 : this->DesWaterMassFlowRate = this->DesignWaterFlowRate * rho;
1206 19 : PlantUtilities::InitComponentNodes(state, 0.0, this->DesWaterMassFlowRate, this->WaterInletNodeNum, this->WaterOutletNodeNum);
1207 19 : this->MyEnvrnFlag = false;
1208 : }
1209 :
1210 68696 : if (!state.dataGlobal->BeginEnvrnFlag) {
1211 68336 : this->MyEnvrnFlag = true;
1212 : }
1213 :
1214 : // Each time initializations
1215 68696 : this->WaterInletNode = this->WaterInletNodeNum;
1216 68696 : this->inletConds.WaterTemp = state.dataLoopNodes->Node(this->WaterInletNode).Temp;
1217 :
1218 68696 : if (this->OutdoorAirInletNodeNum != 0) {
1219 0 : this->inletConds.AirTemp = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).Temp;
1220 0 : this->inletConds.AirHumRat = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).HumRat;
1221 0 : this->inletConds.AirPress = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).Press;
1222 0 : this->inletConds.AirWetBulb = state.dataLoopNodes->Node(this->OutdoorAirInletNodeNum).OutAirWetBulb;
1223 : } else {
1224 68696 : this->inletConds.AirTemp = state.dataEnvrn->OutDryBulbTemp;
1225 68696 : this->inletConds.AirHumRat = state.dataEnvrn->OutHumRat;
1226 68696 : this->inletConds.AirPress = state.dataEnvrn->OutBaroPress;
1227 68696 : this->inletConds.AirWetBulb = state.dataEnvrn->OutWetBulbTemp;
1228 : }
1229 :
1230 68696 : this->WaterMassFlowRate = PlantUtilities::RegulateCondenserCompFlowReqOp(
1231 68696 : state, this->plantLoc, this->DesWaterMassFlowRate * this->EvapFluidCoolerMassFlowRateMultiplier);
1232 :
1233 68696 : PlantUtilities::SetComponentFlowRate(state, this->WaterMassFlowRate, this->WaterInletNodeNum, this->WaterOutletNodeNum, this->plantLoc);
1234 68696 : }
1235 :
1236 15 : void EvapFluidCoolerSpecs::SizeEvapFluidCooler(EnergyPlusData &state)
1237 : {
1238 :
1239 : // SUBROUTINE INFORMATION:
1240 : // AUTHOR Chandan Sharma
1241 : // DATE WRITTEN May 2009
1242 : // MODIFIED Chandan Sharma, April 2010
1243 : // RE-ENGINEERED na
1244 :
1245 : // PURPOSE OF THIS SUBROUTINE:
1246 : // This subroutine is for sizing evaporative fluid cooler Components for which capacities and flow rates
1247 : // have not been specified in the input. This subroutine also calculates evaporative fluid cooler UA if the user
1248 : // has specified evaporative fluid cooler performance via the "Standard Design Capacity" method.
1249 :
1250 : // METHODOLOGY EMPLOYED:
1251 : // Obtains condenser flow rate from the plant sizing array. If evaporative fluid cooler performance is specified
1252 : // via the "Standard Design Capacity" method, the water flow rate is directly proportional to capacity.
1253 :
1254 : // REFERENCES:
1255 : // Based on SizeTower by Don Shirey, Sept/Oct 2002; Richard Raustad, Feb 2005
1256 :
1257 15 : int constexpr MaxIte(500); // Maximum number of iterations
1258 15 : Real64 constexpr Acc(0.0001); // Accuracy of result
1259 30 : std::string const CalledFrom("SizeEvapFluidCooler");
1260 :
1261 : int SolFla; // Flag of solver
1262 : Real64 UA; // Calculated UA value [W/C]
1263 : Real64 OutWaterTempAtUA0; // Water outlet temperature at UA0
1264 : Real64 OutWaterTempAtUA1; // Water outlet temperature at UA1
1265 : Real64 DesignEnteringAirWetBulb; // Intermediate variable to check that design exit
1266 : // temperature specified in the plant:sizing object
1267 : // is higher than the design entering air wet-bulb temp
1268 : // when autosize feature is used
1269 :
1270 15 : Real64 DesEvapFluidCoolerLoad = 0.0; // Design evaporative fluid cooler load [W]
1271 15 : Real64 tmpDesignWaterFlowRate = this->DesignWaterFlowRate;
1272 15 : Real64 tmpHighSpeedFanPower = this->HighSpeedFanPower;
1273 15 : Real64 tmpHighSpeedAirFlowRate = this->HighSpeedAirFlowRate;
1274 :
1275 15 : int PltSizCondNum = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).PlantSizNum;
1276 :
1277 15 : if (this->DesignWaterFlowRateWasAutoSized && this->PerformanceInputMethod_Num != PIM::StandardDesignCapacity) {
1278 10 : if (PltSizCondNum > 0) {
1279 10 : if (state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
1280 8 : tmpDesignWaterFlowRate = state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate * this->SizFac;
1281 8 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
1282 :
1283 : } else {
1284 2 : tmpDesignWaterFlowRate = 0.0;
1285 2 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
1286 : }
1287 10 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1288 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1289 4 : BaseSizer::reportSizerOutput(
1290 2 : state, this->EvapFluidCoolerType, this->Name, "Design Water Flow Rate [m3/s]", this->DesignWaterFlowRate);
1291 : }
1292 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1293 0 : BaseSizer::reportSizerOutput(
1294 0 : state, this->EvapFluidCoolerType, this->Name, "Initial Design Water Flow Rate [m3/s]", this->DesignWaterFlowRate);
1295 : }
1296 : }
1297 : } else {
1298 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1299 0 : ShowSevereError(state, "Autosizing error for evaporative fluid cooler object = " + this->Name);
1300 0 : ShowFatalError(state, "Autosizing of evaporative fluid cooler condenser flow rate requires a loop Sizing:Plant object.");
1301 : }
1302 : }
1303 : // Check when the user specified Condenser/Evaporative Fluid Cooler water design setpoint
1304 : // temperature is less than design inlet air wet bulb temperature
1305 10 : if (this->PerformanceInputMethod_Num == PIM::UFactor) {
1306 10 : DesignEnteringAirWetBulb = 25.6;
1307 : } else {
1308 0 : DesignEnteringAirWetBulb = this->DesignEnteringAirWetBulbTemp;
1309 : }
1310 10 : if (state.dataSize->PlantSizData(PltSizCondNum).ExitTemp <= DesignEnteringAirWetBulb) {
1311 0 : ShowSevereError(state, "Error when autosizing the UA value for Evaporative Fluid Cooler = " + this->Name + '.');
1312 0 : ShowContinueError(state,
1313 0 : format("Design Loop Exit Temperature ({:.2R} C) must be greater than design entering air wet-bulb temperature "
1314 : "({:.2R} C) when autosizing the Evaporative Fluid Cooler UA.",
1315 0 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
1316 0 : DesignEnteringAirWetBulb));
1317 0 : ShowContinueError(state,
1318 : "It is recommended that the Design Loop Exit Temperature = Design Entering Air Wet-bulb Temp plus the Evaporative "
1319 : "Fluid Cooler design approach temperature (e.g., 4 C).");
1320 0 : ShowContinueError(state,
1321 : "If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design Setpoint must be "
1322 : "> Design Entering Air Wet-bulb Temp if autosizing the Evaporative Fluid Cooler.");
1323 0 : ShowFatalError(state, "Review and revise design input values as appropriate.");
1324 : }
1325 : }
1326 :
1327 15 : if (this->PerformanceInputMethod_Num == PIM::UFactor && !this->HighSpeedEvapFluidCoolerUAWasAutoSized) {
1328 0 : if (PltSizCondNum > 0) {
1329 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1330 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1331 : DataGlobalConstants::InitConvTemp,
1332 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1333 0 : CalledFrom);
1334 0 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1335 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1336 0 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
1337 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1338 0 : CalledFrom);
1339 0 : DesEvapFluidCoolerLoad = rho * Cp * tmpDesignWaterFlowRate * state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
1340 0 : this->HighSpeedStandardDesignCapacity = DesEvapFluidCoolerLoad / this->HeatRejectCapNomCapSizingRatio;
1341 : } else {
1342 0 : this->HighSpeedStandardDesignCapacity = 0.0;
1343 : }
1344 : }
1345 :
1346 15 : if (this->PerformanceInputMethod_Num == PIM::StandardDesignCapacity) {
1347 : // Design water flow rate is assumed to be 3 gpm per ton (SI equivalent 5.382E-8 m3/s per watt)
1348 0 : tmpDesignWaterFlowRate = 5.382e-8 * this->HighSpeedStandardDesignCapacity;
1349 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1350 0 : this->DesignWaterFlowRate = tmpDesignWaterFlowRate;
1351 0 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd) {
1352 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1353 0 : BaseSizer::reportSizerOutput(state,
1354 : cEvapFluidCooler_SingleSpeed,
1355 : this->Name,
1356 : "Design Water Flow Rate based on evaporative fluid cooler Standard Design Capacity [m3/s]",
1357 0 : this->DesignWaterFlowRate);
1358 : }
1359 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1360 0 : BaseSizer::reportSizerOutput(
1361 : state,
1362 : cEvapFluidCooler_SingleSpeed,
1363 : this->Name,
1364 : "Initial Design Water Flow Rate based on evaporative fluid cooler Standard Design Capacity [m3/s]",
1365 0 : this->DesignWaterFlowRate);
1366 : }
1367 0 : } else if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1368 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1369 0 : BaseSizer::reportSizerOutput(
1370 : state,
1371 : cEvapFluidCooler_TwoSpeed,
1372 : this->Name,
1373 : "Design Water Flow Rate based on evaporative fluid cooler high-speed Standard Design Capacity [m3/s]",
1374 0 : this->DesignWaterFlowRate);
1375 : }
1376 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1377 0 : BaseSizer::reportSizerOutput(
1378 : state,
1379 : cEvapFluidCooler_TwoSpeed,
1380 : this->Name,
1381 : "Initial Design Water Flow Rate based on evaporative fluid cooler high-speed Standard Design Capacity [m3/s]",
1382 0 : this->DesignWaterFlowRate);
1383 : }
1384 : }
1385 : }
1386 : }
1387 :
1388 15 : PlantUtilities::RegisterPlantCompDesignFlow(state, this->WaterInletNodeNum, tmpDesignWaterFlowRate);
1389 :
1390 15 : if (this->HighSpeedFanPowerWasAutoSized) {
1391 : // We assume the nominal fan power is 0.0105 times the design load
1392 10 : if (this->PerformanceInputMethod_Num == PIM::StandardDesignCapacity) {
1393 0 : tmpHighSpeedFanPower = 0.0105 * this->HighSpeedStandardDesignCapacity;
1394 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
1395 10 : } else if (this->PerformanceInputMethod_Num == PIM::UserSpecifiedDesignCapacity) {
1396 0 : tmpHighSpeedFanPower = 0.0105 * this->HighSpeedUserSpecifiedDesignCapacity;
1397 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
1398 : } else {
1399 10 : if (DesEvapFluidCoolerLoad > 0) {
1400 0 : tmpHighSpeedFanPower = 0.0105 * DesEvapFluidCoolerLoad;
1401 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
1402 10 : } else if (PltSizCondNum > 0) {
1403 10 : if (state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
1404 24 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1405 8 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1406 : DataGlobalConstants::InitConvTemp,
1407 8 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1408 8 : CalledFrom);
1409 32 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1410 8 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1411 8 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
1412 8 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1413 8 : CalledFrom);
1414 8 : DesEvapFluidCoolerLoad = rho * Cp * tmpDesignWaterFlowRate * state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
1415 8 : tmpHighSpeedFanPower = 0.0105 * DesEvapFluidCoolerLoad;
1416 8 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
1417 : } else {
1418 2 : tmpHighSpeedFanPower = 0.0;
1419 2 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedFanPower = tmpHighSpeedFanPower;
1420 : }
1421 : } else {
1422 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1423 0 : ShowSevereError(state, "Autosizing of evaporative fluid cooler fan power requires a loop Sizing:Plant object.");
1424 0 : ShowFatalError(state, " Occurs in evaporative fluid cooler object= " + this->Name);
1425 : }
1426 : }
1427 : }
1428 10 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1429 2 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd) {
1430 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1431 0 : BaseSizer::reportSizerOutput(
1432 0 : state, cEvapFluidCooler_SingleSpeed, this->Name, "Fan Power at Design Air Flow Rate [W]", this->HighSpeedFanPower);
1433 : }
1434 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1435 0 : BaseSizer::reportSizerOutput(state,
1436 : cEvapFluidCooler_SingleSpeed,
1437 : this->Name,
1438 : "Initial Fan Power at Design Air Flow Rate [W]",
1439 0 : this->HighSpeedFanPower);
1440 : }
1441 2 : } else if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1442 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1443 4 : BaseSizer::reportSizerOutput(
1444 2 : state, cEvapFluidCooler_TwoSpeed, this->Name, "Fan Power at High Fan Speed [W]", this->HighSpeedFanPower);
1445 : }
1446 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1447 0 : BaseSizer::reportSizerOutput(
1448 0 : state, cEvapFluidCooler_TwoSpeed, this->Name, "Initial Fan Power at High Fan Speed [W]", this->HighSpeedFanPower);
1449 : }
1450 : }
1451 : }
1452 : }
1453 :
1454 15 : if (this->HighSpeedAirFlowRateWasAutoSized) {
1455 : // Plant Sizing Object is not required to AUTOSIZE this field since its simply a multiple of another field.
1456 :
1457 10 : tmpHighSpeedAirFlowRate = tmpHighSpeedFanPower * 0.5 * (101325.0 / state.dataEnvrn->StdBaroPress) / 190.0;
1458 10 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1459 2 : this->HighSpeedAirFlowRate = tmpHighSpeedAirFlowRate;
1460 :
1461 2 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd) {
1462 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1463 0 : BaseSizer::reportSizerOutput(
1464 0 : state, cEvapFluidCooler_SingleSpeed, this->Name, "Design Air Flow Rate [m3/s]", this->HighSpeedAirFlowRate);
1465 : }
1466 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1467 0 : BaseSizer::reportSizerOutput(
1468 0 : state, cEvapFluidCooler_SingleSpeed, this->Name, "Initial Design Air Flow Rate [m3/s]", this->HighSpeedAirFlowRate);
1469 : }
1470 2 : } else if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1471 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1472 4 : BaseSizer::reportSizerOutput(
1473 2 : state, cEvapFluidCooler_TwoSpeed, this->Name, "Air Flow Rate at High Fan Speed [m3/s]", this->HighSpeedAirFlowRate);
1474 : }
1475 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1476 0 : BaseSizer::reportSizerOutput(state,
1477 : cEvapFluidCooler_TwoSpeed,
1478 : this->Name,
1479 : "Initial Air Flow Rate at High Fan Speed [m3/s]",
1480 0 : this->HighSpeedAirFlowRate);
1481 : }
1482 : }
1483 : }
1484 : }
1485 :
1486 17 : if (this->HighSpeedEvapFluidCoolerUAWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize &&
1487 2 : this->PerformanceInputMethod_Num == PIM::UFactor) {
1488 2 : if (PltSizCondNum > 0) {
1489 2 : if (state.dataSize->PlantSizData(PltSizCondNum).DesVolFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
1490 : // This conditional statement is to trap when the user specified Condenser/Evaporative Fluid Cooler water design setpoint
1491 : // temperature is less than design inlet air wet bulb temperature of 25.6 C
1492 2 : if (state.dataSize->PlantSizData(PltSizCondNum).ExitTemp <= 25.6) {
1493 0 : ShowSevereError(state, "Error when autosizing the UA value for Evaporative Fluid Cooler = " + this->Name + '.');
1494 0 : ShowContinueError(state,
1495 0 : format("Design Loop Exit Temperature ({:.2R} C) must be greater than 25.6 C when autosizing the "
1496 : "Evaporative Fluid Cooler UA.",
1497 0 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp));
1498 0 : ShowContinueError(state,
1499 0 : "The Design Loop Exit Temperature specified in Sizing:Plant object = " +
1500 0 : state.dataSize->PlantSizData(PltSizCondNum).PlantLoopName);
1501 0 : ShowContinueError(state,
1502 : "It is recommended that the Design Loop Exit Temperature = 25.6 C plus the Evaporative Fluid Cooler design "
1503 : "approach temperature (e.g., 4 C).");
1504 0 : ShowContinueError(state,
1505 : "If using HVACTemplate:Plant:ChilledWaterLoop, then check that input field Condenser Water Design Setpoint "
1506 : "must be > 25.6 C if autosizing the Evaporative Fluid Cooler.");
1507 0 : ShowFatalError(state, "Review and revise design input values as appropriate.");
1508 : }
1509 6 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1510 2 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1511 : DataGlobalConstants::InitConvTemp,
1512 2 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1513 2 : CalledFrom);
1514 8 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1515 2 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1516 2 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp,
1517 2 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1518 2 : CalledFrom);
1519 2 : DesEvapFluidCoolerLoad = rho * Cp * tmpDesignWaterFlowRate * state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
1520 2 : Real64 const par1 = rho * tmpDesignWaterFlowRate; // Design water mass flow rate
1521 2 : Real64 const par2 = tmpHighSpeedAirFlowRate; // Design air volume flow rate
1522 : // Lower bound for UA [W/C]
1523 2 : Real64 UA0 = 0.0001 * DesEvapFluidCoolerLoad; // Assume deltaT = 10000K (limit)
1524 2 : Real64 UA1 = DesEvapFluidCoolerLoad; // Assume deltaT = 1K
1525 2 : this->inletConds.WaterTemp =
1526 2 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp + state.dataSize->PlantSizData(PltSizCondNum).DeltaT;
1527 2 : this->inletConds.AirTemp = 35.0;
1528 2 : this->inletConds.AirWetBulb = 25.6;
1529 2 : this->inletConds.AirPress = state.dataEnvrn->StdBaroPress;
1530 2 : this->inletConds.AirHumRat =
1531 4 : Psychrometrics::PsyWFnTdbTwbPb(state, this->inletConds.AirTemp, this->inletConds.AirWetBulb, this->inletConds.AirPress);
1532 270 : auto f = [&state, this, DesEvapFluidCoolerLoad, par1, par2, Cp](Real64 UA) {
1533 : Real64 OutWaterTemp; // outlet water temperature [C]
1534 54 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA, OutWaterTemp);
1535 108 : Real64 const CoolingOutput = Cp * par1 * (this->inletConds.WaterTemp - OutWaterTemp);
1536 108 : return (DesEvapFluidCoolerLoad - CoolingOutput) / DesEvapFluidCoolerLoad;
1537 2 : };
1538 2 : General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
1539 2 : if (SolFla == -1) {
1540 0 : ShowWarningError(state, "Iteration limit exceeded in calculating evaporative fluid cooler UA.");
1541 0 : ShowContinueError(state, "Autosizing of fluid cooler UA failed for evaporative fluid cooler = " + this->Name);
1542 0 : ShowContinueError(state, format("The final UA value = {:.2R}W/C, and the simulation continues...", UA));
1543 2 : } else if (SolFla == -2) {
1544 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA0, OutWaterTempAtUA0);
1545 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA1, OutWaterTempAtUA1);
1546 0 : ShowSevereError(state, CalledFrom + ": The combination of design input values did not allow the calculation of a ");
1547 0 : ShowContinueError(state, "reasonable UA value. Review and revise design input values as appropriate. Specifying hard");
1548 0 : ShowContinueError(state,
1549 : "sizes for some \"autosizable\" fields while autosizing other \"autosizable\" fields may be contributing "
1550 : "to this problem.");
1551 0 : ShowContinueError(state, "This model iterates on UA to find the heat transfer required to provide the design outlet ");
1552 0 : ShowContinueError(state, "water temperature. Initially, the outlet water temperatures at high and low UA values are ");
1553 0 : ShowContinueError(state, "calculated. The Design Exit Water Temperature should be between the outlet water ");
1554 0 : ShowContinueError(state, "temperatures calculated at high and low UA values. If the Design Exit Water Temperature is ");
1555 0 : ShowContinueError(state, "out of this range, the solution will not converge and UA will not be calculated. ");
1556 0 : ShowContinueError(state, "The possible solutions could be to manually input adjusted water and/or air flow rates ");
1557 0 : ShowContinueError(
1558 : state,
1559 : "based on the autosized values shown below or to adjust design evaporative fluid cooler air inlet wet-bulb temperature.");
1560 0 : ShowContinueError(state, "Plant:Sizing object inputs also influence these results (e.g. DeltaT and ExitTemp).");
1561 0 : ShowContinueError(state, "Inputs to the evaporative fluid cooler object:");
1562 0 : ShowContinueError(state,
1563 0 : format("Design Evaporative Fluid Cooler Load [W] = {:.2R}", DesEvapFluidCoolerLoad));
1564 0 : ShowContinueError(
1565 0 : state, format("Design Evaporative Fluid Cooler Water Volume Flow Rate [m3/s] = {:.6R}", this->DesignWaterFlowRate));
1566 0 : ShowContinueError(state, format("Design Evaporative Fluid Cooler Air Volume Flow Rate [m3/s] = {:.2R}", par2));
1567 0 : ShowContinueError(
1568 0 : state, format("Design Evaporative Fluid Cooler Air Inlet Wet-bulb Temp [C] = {:.2R}", this->inletConds.AirWetBulb));
1569 0 : ShowContinueError(
1570 0 : state, format("Design Evaporative Fluid Cooler Water Inlet Temp [C] = {:.2R}", this->inletConds.WaterTemp));
1571 0 : ShowContinueError(state, "Inputs to the plant sizing object:");
1572 0 : ShowContinueError(state,
1573 0 : format("Design Exit Water Temp [C] = {:.2R}",
1574 0 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp));
1575 0 : ShowContinueError(state,
1576 0 : format("Loop Design Temperature Difference [C] = {:.2R}",
1577 0 : state.dataSize->PlantSizData(PltSizCondNum).DeltaT));
1578 0 : ShowContinueError(
1579 0 : state, format("Design Evaporative Fluid Cooler Water Inlet Temp [C] = {:.2R}", this->inletConds.WaterTemp));
1580 0 : ShowContinueError(
1581 0 : state, format("Calculated water outlet temperature at low UA [C](UA = {:.2R} W/C) = {:.2R}", UA0, OutWaterTempAtUA0));
1582 0 : ShowContinueError(
1583 0 : state, format("Calculated water outlet temperature at high UA [C](UA = {:.2R} W/C) = {:.2R}", UA1, OutWaterTempAtUA1));
1584 0 : ShowFatalError(state, "Autosizing of Evaporative Fluid Cooler UA failed for Evaporative Fluid Cooler = " + this->Name);
1585 : }
1586 2 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedEvapFluidCoolerUA = UA;
1587 2 : this->HighSpeedStandardDesignCapacity = DesEvapFluidCoolerLoad / this->HeatRejectCapNomCapSizingRatio;
1588 : } else {
1589 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) this->HighSpeedEvapFluidCoolerUA = 0.0;
1590 : }
1591 2 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1592 2 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd) {
1593 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1594 0 : BaseSizer::reportSizerOutput(state,
1595 : cEvapFluidCooler_SingleSpeed,
1596 : this->Name,
1597 : "U-Factor Times Area Value at Design Air Flow Rate [W/C]",
1598 0 : this->HighSpeedEvapFluidCoolerUA);
1599 : }
1600 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1601 0 : BaseSizer::reportSizerOutput(state,
1602 : cEvapFluidCooler_SingleSpeed,
1603 : this->Name,
1604 : "Initial U-Factor Times Area Value at Design Air Flow Rate [W/C]",
1605 0 : this->HighSpeedEvapFluidCoolerUA);
1606 : }
1607 2 : } else if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1608 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1609 4 : BaseSizer::reportSizerOutput(state,
1610 : cEvapFluidCooler_TwoSpeed,
1611 : this->Name,
1612 : "U-Factor Times Area Value at High Fan Speed [W/C]",
1613 2 : this->HighSpeedEvapFluidCoolerUA);
1614 : }
1615 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1616 0 : BaseSizer::reportSizerOutput(state,
1617 : cEvapFluidCooler_TwoSpeed,
1618 : this->Name,
1619 : "Initial U-Factor Times Area Value at High Fan Speed [W/C]",
1620 0 : this->HighSpeedEvapFluidCoolerUA);
1621 : }
1622 : }
1623 : }
1624 : } else {
1625 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1626 0 : ShowSevereError(state, "Autosizing error for evaporative fluid cooler object = " + this->Name);
1627 0 : ShowFatalError(state, "Autosizing of evaporative fluid cooler UA requires a loop Sizing:Plant object.");
1628 : }
1629 : }
1630 : }
1631 :
1632 15 : if (this->PerformanceInputMethod_Num == PIM::StandardDesignCapacity) {
1633 0 : if (this->DesignWaterFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
1634 : // Standard Design Capacity doesn't include compressor heat;
1635 : // predefined factor was 1.25 W heat rejection per W of delivered cooling, now a user input with 1.25 default
1636 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1637 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1638 : DataGlobalConstants::InitConvTemp,
1639 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1640 0 : CalledFrom);
1641 0 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1642 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1643 : 35.0,
1644 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1645 0 : CalledFrom);
1646 0 : DesEvapFluidCoolerLoad = this->HighSpeedStandardDesignCapacity * this->HeatRejectCapNomCapSizingRatio;
1647 0 : Real64 const par1 = rho * this->DesignWaterFlowRate; // Design water mass flow rate
1648 0 : Real64 const par2 = this->HighSpeedAirFlowRate; // Design air volume flow rate
1649 0 : Real64 UA0 = 0.0001 * DesEvapFluidCoolerLoad; // Assume deltaT = 10000K (limit)
1650 0 : Real64 UA1 = DesEvapFluidCoolerLoad; // Assume deltaT = 1K
1651 0 : this->inletConds.WaterTemp = 35.0; // 95F design inlet water temperature
1652 0 : this->inletConds.AirTemp = 35.0; // 95F design inlet air dry-bulb temp
1653 0 : this->inletConds.AirWetBulb = 25.6; // 78F design inlet air wet-bulb temp
1654 0 : this->inletConds.AirPress = state.dataEnvrn->StdBaroPress;
1655 0 : this->inletConds.AirHumRat =
1656 0 : Psychrometrics::PsyWFnTdbTwbPb(state, this->inletConds.AirTemp, this->inletConds.AirWetBulb, this->inletConds.AirPress);
1657 0 : auto f = [&state, this, DesEvapFluidCoolerLoad, par1, par2, Cp](Real64 UA) {
1658 : Real64 OutWaterTemp; // outlet water temperature [C]
1659 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA, OutWaterTemp);
1660 0 : Real64 const CoolingOutput = Cp * par1 * (this->inletConds.WaterTemp - OutWaterTemp);
1661 0 : return (DesEvapFluidCoolerLoad - CoolingOutput) / DesEvapFluidCoolerLoad;
1662 0 : };
1663 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
1664 0 : if (SolFla == -1) {
1665 0 : ShowWarningError(state, "Iteration limit exceeded in calculating evaporative fluid cooler UA.");
1666 0 : ShowContinueError(state, "Autosizing of fluid cooler UA failed for evaporative fluid cooler = " + this->Name);
1667 0 : ShowContinueError(state, format("The final UA value = {:.2R}W/C, and the simulation continues...", UA));
1668 0 : } else if (SolFla == -2) {
1669 0 : ShowSevereError(state, CalledFrom + ": The combination of design input values did not allow the calculation of a ");
1670 0 : ShowContinueError(state, "reasonable UA value. Review and revise design input values as appropriate. ");
1671 0 : ShowFatalError(state, "Autosizing of Evaporative Fluid Cooler UA failed for Evaporative Fluid Cooler = " + this->Name);
1672 : }
1673 0 : this->HighSpeedEvapFluidCoolerUA = UA;
1674 : } else {
1675 0 : this->HighSpeedEvapFluidCoolerUA = 0.0;
1676 : }
1677 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1678 0 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd) {
1679 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1680 0 : BaseSizer::reportSizerOutput(state,
1681 : cEvapFluidCooler_SingleSpeed,
1682 : this->Name,
1683 : "U-Factor Times Area Value at Design Air Flow Rate [W/C]",
1684 0 : this->HighSpeedEvapFluidCoolerUA);
1685 : }
1686 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1687 0 : BaseSizer::reportSizerOutput(state,
1688 : cEvapFluidCooler_SingleSpeed,
1689 : this->Name,
1690 : "Initial U-Factor Times Area Value at Design Air Flow Rate [W/C]",
1691 0 : this->HighSpeedEvapFluidCoolerUA);
1692 : }
1693 0 : } else if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1694 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1695 0 : BaseSizer::reportSizerOutput(state,
1696 : cEvapFluidCooler_TwoSpeed,
1697 : this->Name,
1698 : "U-Factor Times Area Value at High Fan Speed [W/C]",
1699 0 : this->HighSpeedEvapFluidCoolerUA);
1700 : }
1701 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1702 0 : BaseSizer::reportSizerOutput(state,
1703 : cEvapFluidCooler_TwoSpeed,
1704 : this->Name,
1705 : "Initial U-Factor Times Area Value at High Fan Speed [W/C]",
1706 0 : this->HighSpeedEvapFluidCoolerUA);
1707 : }
1708 : }
1709 : }
1710 : }
1711 :
1712 15 : if (this->PerformanceInputMethod_Num == PIM::UserSpecifiedDesignCapacity) {
1713 5 : if (this->DesignWaterFlowRate >= DataHVACGlobals::SmallWaterVolFlow) {
1714 15 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1715 5 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1716 : DataGlobalConstants::InitConvTemp,
1717 5 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1718 5 : CalledFrom);
1719 15 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1720 5 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1721 : this->DesignEnteringWaterTemp,
1722 5 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1723 5 : CalledFrom);
1724 5 : DesEvapFluidCoolerLoad = this->HighSpeedUserSpecifiedDesignCapacity;
1725 5 : Real64 const par1 = rho * tmpDesignWaterFlowRate; // Design water mass flow rate
1726 5 : Real64 const par2 = tmpHighSpeedAirFlowRate; // Design air volume flow rate
1727 5 : Real64 UA0 = 0.0001 * DesEvapFluidCoolerLoad; // Assume deltaT = 10000K (limit)
1728 5 : Real64 UA1 = DesEvapFluidCoolerLoad; // Assume deltaT = 1K
1729 :
1730 5 : this->inletConds.WaterTemp = this->DesignEnteringWaterTemp;
1731 5 : this->inletConds.AirTemp = this->DesignEnteringAirTemp;
1732 5 : this->inletConds.AirWetBulb = this->DesignEnteringAirWetBulbTemp;
1733 5 : this->inletConds.AirPress = state.dataEnvrn->StdBaroPress;
1734 5 : this->inletConds.AirHumRat =
1735 10 : Psychrometrics::PsyWFnTdbTwbPb(state, this->inletConds.AirTemp, this->inletConds.AirWetBulb, this->inletConds.AirPress);
1736 475 : auto f = [&state, this, DesEvapFluidCoolerLoad, par1, par2, Cp](Real64 UA) {
1737 : Real64 OutWaterTemp; // outlet water temperature [C]
1738 95 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA, OutWaterTemp);
1739 190 : Real64 const CoolingOutput = Cp * par1 * (this->inletConds.WaterTemp - OutWaterTemp);
1740 190 : return (DesEvapFluidCoolerLoad - CoolingOutput) / DesEvapFluidCoolerLoad;
1741 5 : };
1742 5 : General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
1743 5 : if (SolFla == -1) {
1744 0 : ShowWarningError(state, "Iteration limit exceeded in calculating evaporative fluid cooler UA.");
1745 0 : ShowContinueError(state, "Autosizing of fluid cooler UA failed for evaporative fluid cooler = " + this->Name);
1746 0 : ShowContinueError(state, format("The final UA value = {:.2R}W/C, and the simulation continues...", UA));
1747 5 : } else if (SolFla == -2) {
1748 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA0, OutWaterTempAtUA0);
1749 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA1, OutWaterTempAtUA1);
1750 0 : ShowSevereError(state, CalledFrom + ": The combination of design input values did not allow the calculation of a ");
1751 0 : ShowContinueError(state, "reasonable UA value. Review and revise design input values as appropriate. Specifying hard");
1752 0 : ShowContinueError(
1753 : state,
1754 : R"(sizes for some "autosizable" fields while autosizing other "autosizable" fields may be contributing to this problem.)");
1755 0 : ShowContinueError(state, "This model iterates on UA to find the heat transfer required to provide the design outlet ");
1756 0 : ShowContinueError(state, "water temperature. Initially, the outlet water temperatures at high and low UA values are ");
1757 0 : ShowContinueError(state, "calculated. The Design Exit Water Temperature should be between the outlet water ");
1758 0 : ShowContinueError(state, "temperatures calculated at high and low UA values. If the Design Exit Water Temperature is ");
1759 0 : ShowContinueError(state, "out of this range, the solution will not converge and UA will not be calculated. ");
1760 0 : ShowContinueError(state, "The possible solutions could be to manually input adjusted water and/or air flow rates ");
1761 0 : ShowContinueError(
1762 : state,
1763 : "based on the autosized values shown below or to adjust design evaporative fluid cooler air inlet wet-bulb temperature.");
1764 0 : ShowContinueError(state, "Plant:Sizing object inputs also influence these results (e.g. DeltaT and ExitTemp).");
1765 0 : ShowContinueError(state, "Inputs to the evaporative fluid cooler object:");
1766 0 : ShowContinueError(state,
1767 0 : format("Design Evaporative Fluid Cooler Load [W] = {:.2R}", DesEvapFluidCoolerLoad));
1768 0 : ShowContinueError(state,
1769 0 : format("Design Evaporative Fluid Cooler Water Volume Flow Rate [m3/s] = {:.6R}", this->DesignWaterFlowRate));
1770 0 : ShowContinueError(state, format("Design Evaporative Fluid Cooler Air Volume Flow Rate [m3/s] = {:.2R}", par2));
1771 0 : ShowContinueError(state,
1772 0 : format("Design Evaporative Fluid Cooler Air Inlet Wet-bulb Temp [C] = {:.2R}", this->inletConds.AirWetBulb));
1773 0 : ShowContinueError(state,
1774 0 : format("Design Evaporative Fluid Cooler Water Inlet Temp [C] = {:.2R}", this->inletConds.WaterTemp));
1775 0 : ShowContinueError(state, "Inputs to the plant sizing object:");
1776 0 : ShowContinueError(state,
1777 0 : format("Design Exit Water Temp [C] = {:.2R}",
1778 0 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp));
1779 0 : ShowContinueError(state,
1780 0 : format("Loop Design Temperature Difference [C] = {:.2R}",
1781 0 : state.dataSize->PlantSizData(PltSizCondNum).DeltaT));
1782 0 : ShowContinueError(state,
1783 0 : format("Design Evaporative Fluid Cooler Water Inlet Temp [C] = {:.2R}", this->inletConds.WaterTemp));
1784 0 : ShowContinueError(state,
1785 0 : format("Calculated water outlet temperature at low UA [C](UA = {:.2R} W/C) = {:.2R}", UA0, OutWaterTempAtUA0));
1786 0 : ShowContinueError(
1787 0 : state, format("Calculated water outlet temperature at high UA [C](UA = {:.2R} W/C) = {:.2R}", UA1, OutWaterTempAtUA1));
1788 0 : ShowFatalError(state, "Autosizing of Evaporative Fluid Cooler UA failed for Evaporative Fluid Cooler = " + this->Name);
1789 : }
1790 5 : this->HighSpeedEvapFluidCoolerUA = UA;
1791 : } else {
1792 0 : this->HighSpeedEvapFluidCoolerUA = 0.0;
1793 : }
1794 5 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1795 1 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_SingleSpd) {
1796 1 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1797 2 : BaseSizer::reportSizerOutput(state,
1798 : cEvapFluidCooler_SingleSpeed,
1799 : this->Name,
1800 : "U-Factor Times Area Value at Design Air Flow Rate [W/C]",
1801 1 : this->HighSpeedEvapFluidCoolerUA);
1802 : }
1803 1 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1804 0 : BaseSizer::reportSizerOutput(state,
1805 : cEvapFluidCooler_SingleSpeed,
1806 : this->Name,
1807 : "Initial U-Factor Times Area Value at Design Air Flow Rate [W/C]",
1808 0 : this->HighSpeedEvapFluidCoolerUA);
1809 : }
1810 0 : } else if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1811 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1812 0 : BaseSizer::reportSizerOutput(state,
1813 : cEvapFluidCooler_TwoSpeed,
1814 : this->Name,
1815 : "U-Factor Times Area Value at High Fan Speed [W/C]",
1816 0 : this->HighSpeedEvapFluidCoolerUA);
1817 : }
1818 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1819 0 : BaseSizer::reportSizerOutput(state,
1820 : cEvapFluidCooler_TwoSpeed,
1821 : this->Name,
1822 : "Initial U-Factor Times Area Value at High Fan Speed [W/C]",
1823 0 : this->HighSpeedEvapFluidCoolerUA);
1824 : }
1825 : }
1826 : }
1827 : }
1828 :
1829 15 : if (this->LowSpeedAirFlowRateWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1830 2 : this->LowSpeedAirFlowRate = this->LowSpeedAirFlowRateSizingFactor * this->HighSpeedAirFlowRate;
1831 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1832 4 : BaseSizer::reportSizerOutput(
1833 2 : state, this->EvapFluidCoolerType, this->Name, "Air Flow Rate at Low Fan Speed [m3/s]", this->LowSpeedAirFlowRate);
1834 : }
1835 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1836 0 : BaseSizer::reportSizerOutput(
1837 0 : state, this->EvapFluidCoolerType, this->Name, "Initial Air Flow Rate at Low Fan Speed [m3/s]", this->LowSpeedAirFlowRate);
1838 : }
1839 : }
1840 :
1841 15 : if (this->LowSpeedFanPowerWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1842 2 : this->LowSpeedFanPower = this->LowSpeedFanPowerSizingFactor * this->HighSpeedFanPower;
1843 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1844 2 : BaseSizer::reportSizerOutput(state, this->EvapFluidCoolerType, this->Name, "Fan Power at Low Fan Speed [W]", this->LowSpeedFanPower);
1845 : }
1846 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1847 0 : BaseSizer::reportSizerOutput(
1848 0 : state, this->EvapFluidCoolerType, this->Name, "Initial Fan Power at Low Fan Speed [W]", this->LowSpeedFanPower);
1849 : }
1850 : }
1851 :
1852 15 : if (this->LowSpeedEvapFluidCoolerUAWasAutoSized && state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1853 2 : this->LowSpeedEvapFluidCoolerUA = this->LowSpeedEvapFluidCoolerUASizingFactor * this->HighSpeedEvapFluidCoolerUA;
1854 2 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1855 4 : BaseSizer::reportSizerOutput(state,
1856 : this->EvapFluidCoolerType,
1857 : this->Name,
1858 : "U-Factor Times Area Value at Low Fan Speed [W/C]",
1859 2 : this->LowSpeedEvapFluidCoolerUA);
1860 : }
1861 2 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1862 0 : BaseSizer::reportSizerOutput(state,
1863 : this->EvapFluidCoolerType,
1864 : this->Name,
1865 : "Initial U-Factor Times Area Value at Low Fan Speed [W/C]",
1866 0 : this->LowSpeedEvapFluidCoolerUA);
1867 : }
1868 : }
1869 :
1870 15 : if (this->PerformanceInputMethod_Num == PIM::StandardDesignCapacity && this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1871 0 : if (this->DesignWaterFlowRate >= DataHVACGlobals::SmallWaterVolFlow && this->LowSpeedStandardDesignCapacity > 0.0) {
1872 : // Standard design capacity doesn't include compressor heat;
1873 : // predefined factor was 1.25 W heat rejection per W of delivered cooling, now user input with default 1.25
1874 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1875 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1876 : DataGlobalConstants::InitConvTemp,
1877 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1878 0 : CalledFrom);
1879 0 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1880 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1881 : this->DesignEnteringWaterTemp,
1882 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1883 0 : CalledFrom);
1884 0 : DesEvapFluidCoolerLoad = this->LowSpeedStandardDesignCapacity * this->HeatRejectCapNomCapSizingRatio;
1885 0 : Real64 const par1 = rho * tmpDesignWaterFlowRate; // Design water mass flow rate
1886 0 : Real64 const par2 = this->LowSpeedAirFlowRate; // Air volume flow rate at low fan speed
1887 0 : Real64 UA0 = 0.0001 * DesEvapFluidCoolerLoad; // Assume deltaT = 10000K (limit)
1888 0 : Real64 UA1 = DesEvapFluidCoolerLoad; // Assume deltaT = 1K
1889 0 : this->inletConds.WaterTemp = 35.0; // 95F design inlet water temperature
1890 0 : this->inletConds.AirTemp = 35.0; // 95F design inlet air dry-bulb temp
1891 0 : this->inletConds.AirWetBulb = 25.6; // 78F design inlet air wet-bulb temp
1892 0 : this->inletConds.AirPress = state.dataEnvrn->StdBaroPress;
1893 0 : this->inletConds.AirHumRat =
1894 0 : Psychrometrics::PsyWFnTdbTwbPb(state, this->inletConds.AirTemp, this->inletConds.AirWetBulb, this->inletConds.AirPress);
1895 0 : auto f = [&state, this, DesEvapFluidCoolerLoad, par1, par2, Cp](Real64 UA) {
1896 : Real64 OutWaterTemp; // outlet water temperature [C]
1897 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA, OutWaterTemp);
1898 0 : Real64 const CoolingOutput = Cp * par1 * (this->inletConds.WaterTemp - OutWaterTemp);
1899 0 : return (DesEvapFluidCoolerLoad - CoolingOutput) / DesEvapFluidCoolerLoad;
1900 0 : };
1901 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
1902 0 : if (SolFla == -1) {
1903 0 : ShowWarningError(state, "Iteration limit exceeded in calculating evaporative fluid cooler UA.");
1904 0 : ShowContinueError(state, "Autosizing of fluid cooler UA failed for evaporative fluid cooler = " + this->Name);
1905 0 : ShowContinueError(state, format("The final UA value = {:.2R}W/C, and the simulation continues...", UA));
1906 0 : } else if (SolFla == -2) {
1907 0 : ShowSevereError(state, CalledFrom + ": The combination of design input values did not allow the calculation of a ");
1908 0 : ShowContinueError(state, "reasonable low-speed UA value. Review and revise design input values as appropriate. ");
1909 0 : ShowFatalError(state, "Autosizing of Evaporative Fluid Cooler UA failed for Evaporative Fluid Cooler = " + this->Name);
1910 : }
1911 0 : this->LowSpeedEvapFluidCoolerUA = UA;
1912 : } else {
1913 0 : this->LowSpeedEvapFluidCoolerUA = 0.0;
1914 : }
1915 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1916 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
1917 0 : BaseSizer::reportSizerOutput(state,
1918 : this->EvapFluidCoolerType,
1919 : this->Name,
1920 : "U-Factor Times Area Value at Low Fan Speed [W/C]",
1921 0 : this->LowSpeedEvapFluidCoolerUA);
1922 : }
1923 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
1924 0 : BaseSizer::reportSizerOutput(state,
1925 : this->EvapFluidCoolerType,
1926 : this->Name,
1927 : "Initial U-Factor Times Area Value at Low Fan Speed [W/C]",
1928 0 : this->LowSpeedEvapFluidCoolerUA);
1929 : }
1930 : }
1931 : }
1932 :
1933 20 : if (this->PerformanceInputMethod_Num == PIM::UserSpecifiedDesignCapacity &&
1934 5 : this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
1935 0 : if (this->DesignWaterFlowRate >= DataHVACGlobals::SmallWaterVolFlow && this->LowSpeedUserSpecifiedDesignCapacity > 0.0) {
1936 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
1937 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1938 : DataGlobalConstants::InitConvTemp,
1939 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1940 0 : CalledFrom);
1941 0 : Real64 Cp = FluidProperties::GetSpecificHeatGlycol(state,
1942 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
1943 : this->DesignEnteringWaterTemp,
1944 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
1945 0 : CalledFrom);
1946 0 : DesEvapFluidCoolerLoad = this->LowSpeedUserSpecifiedDesignCapacity;
1947 0 : Real64 const par1 = rho * tmpDesignWaterFlowRate; // Design water mass flow rate
1948 0 : Real64 const par2 = this->LowSpeedAirFlowRate; // Air volume flow rate at low fan speed
1949 0 : Real64 UA0 = 0.0001 * DesEvapFluidCoolerLoad; // Assume deltaT = 10000K (limit)
1950 0 : Real64 UA1 = DesEvapFluidCoolerLoad; // Assume deltaT = 1K
1951 0 : this->inletConds.WaterTemp = this->DesignEnteringWaterTemp;
1952 0 : this->inletConds.AirTemp = this->DesignEnteringAirTemp;
1953 0 : this->inletConds.AirWetBulb = this->DesignEnteringAirWetBulbTemp;
1954 0 : this->inletConds.AirPress = state.dataEnvrn->StdBaroPress;
1955 0 : this->inletConds.AirHumRat =
1956 0 : Psychrometrics::PsyWFnTdbTwbPb(state, this->inletConds.AirTemp, this->inletConds.AirWetBulb, this->inletConds.AirPress);
1957 0 : auto f = [&state, this, DesEvapFluidCoolerLoad, par1, par2, Cp](Real64 UA) {
1958 : Real64 OutWaterTemp; // outlet water temperature [C]
1959 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA, OutWaterTemp);
1960 0 : Real64 const CoolingOutput = Cp * par1 * (this->inletConds.WaterTemp - OutWaterTemp);
1961 0 : return (DesEvapFluidCoolerLoad - CoolingOutput) / DesEvapFluidCoolerLoad;
1962 0 : };
1963 0 : General::SolveRoot(state, Acc, MaxIte, SolFla, UA, f, UA0, UA1);
1964 0 : if (SolFla == -1) {
1965 0 : ShowSevereError(state, "Iteration limit exceeded in calculating EvaporativeFluidCooler UA");
1966 0 : ShowFatalError(state, "Autosizing of EvaporativeFluidCooler UA failed for EvaporativeFluidCooler " + this->Name);
1967 0 : } else if (SolFla == -2) {
1968 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA0, OutWaterTempAtUA0);
1969 0 : this->SimSimpleEvapFluidCooler(state, par1, par2, UA1, OutWaterTempAtUA1);
1970 0 : ShowSevereError(state, CalledFrom + ": The combination of design input values did not allow the calculation of a ");
1971 0 : ShowContinueError(state, "reasonable UA value. Review and revise design input values as appropriate. Specifying hard");
1972 0 : ShowContinueError(
1973 : state,
1974 : R"(sizes for some "autosizable" fields while autosizing other "autosizable" fields may be contributing to this problem.)");
1975 0 : ShowContinueError(state, "This model iterates on UA to find the heat transfer required to provide the design outlet ");
1976 0 : ShowContinueError(state, "water temperature. Initially, the outlet water temperatures at high and low UA values are ");
1977 0 : ShowContinueError(state, "calculated. The Design Exit Water Temperature should be between the outlet water ");
1978 0 : ShowContinueError(state, "temperatures calculated at high and low UA values. If the Design Exit Water Temperature is ");
1979 0 : ShowContinueError(state, "out of this range, the solution will not converge and UA will not be calculated. ");
1980 0 : ShowContinueError(state, "Inputs to the Evaporative Fluid Cooler model are:");
1981 0 : ShowContinueError(state, format("Design Evaporative Fluid Cooler Load = {:.2R}", DesEvapFluidCoolerLoad));
1982 0 : ShowContinueError(state, format("Design Evaporative Fluid Cooler Water Volume Flow Rate = {:.2R}", par1));
1983 0 : ShowContinueError(state, format("Design Evaporative Fluid Cooler Air Volume Flow Rate = {:.2R}", par2));
1984 0 : ShowContinueError(state, format("Design Evaporative Fluid Cooler Air Inlet Wet-bulb Temp = {:.2R}", this->inletConds.AirWetBulb));
1985 0 : ShowContinueError(state, format("Design Evaporative Fluid Cooler Water Inlet Temp = {:.2R}", this->inletConds.WaterTemp));
1986 0 : ShowContinueError(state,
1987 0 : format("Design Exit Water Temp = {:.2R}",
1988 0 : state.dataSize->PlantSizData(PltSizCondNum).ExitTemp));
1989 0 : ShowContinueError(state, format("Design Evaporative Fluid Cooler Water Inlet Temp [C] = {:.2R}", this->inletConds.WaterTemp));
1990 0 : ShowContinueError(state, format("Calculated water outlet temperature at low UA({:.2R}) = {:.2R}", UA0, OutWaterTempAtUA0));
1991 0 : ShowContinueError(state, format("Calculated water outlet temperature at high UA({:.2R}) = {:.2R}", UA1, OutWaterTempAtUA1));
1992 0 : ShowFatalError(state, "Autosizing of Evaporative Fluid Cooler UA failed for Evaporative Fluid Cooler = " + this->Name);
1993 : }
1994 0 : this->LowSpeedEvapFluidCoolerUA = UA;
1995 : } else {
1996 0 : this->LowSpeedEvapFluidCoolerUA = 0.0;
1997 : }
1998 0 : if (state.dataPlnt->PlantFirstSizesOkayToFinalize) {
1999 0 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
2000 0 : BaseSizer::reportSizerOutput(state,
2001 : this->EvapFluidCoolerType,
2002 : this->Name,
2003 : "U-Factor Times Area Value at Low Fan Speed [W/C]",
2004 0 : this->LowSpeedEvapFluidCoolerUA);
2005 : }
2006 0 : if (state.dataPlnt->PlantFirstSizesOkayToReport) {
2007 0 : BaseSizer::reportSizerOutput(state,
2008 : this->EvapFluidCoolerType,
2009 : this->Name,
2010 : "Initial U-Factor Times Area Value at Low Fan Speed [W/C]",
2011 0 : this->LowSpeedEvapFluidCoolerUA);
2012 : }
2013 : }
2014 : }
2015 :
2016 15 : if (state.dataPlnt->PlantFinalSizesOkayToReport) {
2017 : // create predefined report
2018 6 : std::string equipName = this->Name;
2019 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchMechType, equipName, this->EvapFluidCoolerType);
2020 6 : OutputReportPredefined::PreDefTableEntry(
2021 3 : state, state.dataOutRptPredefined->pdchMechNomCap, equipName, this->HighSpeedStandardDesignCapacity);
2022 : }
2023 15 : }
2024 :
2025 23565 : void EvapFluidCoolerSpecs::CalcSingleSpeedEvapFluidCooler(EnergyPlusData &state)
2026 : {
2027 :
2028 : // SUBROUTINE INFORMATION:
2029 : // AUTHOR Chandan Sharma
2030 : // DATE WRITTEN May 2009
2031 : // MODIFIED na
2032 : // RE-ENGINEERED na
2033 :
2034 : // PURPOSE OF THIS SUBROUTINE:
2035 : // To simulate the operation of a single-speed fan evaporative fluid cooler.
2036 :
2037 : // METHODOLOGY EMPLOYED:
2038 : // The evaporative fluid cooler is modeled using effectiveness-NTU relationships for
2039 : // counterflow heat exchangers based on Merkel's theory.
2040 : // The subroutine calculates the period of time required to meet a
2041 : // leaving water temperature setpoint. It assumes that part-load
2042 : // operation represents a linear interpolation of two steady-state regimes.
2043 : // Cyclic losses are neglected. The period of time required to meet the
2044 : // leaving water temperature setpoint is used to determine the required
2045 : // fan power and energy.
2046 : // A RunFlag is passed by the upper level manager to indicate the ON/OFF status,
2047 : // or schedule, of the evaporative fluid cooler. If the evaporative fluid cooler is OFF, outlet water
2048 : // temperature and flow rate are passed through the model from inlet node to
2049 : // outlet node without intervention. Reports are also updated with fan power and energy being zero.
2050 : // When the RunFlag indicates an ON condition for the evaporative fluid cooler, the
2051 : // mass flow rate and water temperature are read from the inlet node of the
2052 : // evaporative fluid cooler (water-side). The outdoor air wet-bulb temperature is used
2053 : // as the entering condition to the evaporative fluid cooler (air-side).
2054 : // The evaporative fluid cooler fan is turned on and design parameters are used
2055 : // to calculate the leaving water temperature.
2056 : // If the calculated leaving water temperature is below the setpoint, a fan
2057 : // run-time fraction is calculated and used to determine fan power. The leaving
2058 : // water temperature setpoint is placed on the outlet node. If the calculated
2059 : // leaving water temperature is at or above the setpoint, the calculated
2060 : // leaving water temperature is placed on the outlet node and the fan runs at
2061 : // full power. Water mass flow rate is passed from inlet node to outlet node
2062 : // with no intervention.
2063 : // REFERENCES:
2064 : // ASHRAE HVAC1KIT: A Toolkit for Primary HVAC System Energy Calculation. 1999.
2065 :
2066 : // Based on SingleSpeedTower subroutine by Dan Fisher ,Sept 1998
2067 : // Dec. 2008. BG. added RunFlag logic per original methodology
2068 :
2069 : static constexpr std::string_view RoutineName("CalcSingleSpeedEvapFluidCooler");
2070 23565 : int constexpr MaxIteration(100); // Maximum fluid bypass iteration calculations
2071 26101 : std::string const MaxItChar("100");
2072 23565 : Real64 constexpr BypassFractionThreshold(0.01); // Threshold to stop bypass iteration
2073 23565 : Real64 constexpr OWTLowerLimit(0.0); // The limit of evaporative fluid cooler exit fluid temperature used
2074 : // in the fluid bypass calculation to avoid fluid freezing. For water,
2075 : // it is 0 degreeC and for glycols, it can be much lower. The fluid type
2076 : // is stored at the loop. Current choices are Water and Steam,
2077 : // needs to expand for glycols
2078 :
2079 : Real64 AirFlowRate;
2080 23565 : Real64 UAdesign = 0.0; // UA value at design conditions (entered by user or calculated)
2081 : Real64 CpWater;
2082 23565 : Real64 TempSetPoint = 0.0;
2083 :
2084 : // set inlet and outlet nodes
2085 23565 : this->WaterInletNode = this->WaterInletNodeNum;
2086 23565 : this->WaterOutletNode = this->WaterOutletNodeNum;
2087 23565 : this->Qactual = 0.0;
2088 23565 : this->FanPower = 0.0;
2089 23565 : Real64 inletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNode).Temp;
2090 23565 : this->OutletWaterTemp = inletWaterTemp;
2091 23565 : AirFlowRate = 0.0;
2092 :
2093 26101 : auto loopSide = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum);
2094 23565 : auto calcScheme = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopDemandCalcScheme;
2095 23565 : if (calcScheme == DataPlant::LoopDemandCalcScheme::SingleSetPoint) {
2096 23565 : TempSetPoint = loopSide.TempSetPoint;
2097 0 : } else if (calcScheme == DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand) {
2098 0 : TempSetPoint = loopSide.TempSetPointHi;
2099 : }
2100 :
2101 : // Added for fluid bypass. First assume no fluid bypass
2102 23565 : int BypassFlag = 0;
2103 23565 : this->BypassFraction = 0.0;
2104 :
2105 : // MassFlowTol is a parameter to indicate a no flow condition
2106 28637 : if (this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance ||
2107 5072 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked)
2108 21029 : return;
2109 :
2110 2536 : if (inletWaterTemp > TempSetPoint) {
2111 : // Turn on evaporative fluid cooler fan
2112 2536 : UAdesign = this->HighSpeedEvapFluidCoolerUA;
2113 2536 : AirFlowRate = this->HighSpeedAirFlowRate;
2114 2536 : Real64 FanPowerOn = this->HighSpeedFanPower;
2115 :
2116 2536 : this->SimSimpleEvapFluidCooler(state, this->WaterMassFlowRate, AirFlowRate, UAdesign, this->OutletWaterTemp);
2117 :
2118 2536 : if (this->OutletWaterTemp <= TempSetPoint) {
2119 0 : if (this->capacityControl == CapacityControl::FanCycling || this->OutletWaterTemp <= OWTLowerLimit) {
2120 : // Setpoint was met with pump ON and fan ON, calculate run-time fraction
2121 0 : Real64 FanModeFrac = (TempSetPoint - inletWaterTemp) / (this->OutletWaterTemp - inletWaterTemp);
2122 0 : this->FanPower = FanModeFrac * FanPowerOn;
2123 0 : this->OutletWaterTemp = TempSetPoint;
2124 : } else {
2125 : // FluidBypass, fan runs at full speed for the entire time step
2126 : // FanModeFrac = 1.0;
2127 0 : this->FanPower = FanPowerOn;
2128 0 : BypassFlag = 1;
2129 : }
2130 : } else {
2131 : // Setpoint was not met, evaporative fluid cooler ran at full capacity
2132 : // FanModeFrac = 1.0;
2133 2536 : this->FanPower = FanPowerOn;
2134 : }
2135 0 : } else if (inletWaterTemp <= TempSetPoint) {
2136 : // Inlet water temperature lower than setpoint, assume 100% bypass, evaporative fluid cooler fan off
2137 0 : if (this->capacityControl == CapacityControl::FluidBypass) {
2138 0 : if (inletWaterTemp > OWTLowerLimit) {
2139 0 : this->FanPower = 0.0;
2140 0 : this->BypassFraction = 1.0;
2141 0 : this->OutletWaterTemp = inletWaterTemp;
2142 : }
2143 : }
2144 : }
2145 :
2146 : // Calculate bypass fraction since OWTLowerLimit < OutletWaterTemp < TempSetPoint.
2147 : // The iteration ends when the numer of iteration exceeds the limit or the difference
2148 : // between the new and old bypass fractions is less than the threshold.
2149 2536 : if (BypassFlag == 1) {
2150 0 : Real64 bypassFraction = (TempSetPoint - this->OutletWaterTemp) / (inletWaterTemp - this->OutletWaterTemp);
2151 0 : if (bypassFraction > 1.0 || bypassFraction < 0.0) {
2152 : // Bypass cannot meet setpoint, assume no bypass
2153 0 : this->BypassFraction = 0.0;
2154 0 : AirFlowRate = 0.0;
2155 : } else {
2156 0 : int NumIteration = 0;
2157 0 : Real64 BypassFraction2 = 0.0; // Fluid bypass fraction
2158 0 : Real64 BypassFractionPrev = bypassFraction;
2159 0 : Real64 OutletWaterTempPrev = this->OutletWaterTemp;
2160 0 : while (NumIteration < MaxIteration) {
2161 0 : ++NumIteration;
2162 : // need to iterate for the new OutletWaterTemp while bypassing evaporative fluid cooler water
2163 0 : this->SimSimpleEvapFluidCooler(
2164 0 : state, this->WaterMassFlowRate * (1.0 - bypassFraction), AirFlowRate, UAdesign, this->OutletWaterTemp);
2165 : // Calc new bypassFraction based on the new OutletWaterTemp
2166 0 : if (std::abs(this->OutletWaterTemp - OWTLowerLimit) <= 0.01) {
2167 0 : BypassFraction2 = bypassFraction;
2168 0 : break;
2169 0 : } else if (this->OutletWaterTemp < OWTLowerLimit) {
2170 : // Set OutletWaterTemp = OWTLowerLimit, and use linear interpolation to calculate the bypassFraction
2171 0 : BypassFraction2 = BypassFractionPrev - (BypassFractionPrev - bypassFraction) * (OutletWaterTempPrev - OWTLowerLimit) /
2172 0 : (OutletWaterTempPrev - this->OutletWaterTemp);
2173 0 : this->SimSimpleEvapFluidCooler(
2174 0 : state, this->WaterMassFlowRate * (1.0 - BypassFraction2), AirFlowRate, UAdesign, this->OutletWaterTemp);
2175 0 : if (this->OutletWaterTemp < OWTLowerLimit) {
2176 : // Use previous iteraction values
2177 0 : BypassFraction2 = BypassFractionPrev;
2178 0 : this->OutletWaterTemp = OutletWaterTempPrev;
2179 : }
2180 0 : break;
2181 : } else {
2182 0 : BypassFraction2 = (TempSetPoint - this->OutletWaterTemp) / (inletWaterTemp - this->OutletWaterTemp);
2183 : }
2184 : // Compare two bypassFraction to determine when to stop
2185 0 : if (std::abs(BypassFraction2 - bypassFraction) <= BypassFractionThreshold) break;
2186 0 : BypassFractionPrev = bypassFraction;
2187 0 : OutletWaterTempPrev = this->OutletWaterTemp;
2188 0 : bypassFraction = BypassFraction2;
2189 : }
2190 0 : if (NumIteration > MaxIteration) {
2191 0 : ShowWarningError(state,
2192 0 : "Evaporative fluid cooler fluid bypass iteration exceeds maximum limit of " + MaxItChar + " for " + this->Name);
2193 : }
2194 0 : this->BypassFraction = BypassFraction2;
2195 : // may not meet TempSetPoint due to limit of evaporative fluid cooler outlet temp to OWTLowerLimit
2196 0 : this->OutletWaterTemp = (1.0 - BypassFraction2) * this->OutletWaterTemp + BypassFraction2 * inletWaterTemp;
2197 : }
2198 : }
2199 :
2200 : // Should this be water inlet node num?????
2201 7608 : CpWater = FluidProperties::GetSpecificHeatGlycol(state,
2202 2536 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
2203 2536 : state.dataLoopNodes->Node(this->WaterInletNode).Temp,
2204 2536 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
2205 : RoutineName);
2206 2536 : this->Qactual = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNode).Temp - this->OutletWaterTemp);
2207 2536 : this->AirFlowRateRatio = AirFlowRate / this->HighSpeedAirFlowRate;
2208 : }
2209 :
2210 45116 : void EvapFluidCoolerSpecs::CalcTwoSpeedEvapFluidCooler(EnergyPlusData &state)
2211 : {
2212 :
2213 : // SUBROUTINE INFORMATION:
2214 : // AUTHOR Chandan Sharma
2215 : // DATE WRITTEN May 2009
2216 : // MODIFIED na
2217 : // RE-ENGINEERED na
2218 :
2219 : // PURPOSE OF THIS SUBROUTINE:
2220 : // To simulate the operation of a evaporative fluid cooler with a two-speed fan.
2221 :
2222 : // METHODOLOGY EMPLOYED:
2223 : // The evaporative fluid cooler is modeled using effectiveness-NTU relationships for
2224 : // counterflow heat exchangers based on Merkel's theory.
2225 : // The subroutine calculates the period of time required to meet a
2226 : // leaving water temperature setpoint. It assumes that part-load
2227 : // operation represents a linear interpolation of three steady-state regimes
2228 : // (high-speed fan operation and low-speed fan operation ).
2229 : // Cyclic losses are neglected. The period of time required to meet the
2230 : // leaving water temperature setpoint is used to determine the required
2231 : // fan power and energy. When the leaving water temperature is at or above the setpoint
2232 : // the evaporative fluid cooler fan is turned on,
2233 : // .
2234 : // A RunFlag is passed by the upper level manager to indicate the ON/OFF status,
2235 : // or schedule, of the evaporative fluid cooler. If the evaporative fluid cooler is OFF, outlet water
2236 : // temperature and flow rate are passed through the model from inlet node to
2237 : // outlet node without intervention. Reports are also updated with fan power and fan energy being zero.
2238 : // When the RunFlag indicates an ON condition for the evaporative fluid cooler, the
2239 : // mass flow rate and water temperature are read from the inlet node of the
2240 : // evaporative fluid cooler (water-side). The outdoor air wet-bulb temperature is used
2241 : // as the entering condition to the evaporative fluid cooler (air-side). If the incoming
2242 : // water temperature is above the setpoint, the evaporative fluid cooler fan is turned on
2243 : // and parameters for low fan speed are used to again calculate the leaving
2244 : // water temperature. If the calculated leaving water temperature is
2245 : // below the setpoint, a fan run-time fraction (FanModeFrac) is calculated and
2246 : // used to determine fan power. The leaving water temperature setpoint is placed
2247 : // on the outlet node. If the calculated leaving water temperature is at or above
2248 : // the setpoint, the evaporative fluid cooler fan is turned on 'high speed' and the routine is
2249 : // repeated. If the calculated leaving water temperature is below the setpoint,
2250 : // a fan run-time fraction is calculated for the second stage fan and fan power
2251 : // is calculated as FanModeFrac*HighSpeedFanPower+(1-FanModeFrac)*LowSpeedFanPower.
2252 : // If the calculated leaving water temperature is above the leaving water temp.
2253 : // setpoint, the calculated leaving water temperature is placed on the outlet
2254 : // node and the fan runs at full power (High Speed Fan Power). Water mass flow
2255 : // rate is passed from inlet node to outlet node with no intervention.
2256 : // REFERENCES:
2257 : // ASHRAE HVAC1KIT: A Toolkit for Primary HVAC System Energy Calculation. 1999.
2258 : // Based on TwoSpeedTower by Dan Fisher ,Sept. 1998
2259 : // Dec. 2008. BG. added RunFlag logic per original methodology
2260 :
2261 : static constexpr std::string_view RoutineName("CalcTwoSpeedEvapFluidCooler");
2262 :
2263 45116 : this->WaterInletNode = this->WaterInletNodeNum;
2264 45116 : this->WaterOutletNode = this->WaterOutletNodeNum;
2265 45116 : this->Qactual = 0.0;
2266 45116 : this->FanPower = 0.0;
2267 45116 : this->InletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNode).Temp;
2268 45116 : this->OutletWaterTemp = this->InletWaterTemp;
2269 :
2270 45116 : Real64 OutletWaterTemp1stStage = this->OutletWaterTemp;
2271 45116 : Real64 OutletWaterTemp2ndStage = this->OutletWaterTemp;
2272 45116 : Real64 AirFlowRate = 0.0;
2273 45116 : Real64 TempSetPoint = 0.0;
2274 45116 : switch (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopDemandCalcScheme) {
2275 23566 : case DataPlant::LoopDemandCalcScheme::SingleSetPoint: {
2276 23566 : TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPoint;
2277 23566 : } break;
2278 21550 : case DataPlant::LoopDemandCalcScheme::DualSetPointDeadBand: {
2279 21550 : TempSetPoint = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).TempSetPointHi;
2280 21550 : } break;
2281 0 : default:
2282 0 : break;
2283 : }
2284 :
2285 : // MassFlowTol is a parameter to indicate a no flow condition
2286 60522 : if (this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance ||
2287 15406 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked)
2288 37413 : return;
2289 :
2290 7703 : if (this->InletWaterTemp > TempSetPoint) {
2291 : // Setpoint was not met ,turn on evaporative fluid cooler 1st stage fan
2292 7703 : Real64 UAdesign = this->LowSpeedEvapFluidCoolerUA;
2293 7703 : AirFlowRate = this->LowSpeedAirFlowRate;
2294 7703 : Real64 FanPowerLow = this->LowSpeedFanPower;
2295 : Real64 FanPowerHigh;
2296 7703 : this->SimSimpleEvapFluidCooler(state, this->WaterMassFlowRate, AirFlowRate, UAdesign, OutletWaterTemp1stStage);
2297 :
2298 7703 : if (OutletWaterTemp1stStage <= TempSetPoint) {
2299 : // Setpoint was met with pump ON and fan ON 1st stage, calculate fan mode fraction
2300 3907 : Real64 FanModeFrac = (TempSetPoint - this->InletWaterTemp) / (OutletWaterTemp1stStage - this->InletWaterTemp);
2301 3907 : this->FanPower = FanModeFrac * FanPowerLow;
2302 3907 : this->OutletWaterTemp = TempSetPoint;
2303 3907 : this->Qactual *= FanModeFrac;
2304 : } else {
2305 : // Setpoint was not met, turn on evaporative fluid cooler 2nd stage fan
2306 3796 : UAdesign = this->HighSpeedEvapFluidCoolerUA;
2307 3796 : AirFlowRate = this->HighSpeedAirFlowRate;
2308 3796 : FanPowerHigh = this->HighSpeedFanPower;
2309 :
2310 3796 : this->SimSimpleEvapFluidCooler(state, this->WaterMassFlowRate, AirFlowRate, UAdesign, OutletWaterTemp2ndStage);
2311 :
2312 3796 : if ((OutletWaterTemp2ndStage <= TempSetPoint) && UAdesign > 0.0) {
2313 : // Setpoint was met with pump ON and fan ON 2nd stage, calculate fan mode fraction
2314 1260 : Real64 FanModeFrac = (TempSetPoint - OutletWaterTemp1stStage) / (OutletWaterTemp2ndStage - OutletWaterTemp1stStage);
2315 1260 : this->FanPower = (FanModeFrac * FanPowerHigh) + (1.0 - FanModeFrac) * FanPowerLow;
2316 1260 : this->OutletWaterTemp = TempSetPoint;
2317 : } else {
2318 : // Setpoint was not met, evaporative fluid cooler ran at full capacity
2319 2536 : this->OutletWaterTemp = OutletWaterTemp2ndStage;
2320 2536 : this->FanPower = FanPowerHigh;
2321 : }
2322 : }
2323 : }
2324 :
2325 : // Should this be water inlet node num??
2326 23109 : Real64 CpWater = FluidProperties::GetSpecificHeatGlycol(state,
2327 7703 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
2328 7703 : state.dataLoopNodes->Node(this->WaterInletNode).Temp,
2329 7703 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
2330 7703 : RoutineName);
2331 7703 : this->Qactual = this->WaterMassFlowRate * CpWater * (state.dataLoopNodes->Node(this->WaterInletNode).Temp - this->OutletWaterTemp);
2332 7703 : this->AirFlowRateRatio = AirFlowRate / this->HighSpeedAirFlowRate;
2333 : }
2334 :
2335 14184 : void EvapFluidCoolerSpecs::SimSimpleEvapFluidCooler(
2336 : EnergyPlusData &state, Real64 const waterMassFlowRate, Real64 const AirFlowRate, Real64 const UAdesign, Real64 &outletWaterTemp)
2337 : {
2338 :
2339 : // SUBROUTINE INFORMATION:
2340 : // AUTHOR Chandan Sharma
2341 : // DATE WRITTEN May 2009
2342 : // MODIFIED na
2343 : // RE-ENGINEERED na
2344 :
2345 : // PURPOSE OF THIS SUBROUTINE:
2346 : // See purpose for single speed or Two speed evaporative fluid cooler model
2347 :
2348 : // METHODOLOGY EMPLOYED:
2349 : // See methodology for single speed or two speed evaporative fluid cooler model
2350 :
2351 : // REFERENCES:
2352 : // Based on SimTower subroutine by Dan Fisher Sept. 1998
2353 : // Merkel, F. 1925. Verduftungskuhlung. VDI Forschungsarbeiten, Nr 275, Berlin.
2354 : // ASHRAE 1999. HVAC1KIT: A Toolkit for Primary HVAC System Energy Calculations.
2355 :
2356 14184 : int constexpr IterMax(50); // Maximum number of iterations allowed
2357 14184 : Real64 constexpr WetBulbTolerance(0.00001); // Maximum error for exiting wet-bulb temperature between iterations
2358 14184 : Real64 constexpr DeltaTwbTolerance(0.001); // Maximum error (tolerance) in DeltaTwb for iteration convergence [C]
2359 : static constexpr std::string_view RoutineName("SimSimpleEvapFluidCooler");
2360 :
2361 14184 : this->WaterInletNode = this->WaterInletNodeNum;
2362 14184 : this->WaterOutletNode = this->WaterOutletNodeNum;
2363 14184 : Real64 qActual = 0.0;
2364 14184 : Real64 WetBulbError = 1.0;
2365 14184 : Real64 DeltaTwb = 1.0;
2366 :
2367 : // set local evaporative fluid cooler inlet and outlet temperature variables
2368 14184 : this->InletWaterTemp = this->inletConds.WaterTemp;
2369 14184 : outletWaterTemp = this->InletWaterTemp;
2370 14184 : Real64 InletAirTemp = this->inletConds.AirTemp;
2371 14184 : Real64 InletAirWetBulb = this->inletConds.AirWetBulb;
2372 :
2373 14184 : if (UAdesign == 0.0) return;
2374 :
2375 : // set water and air properties
2376 14184 : Real64 AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state, this->inletConds.AirPress, InletAirTemp, this->inletConds.AirHumRat);
2377 14184 : Real64 AirMassFlowRate = AirFlowRate * AirDensity;
2378 14184 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(this->inletConds.AirHumRat);
2379 28368 : Real64 CpWater = FluidProperties::GetSpecificHeatGlycol(state,
2380 14184 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
2381 : this->InletWaterTemp,
2382 14184 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
2383 14184 : RoutineName);
2384 14184 : Real64 InletAirEnthalpy = Psychrometrics::PsyHFnTdbRhPb(state, InletAirWetBulb, 1.0, this->inletConds.AirPress);
2385 :
2386 : // initialize exiting wet bulb temperature before iterating on final solution
2387 14184 : Real64 OutletAirWetBulb = InletAirWetBulb + 6.0;
2388 :
2389 : // Calculate mass flow rates
2390 14184 : Real64 MdotCpWater = waterMassFlowRate * CpWater;
2391 14184 : int Iter = 0;
2392 113634 : while ((WetBulbError > WetBulbTolerance) && (Iter <= IterMax) && (DeltaTwb > DeltaTwbTolerance)) {
2393 49725 : ++Iter;
2394 49725 : Real64 OutletAirEnthalpy = Psychrometrics::PsyHFnTdbRhPb(state, OutletAirWetBulb, 1.0, this->inletConds.AirPress);
2395 : // calculate the airside specific heat and capacity
2396 49725 : Real64 CpAirside = (OutletAirEnthalpy - InletAirEnthalpy) / (OutletAirWetBulb - InletAirWetBulb);
2397 49725 : Real64 AirCapacity = AirMassFlowRate * CpAirside;
2398 : // calculate the minimum to maximum capacity ratios of airside and waterside
2399 49725 : Real64 CapacityRatioMin = min(AirCapacity, MdotCpWater);
2400 49725 : Real64 CapacityRatioMax = max(AirCapacity, MdotCpWater);
2401 49725 : Real64 CapacityRatio = CapacityRatioMin / CapacityRatioMax;
2402 : // Calculate heat transfer coefficient and number of transfer units (NTU)
2403 49725 : Real64 UAactual = UAdesign * CpAirside / CpAir;
2404 49725 : Real64 NumTransferUnits = UAactual / CapacityRatioMin;
2405 : // calculate heat exchanger effectiveness
2406 : Real64 effectiveness;
2407 49725 : if (CapacityRatio <= 0.995) {
2408 99450 : effectiveness = (1.0 - std::exp(-1.0 * NumTransferUnits * (1.0 - CapacityRatio))) /
2409 49725 : (1.0 - CapacityRatio * std::exp(-1.0 * NumTransferUnits * (1.0 - CapacityRatio)));
2410 : } else {
2411 0 : effectiveness = NumTransferUnits / (1.0 + NumTransferUnits);
2412 : }
2413 : // calculate water to air heat transfer and store last exiting WB temp of air
2414 49725 : qActual = effectiveness * CapacityRatioMin * (this->InletWaterTemp - InletAirWetBulb);
2415 49725 : Real64 OutletAirWetBulbLast = OutletAirWetBulb;
2416 : // calculate new exiting wet bulb temperature of airstream
2417 49725 : OutletAirWetBulb = InletAirWetBulb + qActual / AirCapacity;
2418 : // Check error tolerance and exit if satisfied
2419 49725 : DeltaTwb = std::abs(OutletAirWetBulb - InletAirWetBulb);
2420 : // Add DataGlobalConstants::KelvinConv() to denominator below convert OutletAirWetBulbLast to Kelvin to avoid divide by zero.
2421 : // Wet bulb error units are delta K/K
2422 49725 : WetBulbError = std::abs((OutletAirWetBulb - OutletAirWetBulbLast) / (OutletAirWetBulbLast + DataGlobalConstants::KelvinConv));
2423 : }
2424 :
2425 14184 : if (qActual >= 0.0) {
2426 14184 : outletWaterTemp = this->InletWaterTemp - qActual / MdotCpWater;
2427 : } else {
2428 0 : outletWaterTemp = this->InletWaterTemp;
2429 : }
2430 : }
2431 :
2432 68681 : void EvapFluidCoolerSpecs::CalculateWaterUsage(EnergyPlusData &state)
2433 : {
2434 :
2435 : // SUBROUTINE INFORMATION:
2436 : // AUTHOR Chandan Sharma
2437 : // DATE WRITTEN May 2009
2438 : // MODIFIED na
2439 : // RE-ENGINEERED na
2440 :
2441 : // PURPOSE OF THIS SUBROUTINE:
2442 : // Collect evaporative fluid cooler water useage calculations for
2443 : // reuse by all the evaporative fluid cooler models.
2444 :
2445 : // REFERENCES:
2446 : // Based on CalculateWaterUsage subroutine for cooling tower by B. Griffith, August 2006
2447 :
2448 : static constexpr std::string_view RoutineName("CalculateWaterUsage");
2449 :
2450 68681 : this->BlowdownVdot = 0.0;
2451 68681 : this->EvaporationVdot = 0.0;
2452 :
2453 68681 : Real64 AverageWaterTemp = (this->InletWaterTemp + this->OutletWaterTemp) / 2.0;
2454 :
2455 : // Set water and air properties
2456 68681 : if (this->EvapLossMode == EvapLoss::ByMoistTheory) {
2457 :
2458 : Real64 AirDensity =
2459 68681 : Psychrometrics::PsyRhoAirFnPbTdbW(state, this->inletConds.AirPress, this->inletConds.AirTemp, this->inletConds.AirHumRat);
2460 68681 : Real64 AirMassFlowRate = this->AirFlowRateRatio * this->HighSpeedAirFlowRate * AirDensity;
2461 68681 : Real64 InletAirEnthalpy = Psychrometrics::PsyHFnTdbRhPb(state, this->inletConds.AirWetBulb, 1.0, this->inletConds.AirPress);
2462 :
2463 68681 : if (AirMassFlowRate > 0.0) {
2464 : // Calculate outlet air conditions for determining water usage
2465 :
2466 10239 : Real64 OutletAirEnthalpy = InletAirEnthalpy + this->Qactual / AirMassFlowRate;
2467 10239 : Real64 OutletAirTSat = Psychrometrics::PsyTsatFnHPb(state, OutletAirEnthalpy, this->inletConds.AirPress);
2468 10239 : Real64 OutletAirHumRatSat = Psychrometrics::PsyWFnTdbH(state, OutletAirTSat, OutletAirEnthalpy);
2469 :
2470 : // calculate specific humidity ratios (HUMRAT to mass of moist air not dry air)
2471 10239 : Real64 InSpecificHumRat = this->inletConds.AirHumRat / (1 + this->inletConds.AirHumRat);
2472 10239 : Real64 OutSpecificHumRat = OutletAirHumRatSat / (1 + OutletAirHumRatSat);
2473 :
2474 : // calculate average air temp for density call
2475 10239 : Real64 TairAvg = (this->inletConds.AirTemp + OutletAirTSat) / 2.0;
2476 :
2477 : // Amount of water evaporated
2478 20478 : Real64 rho = FluidProperties::GetDensityGlycol(state,
2479 10239 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
2480 : TairAvg,
2481 10239 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
2482 10239 : RoutineName);
2483 10239 : this->EvaporationVdot = (AirMassFlowRate * (OutSpecificHumRat - InSpecificHumRat)) / rho; // [m3/s]
2484 10239 : if (this->EvaporationVdot < 0.0) this->EvaporationVdot = 0.0;
2485 : } else {
2486 58442 : this->EvaporationVdot = 0.0;
2487 : }
2488 :
2489 0 : } else if (this->EvapLossMode == EvapLoss::ByUserFactor) {
2490 0 : Real64 rho = FluidProperties::GetDensityGlycol(state,
2491 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidName,
2492 : AverageWaterTemp,
2493 0 : state.dataPlnt->PlantLoop(this->plantLoc.loopNum).FluidIndex,
2494 0 : RoutineName);
2495 0 : this->EvaporationVdot = this->UserEvapLossFactor * (this->InletWaterTemp - this->OutletWaterTemp) * (this->WaterMassFlowRate / rho);
2496 0 : if (this->EvaporationVdot < 0.0) this->EvaporationVdot = 0.0;
2497 : } else {
2498 : // should never come here
2499 : }
2500 :
2501 : // amount of water lost due to drift
2502 68681 : this->DriftVdot = this->DesignSprayWaterFlowRate * this->DriftLossFraction * this->AirFlowRateRatio;
2503 :
2504 68681 : if (this->BlowdownMode == Blowdown::BySchedule) {
2505 : // Amount of water lost due to blow down (purging contaminants from evaporative fluid cooler basin)
2506 0 : if (this->SchedIDBlowdown > 0) {
2507 0 : this->BlowdownVdot = ScheduleManager::GetCurrentScheduleValue(state, this->SchedIDBlowdown);
2508 : } else {
2509 0 : this->BlowdownVdot = 0.0;
2510 : }
2511 68681 : } else if (this->BlowdownMode == Blowdown::ByConcentration) {
2512 68681 : if (this->ConcentrationRatio > 2.0) { // protect divide by zero
2513 68681 : this->BlowdownVdot = this->EvaporationVdot / (this->ConcentrationRatio - 1) - this->DriftVdot;
2514 : } else {
2515 0 : this->BlowdownVdot = this->EvaporationVdot - this->DriftVdot;
2516 : }
2517 68681 : if (this->BlowdownVdot < 0.0) this->BlowdownVdot = 0.0;
2518 : } else {
2519 : // should never come here
2520 : }
2521 :
2522 : // Added for fluid bypass
2523 68681 : if (this->capacityControl == CapacityControl::FluidBypass) {
2524 0 : if (this->EvapLossMode == EvapLoss::ByUserFactor) this->EvaporationVdot *= (1 - this->BypassFraction);
2525 0 : this->DriftVdot *= (1 - this->BypassFraction);
2526 0 : this->BlowdownVdot *= (1 - this->BypassFraction);
2527 : }
2528 :
2529 68681 : this->MakeUpVdot = this->EvaporationVdot + this->DriftVdot + this->BlowdownVdot;
2530 :
2531 : // set demand request in Water Storage if needed
2532 68681 : this->StarvedMakeUpVdot = 0.0;
2533 68681 : this->TankSupplyVdot = 0.0;
2534 68681 : if (this->SuppliedByWaterSystem) {
2535 :
2536 : // set demand request
2537 0 : state.dataWaterData->WaterStorage(this->WaterTankID).VdotRequestDemand(this->WaterTankDemandARRID) = this->MakeUpVdot;
2538 :
2539 0 : Real64 AvailTankVdot = state.dataWaterData->WaterStorage(this->WaterTankID)
2540 0 : .VdotAvailDemand(this->WaterTankDemandARRID); // check what tank can currently provide
2541 :
2542 0 : this->TankSupplyVdot = this->MakeUpVdot; // init
2543 0 : if (AvailTankVdot < this->MakeUpVdot) { // calculate starved flow
2544 0 : this->StarvedMakeUpVdot = this->MakeUpVdot - AvailTankVdot;
2545 0 : this->TankSupplyVdot = AvailTankVdot;
2546 : }
2547 : } else { // supplied by mains
2548 : }
2549 :
2550 : // total water usage
2551 : // update report variables
2552 68681 : this->EvaporationVol = this->EvaporationVdot * (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour);
2553 68681 : this->DriftVol = this->DriftVdot * (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour);
2554 68681 : this->BlowdownVol = this->BlowdownVdot * (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour);
2555 68681 : this->MakeUpVol = this->MakeUpVdot * (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour);
2556 68681 : this->TankSupplyVol = this->TankSupplyVdot * (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour);
2557 68681 : this->StarvedMakeUpVol = this->StarvedMakeUpVdot * (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour);
2558 68681 : }
2559 :
2560 68681 : void EvapFluidCoolerSpecs::UpdateEvapFluidCooler(EnergyPlusData &state)
2561 : {
2562 :
2563 : // SUBROUTINE INFORMATION:
2564 : // AUTHOR: Chandan Sharma
2565 : // DATE WRITTEN: May 2009
2566 : // MODIFIED na
2567 : // RE-ENGINEERED na
2568 :
2569 : // PURPOSE OF THIS SUBROUTINE:
2570 : // This subroutine is for passing results to the outlet water node.
2571 :
2572 68681 : Real64 constexpr TempAllowance(0.02); // Minimum difference b/w fluid cooler water outlet temp and
2573 73553 : std::string CharErrOut;
2574 73553 : std::string CharLowOutletTemp;
2575 :
2576 68681 : state.dataLoopNodes->Node(this->WaterOutletNode).Temp = this->OutletWaterTemp;
2577 :
2578 103013 : if (state.dataPlnt->PlantLoop(this->plantLoc.loopNum).LoopSide(this->plantLoc.loopSideNum).FlowLock == DataPlant::FlowLock::Unlocked ||
2579 34332 : state.dataGlobal->WarmupFlag)
2580 63809 : return;
2581 :
2582 : // Check flow rate through evaporative fluid cooler and compare to design flow rate,
2583 : // show warning if greater than Design * Mulitplier
2584 9744 : if (state.dataLoopNodes->Node(this->WaterOutletNode).MassFlowRate >
2585 4872 : this->DesWaterMassFlowRate * this->EvapFluidCoolerMassFlowRateMultiplier) {
2586 0 : ++this->HighMassFlowErrorCount;
2587 0 : if (this->HighMassFlowErrorCount < 2) {
2588 0 : ShowWarningError(state, this->EvapFluidCoolerType + " \"" + this->Name + "\"");
2589 0 : ShowContinueError(state, " Condenser Loop Mass Flow Rate is much greater than the evaporative fluid coolers design mass flow rate.");
2590 0 : ShowContinueError(state,
2591 0 : format(" Condenser Loop Mass Flow Rate = {:.6T}", state.dataLoopNodes->Node(this->WaterOutletNode).MassFlowRate));
2592 0 : ShowContinueError(state, format(" Evaporative Fluid Cooler Design Mass Flow Rate = {:.6T}", this->DesWaterMassFlowRate));
2593 0 : ShowContinueErrorTimeStamp(state, "");
2594 : } else {
2595 0 : ShowRecurringWarningErrorAtEnd(
2596 : state,
2597 0 : this->EvapFluidCoolerType + " \"" + this->Name +
2598 : "\" Condenser Loop Mass Flow Rate is much greater than the evaporative fluid coolers design mass flow rate error",
2599 : this->HighMassFlowErrorIndex,
2600 0 : state.dataLoopNodes->Node(this->WaterOutletNode).MassFlowRate,
2601 0 : state.dataLoopNodes->Node(this->WaterOutletNode).MassFlowRate);
2602 : }
2603 : }
2604 :
2605 : // Check if OutletWaterTemp is below the minimum condenser loop temp and warn user
2606 4872 : Real64 LoopMinTemp = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MinTemp;
2607 4872 : Real64 TempDifference = state.dataPlnt->PlantLoop(this->plantLoc.loopNum).MinTemp - this->OutletWaterTemp;
2608 4872 : if (TempDifference > TempAllowance && this->WaterMassFlowRate > 0.0) {
2609 0 : ++this->OutletWaterTempErrorCount;
2610 0 : if (this->OutletWaterTempErrorCount < 2) {
2611 0 : ShowWarningError(state, this->EvapFluidCoolerType + " \"" + this->Name + "\"");
2612 0 : ShowContinueError(state,
2613 0 : format("Evaporative fluid cooler water outlet temperature ({:6.2F} C) is below the specified minimum condenser "
2614 : "loop temp of {:6.2F} C",
2615 : this->OutletWaterTemp,
2616 0 : LoopMinTemp));
2617 0 : ShowContinueErrorTimeStamp(state, "");
2618 : } else {
2619 0 : ShowRecurringWarningErrorAtEnd(
2620 : state,
2621 0 : this->EvapFluidCoolerType + " \"" + this->Name +
2622 : "\" Evaporative fluid cooler water outlet temperature is below the specified minimum condenser loop temp error",
2623 : this->OutletWaterTempErrorIndex,
2624 : this->OutletWaterTemp,
2625 : this->OutletWaterTemp);
2626 : }
2627 : }
2628 :
2629 : // Check if water mass flow rate is small (e.g. no flow) and warn user
2630 4872 : if (this->WaterMassFlowRate > 0.0 && this->WaterMassFlowRate <= DataBranchAirLoopPlant::MassFlowTolerance) {
2631 0 : ++this->SmallWaterMassFlowErrorCount;
2632 0 : if (this->SmallWaterMassFlowErrorCount < 2) {
2633 0 : ShowWarningError(state, this->EvapFluidCoolerType + " \"" + this->Name + "\"");
2634 0 : ShowContinueError(state, "Evaporative fluid cooler water mass flow rate near zero.");
2635 0 : ShowContinueErrorTimeStamp(state, "");
2636 0 : ShowContinueError(state, format("Actual Mass flow = {:.2T}", this->WaterMassFlowRate));
2637 : } else {
2638 0 : ShowRecurringWarningErrorAtEnd(state,
2639 0 : this->EvapFluidCoolerType + " \"" + this->Name +
2640 : "\" Evaporative fluid cooler water mass flow rate near zero error continues...",
2641 : this->SmallWaterMassFlowErrorIndex,
2642 : this->WaterMassFlowRate,
2643 : this->WaterMassFlowRate);
2644 : }
2645 : }
2646 : }
2647 :
2648 68681 : void EvapFluidCoolerSpecs::ReportEvapFluidCooler(EnergyPlusData &state, bool const RunFlag)
2649 : {
2650 :
2651 : // SUBROUTINE INFORMATION:
2652 : // AUTHOR: Chandan Sharma
2653 : // DATE WRITTEN: May 2009
2654 : // MODIFIED na
2655 : // RE-ENGINEERED na
2656 :
2657 : // PURPOSE OF THIS SUBROUTINE:
2658 : // This subroutine updates the report variables for the evaporative fluid cooler.
2659 :
2660 68681 : Real64 const ReportingConstant = state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
2661 :
2662 68681 : if (!RunFlag) {
2663 48203 : this->fluidCoolerInletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNode).Temp;
2664 48203 : this->fluidCoolerOutletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNode).Temp;
2665 48203 : this->Qactual = 0.0;
2666 48203 : this->FanPower = 0.0;
2667 48203 : this->FanEnergy = 0.0;
2668 48203 : this->AirFlowRateRatio = 0.0;
2669 48203 : this->WaterAmountUsed = 0.0;
2670 48203 : this->BypassFraction = 0.0;
2671 : } else {
2672 20478 : this->fluidCoolerInletWaterTemp = state.dataLoopNodes->Node(this->WaterInletNode).Temp;
2673 20478 : this->fluidCoolerOutletWaterTemp = this->OutletWaterTemp;
2674 20478 : this->FanEnergy = this->FanPower * ReportingConstant;
2675 20478 : this->WaterAmountUsed = this->WaterUsage * ReportingConstant;
2676 : }
2677 68681 : }
2678 :
2679 68696 : void EvapFluidCoolerSpecs::oneTimeInit(EnergyPlusData &state)
2680 : {
2681 68696 : bool ErrorsFound(false); // Flag if input data errors are found
2682 :
2683 68696 : if (this->MyOneTimeFlag) {
2684 :
2685 3 : this->setupOutputVars(state);
2686 :
2687 3 : this->FluidIndex = state.dataPlnt->PlantLoop(state.dataSize->CurLoopNum).FluidIndex;
2688 6 : std::string FluidName = FluidProperties::GetGlycolNameByIndex(state, this->FluidIndex);
2689 :
2690 3 : if (UtilityRoutines::SameString(this->PerformanceInputMethod, "STANDARDDESIGNCAPACITY")) {
2691 0 : this->PerformanceInputMethod_Num = PIM::StandardDesignCapacity;
2692 0 : if (FluidName != "WATER") {
2693 0 : ShowSevereError(state,
2694 0 : state.dataIPShortCut->cCurrentModuleObject + " = \"" + this->Name +
2695 : R"(". StandardDesignCapacity performance input method is only valid for fluid type = "Water".)");
2696 0 : ShowContinueError(state,
2697 0 : "Currently, Fluid Type = " + FluidName +
2698 0 : " in CondenserLoop = " + state.dataPlnt->PlantLoop(state.dataSize->CurLoopNum).Name);
2699 0 : ErrorsFound = true;
2700 : }
2701 : }
2702 :
2703 3 : this->MyOneTimeFlag = false;
2704 : }
2705 :
2706 68696 : if (this->OneTimeFlagForEachEvapFluidCooler) {
2707 : // Locate the tower on the plant loops for later usage
2708 3 : PlantUtilities::ScanPlantLoopsForObject(state, this->Name, this->Type, this->plantLoc, ErrorsFound, _, _, _, _, _);
2709 :
2710 3 : if (ErrorsFound) {
2711 0 : ShowFatalError(state, "InitEvapFluidCooler: Program terminated due to previous condition(s).");
2712 : }
2713 :
2714 3 : if (this->Type == DataPlant::PlantEquipmentType::EvapFluidCooler_TwoSpd) {
2715 2 : if (this->DesignWaterFlowRate > 0.0) {
2716 0 : if (this->HighSpeedAirFlowRate <= this->LowSpeedAirFlowRate) {
2717 0 : ShowSevereError(state,
2718 0 : "EvaporativeFluidCooler:TwoSpeed \"" + this->Name +
2719 : "\". Low speed air flow rate must be less than the high speed air flow rate.");
2720 0 : ErrorsFound = true;
2721 : }
2722 0 : if ((this->HighSpeedEvapFluidCoolerUA > 0.0) && (this->LowSpeedEvapFluidCoolerUA > 0.0) &&
2723 0 : (this->HighSpeedEvapFluidCoolerUA <= this->LowSpeedEvapFluidCoolerUA)) {
2724 0 : ShowSevereError(state,
2725 0 : "EvaporativeFluidCooler:TwoSpeed \"" + this->Name +
2726 : "\". Evaporative fluid cooler UA at low fan speed must be less than the evaporative fluid cooler UA at "
2727 : "high fan speed.");
2728 0 : ErrorsFound = true;
2729 : }
2730 : }
2731 : }
2732 :
2733 3 : if (ErrorsFound) {
2734 0 : ShowFatalError(state, "InitEvapFluidCooler: Program terminated due to previous condition(s).");
2735 : }
2736 :
2737 3 : this->OneTimeFlagForEachEvapFluidCooler = false;
2738 : }
2739 68696 : }
2740 :
2741 : } // namespace EvaporativeFluidCoolers
2742 :
2743 2313 : } // namespace EnergyPlus
|