LCOV - code coverage report
Current view: top level - EnergyPlus - WaterManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 53.4 % 859 459
Test Date: 2025-06-02 12:03:30 Functions: 71.4 % 14 10

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

Generated by: LCOV version 2.0-1