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