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