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