Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cassert>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Array1D.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Construction.hh>
57 : #include <EnergyPlus/Data/EnergyPlusData.hh>
58 : #include <EnergyPlus/DataEnvironment.hh>
59 : #include <EnergyPlus/DataHVACGlobals.hh>
60 : #include <EnergyPlus/DataHeatBalance.hh>
61 : #include <EnergyPlus/DataIPShortCuts.hh>
62 : #include <EnergyPlus/DataSurfaces.hh>
63 : #include <EnergyPlus/DataWater.hh>
64 : #include <EnergyPlus/EcoRoofManager.hh>
65 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
66 : #include <EnergyPlus/OutputProcessor.hh>
67 : #include <EnergyPlus/OutputReportPredefined.hh>
68 : #include <EnergyPlus/ScheduleManager.hh>
69 : #include <EnergyPlus/UtilityRoutines.hh>
70 : #include <EnergyPlus/WaterManager.hh>
71 : #include <EnergyPlus/WeatherManager.hh>
72 :
73 : namespace EnergyPlus {
74 :
75 : namespace WaterManager {
76 :
77 : // Module containing the routines dealing with the management of water
78 :
79 : // MODULE INFORMATION:
80 : // AUTHOR Brent Griffith
81 : // DATE WRITTEN August 2006
82 : // MODIFIED DJS to add ecoroof irrigation Jan 2007
83 : // RE-ENGINEERED na
84 :
85 : using namespace DataWater;
86 :
87 : constexpr std::array<std::string_view, (int)ControlSupplyType::Num> controlSupplyTypeNames = {
88 : "None", "Mains", "GroundwaterWell", "GroundwaterWellMainsBackup", "OtherTank", "OtherTankMainsBackup"};
89 : constexpr std::array<std::string_view, (int)ControlSupplyType::Num> controlSupplyTypeNamesUC = {
90 : "NONE", "MAINS", "GROUNDWATERWELL", "GROUNDWATERWELLMAINSBACKUP", "OTHERTANK", "OTHERTANKMAINSBACKUP"};
91 :
92 : constexpr std::array<std::string_view, (int)TankThermalMode::Num> tankThermalModeNames = {"ScheduledTemperature", "ThermalModel"};
93 : constexpr std::array<std::string_view, (int)TankThermalMode::Num> tankThermalModeNamesUC = {"SCHEDULEDTEMPERATURE", "THERMALMODEL"};
94 :
95 : constexpr std::array<std::string_view, (int)AmbientTempType::Num> ambientTempTypeNames = {"Schedule", "Zone", "Outdoors"};
96 : constexpr std::array<std::string_view, (int)AmbientTempType::Num> ambientTempTypeNamesUC = {"SCHEDULE", "ZONE", "OUTDOORS"};
97 :
98 : constexpr std::array<std::string_view, (int)RainLossFactor::Num> rainLossFactorNames = {"Constant", "Scheduled"};
99 : constexpr std::array<std::string_view, (int)RainLossFactor::Num> rainLossFactorNamesUC = {"CONSTANT", "SCHEDULED"};
100 :
101 : constexpr std::array<std::string_view, (int)GroundWaterTable::Num> groundWaterTableNames = {"Constant", "Scheduled"};
102 : constexpr std::array<std::string_view, (int)GroundWaterTable::Num> groundWaterTableNamesUC = {"CONSTANT", "SCHEDULED"};
103 :
104 : constexpr std::array<std::string_view, (int)IrrigationMode::Num> irrigationModeNames = {"Schedule", "SmartSchedule"};
105 : constexpr std::array<std::string_view, (int)IrrigationMode::Num> irrigationModeNamesUC = {"SCHEDULE", "SMARTSCHEDULE"};
106 :
107 : constexpr std::array<std::string_view, (int)RainfallMode::Num> rainfallModeNames = {"None", "ScheduleAndDesignLevel", "EPWPrecipitation"};
108 : constexpr std::array<std::string_view, (int)RainfallMode::Num> rainfallModeNamesUC = {"NONE", "SCHEDULEANDDESIGNLEVEL", "EPWPRECIPITATION"};
109 :
110 287268 : void ManageWater(EnergyPlusData &state)
111 : {
112 :
113 : // SUBROUTINE INFORMATION:
114 : // AUTHOR B. Griffith
115 : // DATE WRITTEN August 2006
116 : // MODIFIED na
117 : // RE-ENGINEERED na
118 :
119 : // PURPOSE OF THIS SUBROUTINE:
120 : // This is the top-level driver subroutine for managine water systems in the building
121 : // Routine is called at the system timestep level from ManageHVAC
122 : // (somewhat analogous to SimHVAC)
123 :
124 : // METHODOLOGY EMPLOYED:
125 : // State variables are continually recalculated each system iteration
126 : // except when appropriate to update them. IF this module is moved up
127 : // to a different timestep (with less iteration), then numerical solution
128 : // may need to be added. Iteration is being used to solve interdependencies
129 : // of storage, supply, and demand modeling of water system.
130 : // Most data are declared in data-only module DataWater.hh
131 : // Calling order,
132 : // storage tanks
133 : // supply
134 : // demands
135 : // IF first/last timestep, then do an update.
136 :
137 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
138 287268 : int RainColNum(0);
139 287268 : int TankNum(0);
140 287268 : int WellNum(0);
141 :
142 287268 : if (state.dataWaterManager->GetInputFlag) {
143 102 : GetWaterManagerInput(state);
144 102 : state.dataWaterManager->GetInputFlag = false;
145 : }
146 :
147 287268 : if (!(state.dataWaterData->AnyWaterSystemsInModel)) {
148 0 : return;
149 : }
150 :
151 : // this is the main water manager
152 : // first call all the water storage tanks
153 : // (these called first to make control decisions)
154 287274 : for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
155 6 : CalcWaterStorageTank(state, TankNum);
156 : } // tank loop
157 :
158 287268 : for (RainColNum = 1; RainColNum <= state.dataWaterData->NumRainCollectors; ++RainColNum) {
159 0 : CalcRainCollector(state, RainColNum);
160 : }
161 :
162 287274 : for (WellNum = 1; WellNum <= state.dataWaterData->NumGroundWaterWells; ++WellNum) {
163 6 : CalcGroundwaterWell(state, WellNum);
164 : }
165 :
166 : // call the tanks again to get updated rain and well activity
167 287274 : for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
168 6 : CalcWaterStorageTank(state, TankNum);
169 : } // tank loop
170 : }
171 :
172 297255 : void ManageWaterInits(EnergyPlusData &state)
173 : {
174 297255 : if (!(state.dataWaterData->AnyWaterSystemsInModel)) {
175 127 : return;
176 : }
177 :
178 297128 : UpdateWaterManager(state);
179 297128 : UpdateIrrigation(state);
180 : }
181 :
182 109 : void GetWaterManagerInput(EnergyPlusData &state)
183 : {
184 :
185 : // SUBROUTINE INFORMATION:
186 : // AUTHOR B. Griffith
187 : // DATE WRITTEN August 2006
188 : // MODIFIED na
189 : // RE-ENGINEERED na
190 :
191 : static constexpr std::string_view routineName = "GetWaterManagerInput";
192 :
193 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
194 : int Item; // Item to be "gotten"
195 109 : int NumAlphas(0); // Number of Alphas for each GetObjectItem call
196 109 : int NumNumbers(0); // Number of Numbers for each GetObjectItem call
197 109 : int IOStatus(0); // Used in GetObjectItem
198 109 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
199 109 : int MaxNumAlphas(0); // argument for call to GetObjectDefMaxArgs
200 109 : int MaxNumNumbers(0); // argument for call to GetObjectDefMaxArgs
201 109 : int TotalArgs(0); // argument for call to GetObjectDefMaxArgs
202 109 : int alphaOffset(0);
203 109 : std::string objNameMsg;
204 109 : Array1D_string cAlphaFieldNames;
205 109 : Array1D_string cNumericFieldNames;
206 109 : Array1D_bool lNumericFieldBlanks;
207 109 : Array1D_bool lAlphaFieldBlanks;
208 109 : Array1D_string cAlphaArgs;
209 109 : Array1D<Real64> rNumericArgs;
210 109 : std::string cCurrentModuleObject;
211 : int NumIrrigation;
212 : int Dummy;
213 :
214 109 : if ((state.dataWaterManager->MyOneTimeFlag) && (!(state.dataWaterData->WaterSystemGetInputCalled))) { // big block for entire subroutine
215 : // initialize rainfall model
216 108 : state.dataWaterData->RainFall.ModeID = RainfallMode::None;
217 :
218 108 : cCurrentModuleObject = "WaterUse:Storage";
219 108 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
220 108 : MaxNumNumbers = NumNumbers;
221 108 : MaxNumAlphas = NumAlphas;
222 108 : cCurrentModuleObject = "WaterUse:RainCollector";
223 108 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
224 108 : MaxNumNumbers = max(MaxNumNumbers, NumNumbers);
225 108 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
226 108 : cCurrentModuleObject = "WaterUse:Well";
227 108 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
228 108 : MaxNumNumbers = max(MaxNumNumbers, NumNumbers);
229 108 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
230 108 : cCurrentModuleObject = "Site:Precipitation";
231 108 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
232 108 : MaxNumNumbers = max(MaxNumNumbers, NumNumbers);
233 108 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
234 108 : cCurrentModuleObject = "RoofIrrigation";
235 108 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
236 108 : MaxNumNumbers = max(MaxNumNumbers, NumNumbers);
237 108 : MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
238 :
239 108 : cAlphaFieldNames.allocate(MaxNumAlphas);
240 108 : cAlphaArgs.allocate(MaxNumAlphas);
241 108 : lAlphaFieldBlanks.dimension(MaxNumAlphas, false);
242 108 : cNumericFieldNames.allocate(MaxNumNumbers);
243 108 : rNumericArgs.dimension(MaxNumNumbers, 0.0);
244 108 : lNumericFieldBlanks.dimension(MaxNumNumbers, false);
245 :
246 108 : state.dataWaterManager->MyOneTimeFlag = false;
247 108 : cCurrentModuleObject = "WaterUse:Storage";
248 108 : state.dataWaterData->NumWaterStorageTanks = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
249 108 : if (state.dataWaterData->NumWaterStorageTanks > 0) {
250 2 : state.dataWaterData->AnyWaterSystemsInModel = true;
251 2 : if (!(allocated(state.dataWaterData->WaterStorage))) {
252 2 : state.dataWaterData->WaterStorage.allocate(state.dataWaterData->NumWaterStorageTanks);
253 : }
254 :
255 4 : for (Item = 1; Item <= state.dataWaterData->NumWaterStorageTanks; ++Item) {
256 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
257 : cCurrentModuleObject,
258 : Item,
259 : cAlphaArgs,
260 : NumAlphas,
261 : rNumericArgs,
262 : NumNumbers,
263 : IOStatus,
264 : _,
265 : _,
266 : cAlphaFieldNames,
267 : cNumericFieldNames);
268 :
269 2 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
270 :
271 2 : state.dataWaterData->AnyWaterSystemsInModel = true;
272 2 : state.dataWaterData->WaterStorage(Item).Name = cAlphaArgs(1);
273 2 : Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
274 2 : objNameMsg = cCurrentModuleObject + " = " + cAlphaArgs(1);
275 :
276 2 : state.dataWaterData->WaterStorage(Item).QualitySubCategoryName = cAlphaArgs(2);
277 :
278 2 : state.dataWaterData->WaterStorage(Item).MaxCapacity = rNumericArgs(1);
279 2 : if (state.dataWaterData->WaterStorage(Item).MaxCapacity == 0.0) { // default
280 0 : state.dataWaterData->WaterStorage(Item).MaxCapacity = Constant::BigNumber;
281 : }
282 :
283 2 : state.dataWaterData->WaterStorage(Item).InitialVolume = rNumericArgs(2);
284 2 : state.dataWaterData->WaterStorage(Item).MaxInFlowRate = rNumericArgs(3);
285 2 : if (state.dataWaterData->WaterStorage(Item).MaxInFlowRate == 0.0) { // default
286 0 : state.dataWaterData->WaterStorage(Item).MaxInFlowRate = Constant::BigNumber;
287 : }
288 :
289 2 : state.dataWaterData->WaterStorage(Item).MaxOutFlowRate = rNumericArgs(4);
290 2 : if (state.dataWaterData->WaterStorage(Item).MaxOutFlowRate == 0.0) { // default
291 2 : state.dataWaterData->WaterStorage(Item).MaxOutFlowRate = Constant::BigNumber;
292 : }
293 :
294 2 : state.dataWaterData->WaterStorage(Item).OverflowTankName = cAlphaArgs(3); // setup later
295 :
296 2 : if (lAlphaFieldBlanks(4)) {
297 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(4));
298 0 : ErrorsFound = true;
299 2 : } else if ((state.dataWaterData->WaterStorage(Item).ControlSupply = static_cast<ControlSupplyType>(
300 4 : getEnumValue(controlSupplyTypeNamesUC, cAlphaArgs(4)))) == ControlSupplyType::Invalid) {
301 0 : ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
302 0 : ErrorsFound = true;
303 : }
304 :
305 2 : state.dataWaterData->WaterStorage(Item).ValveOnCapacity = rNumericArgs(5);
306 2 : state.dataWaterData->WaterStorage(Item).ValveOffCapacity = rNumericArgs(6);
307 2 : if (state.dataWaterData->WaterStorage(Item).ControlSupply != ControlSupplyType::NoControlLevel) {
308 2 : if (state.dataWaterData->WaterStorage(Item).ValveOffCapacity < state.dataWaterData->WaterStorage(Item).ValveOnCapacity) {
309 0 : ShowSevereError(state, format("Invalid {} and/or {}", cNumericFieldNames(5), cNumericFieldNames(6)));
310 0 : ShowContinueError(state, format("Entered in {}={}", cCurrentModuleObject, cAlphaArgs(1)));
311 0 : ShowContinueError(state, format("{} must be greater than {}", cNumericFieldNames(6), cNumericFieldNames(5)));
312 0 : ShowContinueError(state,
313 0 : format("Check value for {} = {:.5R}",
314 : cNumericFieldNames(5),
315 0 : state.dataWaterData->WaterStorage(Item).ValveOnCapacity));
316 0 : ShowContinueError(state,
317 0 : format("which must be lower than {} = {:.5R}",
318 : cNumericFieldNames(6),
319 0 : state.dataWaterData->WaterStorage(Item).ValveOffCapacity));
320 0 : ErrorsFound = true;
321 : }
322 : }
323 :
324 2 : state.dataWaterData->WaterStorage(Item).BackupMainsCapacity = rNumericArgs(7);
325 2 : if (state.dataWaterData->WaterStorage(Item).BackupMainsCapacity > 0.0) { // add backup to well and other thank supply
326 2 : if (state.dataWaterData->WaterStorage(Item).ControlSupply == ControlSupplyType::WellFloatValve) {
327 2 : state.dataWaterData->WaterStorage(Item).ControlSupply = ControlSupplyType::WellFloatMainsBackup;
328 : }
329 2 : if (state.dataWaterData->WaterStorage(Item).ControlSupply == ControlSupplyType::OtherTankFloatValve) {
330 0 : state.dataWaterData->WaterStorage(Item).ControlSupply = ControlSupplyType::TankMainsBackup;
331 : }
332 : }
333 :
334 2 : state.dataWaterData->WaterStorage(Item).SupplyTankName = cAlphaArgs(5); // set up later
335 :
336 2 : if (lAlphaFieldBlanks(6)) {
337 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(6));
338 0 : ErrorsFound = true;
339 2 : } else if ((state.dataWaterData->WaterStorage(Item).ThermalMode =
340 4 : static_cast<TankThermalMode>(getEnumValue(tankThermalModeNamesUC, cAlphaArgs(6)))) == TankThermalMode::Invalid) {
341 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(6), cAlphaArgs(6));
342 0 : ErrorsFound = true;
343 : }
344 :
345 2 : if (state.dataWaterData->WaterStorage(Item).ThermalMode == TankThermalMode::Scheduled) {
346 :
347 2 : if (lAlphaFieldBlanks(7)) {
348 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(7));
349 0 : ErrorsFound = true;
350 2 : } else if ((state.dataWaterData->WaterStorage(Item).tempSched = Sched::GetSchedule(state, cAlphaArgs(7))) == nullptr) {
351 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(7), cAlphaArgs(7));
352 0 : ErrorsFound = true;
353 2 : } else if (!state.dataWaterData->WaterStorage(Item).tempSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 100.0)) {
354 0 : Sched::ShowSevereBadMinMax(state, eoh, cAlphaFieldNames(7), cAlphaArgs(7), Clusive::In, 0.0, Clusive::In, 100.0);
355 0 : ErrorsFound = true;
356 : }
357 : }
358 :
359 2 : if (state.dataWaterData->WaterStorage(Item).ThermalMode == TankThermalMode::ZoneCoupled) {
360 :
361 0 : if (lAlphaFieldBlanks(8)) {
362 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(8));
363 0 : ErrorsFound = true;
364 0 : } else if ((state.dataWaterData->WaterStorage(Item).AmbientTempIndicator = static_cast<AmbientTempType>(
365 0 : getEnumValue(ambientTempTypeNamesUC, cAlphaArgs(8)))) == AmbientTempType::Invalid) {
366 0 : ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(8), cAlphaArgs(8));
367 0 : ErrorsFound = true;
368 0 : } else if (state.dataWaterData->WaterStorage(Item).AmbientTempIndicator == AmbientTempType::Schedule) {
369 0 : if (lAlphaFieldBlanks(9)) {
370 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(9));
371 0 : ErrorsFound = true;
372 0 : } else if ((state.dataWaterData->WaterStorage(Item).ambientTempSched = Sched::GetSchedule(state, cAlphaArgs(9))) ==
373 : nullptr) {
374 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(9), cAlphaArgs(9));
375 0 : ErrorsFound = true;
376 : }
377 : }
378 :
379 0 : state.dataWaterData->WaterStorage(Item).ZoneID = Util::FindItemInList(cAlphaArgs(10), state.dataHeatBal->Zone);
380 0 : if ((state.dataWaterData->WaterStorage(Item).ZoneID == 0) &&
381 0 : (state.dataWaterData->WaterStorage(Item).AmbientTempIndicator == AmbientTempType::Zone)) {
382 0 : ShowSevereError(state, format("Invalid {}={}", cAlphaFieldNames(10), cAlphaArgs(10)));
383 0 : ShowContinueError(state, format("Entered in {}={}", cCurrentModuleObject, cAlphaArgs(1)));
384 0 : ErrorsFound = true;
385 : }
386 0 : state.dataWaterData->WaterStorage(Item).SurfArea = rNumericArgs(8);
387 0 : state.dataWaterData->WaterStorage(Item).UValue = rNumericArgs(9);
388 0 : state.dataWaterData->WaterStorage(Item).SurfMaterialName = cAlphaArgs(11);
389 : // todo verify material collect and store useful data from it.
390 : }
391 : }
392 : } // num water storage tanks > 0
393 :
394 108 : cCurrentModuleObject = "WaterUse:RainCollector";
395 108 : state.dataWaterData->NumRainCollectors = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
396 108 : if (state.dataWaterData->NumRainCollectors > 0) {
397 0 : if (!(allocated(state.dataWaterData->RainCollector))) {
398 0 : state.dataWaterData->RainCollector.allocate(state.dataWaterData->NumRainCollectors);
399 : }
400 : // allow extensible reference to surfaces.
401 0 : state.dataWaterData->AnyWaterSystemsInModel = true;
402 :
403 0 : if (state.dataWaterData->RainFall.ModeID == RainfallMode::None) {
404 0 : state.dataWaterData->RainFall.ModeID = RainfallMode::EPWPrecipitation;
405 : }
406 :
407 0 : for (Item = 1; Item <= state.dataWaterData->NumRainCollectors; ++Item) {
408 0 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
409 : cCurrentModuleObject,
410 : Item,
411 : cAlphaArgs,
412 : NumAlphas,
413 : rNumericArgs,
414 : NumNumbers,
415 : IOStatus,
416 : _,
417 : _,
418 : cAlphaFieldNames,
419 : cNumericFieldNames);
420 :
421 0 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
422 :
423 0 : state.dataWaterData->RainCollector(Item).Name = cAlphaArgs(1);
424 0 : Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
425 0 : objNameMsg = cCurrentModuleObject + " Named " + cAlphaArgs(1);
426 :
427 0 : state.dataWaterData->RainCollector(Item).StorageTankName = cAlphaArgs(2);
428 0 : state.dataWaterData->RainCollector(Item).StorageTankID = Util::FindItemInList(cAlphaArgs(2), state.dataWaterData->WaterStorage);
429 0 : if (state.dataWaterData->RainCollector(Item).StorageTankID == 0) {
430 0 : ShowSevereError(state, format("Invalid {}={}", cAlphaFieldNames(2), cAlphaArgs(2)));
431 0 : ShowContinueError(state, format("Entered in {}={}", cCurrentModuleObject, cAlphaArgs(1)));
432 0 : ErrorsFound = true;
433 : }
434 :
435 0 : if (lAlphaFieldBlanks(3)) {
436 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(3));
437 0 : ErrorsFound = true;
438 0 : } else if ((state.dataWaterData->RainCollector(Item).LossFactorMode =
439 0 : static_cast<RainLossFactor>(getEnumValue(rainLossFactorNamesUC, cAlphaArgs(3)))) == RainLossFactor::Invalid) {
440 0 : ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(3), cAlphaArgs(3));
441 0 : ErrorsFound = true;
442 : }
443 0 : state.dataWaterData->RainCollector(Item).LossFactor = rNumericArgs(1);
444 0 : if (state.dataWaterData->RainCollector(Item).LossFactor > 1.0) {
445 0 : ShowWarningError(state, format("Invalid {}={:.2R}", cNumericFieldNames(1), rNumericArgs(1)));
446 0 : ShowContinueError(state, format("Entered in {}={}", cCurrentModuleObject, cAlphaArgs(1)));
447 0 : ShowContinueError(state, "found rain water collection loss factor greater than 1.0, simulation continues");
448 : }
449 0 : if (state.dataWaterData->RainCollector(Item).LossFactor < 0.0) {
450 0 : ShowSevereError(state, format("Invalid {}={:.2R}", cNumericFieldNames(1), rNumericArgs(1)));
451 0 : ShowContinueError(state, format("Entered in {}={}", cCurrentModuleObject, cAlphaArgs(1)));
452 0 : ShowContinueError(state, "found rain water collection loss factor less than 0.0");
453 0 : ErrorsFound = true;
454 : }
455 :
456 0 : if (state.dataWaterData->RainCollector(Item).LossFactorMode == RainLossFactor::Scheduled) {
457 0 : if (lAlphaFieldBlanks(4)) {
458 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(4));
459 0 : ErrorsFound = true;
460 0 : } else if ((state.dataWaterData->RainCollector(Item).lossFactorSched = Sched::GetSchedule(state, cAlphaArgs(4))) == nullptr) {
461 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
462 0 : ErrorsFound = true;
463 0 : } else if (!state.dataWaterData->RainCollector(Item).lossFactorSched->checkMinVal(state, Clusive::In, 0.0)) {
464 0 : Sched::ShowSevereBadMin(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4), Clusive::In, 0.0);
465 0 : ErrorsFound = true;
466 0 : } else if (!state.dataWaterData->RainCollector(Item).lossFactorSched->checkMaxVal(state, Clusive::In, 1.0)) {
467 0 : Sched::ShowWarningBadMax(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4), Clusive::In, 1.0, "");
468 : }
469 : }
470 0 : state.dataWaterData->RainCollector(Item).MaxCollectRate = rNumericArgs(1);
471 0 : if (state.dataWaterData->RainCollector(Item).MaxCollectRate == 0.0) {
472 0 : state.dataWaterData->RainCollector(Item).MaxCollectRate = 100000000000.0;
473 : }
474 :
475 : // number of surfaces is extensible and = NumAlphas - alphaOffset
476 0 : alphaOffset = 4; // update this if more alphas inserted ahead of extensible surface listing
477 0 : state.dataWaterData->RainCollector(Item).NumCollectSurfs = NumAlphas - alphaOffset;
478 0 : state.dataWaterData->RainCollector(Item).SurfName.allocate(state.dataWaterData->RainCollector(Item).NumCollectSurfs);
479 0 : state.dataWaterData->RainCollector(Item).SurfID.allocate(state.dataWaterData->RainCollector(Item).NumCollectSurfs);
480 0 : for (int SurfNum = 1; SurfNum <= state.dataWaterData->RainCollector(Item).NumCollectSurfs; ++SurfNum) {
481 0 : state.dataWaterData->RainCollector(Item).SurfName(SurfNum) = cAlphaArgs(SurfNum + alphaOffset);
482 0 : state.dataWaterData->RainCollector(Item).SurfID(SurfNum) =
483 0 : Util::FindItemInList(cAlphaArgs(SurfNum + alphaOffset), state.dataSurface->Surface);
484 0 : if (state.dataWaterData->RainCollector(Item).SurfID(SurfNum) == 0) {
485 0 : ShowSevereError(state,
486 0 : format("Invalid {}={}", cAlphaFieldNames(SurfNum + alphaOffset), cAlphaArgs(SurfNum + alphaOffset)));
487 0 : ShowContinueError(state, format("Entered in {}={}", cCurrentModuleObject, cAlphaArgs(1)));
488 0 : ErrorsFound = true;
489 : }
490 : }
491 :
492 : // now setup horizontal surface area
493 0 : Real64 tmpArea = 0.0;
494 0 : Real64 tmpNumerator = 0.0;
495 0 : Real64 tmpDenominator = 0.0;
496 0 : for (int SurfNum = 1; SurfNum <= state.dataWaterData->RainCollector(Item).NumCollectSurfs; ++SurfNum) {
497 0 : int ThisSurf = state.dataWaterData->RainCollector(Item).SurfID(SurfNum);
498 0 : tmpArea += state.dataSurface->Surface(ThisSurf).GrossArea * state.dataSurface->Surface(ThisSurf).CosTilt;
499 0 : tmpNumerator += state.dataSurface->Surface(ThisSurf).Centroid.z * state.dataSurface->Surface(ThisSurf).GrossArea;
500 0 : tmpDenominator += state.dataSurface->Surface(ThisSurf).GrossArea;
501 : }
502 0 : state.dataWaterData->RainCollector(Item).HorizArea = tmpArea;
503 : // now setup vertical hieght above ground for height dependent outdoor temps
504 0 : state.dataWaterData->RainCollector(Item).MeanHeight = tmpNumerator / tmpDenominator;
505 :
506 : // now set up tank supply connection
507 0 : InternalSetupTankSupplyComponent(state,
508 0 : state.dataWaterData->RainCollector(Item).Name,
509 : cCurrentModuleObject,
510 0 : state.dataWaterData->RainCollector(Item).StorageTankName,
511 : ErrorsFound,
512 0 : state.dataWaterData->RainCollector(Item).StorageTankID,
513 0 : state.dataWaterData->RainCollector(Item).StorageTankSupplyARRID);
514 : }
515 : } // (NumRainCollectors > 0)
516 :
517 108 : cCurrentModuleObject = "WaterUse:Well";
518 108 : state.dataWaterData->NumGroundWaterWells = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
519 108 : if (state.dataWaterData->NumGroundWaterWells > 0) {
520 2 : state.dataWaterData->AnyWaterSystemsInModel = true;
521 2 : state.dataWaterData->GroundwaterWell.allocate(state.dataWaterData->NumGroundWaterWells);
522 4 : for (Item = 1; Item <= state.dataWaterData->NumGroundWaterWells; ++Item) {
523 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
524 : cCurrentModuleObject,
525 : Item,
526 : cAlphaArgs,
527 : NumAlphas,
528 : rNumericArgs,
529 : NumNumbers,
530 : IOStatus,
531 : _,
532 : lAlphaFieldBlanks,
533 : cAlphaFieldNames,
534 : cNumericFieldNames);
535 :
536 2 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
537 :
538 2 : state.dataWaterData->GroundwaterWell(Item).Name = cAlphaArgs(1);
539 2 : Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
540 2 : objNameMsg = cCurrentModuleObject + " Named " + cAlphaArgs(1);
541 2 : state.dataWaterData->GroundwaterWell(Item).StorageTankName = cAlphaArgs(2);
542 :
543 4 : InternalSetupTankSupplyComponent(state,
544 2 : state.dataWaterData->GroundwaterWell(Item).Name,
545 : cCurrentModuleObject,
546 2 : state.dataWaterData->GroundwaterWell(Item).StorageTankName,
547 : ErrorsFound,
548 2 : state.dataWaterData->GroundwaterWell(Item).StorageTankID,
549 2 : state.dataWaterData->GroundwaterWell(Item).StorageTankSupplyARRID);
550 :
551 2 : if (allocated(state.dataWaterData->WaterStorage)) {
552 2 : state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(Item).StorageTankID).GroundWellID = Item;
553 : }
554 :
555 2 : state.dataWaterData->GroundwaterWell(Item).PumpDepth = rNumericArgs(1);
556 2 : state.dataWaterData->GroundwaterWell(Item).PumpNomVolFlowRate = rNumericArgs(2);
557 2 : state.dataWaterData->GroundwaterWell(Item).PumpNomHead = rNumericArgs(3);
558 2 : state.dataWaterData->GroundwaterWell(Item).PumpNomPowerUse = rNumericArgs(4);
559 2 : state.dataWaterData->GroundwaterWell(Item).PumpEfficiency = rNumericArgs(5);
560 2 : state.dataWaterData->GroundwaterWell(Item).WellRecoveryRate = rNumericArgs(6);
561 2 : state.dataWaterData->GroundwaterWell(Item).NomWellStorageVol = rNumericArgs(7);
562 :
563 2 : if (lAlphaFieldBlanks(3)) {
564 : // This is not an error
565 0 : } else if ((state.dataWaterData->GroundwaterWell(Item).GroundwaterTableMode = static_cast<GroundWaterTable>(
566 0 : getEnumValue(groundWaterTableNamesUC, cAlphaArgs(3)))) == GroundWaterTable::Invalid) {
567 0 : ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(3), cAlphaArgs(3));
568 0 : ErrorsFound = true;
569 : }
570 :
571 : // N8, \field water table depth
572 2 : state.dataWaterData->GroundwaterWell(Item).WaterTableDepth = rNumericArgs(8);
573 : // A4; \field water table depth schedule
574 2 : if (state.dataWaterData->GroundwaterWell(Item).GroundwaterTableMode == GroundWaterTable::Scheduled) {
575 0 : if (lAlphaFieldBlanks(4)) {
576 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(4));
577 0 : ErrorsFound = true;
578 0 : } else if ((state.dataWaterData->GroundwaterWell(Item).waterTableDepthSched = Sched::GetSchedule(state, cAlphaArgs(4))) ==
579 : nullptr) {
580 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
581 0 : ErrorsFound = true;
582 : }
583 : }
584 : }
585 : } //(NumGroundWaterWells > 0)
586 :
587 : // do some water tank setup
588 108 : cCurrentModuleObject = "WaterUse:Storage";
589 108 : if (state.dataWaterData->NumWaterStorageTanks > 0) {
590 4 : for (Item = 1; Item <= state.dataWaterData->NumWaterStorageTanks; ++Item) {
591 : // check that all storage tanks with ground well controls actually had wells pointing to them
592 4 : if ((state.dataWaterData->WaterStorage(Item).ControlSupply == ControlSupplyType::WellFloatValve) ||
593 2 : (state.dataWaterData->WaterStorage(Item).ControlSupply == ControlSupplyType::WellFloatMainsBackup)) {
594 2 : if (state.dataWaterData->WaterStorage(Item).GroundWellID == 0) {
595 0 : ShowSevereError(state,
596 0 : format("{}= \"{}\" does not have a WaterUse:Well (groundwater well) that names it.",
597 : cCurrentModuleObject,
598 0 : state.dataWaterData->WaterStorage(Item).Name));
599 0 : ErrorsFound = true;
600 : }
601 : }
602 :
603 : // setup tanks whose level is controlled by supply from another tank
604 4 : if ((state.dataWaterData->WaterStorage(Item).ControlSupply == ControlSupplyType::OtherTankFloatValve) ||
605 2 : (state.dataWaterData->WaterStorage(Item).ControlSupply == ControlSupplyType::TankMainsBackup)) {
606 0 : state.dataWaterData->WaterStorage(Item).SupplyTankID =
607 0 : Util::FindItemInList(state.dataWaterData->WaterStorage(Item).SupplyTankName, state.dataWaterData->WaterStorage);
608 0 : if (state.dataWaterData->WaterStorage(Item).SupplyTankID == 0) {
609 0 : ShowSevereError(state,
610 0 : format("Other tank called {} not found for {} Named {}",
611 0 : state.dataWaterData->WaterStorage(Item).SupplyTankName,
612 : cCurrentModuleObject,
613 0 : state.dataWaterData->WaterStorage(Item).Name)); // TODO rename point
614 0 : ErrorsFound = true;
615 : }
616 0 : InternalSetupTankDemandComponent(state,
617 0 : state.dataWaterData->WaterStorage(Item).Name,
618 : cCurrentModuleObject,
619 0 : state.dataWaterData->WaterStorage(Item).SupplyTankName,
620 : ErrorsFound,
621 0 : state.dataWaterData->WaterStorage(Item).SupplyTankID,
622 0 : state.dataWaterData->WaterStorage(Item).SupplyTankDemandARRID);
623 : // call to setup tank supply as well
624 0 : InternalSetupTankSupplyComponent(state,
625 0 : state.dataWaterData->WaterStorage(Item).SupplyTankName,
626 : cCurrentModuleObject,
627 0 : state.dataWaterData->WaterStorage(Item).Name,
628 : ErrorsFound,
629 : Dummy,
630 : Dummy);
631 : }
632 : // setup overflow inputs
633 2 : state.dataWaterData->WaterStorage(Item).OverflowTankID =
634 2 : Util::FindItemInList(state.dataWaterData->WaterStorage(Item).OverflowTankName, state.dataWaterData->WaterStorage);
635 2 : if (state.dataWaterData->WaterStorage(Item).OverflowTankID == 0) {
636 : // if blank, then okay it is discarded. but if not blank then error
637 2 : if (is_blank(state.dataWaterData->WaterStorage(Item).OverflowTankName)) {
638 2 : state.dataWaterData->WaterStorage(Item).OverflowMode = Overflow::Discarded;
639 : } else {
640 0 : ShowSevereError(state,
641 0 : format("Overflow tank name of {} not found for {} Named {}",
642 0 : state.dataWaterData->WaterStorage(Item).OverflowTankName,
643 : cCurrentModuleObject,
644 0 : state.dataWaterData->WaterStorage(Item).Name));
645 0 : ErrorsFound = true;
646 : }
647 : } else {
648 0 : state.dataWaterData->WaterStorage(Item).OverflowMode = Overflow::ToTank;
649 : }
650 2 : if (state.dataWaterData->WaterStorage(Item).OverflowMode == Overflow::ToTank) {
651 0 : InternalSetupTankSupplyComponent(state,
652 0 : state.dataWaterData->WaterStorage(Item).Name,
653 : cCurrentModuleObject,
654 0 : state.dataWaterData->WaterStorage(Item).OverflowTankName,
655 : ErrorsFound,
656 0 : state.dataWaterData->WaterStorage(Item).OverflowTankID,
657 0 : state.dataWaterData->WaterStorage(Item).OverflowTankSupplyARRID);
658 : }
659 : }
660 : }
661 :
662 108 : cCurrentModuleObject = "Site:Precipitation";
663 108 : state.dataWaterData->NumSiteRainFall = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
664 108 : if (state.dataWaterData->NumSiteRainFall > 1) { // throw error
665 0 : ShowSevereError(state, format("Only one {} object is allowed", cCurrentModuleObject));
666 0 : ErrorsFound = true;
667 : }
668 :
669 108 : if (state.dataWaterData->NumSiteRainFall == 1) {
670 4 : state.dataWaterData->AnyWaterSystemsInModel = true;
671 4 : state.dataInputProcessing->inputProcessor->getObjectItem(
672 : state, cCurrentModuleObject, 1, cAlphaArgs, NumAlphas, rNumericArgs, NumNumbers, IOStatus);
673 :
674 4 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
675 :
676 4 : if (Util::SameString(cAlphaArgs(1), "ScheduleAndDesignLevel")) {
677 4 : state.dataWaterData->RainFall.ModeID = RainfallMode::RainSchedDesign;
678 : } else {
679 0 : ShowSevereError(state, format("Precipitation Model Type of {} is incorrect.", cCurrentModuleObject));
680 0 : ShowContinueError(state, "Only available option is ScheduleAndDesignLevel.");
681 0 : ErrorsFound = true;
682 : }
683 :
684 4 : if (state.dataWaterData->RainFall.ModeID == RainfallMode::RainSchedDesign) {
685 4 : if (lAlphaFieldBlanks(2)) {
686 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
687 0 : ErrorsFound = true;
688 4 : } else if ((state.dataWaterData->RainFall.rainSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
689 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
690 0 : ErrorsFound = true;
691 4 : } else if (!state.dataWaterData->RainFall.rainSched->checkMinVal(state, Clusive::In, 0.0)) {
692 0 : Sched::ShowSevereBadMin(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2), Clusive::In, 0.0);
693 0 : ErrorsFound = true;
694 : }
695 : }
696 :
697 4 : state.dataWaterData->RainFall.DesignAnnualRain = rNumericArgs(1);
698 4 : state.dataWaterData->RainFall.NomAnnualRain = rNumericArgs(2);
699 : }
700 :
701 108 : cCurrentModuleObject = "RoofIrrigation";
702 108 : NumIrrigation = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
703 108 : if (NumIrrigation > 1) {
704 0 : ShowSevereError(state, format("Only one {} object is allowed", cCurrentModuleObject));
705 0 : ErrorsFound = true;
706 : }
707 :
708 108 : if (NumIrrigation == 1) {
709 1 : state.dataWaterData->AnyIrrigationInModel = true;
710 1 : state.dataInputProcessing->inputProcessor->getObjectItem(
711 : state, cCurrentModuleObject, 1, cAlphaArgs, NumAlphas, rNumericArgs, NumNumbers, IOStatus);
712 :
713 1 : ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
714 :
715 1 : if (lAlphaFieldBlanks(1)) {
716 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(1));
717 0 : ErrorsFound = true;
718 2 : } else if ((state.dataWaterData->Irrigation.ModeID =
719 1 : static_cast<IrrigationMode>(getEnumValue(irrigationModeNamesUC, cAlphaArgs(1)))) == IrrigationMode::Invalid) {
720 0 : ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(1), cAlphaArgs(1));
721 0 : ErrorsFound = true;
722 : }
723 :
724 1 : if (state.dataWaterData->RainFall.ModeID == RainfallMode::None) {
725 1 : state.dataWaterData->RainFall.ModeID = RainfallMode::EPWPrecipitation;
726 : }
727 :
728 2 : if (state.dataWaterData->Irrigation.ModeID == IrrigationMode::SchedDesign ||
729 1 : state.dataWaterData->Irrigation.ModeID == IrrigationMode::SmartSched) {
730 1 : if (lAlphaFieldBlanks(2)) {
731 0 : ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
732 0 : ErrorsFound = true;
733 1 : } else if ((state.dataWaterData->Irrigation.irrSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
734 0 : ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
735 0 : ErrorsFound = true;
736 1 : } else if (!state.dataWaterData->Irrigation.irrSched->checkMinVal(state, Clusive::In, 0.0)) {
737 0 : Sched::ShowSevereBadMin(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2), Clusive::In, 0.0);
738 0 : ErrorsFound = true;
739 : }
740 : }
741 :
742 : // If we later add a designannualirrigation and a nominalannualirrigation variable (for scaling) those
743 : // would be assigned here... as with the Rainfall...
744 1 : state.dataWaterData->Irrigation.IrrigationThreshold = 0.4;
745 1 : if (state.dataWaterData->Irrigation.ModeID == IrrigationMode::SmartSched && NumNumbers > 0) {
746 1 : if (rNumericArgs(1) > 100.0 || rNumericArgs(1) < 0.0) {
747 0 : ShowSevereError(state, format("Irrigation threshold for {} object has values > 100 or < 0.", cCurrentModuleObject));
748 0 : ErrorsFound = true;
749 : } else {
750 1 : state.dataWaterData->Irrigation.IrrigationThreshold = rNumericArgs(1) / 100.0;
751 : }
752 : }
753 :
754 : } // NumIrrigation ==1
755 :
756 108 : if (state.dataWaterData->RainFall.ModeID == RainfallMode::EPWPrecipitation) {
757 3 : ShowWarningError(state,
758 : "Precipitation depth from the weather file will be used. Please make sure this .epw field has valid data. "
759 : "Site:Precipitation may be used to override the weather file data.");
760 : }
761 :
762 108 : state.dataWaterData->AnyWaterSystemsInModel = true;
763 108 : state.dataWaterData->WaterSystemGetInputCalled = true;
764 108 : state.dataWaterManager->MyOneTimeFlag = false;
765 :
766 108 : cAlphaFieldNames.deallocate();
767 108 : cAlphaArgs.deallocate();
768 108 : lAlphaFieldBlanks.deallocate();
769 108 : cNumericFieldNames.deallocate();
770 108 : rNumericArgs.deallocate();
771 108 : lNumericFieldBlanks.deallocate();
772 :
773 108 : if (ErrorsFound) {
774 0 : ShowFatalError(state, "Errors found in processing input for water manager objects");
775 : }
776 : // <SetupOutputVariables here...>, CurrentModuleObject='WaterUse:Storage'
777 110 : for (Item = 1; Item <= state.dataWaterData->NumWaterStorageTanks; ++Item) {
778 : // this next one is a measure of the state of water in the tank, not a flux of m3 that needs to be summed
779 4 : SetupOutputVariable(state,
780 : "Water System Storage Tank Volume",
781 : Constant::Units::m3,
782 2 : state.dataWaterData->WaterStorage(Item).ThisTimeStepVolume,
783 : OutputProcessor::TimeStepType::System,
784 : OutputProcessor::StoreType::Average,
785 2 : state.dataWaterData->WaterStorage(Item).Name);
786 4 : SetupOutputVariable(state,
787 : "Water System Storage Tank Net Volume Flow Rate",
788 : Constant::Units::m3_s,
789 2 : state.dataWaterData->WaterStorage(Item).NetVdot,
790 : OutputProcessor::TimeStepType::System,
791 : OutputProcessor::StoreType::Average,
792 2 : state.dataWaterData->WaterStorage(Item).Name);
793 4 : SetupOutputVariable(state,
794 : "Water System Storage Tank Inlet Volume Flow Rate",
795 : Constant::Units::m3_s,
796 2 : state.dataWaterData->WaterStorage(Item).VdotToTank,
797 : OutputProcessor::TimeStepType::System,
798 : OutputProcessor::StoreType::Average,
799 2 : state.dataWaterData->WaterStorage(Item).Name);
800 4 : SetupOutputVariable(state,
801 : "Water System Storage Tank Outlet Volume Flow Rate",
802 : Constant::Units::m3_s,
803 2 : state.dataWaterData->WaterStorage(Item).VdotFromTank,
804 : OutputProcessor::TimeStepType::System,
805 : OutputProcessor::StoreType::Average,
806 2 : state.dataWaterData->WaterStorage(Item).Name);
807 4 : SetupOutputVariable(state,
808 : "Water System Storage Tank Mains Water Volume",
809 : Constant::Units::m3,
810 2 : state.dataWaterData->WaterStorage(Item).MainsDrawVol,
811 : OutputProcessor::TimeStepType::System,
812 : OutputProcessor::StoreType::Sum,
813 2 : state.dataWaterData->WaterStorage(Item).Name,
814 : Constant::eResource::MainsWater,
815 : OutputProcessor::Group::HVAC,
816 : OutputProcessor::EndUseCat::WaterSystem,
817 2 : state.dataWaterData->WaterStorage(Item).QualitySubCategoryName);
818 4 : SetupOutputVariable(state,
819 : "Water System Storage Tank Mains Water Volume Flow Rate",
820 : Constant::Units::m3_s,
821 2 : state.dataWaterData->WaterStorage(Item).MainsDrawVdot,
822 : OutputProcessor::TimeStepType::System,
823 : OutputProcessor::StoreType::Average,
824 2 : state.dataWaterData->WaterStorage(Item).Name);
825 4 : SetupOutputVariable(state,
826 : "Water System Storage Tank Water Temperature",
827 : Constant::Units::C,
828 2 : state.dataWaterData->WaterStorage(Item).Twater,
829 : OutputProcessor::TimeStepType::System,
830 : OutputProcessor::StoreType::Average,
831 2 : state.dataWaterData->WaterStorage(Item).Name);
832 4 : SetupOutputVariable(state,
833 : "Water System Storage Tank Overflow Volume Flow Rate",
834 : Constant::Units::m3_s,
835 2 : state.dataWaterData->WaterStorage(Item).VdotOverflow,
836 : OutputProcessor::TimeStepType::System,
837 : OutputProcessor::StoreType::Average,
838 2 : state.dataWaterData->WaterStorage(Item).Name);
839 2 : if (state.dataWaterData->WaterStorage(Item).OverflowMode == Overflow::Discarded) {
840 4 : SetupOutputVariable(state,
841 : "Water System Storage Tank Overflow Water Volume",
842 : Constant::Units::m3,
843 2 : state.dataWaterData->WaterStorage(Item).VolOverflow,
844 : OutputProcessor::TimeStepType::System,
845 : OutputProcessor::StoreType::Sum,
846 2 : state.dataWaterData->WaterStorage(Item).Name);
847 : } else {
848 0 : SetupOutputVariable(state,
849 : "Water System Storage Tank Overflow Water Volume",
850 : Constant::Units::m3,
851 0 : state.dataWaterData->WaterStorage(Item).VolOverflow,
852 : OutputProcessor::TimeStepType::System,
853 : OutputProcessor::StoreType::Sum,
854 0 : state.dataWaterData->WaterStorage(Item).Name);
855 : }
856 4 : SetupOutputVariable(state,
857 : "Water System Storage Tank Overflow Temperature",
858 : Constant::Units::C,
859 2 : state.dataWaterData->WaterStorage(Item).TwaterOverflow,
860 : OutputProcessor::TimeStepType::System,
861 : OutputProcessor::StoreType::Average,
862 2 : state.dataWaterData->WaterStorage(Item).Name);
863 : }
864 :
865 108 : if (NumIrrigation == 1) { // CurrentModuleObject='RoofIrrigation'
866 4 : SetupOutputVariable(state,
867 : "Water System Roof Irrigation Scheduled Depth",
868 : Constant::Units::m,
869 1 : state.dataWaterData->Irrigation.ScheduledAmount,
870 : OutputProcessor::TimeStepType::System,
871 : OutputProcessor::StoreType::Sum,
872 : "RoofIrrigation");
873 4 : SetupOutputVariable(state,
874 : "Water System Roof Irrigation Actual Depth",
875 : Constant::Units::m,
876 1 : state.dataWaterData->Irrigation.ActualAmount,
877 : OutputProcessor::TimeStepType::System,
878 : OutputProcessor::StoreType::Sum,
879 : "RoofIrrigation");
880 : }
881 :
882 108 : for (Item = 1; Item <= state.dataWaterData->NumRainCollectors; ++Item) { // CurrentModuleObject='WaterUse:RainCollector'
883 0 : SetupOutputVariable(state,
884 : "Water System Rainwater Collector Volume Flow Rate",
885 : Constant::Units::m3_s,
886 0 : state.dataWaterData->RainCollector(Item).VdotAvail,
887 : OutputProcessor::TimeStepType::System,
888 : OutputProcessor::StoreType::Average,
889 0 : state.dataWaterData->RainCollector(Item).Name);
890 0 : SetupOutputVariable(state,
891 : "Water System Rainwater Collector Volume",
892 : Constant::Units::m3,
893 0 : state.dataWaterData->RainCollector(Item).VolCollected,
894 : OutputProcessor::TimeStepType::System,
895 : OutputProcessor::StoreType::Sum,
896 0 : state.dataWaterData->RainCollector(Item).Name,
897 : Constant::eResource::OnSiteWater,
898 : OutputProcessor::Group::HVAC,
899 : OutputProcessor::EndUseCat::RainWater);
900 : }
901 :
902 110 : for (Item = 1; Item <= state.dataWaterData->NumGroundWaterWells; ++Item) { // CurrentModuleObject='WaterUse:Well'
903 4 : SetupOutputVariable(state,
904 : "Water System Groundwater Well Requested Volume Flow Rate",
905 : Constant::Units::m3_s,
906 2 : state.dataWaterData->GroundwaterWell(Item).VdotRequest,
907 : OutputProcessor::TimeStepType::System,
908 : OutputProcessor::StoreType::Average,
909 2 : state.dataWaterData->GroundwaterWell(Item).Name);
910 4 : SetupOutputVariable(state,
911 : "Water System Groundwater Well Volume Flow Rate",
912 : Constant::Units::m3_s,
913 2 : state.dataWaterData->GroundwaterWell(Item).VdotDelivered,
914 : OutputProcessor::TimeStepType::System,
915 : OutputProcessor::StoreType::Average,
916 2 : state.dataWaterData->GroundwaterWell(Item).Name);
917 4 : SetupOutputVariable(state,
918 : "Water System Groundwater Well Volume",
919 : Constant::Units::m3,
920 2 : state.dataWaterData->GroundwaterWell(Item).VolDelivered,
921 : OutputProcessor::TimeStepType::System,
922 : OutputProcessor::StoreType::Sum,
923 2 : state.dataWaterData->GroundwaterWell(Item).Name,
924 : Constant::eResource::OnSiteWater,
925 : OutputProcessor::Group::HVAC,
926 : OutputProcessor::EndUseCat::WellWater);
927 4 : SetupOutputVariable(state,
928 : "Water System Groundwater Well Pump Electricity Rate",
929 : Constant::Units::W,
930 2 : state.dataWaterData->GroundwaterWell(Item).PumpPower,
931 : OutputProcessor::TimeStepType::System,
932 : OutputProcessor::StoreType::Average,
933 2 : state.dataWaterData->GroundwaterWell(Item).Name);
934 4 : SetupOutputVariable(state,
935 : "Water System Groundwater Well Pump Electricity Energy",
936 : Constant::Units::J,
937 2 : state.dataWaterData->GroundwaterWell(Item).PumpEnergy,
938 : OutputProcessor::TimeStepType::System,
939 : OutputProcessor::StoreType::Sum,
940 2 : state.dataWaterData->GroundwaterWell(Item).Name,
941 : Constant::eResource::Electricity,
942 : OutputProcessor::Group::HVAC,
943 : OutputProcessor::EndUseCat::WaterSystem);
944 : }
945 :
946 : } // my one time flag block
947 109 : }
948 :
949 326126 : void UpdatePrecipitation(EnergyPlusData &state)
950 : {
951 : // SUBROUTINE INFORMATION:
952 : // AUTHOR B. Griffith
953 : // DATE WRITTEN August 2006
954 : // MODIFIED na
955 : // RE-ENGINEERED na
956 :
957 : // PURPOSE OF THIS SUBROUTINE:
958 : // update the current rate of precipitation
959 :
960 : Real64 schedRate;
961 : Real64 ScaleFactor;
962 :
963 : // when the site:precipitation exists, use the precipitation schedule
964 326126 : if (state.dataWaterData->RainFall.ModeID == RainfallMode::RainSchedDesign) {
965 198 : schedRate = state.dataWaterData->RainFall.rainSched->getCurrentVal(); // m/hr
966 198 : if (state.dataWaterData->RainFall.NomAnnualRain > 0.0) {
967 197 : ScaleFactor = state.dataWaterData->RainFall.DesignAnnualRain / state.dataWaterData->RainFall.NomAnnualRain;
968 : } else {
969 1 : ScaleFactor = 0.0;
970 : }
971 198 : state.dataWaterData->RainFall.CurrentRate = schedRate * ScaleFactor / Constant::rSecsInHour; // convert to m/s
972 : } else {
973 : // placeholder: add EP checks for out of range precipitation value later -- yujie
974 : // when there's no site:precipitation but non-zero epw precipitation, uset the epw precipitation as the CurrentRate
975 325928 : if (state.dataEnvrn->LiquidPrecipitation > 0.0) {
976 : // LiquidPrecipitation is for a certain timestep in an hour, the rate = depth / seconds in a timestep
977 320 : state.dataWaterData->RainFall.CurrentRate = state.dataEnvrn->LiquidPrecipitation / state.dataGlobal->TimeStepZoneSec;
978 : } else {
979 325608 : state.dataWaterData->RainFall.CurrentRate = 0.0;
980 : }
981 : }
982 326126 : state.dataWaterData->RainFall.CurrentAmount = state.dataWaterData->RainFall.CurrentRate * state.dataGlobal->TimeStepZoneSec;
983 326126 : state.dataEcoRoofMgr->CurrentPrecipitation = state.dataWaterData->RainFall.CurrentAmount; // units of m
984 :
985 326126 : if (state.dataWaterData->RainFall.ModeID == RainfallMode::RainSchedDesign) {
986 198 : if ((state.dataEnvrn->RunPeriodEnvironment) && (!state.dataGlobal->WarmupFlag)) {
987 1 : int month = state.dataEnvrn->Month;
988 1 : state.dataWaterData->RainFall.MonthlyTotalPrecInSitePrec.at(month - 1) += state.dataWaterData->RainFall.CurrentAmount * 1000.0;
989 : }
990 : }
991 326126 : }
992 :
993 297128 : void UpdateIrrigation(EnergyPlusData &state)
994 : {
995 :
996 : // SUBROUTINE INFORMATION:
997 : // AUTHOR D. Sailor
998 : // DATE WRITTEN Dec 2006
999 : // MODIFIED na
1000 : // RE-ENGINEERED na
1001 :
1002 : // PURPOSE OF THIS SUBROUTINE:
1003 : // update the current rate of irrigation
1004 :
1005 297128 : Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
1006 :
1007 : Real64 schedRate;
1008 :
1009 297128 : state.dataWaterData->Irrigation.ScheduledAmount = 0.0;
1010 :
1011 297128 : if (state.dataWaterData->Irrigation.ModeID == IrrigationMode::SchedDesign) {
1012 0 : schedRate = state.dataWaterData->Irrigation.irrSched->getCurrentVal(); // m/hr
1013 0 : state.dataWaterData->Irrigation.ScheduledAmount = schedRate * TimeStepSys; // convert to m/timestep
1014 :
1015 297128 : } else if (state.dataWaterData->Irrigation.ModeID == IrrigationMode::SmartSched) {
1016 0 : schedRate = state.dataWaterData->Irrigation.irrSched->getCurrentVal(); // m/hr
1017 0 : state.dataWaterData->Irrigation.ScheduledAmount = schedRate * TimeStepSys; // convert to m/timestep
1018 : }
1019 297128 : }
1020 :
1021 12 : void CalcWaterStorageTank(EnergyPlusData &state, int const TankNum) // Index of storage tank
1022 : {
1023 :
1024 : // SUBROUTINE INFORMATION:
1025 : // AUTHOR B. Griffith
1026 : // DATE WRITTEN August 2006
1027 : // MODIFIED na
1028 : // RE-ENGINEERED na
1029 :
1030 : // PURPOSE OF THIS SUBROUTINE:
1031 : // Collect the calculations used to update the modeled values
1032 : // for the storage tanks at each system timestep
1033 :
1034 : // Using/Aliasing
1035 12 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
1036 :
1037 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1038 12 : Real64 OrigVdotDemandRequest(0.0);
1039 12 : Real64 TotVdotDemandAvail(0.0);
1040 12 : Real64 OrigVolDemandRequest(0.0);
1041 12 : Real64 TotVolDemandAvail(0.0);
1042 12 : Real64 OrigVdotSupplyAvail(0.0);
1043 12 : Real64 TotVdotSupplyAvail(0.0);
1044 12 : Real64 TotVolSupplyAvail(0.0);
1045 12 : Real64 overflowVdot(0.0);
1046 12 : Real64 overflowVol(0.0);
1047 12 : Real64 NetVdotAdd(0.0);
1048 12 : Real64 NetVolAdd(0.0);
1049 12 : Real64 FillVolRequest(0.0);
1050 12 : Real64 TotVolAllowed(0.0);
1051 12 : Real64 underflowVdot(0.0);
1052 12 : Real64 VolumePredict(0.0);
1053 :
1054 12 : if (state.dataGlobal->BeginTimeStepFlag) {
1055 : // initializations are done in UpdateWaterManager
1056 : }
1057 :
1058 12 : overflowVdot = 0.0;
1059 12 : if (state.dataWaterData->WaterStorage(TankNum).NumWaterSupplies > 0) {
1060 12 : OrigVdotSupplyAvail = sum(state.dataWaterData->WaterStorage(TankNum).VdotAvailSupply);
1061 : } else {
1062 0 : OrigVdotSupplyAvail = 0.0;
1063 : }
1064 12 : TotVdotSupplyAvail = OrigVdotSupplyAvail; // Init
1065 12 : if (TotVdotSupplyAvail > state.dataWaterData->WaterStorage(TankNum).MaxInFlowRate) {
1066 : // pipe/filter rate constraints on inlet
1067 0 : overflowVdot = TotVdotSupplyAvail - state.dataWaterData->WaterStorage(TankNum).MaxInFlowRate;
1068 0 : state.dataWaterManager->overflowTwater =
1069 0 : sum(state.dataWaterData->WaterStorage(TankNum).VdotAvailSupply * state.dataWaterData->WaterStorage(TankNum).TwaterSupply) /
1070 0 : sum(state.dataWaterData->WaterStorage(TankNum).VdotAvailSupply);
1071 0 : TotVdotSupplyAvail = state.dataWaterData->WaterStorage(TankNum).MaxInFlowRate;
1072 : }
1073 12 : TotVolSupplyAvail = TotVdotSupplyAvail * TimeStepSysSec;
1074 12 : overflowVol = overflowVdot * TimeStepSysSec;
1075 :
1076 12 : underflowVdot = 0.0;
1077 12 : if (state.dataWaterData->WaterStorage(TankNum).NumWaterDemands > 0) {
1078 12 : OrigVdotDemandRequest = sum(state.dataWaterData->WaterStorage(TankNum).VdotRequestDemand);
1079 : } else {
1080 0 : OrigVdotDemandRequest = 0.0;
1081 : }
1082 12 : OrigVolDemandRequest = OrigVdotDemandRequest * TimeStepSysSec;
1083 12 : TotVdotDemandAvail = OrigVdotDemandRequest; // initialize to satisfied then modify if needed
1084 12 : if (TotVdotDemandAvail > state.dataWaterData->WaterStorage(TankNum).MaxOutFlowRate) {
1085 : // pipe/filter rate constraints on outlet
1086 0 : underflowVdot = OrigVdotDemandRequest - state.dataWaterData->WaterStorage(TankNum).MaxOutFlowRate;
1087 0 : TotVdotDemandAvail = state.dataWaterData->WaterStorage(TankNum).MaxOutFlowRate;
1088 : }
1089 12 : TotVolDemandAvail = TotVdotDemandAvail * TimeStepSysSec;
1090 :
1091 12 : NetVdotAdd = TotVdotSupplyAvail - TotVdotDemandAvail;
1092 12 : NetVolAdd = NetVdotAdd * TimeStepSysSec;
1093 :
1094 12 : VolumePredict = state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume + NetVolAdd;
1095 :
1096 : // would tank capacity be exceeded?
1097 12 : TotVolAllowed = state.dataWaterData->WaterStorage(TankNum).MaxCapacity - state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume;
1098 12 : if (VolumePredict > state.dataWaterData->WaterStorage(TankNum).MaxCapacity) { // too much
1099 : // added overflow to inlet rate limit, new temperature model
1100 0 : Real64 OverFillVolume = (VolumePredict - state.dataWaterData->WaterStorage(TankNum).MaxCapacity);
1101 0 : state.dataWaterManager->overflowTwater =
1102 0 : (state.dataWaterManager->overflowTwater * overflowVol + OverFillVolume * state.dataWaterData->WaterStorage(TankNum).Twater) /
1103 0 : (overflowVol + OverFillVolume);
1104 0 : overflowVol += OverFillVolume;
1105 0 : NetVolAdd -= OverFillVolume;
1106 0 : NetVdotAdd = NetVolAdd / TimeStepSysSec;
1107 0 : VolumePredict = state.dataWaterData->WaterStorage(TankNum).MaxCapacity;
1108 : }
1109 :
1110 : // Is tank too low to meet the request?
1111 12 : if (VolumePredict < 0.0) {
1112 0 : Real64 AvailVolume = state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume + TotVolSupplyAvail;
1113 0 : AvailVolume = max(0.0, AvailVolume);
1114 0 : TotVolDemandAvail = AvailVolume;
1115 0 : TotVdotDemandAvail = AvailVolume / TimeStepSysSec;
1116 0 : underflowVdot = OrigVdotDemandRequest - TotVdotDemandAvail;
1117 0 : NetVdotAdd = TotVdotSupplyAvail - TotVdotDemandAvail;
1118 0 : NetVolAdd = NetVdotAdd * TimeStepSysSec;
1119 0 : VolumePredict = 0.0;
1120 : }
1121 :
1122 12 : if (TotVdotDemandAvail < OrigVdotDemandRequest) { // starvation
1123 : // even distribution
1124 0 : if (OrigVdotDemandRequest > 0.0) {
1125 0 : state.dataWaterData->WaterStorage(TankNum).VdotAvailDemand =
1126 0 : (TotVdotDemandAvail / OrigVdotDemandRequest) * state.dataWaterData->WaterStorage(TankNum).VdotRequestDemand;
1127 : } else {
1128 0 : state.dataWaterData->WaterStorage(TankNum).VdotAvailDemand = 0.0;
1129 : }
1130 : } else { // requested demand can be served
1131 12 : if (state.dataWaterData->WaterStorage(TankNum).NumWaterDemands > 0) {
1132 12 : state.dataWaterData->WaterStorage(TankNum).VdotAvailDemand = state.dataWaterData->WaterStorage(TankNum).VdotRequestDemand;
1133 : }
1134 : }
1135 :
1136 : // is tank lower than float valve on capacity and requesting fill from controlled supplier?
1137 12 : FillVolRequest = 0.0;
1138 :
1139 23 : if (((VolumePredict) < state.dataWaterData->WaterStorage(TankNum).ValveOnCapacity) ||
1140 11 : state.dataWaterData->WaterStorage(TankNum).LastTimeStepFilling) { // turn on supply to fill tank
1141 4 : FillVolRequest = state.dataWaterData->WaterStorage(TankNum).ValveOffCapacity - VolumePredict;
1142 :
1143 4 : state.dataWaterData->WaterStorage(TankNum).LastTimeStepFilling = true;
1144 :
1145 : // set mains draws for float on (all the way to Float off)
1146 4 : if (state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::MainsFloatValve) {
1147 :
1148 0 : state.dataWaterData->WaterStorage(TankNum).MainsDrawVdot = FillVolRequest / TimeStepSysSec;
1149 0 : NetVolAdd = FillVolRequest;
1150 : }
1151 : // set demand request in supplying tank if needed
1152 8 : if ((state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::OtherTankFloatValve) ||
1153 4 : (state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::TankMainsBackup)) {
1154 0 : state.dataWaterData->WaterStorage(state.dataWaterData->WaterStorage(TankNum).SupplyTankID)
1155 0 : .VdotRequestDemand(state.dataWaterData->WaterStorage(TankNum).SupplyTankDemandARRID) = FillVolRequest / TimeStepSysSec;
1156 : }
1157 :
1158 : // set demand request in groundwater well if needed
1159 8 : if ((state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatValve) ||
1160 4 : (state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatMainsBackup)) {
1161 4 : state.dataWaterData->GroundwaterWell(state.dataWaterData->WaterStorage(TankNum).GroundWellID).VdotRequest =
1162 4 : FillVolRequest / TimeStepSysSec;
1163 : }
1164 : }
1165 :
1166 : // set mains flow if mains backup active
1167 12 : if ((VolumePredict) < state.dataWaterData->WaterStorage(TankNum).BackupMainsCapacity) { // turn on supply
1168 0 : if ((state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatMainsBackup) ||
1169 0 : (state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::TankMainsBackup)) {
1170 0 : FillVolRequest = state.dataWaterData->WaterStorage(TankNum).ValveOffCapacity - VolumePredict;
1171 0 : state.dataWaterData->WaterStorage(TankNum).MainsDrawVdot = FillVolRequest / TimeStepSysSec;
1172 0 : NetVolAdd = FillVolRequest;
1173 : }
1174 : }
1175 :
1176 12 : state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume + NetVolAdd;
1177 12 : if (state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume >= state.dataWaterData->WaterStorage(TankNum).ValveOffCapacity) {
1178 1 : state.dataWaterData->WaterStorage(TankNum).LastTimeStepFilling = false;
1179 : }
1180 :
1181 12 : state.dataWaterData->WaterStorage(TankNum).VdotOverflow = overflowVol / TimeStepSysSec;
1182 12 : state.dataWaterData->WaterStorage(TankNum).VolOverflow = overflowVol;
1183 12 : state.dataWaterData->WaterStorage(TankNum).TwaterOverflow = state.dataWaterManager->overflowTwater;
1184 12 : state.dataWaterData->WaterStorage(TankNum).NetVdot = NetVolAdd / TimeStepSysSec;
1185 12 : state.dataWaterData->WaterStorage(TankNum).MainsDrawVol = state.dataWaterData->WaterStorage(TankNum).MainsDrawVdot * TimeStepSysSec;
1186 12 : state.dataWaterData->WaterStorage(TankNum).VdotToTank = TotVdotSupplyAvail;
1187 12 : state.dataWaterData->WaterStorage(TankNum).VdotFromTank = TotVdotDemandAvail;
1188 :
1189 12 : switch (state.dataWaterData->WaterStorage(TankNum).ThermalMode) {
1190 12 : case TankThermalMode::Scheduled: {
1191 12 : state.dataWaterData->WaterStorage(TankNum).Twater = state.dataWaterData->WaterStorage(TankNum).tempSched->getCurrentVal();
1192 12 : state.dataWaterData->WaterStorage(TankNum).TouterSkin = state.dataWaterData->WaterStorage(TankNum).Twater;
1193 12 : } break;
1194 0 : case TankThermalMode::ZoneCoupled: {
1195 0 : ShowFatalError(state, "WaterUse:Storage (Water Storage Tank) zone thermal model incomplete");
1196 0 : } break;
1197 0 : default:
1198 0 : break;
1199 : }
1200 :
1201 : // set supply avail data from overflows in Receiving tank
1202 12 : if (state.dataWaterData->WaterStorage(TankNum).OverflowMode == Overflow::ToTank) {
1203 0 : state.dataWaterData->WaterStorage(state.dataWaterData->WaterStorage(TankNum).OverflowTankID)
1204 0 : .VdotAvailSupply(state.dataWaterData->WaterStorage(TankNum).OverflowTankSupplyARRID) =
1205 0 : state.dataWaterData->WaterStorage(TankNum).VdotOverflow;
1206 0 : state.dataWaterData->WaterStorage(state.dataWaterData->WaterStorage(TankNum).OverflowTankID)
1207 0 : .TwaterSupply(state.dataWaterData->WaterStorage(TankNum).OverflowTankSupplyARRID) =
1208 0 : state.dataWaterData->WaterStorage(TankNum).TwaterOverflow;
1209 : }
1210 12 : }
1211 :
1212 0 : void SetupTankSupplyComponent(EnergyPlusData &state,
1213 : std::string_view CompName,
1214 : std::string_view CompType,
1215 : std::string_view TankName,
1216 : bool &ErrorsFound,
1217 : int &TankIndex,
1218 : int &WaterSupplyIndex)
1219 : {
1220 :
1221 : // SUBROUTINE INFORMATION:
1222 : // AUTHOR B. Griffith
1223 : // DATE WRITTEN August 2006
1224 : // MODIFIED na
1225 : // RE-ENGINEERED na
1226 :
1227 : // PURPOSE OF THIS SUBROUTINE:
1228 : // Each simulated component that can supply water to a tank
1229 : // makes one call to this subroutine to obtain the data
1230 : // array index it should use to set values in the
1231 : // VdotAvailSupply
1232 :
1233 : // METHODOLOGY EMPLOYED:
1234 : // push the VdotAvailToTank array and return
1235 :
1236 0 : if (!(state.dataWaterData->WaterSystemGetInputCalled)) {
1237 0 : GetWaterManagerInput(state);
1238 : }
1239 :
1240 0 : InternalSetupTankSupplyComponent(state, CompName, CompType, TankName, ErrorsFound, TankIndex, WaterSupplyIndex);
1241 0 : }
1242 :
1243 2 : void InternalSetupTankSupplyComponent(EnergyPlusData &state,
1244 : std::string_view CompName,
1245 : std::string_view CompType,
1246 : std::string_view TankName,
1247 : bool &ErrorsFound,
1248 : int &TankIndex,
1249 : int &WaterSupplyIndex)
1250 : {
1251 :
1252 : // SUBROUTINE INFORMATION:
1253 : // AUTHOR B. Griffith
1254 : // DATE WRITTEN August 2006
1255 : // MODIFIED na
1256 : // RE-ENGINEERED na
1257 :
1258 : // PURPOSE OF THIS SUBROUTINE:
1259 : // Each simulated component that can supply water to a tank
1260 : // makes one call to this subroutine to obtain the data
1261 : // array index it should use to set values in the
1262 : // VdotAvailSupply
1263 :
1264 : // METHODOLOGY EMPLOYED:
1265 : // push the VdotAvailToTank array and return
1266 :
1267 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1268 : int oldNumSupply;
1269 2 : Array1D_string oldSupplyCompNames;
1270 2 : Array1D_string oldSupplyCompTypes;
1271 :
1272 2 : TankIndex = Util::FindItemInList(TankName, state.dataWaterData->WaterStorage);
1273 2 : if (TankIndex == 0) {
1274 0 : ShowSevereError(state, format("WaterUse:Storage (Water Storage Tank) =\"{}\" not found in {} called {}", TankName, CompType, CompName));
1275 0 : ErrorsFound = true;
1276 0 : return; // So we don't pass TankIndex=0
1277 : }
1278 2 : oldNumSupply = state.dataWaterData->WaterStorage(TankIndex).NumWaterSupplies;
1279 2 : if (oldNumSupply > 0) { // do array push
1280 0 : if (allocated(oldSupplyCompNames)) {
1281 0 : oldSupplyCompNames.deallocate();
1282 : }
1283 0 : oldSupplyCompNames.allocate(oldNumSupply);
1284 0 : if (allocated(oldSupplyCompTypes)) {
1285 0 : oldSupplyCompTypes.deallocate();
1286 : }
1287 0 : oldSupplyCompTypes.allocate(oldNumSupply);
1288 0 : if (allocated(state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames)) {
1289 0 : oldSupplyCompNames = state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames;
1290 0 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames.deallocate();
1291 0 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames.allocate(oldNumSupply + 1);
1292 0 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames({1, oldNumSupply}) = oldSupplyCompNames; // array assignment
1293 0 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames(oldNumSupply + 1) = CompName;
1294 : }
1295 0 : if (allocated(state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes)) {
1296 0 : oldSupplyCompTypes = state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes;
1297 0 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes.deallocate();
1298 0 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes.allocate(oldNumSupply + 1);
1299 0 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes({1, oldNumSupply}) = oldSupplyCompTypes; // array assignment
1300 0 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes(oldNumSupply + 1) = CompType;
1301 : }
1302 0 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailSupply.deallocate();
1303 0 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailSupply.allocate(oldNumSupply + 1);
1304 0 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailSupply = 0.0; // initialize
1305 0 : state.dataWaterData->WaterStorage(TankIndex).TwaterSupply.deallocate();
1306 0 : state.dataWaterData->WaterStorage(TankIndex).TwaterSupply.allocate(oldNumSupply + 1);
1307 0 : state.dataWaterData->WaterStorage(TankIndex).TwaterSupply = 0.0; // initialize
1308 0 : WaterSupplyIndex = oldNumSupply + 1;
1309 0 : ++state.dataWaterData->WaterStorage(TankIndex).NumWaterSupplies;
1310 : } else { // first time (no push)
1311 :
1312 2 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailSupply.allocate(1);
1313 2 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailSupply = 0.0; // initialize
1314 2 : state.dataWaterData->WaterStorage(TankIndex).TwaterSupply.allocate(1);
1315 2 : state.dataWaterData->WaterStorage(TankIndex).TwaterSupply = 0.0; // initialize
1316 2 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames.allocate(1);
1317 2 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames(1) = CompName;
1318 2 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes.allocate(1);
1319 2 : state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes(1) = CompType;
1320 2 : WaterSupplyIndex = 1;
1321 2 : state.dataWaterData->WaterStorage(TankIndex).NumWaterSupplies = 1;
1322 : }
1323 2 : }
1324 :
1325 0 : void SetupTankDemandComponent(EnergyPlusData &state,
1326 : std::string_view CompName,
1327 : std::string_view const CompType,
1328 : std::string_view TankName,
1329 : bool &ErrorsFound,
1330 : int &TankIndex,
1331 : int &WaterDemandIndex)
1332 : {
1333 :
1334 : // SUBROUTINE INFORMATION:
1335 : // AUTHOR B. Griffith
1336 : // DATE WRITTEN August 2006
1337 : // MODIFIED na
1338 : // RE-ENGINEERED na
1339 :
1340 : // PURPOSE OF THIS SUBROUTINE:
1341 : // Each simulated component that can supply water to a tank
1342 : // makes one call to this subroutine to obtain the data
1343 : // array index it should use to set values in the
1344 : // VdotAvailSupply
1345 :
1346 : // METHODOLOGY EMPLOYED:
1347 : // push the VdotAvailToTank array and return
1348 :
1349 0 : if (!(state.dataWaterData->WaterSystemGetInputCalled)) {
1350 0 : GetWaterManagerInput(state);
1351 : }
1352 :
1353 0 : InternalSetupTankDemandComponent(state, CompName, CompType, TankName, ErrorsFound, TankIndex, WaterDemandIndex);
1354 0 : }
1355 :
1356 0 : void InternalSetupTankDemandComponent(EnergyPlusData &state,
1357 : std::string_view CompName,
1358 : std::string_view const CompType,
1359 : std::string_view TankName,
1360 : bool &ErrorsFound,
1361 : int &TankIndex,
1362 : int &WaterDemandIndex)
1363 : {
1364 :
1365 : // SUBROUTINE INFORMATION:
1366 : // AUTHOR B. Griffith
1367 : // DATE WRITTEN August 2006
1368 : // MODIFIED na
1369 : // RE-ENGINEERED na
1370 :
1371 : // PURPOSE OF THIS SUBROUTINE:
1372 : // Each simulated component that can supply water to a tank
1373 : // makes one call to this subroutine to obtain the data
1374 : // array index it should use to set values in the
1375 : // VdotAvailSupply
1376 :
1377 : // METHODOLOGY EMPLOYED:
1378 : // push the VdotAvailToTank array and return
1379 :
1380 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1381 : int oldNumDemand;
1382 0 : Array1D_string oldDemandCompNames;
1383 0 : Array1D_string oldDemandCompTypes;
1384 :
1385 0 : TankIndex = Util::FindItemInList(TankName, state.dataWaterData->WaterStorage);
1386 0 : if (TankIndex == 0) {
1387 0 : ShowSevereError(state, format("WaterUse:Storage (Water Storage Tank) =\"{}\" not found in {} called {}", TankName, CompType, CompName));
1388 0 : ErrorsFound = true;
1389 0 : return;
1390 : }
1391 0 : oldNumDemand = state.dataWaterData->WaterStorage(TankIndex).NumWaterDemands;
1392 0 : if (oldNumDemand > 0) { // do array push
1393 0 : if (allocated(oldDemandCompNames)) {
1394 0 : oldDemandCompNames.deallocate();
1395 : }
1396 0 : oldDemandCompNames.allocate(oldNumDemand);
1397 0 : if (allocated(oldDemandCompTypes)) {
1398 0 : oldDemandCompTypes.deallocate();
1399 : }
1400 0 : oldDemandCompTypes.allocate(oldNumDemand);
1401 0 : if (allocated(state.dataWaterData->WaterStorage(TankIndex).DemandCompNames)) {
1402 0 : oldDemandCompNames = state.dataWaterData->WaterStorage(TankIndex).DemandCompNames;
1403 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompNames.deallocate();
1404 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompNames.allocate(oldNumDemand + 1);
1405 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompNames({1, oldNumDemand}) = oldDemandCompNames; // array assignment
1406 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompNames(oldNumDemand + 1) = CompName;
1407 : }
1408 0 : if (allocated(state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes)) {
1409 0 : oldDemandCompTypes = state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes;
1410 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes.deallocate();
1411 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes.allocate(oldNumDemand + 1);
1412 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes({1, oldNumDemand}) = oldDemandCompTypes; // array assignment
1413 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes(oldNumDemand + 1) = CompType;
1414 : }
1415 :
1416 0 : state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand.deallocate();
1417 0 : state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand.allocate(oldNumDemand + 1);
1418 0 : state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand = 0.0; // initialize
1419 :
1420 0 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand.deallocate();
1421 0 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand.allocate(oldNumDemand + 1);
1422 0 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand = 0.0; // initialize
1423 :
1424 0 : WaterDemandIndex = oldNumDemand + 1;
1425 0 : ++state.dataWaterData->WaterStorage(TankIndex).NumWaterDemands;
1426 : } else { // first time (no push)
1427 :
1428 0 : state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand.allocate(1);
1429 0 : state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand = 0.0; // initialize
1430 0 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand.allocate(1);
1431 0 : state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand = 0.0; // initialize
1432 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompNames.allocate(1);
1433 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompNames(1) = CompName;
1434 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes.allocate(1);
1435 0 : state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes(1) = CompType;
1436 0 : state.dataWaterData->WaterStorage(TankIndex).NumWaterDemands = 1;
1437 0 : WaterDemandIndex = 1;
1438 : }
1439 0 : }
1440 :
1441 0 : void CalcRainCollector(EnergyPlusData &state, int const RainColNum) // Index of rain collector
1442 : {
1443 :
1444 : // SUBROUTINE INFORMATION:
1445 : // AUTHOR B. Griffith
1446 : // DATE WRITTEN August 2006
1447 : // MODIFIED na
1448 : // RE-ENGINEERED na
1449 :
1450 : // PURPOSE OF THIS SUBROUTINE:
1451 : // Collect the calculations used to update the modeled values
1452 : // for the rain collector at each system timestep
1453 :
1454 : using DataEnvironment::OutWetBulbTempAt;
1455 0 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
1456 :
1457 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1458 0 : Real64 LossFactor(0.0);
1459 : Real64 VdotAvail;
1460 :
1461 : // If (.NOT.(IsRain)) Then ! is it raining now? No don't use this flag since precip schedule might differ from weather file
1462 0 : if (state.dataWaterData->RainFall.CurrentRate <= 0.0) {
1463 : // set available supply rate in WaterStorage
1464 0 : state.dataWaterData->WaterStorage(state.dataWaterData->RainCollector(RainColNum).StorageTankID)
1465 0 : .VdotAvailSupply(state.dataWaterData->RainCollector(RainColNum).StorageTankSupplyARRID) = 0.0;
1466 : // temperature of water supply is modeled as the same as outdoor drybulb.
1467 0 : state.dataWaterData->WaterStorage(state.dataWaterData->RainCollector(RainColNum).StorageTankID)
1468 0 : .TwaterSupply(state.dataWaterData->RainCollector(RainColNum).StorageTankSupplyARRID) = 0.0;
1469 :
1470 0 : state.dataWaterData->RainCollector(RainColNum).VdotAvail = 0.0;
1471 0 : state.dataWaterData->RainCollector(RainColNum).VolCollected = 0.0;
1472 : } else {
1473 :
1474 0 : switch (state.dataWaterData->RainCollector(RainColNum).LossFactorMode) {
1475 0 : case RainLossFactor::Constant: {
1476 0 : LossFactor = state.dataWaterData->RainCollector(RainColNum).LossFactor;
1477 0 : } break;
1478 0 : case RainLossFactor::Scheduled: {
1479 0 : LossFactor = state.dataWaterData->RainCollector(RainColNum).lossFactorSched->getCurrentVal();
1480 0 : } break;
1481 0 : default: {
1482 0 : assert(false);
1483 : } break;
1484 : }
1485 :
1486 0 : VdotAvail = state.dataWaterData->RainFall.CurrentRate * state.dataWaterData->RainCollector(RainColNum).HorizArea * (1.0 - LossFactor);
1487 :
1488 0 : int month = state.dataEnvrn->Month;
1489 :
1490 0 : if (VdotAvail > state.dataWaterData->RainCollector(RainColNum).MaxCollectRate) {
1491 0 : VdotAvail = state.dataWaterData->RainCollector(RainColNum).MaxCollectRate;
1492 : }
1493 :
1494 : // set available supply rate in WaterStorage
1495 0 : state.dataWaterData->WaterStorage(state.dataWaterData->RainCollector(RainColNum).StorageTankID)
1496 0 : .VdotAvailSupply(state.dataWaterData->RainCollector(RainColNum).StorageTankSupplyARRID) = VdotAvail;
1497 :
1498 : // temperature of water supply is modeled as the same as outdoor drybulb.
1499 0 : state.dataWaterData->WaterStorage(state.dataWaterData->RainCollector(RainColNum).StorageTankID)
1500 0 : .TwaterSupply(state.dataWaterData->RainCollector(RainColNum).StorageTankSupplyARRID) =
1501 0 : OutWetBulbTempAt(state, state.dataWaterData->RainCollector(RainColNum).MeanHeight);
1502 :
1503 0 : state.dataWaterData->RainCollector(RainColNum).VdotAvail = VdotAvail;
1504 0 : state.dataWaterData->RainCollector(RainColNum).VolCollected = VdotAvail * TimeStepSysSec;
1505 0 : if ((state.dataEnvrn->RunPeriodEnvironment) && (!state.dataGlobal->WarmupFlag)) {
1506 0 : state.dataWaterData->RainCollector(RainColNum).VolCollectedMonthly.at(month - 1) +=
1507 0 : state.dataWaterData->RainCollector(RainColNum).VolCollected;
1508 : }
1509 : }
1510 0 : }
1511 :
1512 6 : void CalcGroundwaterWell(EnergyPlusData &state, int const WellNum) // Index of well
1513 : {
1514 :
1515 : // SUBROUTINE INFORMATION:
1516 : // AUTHOR B. Griffith
1517 : // DATE WRITTEN August 2006
1518 : // MODIFIED na
1519 : // RE-ENGINEERED na
1520 :
1521 : // PURPOSE OF THIS SUBROUTINE:
1522 : // Collect the calculations used to update the modeled values
1523 : // for the groundwater wells at each system timestep
1524 :
1525 : // METHODOLOGY EMPLOYED:
1526 : // starting simple and ignoring well storage and complex rate restrictions.
1527 : // just uses nominal pump rate and power (assuming well designed well).
1528 :
1529 6 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
1530 :
1531 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1532 : Real64 VdotDelivered;
1533 : Real64 PumpPower;
1534 :
1535 6 : VdotDelivered = 0.0;
1536 6 : PumpPower = 0.0;
1537 6 : if (state.dataWaterData->GroundwaterWell(WellNum).VdotRequest > 0.0) {
1538 :
1539 2 : if (state.dataWaterData->GroundwaterWell(WellNum).VdotRequest >=
1540 2 : state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate) { // run flat out
1541 1 : state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(WellNum).StorageTankID)
1542 1 : .VdotAvailSupply(state.dataWaterData->GroundwaterWell(WellNum).StorageTankSupplyARRID) =
1543 1 : state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate;
1544 1 : state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(WellNum).StorageTankID)
1545 2 : .TwaterSupply(state.dataWaterData->GroundwaterWell(WellNum).StorageTankSupplyARRID) =
1546 1 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::Deep];
1547 1 : VdotDelivered = state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate;
1548 1 : PumpPower = state.dataWaterData->GroundwaterWell(WellNum).PumpNomPowerUse;
1549 : }
1550 :
1551 : // the run at part load to just meet request
1552 2 : if (state.dataWaterData->GroundwaterWell(WellNum).VdotRequest < state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate) {
1553 1 : state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(WellNum).StorageTankID)
1554 1 : .VdotAvailSupply(state.dataWaterData->GroundwaterWell(WellNum).StorageTankSupplyARRID) =
1555 1 : state.dataWaterData->GroundwaterWell(WellNum).VdotRequest;
1556 1 : state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(WellNum).StorageTankID)
1557 2 : .TwaterSupply(state.dataWaterData->GroundwaterWell(WellNum).StorageTankSupplyARRID) =
1558 1 : state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::Deep];
1559 :
1560 1 : VdotDelivered = state.dataWaterData->GroundwaterWell(WellNum).VdotRequest;
1561 1 : PumpPower = state.dataWaterData->GroundwaterWell(WellNum).PumpNomPowerUse *
1562 1 : state.dataWaterData->GroundwaterWell(WellNum).VdotRequest /
1563 1 : state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate;
1564 : }
1565 : }
1566 :
1567 6 : state.dataWaterData->GroundwaterWell(WellNum).VdotDelivered = VdotDelivered;
1568 6 : state.dataWaterData->GroundwaterWell(WellNum).VolDelivered = VdotDelivered * TimeStepSysSec;
1569 6 : state.dataWaterData->GroundwaterWell(WellNum).PumpPower = PumpPower;
1570 6 : state.dataWaterData->GroundwaterWell(WellNum).PumpEnergy = PumpPower * TimeStepSysSec;
1571 6 : }
1572 :
1573 297134 : void UpdateWaterManager(EnergyPlusData &state)
1574 : {
1575 :
1576 : // SUBROUTINE INFORMATION:
1577 : // AUTHOR B. Griffith
1578 : // DATE WRITTEN August 2006
1579 : // MODIFIED na
1580 : // RE-ENGINEERED na
1581 :
1582 : // PURPOSE OF THIS SUBROUTINE:
1583 : // The water manger is iterating and
1584 : // we need to do the timestep record keeping
1585 : // for tracking state variables.
1586 : // this routine updates variables
1587 : // that hold the value of the Last Timestep
1588 :
1589 : // Using/Aliasing
1590 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1591 : int TankNum;
1592 : int RainColNum;
1593 : int WellNum;
1594 :
1595 297134 : if (state.dataGlobal->BeginEnvrnFlag && state.dataWaterManager->MyEnvrnFlag) {
1596 400 : for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
1597 :
1598 0 : state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).InitialVolume;
1599 0 : state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).InitialVolume;
1600 : }
1601 400 : if ((!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation) && state.dataWaterManager->MyTankDemandCheckFlag) {
1602 79 : if (state.dataWaterData->NumWaterStorageTanks > 0) {
1603 0 : for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
1604 0 : if (state.dataWaterData->WaterStorage(TankNum).NumWaterDemands == 0) {
1605 0 : ShowWarningError(state, "Found WaterUse:Storage that has nothing connected to draw water from it.");
1606 0 : ShowContinueError(state, format("Occurs for WaterUse:Storage = {}", state.dataWaterData->WaterStorage(TankNum).Name));
1607 0 : ShowContinueError(state, "Check that input for water consuming components specifies a water supply tank.");
1608 : }
1609 : }
1610 : }
1611 79 : state.dataWaterManager->MyTankDemandCheckFlag = false;
1612 : }
1613 :
1614 400 : state.dataWaterManager->MyEnvrnFlag = false;
1615 400 : state.dataWaterManager->MyWarmupFlag = true;
1616 : } // end environmental inits
1617 297134 : if (!state.dataGlobal->BeginEnvrnFlag) {
1618 295982 : state.dataWaterManager->MyEnvrnFlag = true;
1619 : }
1620 :
1621 297134 : if (state.dataWaterManager->MyWarmupFlag && (!state.dataGlobal->WarmupFlag)) { // do environment inits. just went out of warmup mode
1622 216 : for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
1623 0 : state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).InitialVolume;
1624 0 : state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).InitialVolume;
1625 0 : state.dataWaterData->WaterStorage(TankNum).LastTimeStepTemp = state.dataWaterData->WaterStorage(TankNum).InitialTankTemp;
1626 : }
1627 216 : state.dataWaterManager->MyWarmupFlag = false;
1628 : }
1629 :
1630 297140 : for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
1631 : // main location for inits for new timestep.
1632 6 : state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume = max(state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume, 0.0);
1633 6 : state.dataWaterData->WaterStorage(TankNum).MainsDrawVdot = 0.0;
1634 6 : state.dataWaterData->WaterStorage(TankNum).MainsDrawVol = 0.0;
1635 6 : state.dataWaterData->WaterStorage(TankNum).NetVdot = 0.0;
1636 6 : state.dataWaterData->WaterStorage(TankNum).VdotFromTank = 0.0;
1637 6 : state.dataWaterData->WaterStorage(TankNum).VdotToTank = 0.0;
1638 6 : if (state.dataWaterData->WaterStorage(TankNum).NumWaterDemands > 0) {
1639 : // don't reset the requested demand, it is up to the other components to update it themselves
1640 : // WaterStorage( TankNum ).VdotRequestDemand = 0.0;
1641 : // the available demand is calculated here in the calc routine, so its fine to initialize it
1642 6 : state.dataWaterData->WaterStorage(TankNum).VdotAvailDemand = 0.0;
1643 : }
1644 6 : state.dataWaterData->WaterStorage(TankNum).VdotOverflow = 0.0;
1645 6 : if (state.dataWaterData->WaterStorage(TankNum).NumWaterSupplies > 0) {
1646 : // TODO: Figure out what to do with this...the available supply should be updated by the components
1647 : // This was an issue because the coil supply was being stomped by this assignment to zero, so no tank action was happening
1648 6 : state.dataWaterData->WaterStorage(TankNum).VdotAvailSupply = 0.0;
1649 : }
1650 12 : if ((state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatValve) ||
1651 6 : (state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatMainsBackup)) {
1652 6 : if (allocated(state.dataWaterData->GroundwaterWell)) {
1653 6 : state.dataWaterData->GroundwaterWell(state.dataWaterData->WaterStorage(TankNum).GroundWellID).VdotRequest = 0.0;
1654 : }
1655 : }
1656 : } // tank loop
1657 :
1658 297134 : for (RainColNum = 1; RainColNum <= state.dataWaterData->NumRainCollectors; ++RainColNum) {
1659 :
1660 0 : state.dataWaterData->RainCollector(RainColNum).VdotAvail = 0.0;
1661 0 : state.dataWaterData->RainCollector(RainColNum).VolCollected = 0.0;
1662 : }
1663 :
1664 297140 : for (WellNum = 1; WellNum <= state.dataWaterData->NumGroundWaterWells; ++WellNum) {
1665 6 : state.dataWaterData->GroundwaterWell(WellNum).VdotRequest = 0.0;
1666 6 : state.dataWaterData->GroundwaterWell(WellNum).VdotDelivered = 0.0;
1667 6 : state.dataWaterData->GroundwaterWell(WellNum).VolDelivered = 0.0;
1668 6 : state.dataWaterData->GroundwaterWell(WellNum).PumpPower = 0.0;
1669 6 : state.dataWaterData->GroundwaterWell(WellNum).PumpEnergy = 0.0;
1670 : }
1671 297134 : }
1672 :
1673 73 : void ReportRainfall(EnergyPlusData &state)
1674 : {
1675 73 : constexpr std::array<std::string_view, 12> Months{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
1676 949 : for (int i = 0; i < 12; i++) {
1677 1752 : OutputReportPredefined::PreDefTableEntry(state,
1678 876 : state.dataOutRptPredefined->pdchMonthlyTotalPrecInWeather,
1679 876 : Months[i],
1680 876 : state.dataWaterData->RainFall.MonthlyTotalPrecInWeather[i]);
1681 876 : OutputReportPredefined::PreDefTableEntry(
1682 876 : state, state.dataOutRptPredefined->pdchMonthlyTotalHrRain, Months[i], state.dataWaterData->RainFall.numRainyHoursInWeather[i]);
1683 : }
1684 : // report site:precipitation
1685 73 : if (state.dataWaterData->RainFall.ModeID == RainfallMode::RainSchedDesign) {
1686 13 : for (int i = 0; i < 12; i++) {
1687 24 : OutputReportPredefined::PreDefTableEntry(state,
1688 12 : state.dataOutRptPredefined->pdchMonthlyTotalPrecInSitePrec,
1689 12 : Months[i],
1690 12 : state.dataWaterData->RainFall.MonthlyTotalPrecInSitePrec[i]);
1691 : }
1692 : }
1693 : // report rain collector
1694 73 : if (state.dataWaterData->NumWaterStorageTanks > 0) {
1695 0 : for (int i = 0; i < 12; i++) {
1696 0 : Real64 accVolCollectedMonthly = 0.0;
1697 0 : for (int Item = 1; Item <= state.dataWaterData->NumRainCollectors; Item++) {
1698 0 : accVolCollectedMonthly += state.dataWaterData->RainCollector(Item).VolCollectedMonthly[i];
1699 : }
1700 0 : OutputReportPredefined::PreDefTableEntry(
1701 0 : state, state.dataOutRptPredefined->pdchMonthlyTotalRainCol, Months[i], accVolCollectedMonthly);
1702 : }
1703 : }
1704 : // report eco roof
1705 311 : for (auto const &c : state.dataConstruction->Construct) {
1706 238 : if (c.TypeIsEcoRoof) {
1707 0 : for (int i = 0; i < 12; i++) {
1708 0 : OutputReportPredefined::PreDefTableEntry(
1709 0 : state, state.dataOutRptPredefined->pdchMonthlyTotalIrrDep, Months[i], state.dataEcoRoofMgr->MonthlyIrrigation[i]);
1710 : }
1711 0 : break;
1712 : }
1713 : }
1714 73 : }
1715 :
1716 : } // namespace WaterManager
1717 :
1718 : } // namespace EnergyPlus
|