LCOV - code coverage report
Current view: top level - EnergyPlus - WaterManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 70.4 % 859 605
Test Date: 2025-06-02 07:23:51 Functions: 92.9 % 14 13

            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      3588830 :     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      3588830 :         int RainColNum(0);
     139      3588830 :         int TankNum(0);
     140      3588830 :         int WellNum(0);
     141              : 
     142      3588830 :         if (state.dataWaterManager->GetInputFlag) {
     143          801 :             GetWaterManagerInput(state);
     144          801 :             state.dataWaterManager->GetInputFlag = false;
     145              :         }
     146              : 
     147      3588830 :         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      3601877 :         for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
     155        13047 :             CalcWaterStorageTank(state, TankNum);
     156              :         } // tank loop
     157              : 
     158      3595787 :         for (RainColNum = 1; RainColNum <= state.dataWaterData->NumRainCollectors; ++RainColNum) {
     159         6957 :             CalcRainCollector(state, RainColNum);
     160              :         }
     161              : 
     162      3595787 :         for (WellNum = 1; WellNum <= state.dataWaterData->NumGroundWaterWells; ++WellNum) {
     163         6957 :             CalcGroundwaterWell(state, WellNum);
     164              :         }
     165              : 
     166              :         // call the tanks again to get updated rain and well activity
     167      3601877 :         for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
     168        13047 :             CalcWaterStorageTank(state, TankNum);
     169              :         } // tank loop
     170              :     }
     171              : 
     172      3896580 :     void ManageWaterInits(EnergyPlusData &state)
     173              :     {
     174      3896580 :         if (!(state.dataWaterData->AnyWaterSystemsInModel)) {
     175         1126 :             return;
     176              :         }
     177              : 
     178      3895454 :         UpdateWaterManager(state);
     179      3895454 :         UpdateIrrigation(state);
     180              :     }
     181              : 
     182          806 :     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          806 :         int NumAlphas(0);        // Number of Alphas for each GetObjectItem call
     196          806 :         int NumNumbers(0);       // Number of Numbers for each GetObjectItem call
     197          806 :         int IOStatus(0);         // Used in GetObjectItem
     198          806 :         bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
     199          806 :         int MaxNumAlphas(0);     // argument for call to GetObjectDefMaxArgs
     200          806 :         int MaxNumNumbers(0);    // argument for call to GetObjectDefMaxArgs
     201          806 :         int TotalArgs(0);        // argument for call to GetObjectDefMaxArgs
     202          806 :         int alphaOffset(0);
     203          806 :         std::string objNameMsg;
     204          806 :         Array1D_string cAlphaFieldNames;
     205          806 :         Array1D_string cNumericFieldNames;
     206          806 :         Array1D_bool lNumericFieldBlanks;
     207          806 :         Array1D_bool lAlphaFieldBlanks;
     208          806 :         Array1D_string cAlphaArgs;
     209          806 :         Array1D<Real64> rNumericArgs;
     210          806 :         std::string cCurrentModuleObject;
     211              :         int NumIrrigation;
     212              :         int Dummy;
     213              : 
     214          806 :         if ((state.dataWaterManager->MyOneTimeFlag) && (!(state.dataWaterData->WaterSystemGetInputCalled))) { // big block for entire subroutine
     215              :             // initialize rainfall model
     216          801 :             state.dataWaterData->RainFall.ModeID = RainfallMode::None;
     217              : 
     218          801 :             cCurrentModuleObject = "WaterUse:Storage";
     219          801 :             state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
     220          801 :             MaxNumNumbers = NumNumbers;
     221          801 :             MaxNumAlphas = NumAlphas;
     222          801 :             cCurrentModuleObject = "WaterUse:RainCollector";
     223          801 :             state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
     224          801 :             MaxNumNumbers = max(MaxNumNumbers, NumNumbers);
     225          801 :             MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
     226          801 :             cCurrentModuleObject = "WaterUse:Well";
     227          801 :             state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
     228          801 :             MaxNumNumbers = max(MaxNumNumbers, NumNumbers);
     229          801 :             MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
     230          801 :             cCurrentModuleObject = "Site:Precipitation";
     231          801 :             state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
     232          801 :             MaxNumNumbers = max(MaxNumNumbers, NumNumbers);
     233          801 :             MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
     234          801 :             cCurrentModuleObject = "RoofIrrigation";
     235          801 :             state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
     236          801 :             MaxNumNumbers = max(MaxNumNumbers, NumNumbers);
     237          801 :             MaxNumAlphas = max(MaxNumAlphas, NumAlphas);
     238              : 
     239          801 :             cAlphaFieldNames.allocate(MaxNumAlphas);
     240          801 :             cAlphaArgs.allocate(MaxNumAlphas);
     241          801 :             lAlphaFieldBlanks.dimension(MaxNumAlphas, false);
     242          801 :             cNumericFieldNames.allocate(MaxNumNumbers);
     243          801 :             rNumericArgs.dimension(MaxNumNumbers, 0.0);
     244          801 :             lNumericFieldBlanks.dimension(MaxNumNumbers, false);
     245              : 
     246          801 :             state.dataWaterManager->MyOneTimeFlag = false;
     247          801 :             cCurrentModuleObject = "WaterUse:Storage";
     248          801 :             state.dataWaterData->NumWaterStorageTanks = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     249          801 :             if (state.dataWaterData->NumWaterStorageTanks > 0) {
     250            5 :                 state.dataWaterData->AnyWaterSystemsInModel = true;
     251            5 :                 if (!(allocated(state.dataWaterData->WaterStorage))) {
     252            5 :                     state.dataWaterData->WaterStorage.allocate(state.dataWaterData->NumWaterStorageTanks);
     253              :                 }
     254              : 
     255           10 :                 for (Item = 1; Item <= state.dataWaterData->NumWaterStorageTanks; ++Item) {
     256            5 :                     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            5 :                     ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
     270              : 
     271            5 :                     state.dataWaterData->AnyWaterSystemsInModel = true;
     272            5 :                     state.dataWaterData->WaterStorage(Item).Name = cAlphaArgs(1);
     273            5 :                     Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
     274            5 :                     objNameMsg = cCurrentModuleObject + " = " + cAlphaArgs(1);
     275              : 
     276            5 :                     state.dataWaterData->WaterStorage(Item).QualitySubCategoryName = cAlphaArgs(2);
     277              : 
     278            5 :                     state.dataWaterData->WaterStorage(Item).MaxCapacity = rNumericArgs(1);
     279            5 :                     if (state.dataWaterData->WaterStorage(Item).MaxCapacity == 0.0) { // default
     280            0 :                         state.dataWaterData->WaterStorage(Item).MaxCapacity = Constant::BigNumber;
     281              :                     }
     282              : 
     283            5 :                     state.dataWaterData->WaterStorage(Item).InitialVolume = rNumericArgs(2);
     284            5 :                     state.dataWaterData->WaterStorage(Item).MaxInFlowRate = rNumericArgs(3);
     285            5 :                     if (state.dataWaterData->WaterStorage(Item).MaxInFlowRate == 0.0) { // default
     286            3 :                         state.dataWaterData->WaterStorage(Item).MaxInFlowRate = Constant::BigNumber;
     287              :                     }
     288              : 
     289            5 :                     state.dataWaterData->WaterStorage(Item).MaxOutFlowRate = rNumericArgs(4);
     290            5 :                     if (state.dataWaterData->WaterStorage(Item).MaxOutFlowRate == 0.0) { // default
     291            3 :                         state.dataWaterData->WaterStorage(Item).MaxOutFlowRate = Constant::BigNumber;
     292              :                     }
     293              : 
     294            5 :                     state.dataWaterData->WaterStorage(Item).OverflowTankName = cAlphaArgs(3); // setup later
     295              : 
     296            5 :                     if (lAlphaFieldBlanks(4)) {
     297            0 :                         ShowSevereEmptyField(state, eoh, cAlphaFieldNames(4));
     298            0 :                         ErrorsFound = true;
     299            5 :                     } else if ((state.dataWaterData->WaterStorage(Item).ControlSupply = static_cast<ControlSupplyType>(
     300           10 :                                     getEnumValue(controlSupplyTypeNamesUC, cAlphaArgs(4)))) == ControlSupplyType::Invalid) {
     301            0 :                         ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
     302            0 :                         ErrorsFound = true;
     303              :                     }
     304              : 
     305            5 :                     state.dataWaterData->WaterStorage(Item).ValveOnCapacity = rNumericArgs(5);
     306            5 :                     state.dataWaterData->WaterStorage(Item).ValveOffCapacity = rNumericArgs(6);
     307            5 :                     if (state.dataWaterData->WaterStorage(Item).ControlSupply != ControlSupplyType::NoControlLevel) {
     308            5 :                         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            5 :                     state.dataWaterData->WaterStorage(Item).BackupMainsCapacity = rNumericArgs(7);
     325            5 :                     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            5 :                     state.dataWaterData->WaterStorage(Item).SupplyTankName = cAlphaArgs(5); // set up later
     335              : 
     336            5 :                     if (lAlphaFieldBlanks(6)) {
     337            0 :                         ShowSevereEmptyField(state, eoh, cAlphaFieldNames(6));
     338            0 :                         ErrorsFound = true;
     339            5 :                     } else if ((state.dataWaterData->WaterStorage(Item).ThermalMode =
     340           10 :                                     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            5 :                     if (state.dataWaterData->WaterStorage(Item).ThermalMode == TankThermalMode::Scheduled) {
     346              : 
     347            5 :                         if (lAlphaFieldBlanks(7)) {
     348            0 :                             ShowSevereEmptyField(state, eoh, cAlphaFieldNames(7));
     349            0 :                             ErrorsFound = true;
     350            5 :                         } 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            5 :                         } 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            5 :                     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          801 :             cCurrentModuleObject = "WaterUse:RainCollector";
     395          801 :             state.dataWaterData->NumRainCollectors = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     396          801 :             if (state.dataWaterData->NumRainCollectors > 0) {
     397            2 :                 if (!(allocated(state.dataWaterData->RainCollector))) {
     398            2 :                     state.dataWaterData->RainCollector.allocate(state.dataWaterData->NumRainCollectors);
     399              :                 }
     400              :                 // allow extensible reference to surfaces.
     401            2 :                 state.dataWaterData->AnyWaterSystemsInModel = true;
     402              : 
     403            2 :                 if (state.dataWaterData->RainFall.ModeID == RainfallMode::None) {
     404            2 :                     state.dataWaterData->RainFall.ModeID = RainfallMode::EPWPrecipitation;
     405              :                 }
     406              : 
     407            4 :                 for (Item = 1; Item <= state.dataWaterData->NumRainCollectors; ++Item) {
     408            2 :                     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            2 :                     ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
     422              : 
     423            2 :                     state.dataWaterData->RainCollector(Item).Name = cAlphaArgs(1);
     424            2 :                     Util::IsNameEmpty(state, cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
     425            2 :                     objNameMsg = cCurrentModuleObject + " Named " + cAlphaArgs(1);
     426              : 
     427            2 :                     state.dataWaterData->RainCollector(Item).StorageTankName = cAlphaArgs(2);
     428            2 :                     state.dataWaterData->RainCollector(Item).StorageTankID = Util::FindItemInList(cAlphaArgs(2), state.dataWaterData->WaterStorage);
     429            2 :                     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            2 :                     if (lAlphaFieldBlanks(3)) {
     436            0 :                         ShowSevereEmptyField(state, eoh, cAlphaFieldNames(3));
     437            0 :                         ErrorsFound = true;
     438            2 :                     } else if ((state.dataWaterData->RainCollector(Item).LossFactorMode =
     439            4 :                                     static_cast<RainLossFactor>(getEnumValue(rainLossFactorNamesUC, cAlphaArgs(3)))) == RainLossFactor::Invalid) {
     440            0 :                         ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(3), cAlphaArgs(3));
     441            0 :                         ErrorsFound = true;
     442              :                     }
     443            2 :                     state.dataWaterData->RainCollector(Item).LossFactor = rNumericArgs(1);
     444            2 :                     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            2 :                     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            2 :                     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            2 :                     state.dataWaterData->RainCollector(Item).MaxCollectRate = rNumericArgs(1);
     471            2 :                     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            2 :                     alphaOffset = 4; // update this if more alphas inserted ahead of extensible surface listing
     477            2 :                     state.dataWaterData->RainCollector(Item).NumCollectSurfs = NumAlphas - alphaOffset;
     478            2 :                     state.dataWaterData->RainCollector(Item).SurfName.allocate(state.dataWaterData->RainCollector(Item).NumCollectSurfs);
     479            2 :                     state.dataWaterData->RainCollector(Item).SurfID.allocate(state.dataWaterData->RainCollector(Item).NumCollectSurfs);
     480            4 :                     for (int SurfNum = 1; SurfNum <= state.dataWaterData->RainCollector(Item).NumCollectSurfs; ++SurfNum) {
     481            2 :                         state.dataWaterData->RainCollector(Item).SurfName(SurfNum) = cAlphaArgs(SurfNum + alphaOffset);
     482            2 :                         state.dataWaterData->RainCollector(Item).SurfID(SurfNum) =
     483            2 :                             Util::FindItemInList(cAlphaArgs(SurfNum + alphaOffset), state.dataSurface->Surface);
     484            2 :                         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            2 :                     Real64 tmpArea = 0.0;
     494            2 :                     Real64 tmpNumerator = 0.0;
     495            2 :                     Real64 tmpDenominator = 0.0;
     496            4 :                     for (int SurfNum = 1; SurfNum <= state.dataWaterData->RainCollector(Item).NumCollectSurfs; ++SurfNum) {
     497            2 :                         int ThisSurf = state.dataWaterData->RainCollector(Item).SurfID(SurfNum);
     498            2 :                         tmpArea += state.dataSurface->Surface(ThisSurf).GrossArea * state.dataSurface->Surface(ThisSurf).CosTilt;
     499            2 :                         tmpNumerator += state.dataSurface->Surface(ThisSurf).Centroid.z * state.dataSurface->Surface(ThisSurf).GrossArea;
     500            2 :                         tmpDenominator += state.dataSurface->Surface(ThisSurf).GrossArea;
     501              :                     }
     502            2 :                     state.dataWaterData->RainCollector(Item).HorizArea = tmpArea;
     503              :                     // now setup vertical hieght above ground for height dependent outdoor temps
     504            2 :                     state.dataWaterData->RainCollector(Item).MeanHeight = tmpNumerator / tmpDenominator;
     505              : 
     506              :                     // now set up tank supply connection
     507            4 :                     InternalSetupTankSupplyComponent(state,
     508            2 :                                                      state.dataWaterData->RainCollector(Item).Name,
     509              :                                                      cCurrentModuleObject,
     510            2 :                                                      state.dataWaterData->RainCollector(Item).StorageTankName,
     511              :                                                      ErrorsFound,
     512            2 :                                                      state.dataWaterData->RainCollector(Item).StorageTankID,
     513            2 :                                                      state.dataWaterData->RainCollector(Item).StorageTankSupplyARRID);
     514              :                 }
     515              :             } // (NumRainCollectors > 0)
     516              : 
     517          801 :             cCurrentModuleObject = "WaterUse:Well";
     518          801 :             state.dataWaterData->NumGroundWaterWells = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     519          801 :             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          801 :             cCurrentModuleObject = "WaterUse:Storage";
     589          801 :             if (state.dataWaterData->NumWaterStorageTanks > 0) {
     590           10 :                 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           10 :                     if ((state.dataWaterData->WaterStorage(Item).ControlSupply == ControlSupplyType::WellFloatValve) ||
     593            5 :                         (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           10 :                     if ((state.dataWaterData->WaterStorage(Item).ControlSupply == ControlSupplyType::OtherTankFloatValve) ||
     605            5 :                         (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            5 :                     state.dataWaterData->WaterStorage(Item).OverflowTankID =
     634            5 :                         Util::FindItemInList(state.dataWaterData->WaterStorage(Item).OverflowTankName, state.dataWaterData->WaterStorage);
     635            5 :                     if (state.dataWaterData->WaterStorage(Item).OverflowTankID == 0) {
     636              :                         // if blank, then okay it is discarded.  but if not blank then error
     637            5 :                         if (is_blank(state.dataWaterData->WaterStorage(Item).OverflowTankName)) {
     638            5 :                             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            5 :                     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          801 :             cCurrentModuleObject = "Site:Precipitation";
     663          801 :             state.dataWaterData->NumSiteRainFall = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     664          801 :             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          801 :             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          801 :             cCurrentModuleObject = "RoofIrrigation";
     702          801 :             NumIrrigation = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     703          801 :             if (NumIrrigation > 1) {
     704            0 :                 ShowSevereError(state, format("Only one {} object is allowed", cCurrentModuleObject));
     705            0 :                 ErrorsFound = true;
     706              :             }
     707              : 
     708          801 :             if (NumIrrigation == 1) {
     709            4 :                 state.dataWaterData->AnyIrrigationInModel = true;
     710            4 :                 state.dataInputProcessing->inputProcessor->getObjectItem(
     711              :                     state, cCurrentModuleObject, 1, cAlphaArgs, NumAlphas, rNumericArgs, NumNumbers, IOStatus);
     712              : 
     713            4 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
     714              : 
     715            4 :                 if (lAlphaFieldBlanks(1)) {
     716            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(1));
     717            0 :                     ErrorsFound = true;
     718            8 :                 } else if ((state.dataWaterData->Irrigation.ModeID =
     719            4 :                                 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            4 :                 if (state.dataWaterData->RainFall.ModeID == RainfallMode::None) {
     725            1 :                     state.dataWaterData->RainFall.ModeID = RainfallMode::EPWPrecipitation;
     726              :                 }
     727              : 
     728            8 :                 if (state.dataWaterData->Irrigation.ModeID == IrrigationMode::SchedDesign ||
     729            4 :                     state.dataWaterData->Irrigation.ModeID == IrrigationMode::SmartSched) {
     730            4 :                     if (lAlphaFieldBlanks(2)) {
     731            0 :                         ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
     732            0 :                         ErrorsFound = true;
     733            4 :                     } 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            4 :                     } 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            4 :                 state.dataWaterData->Irrigation.IrrigationThreshold = 0.4;
     745            4 :                 if (state.dataWaterData->Irrigation.ModeID == IrrigationMode::SmartSched && NumNumbers > 0) {
     746            0 :                     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            0 :                         state.dataWaterData->Irrigation.IrrigationThreshold = rNumericArgs(1) / 100.0;
     751              :                     }
     752              :                 }
     753              : 
     754              :             } // NumIrrigation ==1
     755              : 
     756          801 :             if (state.dataWaterData->RainFall.ModeID == RainfallMode::EPWPrecipitation) {
     757            6 :                 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          801 :             state.dataWaterData->AnyWaterSystemsInModel = true;
     763          801 :             state.dataWaterData->WaterSystemGetInputCalled = true;
     764          801 :             state.dataWaterManager->MyOneTimeFlag = false;
     765              : 
     766          801 :             cAlphaFieldNames.deallocate();
     767          801 :             cAlphaArgs.deallocate();
     768          801 :             lAlphaFieldBlanks.deallocate();
     769          801 :             cNumericFieldNames.deallocate();
     770          801 :             rNumericArgs.deallocate();
     771          801 :             lNumericFieldBlanks.deallocate();
     772              : 
     773          801 :             if (ErrorsFound) {
     774            0 :                 ShowFatalError(state, "Errors found in processing input for water manager objects");
     775              :             }
     776              :             // <SetupOutputVariables here...>, CurrentModuleObject='WaterUse:Storage'
     777          806 :             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           10 :                 SetupOutputVariable(state,
     780              :                                     "Water System Storage Tank Volume",
     781              :                                     Constant::Units::m3,
     782            5 :                                     state.dataWaterData->WaterStorage(Item).ThisTimeStepVolume,
     783              :                                     OutputProcessor::TimeStepType::System,
     784              :                                     OutputProcessor::StoreType::Average,
     785            5 :                                     state.dataWaterData->WaterStorage(Item).Name);
     786           10 :                 SetupOutputVariable(state,
     787              :                                     "Water System Storage Tank Net Volume Flow Rate",
     788              :                                     Constant::Units::m3_s,
     789            5 :                                     state.dataWaterData->WaterStorage(Item).NetVdot,
     790              :                                     OutputProcessor::TimeStepType::System,
     791              :                                     OutputProcessor::StoreType::Average,
     792            5 :                                     state.dataWaterData->WaterStorage(Item).Name);
     793           10 :                 SetupOutputVariable(state,
     794              :                                     "Water System Storage Tank Inlet Volume Flow Rate",
     795              :                                     Constant::Units::m3_s,
     796            5 :                                     state.dataWaterData->WaterStorage(Item).VdotToTank,
     797              :                                     OutputProcessor::TimeStepType::System,
     798              :                                     OutputProcessor::StoreType::Average,
     799            5 :                                     state.dataWaterData->WaterStorage(Item).Name);
     800           10 :                 SetupOutputVariable(state,
     801              :                                     "Water System Storage Tank Outlet Volume Flow Rate",
     802              :                                     Constant::Units::m3_s,
     803            5 :                                     state.dataWaterData->WaterStorage(Item).VdotFromTank,
     804              :                                     OutputProcessor::TimeStepType::System,
     805              :                                     OutputProcessor::StoreType::Average,
     806            5 :                                     state.dataWaterData->WaterStorage(Item).Name);
     807           10 :                 SetupOutputVariable(state,
     808              :                                     "Water System Storage Tank Mains Water Volume",
     809              :                                     Constant::Units::m3,
     810            5 :                                     state.dataWaterData->WaterStorage(Item).MainsDrawVol,
     811              :                                     OutputProcessor::TimeStepType::System,
     812              :                                     OutputProcessor::StoreType::Sum,
     813            5 :                                     state.dataWaterData->WaterStorage(Item).Name,
     814              :                                     Constant::eResource::MainsWater,
     815              :                                     OutputProcessor::Group::HVAC,
     816              :                                     OutputProcessor::EndUseCat::WaterSystem,
     817            5 :                                     state.dataWaterData->WaterStorage(Item).QualitySubCategoryName);
     818           10 :                 SetupOutputVariable(state,
     819              :                                     "Water System Storage Tank Mains Water Volume Flow Rate",
     820              :                                     Constant::Units::m3_s,
     821            5 :                                     state.dataWaterData->WaterStorage(Item).MainsDrawVdot,
     822              :                                     OutputProcessor::TimeStepType::System,
     823              :                                     OutputProcessor::StoreType::Average,
     824            5 :                                     state.dataWaterData->WaterStorage(Item).Name);
     825           10 :                 SetupOutputVariable(state,
     826              :                                     "Water System Storage Tank Water Temperature",
     827              :                                     Constant::Units::C,
     828            5 :                                     state.dataWaterData->WaterStorage(Item).Twater,
     829              :                                     OutputProcessor::TimeStepType::System,
     830              :                                     OutputProcessor::StoreType::Average,
     831            5 :                                     state.dataWaterData->WaterStorage(Item).Name);
     832           10 :                 SetupOutputVariable(state,
     833              :                                     "Water System Storage Tank Overflow Volume Flow Rate",
     834              :                                     Constant::Units::m3_s,
     835            5 :                                     state.dataWaterData->WaterStorage(Item).VdotOverflow,
     836              :                                     OutputProcessor::TimeStepType::System,
     837              :                                     OutputProcessor::StoreType::Average,
     838            5 :                                     state.dataWaterData->WaterStorage(Item).Name);
     839            5 :                 if (state.dataWaterData->WaterStorage(Item).OverflowMode == Overflow::Discarded) {
     840           10 :                     SetupOutputVariable(state,
     841              :                                         "Water System Storage Tank Overflow Water Volume",
     842              :                                         Constant::Units::m3,
     843            5 :                                         state.dataWaterData->WaterStorage(Item).VolOverflow,
     844              :                                         OutputProcessor::TimeStepType::System,
     845              :                                         OutputProcessor::StoreType::Sum,
     846            5 :                                         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           10 :                 SetupOutputVariable(state,
     857              :                                     "Water System Storage Tank Overflow Temperature",
     858              :                                     Constant::Units::C,
     859            5 :                                     state.dataWaterData->WaterStorage(Item).TwaterOverflow,
     860              :                                     OutputProcessor::TimeStepType::System,
     861              :                                     OutputProcessor::StoreType::Average,
     862            5 :                                     state.dataWaterData->WaterStorage(Item).Name);
     863              :             }
     864              : 
     865          801 :             if (NumIrrigation == 1) { // CurrentModuleObject='RoofIrrigation'
     866           16 :                 SetupOutputVariable(state,
     867              :                                     "Water System Roof Irrigation Scheduled Depth",
     868              :                                     Constant::Units::m,
     869            4 :                                     state.dataWaterData->Irrigation.ScheduledAmount,
     870              :                                     OutputProcessor::TimeStepType::System,
     871              :                                     OutputProcessor::StoreType::Sum,
     872              :                                     "RoofIrrigation");
     873           16 :                 SetupOutputVariable(state,
     874              :                                     "Water System Roof Irrigation Actual Depth",
     875              :                                     Constant::Units::m,
     876            4 :                                     state.dataWaterData->Irrigation.ActualAmount,
     877              :                                     OutputProcessor::TimeStepType::System,
     878              :                                     OutputProcessor::StoreType::Sum,
     879              :                                     "RoofIrrigation");
     880              :             }
     881              : 
     882          803 :             for (Item = 1; Item <= state.dataWaterData->NumRainCollectors; ++Item) { // CurrentModuleObject='WaterUse:RainCollector'
     883            4 :                 SetupOutputVariable(state,
     884              :                                     "Water System Rainwater Collector Volume Flow Rate",
     885              :                                     Constant::Units::m3_s,
     886            2 :                                     state.dataWaterData->RainCollector(Item).VdotAvail,
     887              :                                     OutputProcessor::TimeStepType::System,
     888              :                                     OutputProcessor::StoreType::Average,
     889            2 :                                     state.dataWaterData->RainCollector(Item).Name);
     890            4 :                 SetupOutputVariable(state,
     891              :                                     "Water System Rainwater Collector Volume",
     892              :                                     Constant::Units::m3,
     893            2 :                                     state.dataWaterData->RainCollector(Item).VolCollected,
     894              :                                     OutputProcessor::TimeStepType::System,
     895              :                                     OutputProcessor::StoreType::Sum,
     896            2 :                                     state.dataWaterData->RainCollector(Item).Name,
     897              :                                     Constant::eResource::OnSiteWater,
     898              :                                     OutputProcessor::Group::HVAC,
     899              :                                     OutputProcessor::EndUseCat::RainWater);
     900              :             }
     901              : 
     902          803 :             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          806 :     }
     948              : 
     949      2925340 :     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      2925340 :         if (state.dataWaterData->RainFall.ModeID == RainfallMode::RainSchedDesign) {
     965        54776 :             schedRate = state.dataWaterData->RainFall.rainSched->getCurrentVal(); // m/hr
     966        54776 :             if (state.dataWaterData->RainFall.NomAnnualRain > 0.0) {
     967        54776 :                 ScaleFactor = state.dataWaterData->RainFall.DesignAnnualRain / state.dataWaterData->RainFall.NomAnnualRain;
     968              :             } else {
     969            0 :                 ScaleFactor = 0.0;
     970              :             }
     971        54776 :             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      2870564 :             if (state.dataEnvrn->LiquidPrecipitation > 0.0) {
     976              :                 // LiquidPrecipitation is for a certain timestep in an hour, the rate = depth / seconds in a timestep
     977         2008 :                 state.dataWaterData->RainFall.CurrentRate = state.dataEnvrn->LiquidPrecipitation / state.dataGlobal->TimeStepZoneSec;
     978              :             } else {
     979      2868556 :                 state.dataWaterData->RainFall.CurrentRate = 0.0;
     980              :             }
     981              :         }
     982      2925340 :         state.dataWaterData->RainFall.CurrentAmount = state.dataWaterData->RainFall.CurrentRate * state.dataGlobal->TimeStepZoneSec;
     983      2925340 :         state.dataEcoRoofMgr->CurrentPrecipitation = state.dataWaterData->RainFall.CurrentAmount; //  units of m
     984              : 
     985      2925340 :         if (state.dataWaterData->RainFall.ModeID == RainfallMode::RainSchedDesign) {
     986        54776 :             if ((state.dataEnvrn->RunPeriodEnvironment) && (!state.dataGlobal->WarmupFlag)) {
     987            0 :                 int month = state.dataEnvrn->Month;
     988            0 :                 state.dataWaterData->RainFall.MonthlyTotalPrecInSitePrec.at(month - 1) += state.dataWaterData->RainFall.CurrentAmount * 1000.0;
     989              :             }
     990              :         }
     991      2925340 :     }
     992              : 
     993      3895454 :     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      3895454 :         Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys;
    1006              : 
    1007              :         Real64 schedRate;
    1008              : 
    1009      3895454 :         state.dataWaterData->Irrigation.ScheduledAmount = 0.0;
    1010              : 
    1011      3895454 :         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      3895454 :         } else if (state.dataWaterData->Irrigation.ModeID == IrrigationMode::SmartSched) {
    1016        89018 :             schedRate = state.dataWaterData->Irrigation.irrSched->getCurrentVal();     // m/hr
    1017        89018 :             state.dataWaterData->Irrigation.ScheduledAmount = schedRate * TimeStepSys; // convert to m/timestep
    1018              :         }
    1019      3895454 :     }
    1020              : 
    1021        26094 :     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        26094 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    1036              : 
    1037              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1038        26094 :         Real64 OrigVdotDemandRequest(0.0);
    1039        26094 :         Real64 TotVdotDemandAvail(0.0);
    1040        26094 :         Real64 OrigVolDemandRequest(0.0);
    1041        26094 :         Real64 TotVolDemandAvail(0.0);
    1042        26094 :         Real64 OrigVdotSupplyAvail(0.0);
    1043        26094 :         Real64 TotVdotSupplyAvail(0.0);
    1044        26094 :         Real64 TotVolSupplyAvail(0.0);
    1045        26094 :         Real64 overflowVdot(0.0);
    1046        26094 :         Real64 overflowVol(0.0);
    1047        26094 :         Real64 NetVdotAdd(0.0);
    1048        26094 :         Real64 NetVolAdd(0.0);
    1049        26094 :         Real64 FillVolRequest(0.0);
    1050        26094 :         Real64 TotVolAllowed(0.0);
    1051        26094 :         Real64 underflowVdot(0.0);
    1052        26094 :         Real64 VolumePredict(0.0);
    1053              : 
    1054        26094 :         if (state.dataGlobal->BeginTimeStepFlag) {
    1055              :             // initializations are done in UpdateWaterManager
    1056              :         }
    1057              : 
    1058        26094 :         overflowVdot = 0.0;
    1059        26094 :         if (state.dataWaterData->WaterStorage(TankNum).NumWaterSupplies > 0) {
    1060        13914 :             OrigVdotSupplyAvail = sum(state.dataWaterData->WaterStorage(TankNum).VdotAvailSupply);
    1061              :         } else {
    1062        12180 :             OrigVdotSupplyAvail = 0.0;
    1063              :         }
    1064        26094 :         TotVdotSupplyAvail = OrigVdotSupplyAvail; // Init
    1065        26094 :         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        26094 :         TotVolSupplyAvail = TotVdotSupplyAvail * TimeStepSysSec;
    1074        26094 :         overflowVol = overflowVdot * TimeStepSysSec;
    1075              : 
    1076        26094 :         underflowVdot = 0.0;
    1077        26094 :         if (state.dataWaterData->WaterStorage(TankNum).NumWaterDemands > 0) {
    1078        26094 :             OrigVdotDemandRequest = sum(state.dataWaterData->WaterStorage(TankNum).VdotRequestDemand);
    1079              :         } else {
    1080            0 :             OrigVdotDemandRequest = 0.0;
    1081              :         }
    1082        26094 :         OrigVolDemandRequest = OrigVdotDemandRequest * TimeStepSysSec;
    1083        26094 :         TotVdotDemandAvail = OrigVdotDemandRequest; // initialize to satisfied then modify if needed
    1084        26094 :         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        26094 :         TotVolDemandAvail = TotVdotDemandAvail * TimeStepSysSec;
    1090              : 
    1091        26094 :         NetVdotAdd = TotVdotSupplyAvail - TotVdotDemandAvail;
    1092        26094 :         NetVolAdd = NetVdotAdd * TimeStepSysSec;
    1093              : 
    1094        26094 :         VolumePredict = state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume + NetVolAdd;
    1095              : 
    1096              :         // would tank capacity be exceeded?
    1097        26094 :         TotVolAllowed = state.dataWaterData->WaterStorage(TankNum).MaxCapacity - state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume;
    1098        26094 :         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        26094 :         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        26094 :         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        26094 :             if (state.dataWaterData->WaterStorage(TankNum).NumWaterDemands > 0) {
    1132        26094 :                 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        26094 :         FillVolRequest = 0.0;
    1138              : 
    1139        52118 :         if (((VolumePredict) < state.dataWaterData->WaterStorage(TankNum).ValveOnCapacity) ||
    1140        26024 :             state.dataWaterData->WaterStorage(TankNum).LastTimeStepFilling) { // turn on supply to fill tank
    1141          140 :             FillVolRequest = state.dataWaterData->WaterStorage(TankNum).ValveOffCapacity - VolumePredict;
    1142              : 
    1143          140 :             state.dataWaterData->WaterStorage(TankNum).LastTimeStepFilling = true;
    1144              : 
    1145              :             // set mains draws for float on (all the way to Float off)
    1146          140 :             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          280 :             if ((state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::OtherTankFloatValve) ||
    1153          140 :                 (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          280 :             if ((state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatValve) ||
    1160          140 :                 (state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatMainsBackup)) {
    1161          140 :                 state.dataWaterData->GroundwaterWell(state.dataWaterData->WaterStorage(TankNum).GroundWellID).VdotRequest =
    1162          140 :                     FillVolRequest / TimeStepSysSec;
    1163              :             }
    1164              :         }
    1165              : 
    1166              :         // set mains flow if mains backup active
    1167        26094 :         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        26094 :         state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume + NetVolAdd;
    1177        26094 :         if (state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume >= state.dataWaterData->WaterStorage(TankNum).ValveOffCapacity) {
    1178         9418 :             state.dataWaterData->WaterStorage(TankNum).LastTimeStepFilling = false;
    1179              :         }
    1180              : 
    1181        26094 :         state.dataWaterData->WaterStorage(TankNum).VdotOverflow = overflowVol / TimeStepSysSec;
    1182        26094 :         state.dataWaterData->WaterStorage(TankNum).VolOverflow = overflowVol;
    1183        26094 :         state.dataWaterData->WaterStorage(TankNum).TwaterOverflow = state.dataWaterManager->overflowTwater;
    1184        26094 :         state.dataWaterData->WaterStorage(TankNum).NetVdot = NetVolAdd / TimeStepSysSec;
    1185        26094 :         state.dataWaterData->WaterStorage(TankNum).MainsDrawVol = state.dataWaterData->WaterStorage(TankNum).MainsDrawVdot * TimeStepSysSec;
    1186        26094 :         state.dataWaterData->WaterStorage(TankNum).VdotToTank = TotVdotSupplyAvail;
    1187        26094 :         state.dataWaterData->WaterStorage(TankNum).VdotFromTank = TotVdotDemandAvail;
    1188              : 
    1189        26094 :         switch (state.dataWaterData->WaterStorage(TankNum).ThermalMode) {
    1190        26094 :         case TankThermalMode::Scheduled: {
    1191        26094 :             state.dataWaterData->WaterStorage(TankNum).Twater = state.dataWaterData->WaterStorage(TankNum).tempSched->getCurrentVal();
    1192        26094 :             state.dataWaterData->WaterStorage(TankNum).TouterSkin = state.dataWaterData->WaterStorage(TankNum).Twater;
    1193        26094 :         } 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        26094 :         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        26094 :     }
    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            4 :     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            4 :         Array1D_string oldSupplyCompNames;
    1270            4 :         Array1D_string oldSupplyCompTypes;
    1271              : 
    1272            4 :         TankIndex = Util::FindItemInList(TankName, state.dataWaterData->WaterStorage);
    1273            4 :         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            4 :         oldNumSupply = state.dataWaterData->WaterStorage(TankIndex).NumWaterSupplies;
    1279            4 :         if (oldNumSupply > 0) { // do array push
    1280            2 :             if (allocated(oldSupplyCompNames)) {
    1281            0 :                 oldSupplyCompNames.deallocate();
    1282              :             }
    1283            2 :             oldSupplyCompNames.allocate(oldNumSupply);
    1284            2 :             if (allocated(oldSupplyCompTypes)) {
    1285            0 :                 oldSupplyCompTypes.deallocate();
    1286              :             }
    1287            2 :             oldSupplyCompTypes.allocate(oldNumSupply);
    1288            2 :             if (allocated(state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames)) {
    1289            2 :                 oldSupplyCompNames = state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames;
    1290            2 :                 state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames.deallocate();
    1291            2 :                 state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames.allocate(oldNumSupply + 1);
    1292            2 :                 state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames({1, oldNumSupply}) = oldSupplyCompNames; // array assignment
    1293            2 :                 state.dataWaterData->WaterStorage(TankIndex).SupplyCompNames(oldNumSupply + 1) = CompName;
    1294              :             }
    1295            2 :             if (allocated(state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes)) {
    1296            2 :                 oldSupplyCompTypes = state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes;
    1297            2 :                 state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes.deallocate();
    1298            2 :                 state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes.allocate(oldNumSupply + 1);
    1299            2 :                 state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes({1, oldNumSupply}) = oldSupplyCompTypes; // array assignment
    1300            2 :                 state.dataWaterData->WaterStorage(TankIndex).SupplyCompTypes(oldNumSupply + 1) = CompType;
    1301              :             }
    1302            2 :             state.dataWaterData->WaterStorage(TankIndex).VdotAvailSupply.deallocate();
    1303            2 :             state.dataWaterData->WaterStorage(TankIndex).VdotAvailSupply.allocate(oldNumSupply + 1);
    1304            2 :             state.dataWaterData->WaterStorage(TankIndex).VdotAvailSupply = 0.0; // initialize
    1305            2 :             state.dataWaterData->WaterStorage(TankIndex).TwaterSupply.deallocate();
    1306            2 :             state.dataWaterData->WaterStorage(TankIndex).TwaterSupply.allocate(oldNumSupply + 1);
    1307            2 :             state.dataWaterData->WaterStorage(TankIndex).TwaterSupply = 0.0; // initialize
    1308            2 :             WaterSupplyIndex = oldNumSupply + 1;
    1309            2 :             ++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            4 :     }
    1324              : 
    1325            6 :     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            6 :         if (!(state.dataWaterData->WaterSystemGetInputCalled)) {
    1350            5 :             GetWaterManagerInput(state);
    1351              :         }
    1352              : 
    1353            6 :         InternalSetupTankDemandComponent(state, CompName, CompType, TankName, ErrorsFound, TankIndex, WaterDemandIndex);
    1354            6 :     }
    1355              : 
    1356            6 :     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            6 :         Array1D_string oldDemandCompNames;
    1383            6 :         Array1D_string oldDemandCompTypes;
    1384              : 
    1385            6 :         TankIndex = Util::FindItemInList(TankName, state.dataWaterData->WaterStorage);
    1386            6 :         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            6 :         oldNumDemand = state.dataWaterData->WaterStorage(TankIndex).NumWaterDemands;
    1392            6 :         if (oldNumDemand > 0) { // do array push
    1393            1 :             if (allocated(oldDemandCompNames)) {
    1394            0 :                 oldDemandCompNames.deallocate();
    1395              :             }
    1396            1 :             oldDemandCompNames.allocate(oldNumDemand);
    1397            1 :             if (allocated(oldDemandCompTypes)) {
    1398            0 :                 oldDemandCompTypes.deallocate();
    1399              :             }
    1400            1 :             oldDemandCompTypes.allocate(oldNumDemand);
    1401            1 :             if (allocated(state.dataWaterData->WaterStorage(TankIndex).DemandCompNames)) {
    1402            1 :                 oldDemandCompNames = state.dataWaterData->WaterStorage(TankIndex).DemandCompNames;
    1403            1 :                 state.dataWaterData->WaterStorage(TankIndex).DemandCompNames.deallocate();
    1404            1 :                 state.dataWaterData->WaterStorage(TankIndex).DemandCompNames.allocate(oldNumDemand + 1);
    1405            1 :                 state.dataWaterData->WaterStorage(TankIndex).DemandCompNames({1, oldNumDemand}) = oldDemandCompNames; // array assignment
    1406            1 :                 state.dataWaterData->WaterStorage(TankIndex).DemandCompNames(oldNumDemand + 1) = CompName;
    1407              :             }
    1408            1 :             if (allocated(state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes)) {
    1409            1 :                 oldDemandCompTypes = state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes;
    1410            1 :                 state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes.deallocate();
    1411            1 :                 state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes.allocate(oldNumDemand + 1);
    1412            1 :                 state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes({1, oldNumDemand}) = oldDemandCompTypes; // array assignment
    1413            1 :                 state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes(oldNumDemand + 1) = CompType;
    1414              :             }
    1415              : 
    1416            1 :             state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand.deallocate();
    1417            1 :             state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand.allocate(oldNumDemand + 1);
    1418            1 :             state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand = 0.0; // initialize
    1419              : 
    1420            1 :             state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand.deallocate();
    1421            1 :             state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand.allocate(oldNumDemand + 1);
    1422            1 :             state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand = 0.0; // initialize
    1423              : 
    1424            1 :             WaterDemandIndex = oldNumDemand + 1;
    1425            1 :             ++state.dataWaterData->WaterStorage(TankIndex).NumWaterDemands;
    1426              :         } else { // first time (no push)
    1427              : 
    1428            5 :             state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand.allocate(1);
    1429            5 :             state.dataWaterData->WaterStorage(TankIndex).VdotRequestDemand = 0.0; // initialize
    1430            5 :             state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand.allocate(1);
    1431            5 :             state.dataWaterData->WaterStorage(TankIndex).VdotAvailDemand = 0.0; // initialize
    1432            5 :             state.dataWaterData->WaterStorage(TankIndex).DemandCompNames.allocate(1);
    1433            5 :             state.dataWaterData->WaterStorage(TankIndex).DemandCompNames(1) = CompName;
    1434            5 :             state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes.allocate(1);
    1435            5 :             state.dataWaterData->WaterStorage(TankIndex).DemandCompTypes(1) = CompType;
    1436            5 :             state.dataWaterData->WaterStorage(TankIndex).NumWaterDemands = 1;
    1437            5 :             WaterDemandIndex = 1;
    1438              :         }
    1439            6 :     }
    1440              : 
    1441         6957 :     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         6957 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    1456              : 
    1457              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1458         6957 :         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         6957 :         if (state.dataWaterData->RainFall.CurrentRate <= 0.0) {
    1463              :             // set available supply rate in WaterStorage
    1464         6957 :             state.dataWaterData->WaterStorage(state.dataWaterData->RainCollector(RainColNum).StorageTankID)
    1465         6957 :                 .VdotAvailSupply(state.dataWaterData->RainCollector(RainColNum).StorageTankSupplyARRID) = 0.0;
    1466              :             // temperature of water supply is modeled as the same as outdoor drybulb.
    1467         6957 :             state.dataWaterData->WaterStorage(state.dataWaterData->RainCollector(RainColNum).StorageTankID)
    1468         6957 :                 .TwaterSupply(state.dataWaterData->RainCollector(RainColNum).StorageTankSupplyARRID) = 0.0;
    1469              : 
    1470         6957 :             state.dataWaterData->RainCollector(RainColNum).VdotAvail = 0.0;
    1471         6957 :             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         6957 :     }
    1511              : 
    1512         6957 :     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         6957 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    1530              : 
    1531              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1532              :         Real64 VdotDelivered;
    1533              :         Real64 PumpPower;
    1534              : 
    1535         6957 :         VdotDelivered = 0.0;
    1536         6957 :         PumpPower = 0.0;
    1537         6957 :         if (state.dataWaterData->GroundwaterWell(WellNum).VdotRequest > 0.0) {
    1538              : 
    1539           70 :             if (state.dataWaterData->GroundwaterWell(WellNum).VdotRequest >=
    1540           70 :                 state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate) { // run flat out
    1541            0 :                 state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(WellNum).StorageTankID)
    1542            0 :                     .VdotAvailSupply(state.dataWaterData->GroundwaterWell(WellNum).StorageTankSupplyARRID) =
    1543            0 :                     state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate;
    1544            0 :                 state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(WellNum).StorageTankID)
    1545            0 :                     .TwaterSupply(state.dataWaterData->GroundwaterWell(WellNum).StorageTankSupplyARRID) =
    1546            0 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::Deep];
    1547            0 :                 VdotDelivered = state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate;
    1548            0 :                 PumpPower = state.dataWaterData->GroundwaterWell(WellNum).PumpNomPowerUse;
    1549              :             }
    1550              : 
    1551              :             // the run at part load to just meet request
    1552           70 :             if (state.dataWaterData->GroundwaterWell(WellNum).VdotRequest < state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate) {
    1553           70 :                 state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(WellNum).StorageTankID)
    1554           70 :                     .VdotAvailSupply(state.dataWaterData->GroundwaterWell(WellNum).StorageTankSupplyARRID) =
    1555           70 :                     state.dataWaterData->GroundwaterWell(WellNum).VdotRequest;
    1556           70 :                 state.dataWaterData->WaterStorage(state.dataWaterData->GroundwaterWell(WellNum).StorageTankID)
    1557          140 :                     .TwaterSupply(state.dataWaterData->GroundwaterWell(WellNum).StorageTankSupplyARRID) =
    1558           70 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::Deep];
    1559              : 
    1560           70 :                 VdotDelivered = state.dataWaterData->GroundwaterWell(WellNum).VdotRequest;
    1561           70 :                 PumpPower = state.dataWaterData->GroundwaterWell(WellNum).PumpNomPowerUse *
    1562           70 :                             state.dataWaterData->GroundwaterWell(WellNum).VdotRequest /
    1563           70 :                             state.dataWaterData->GroundwaterWell(WellNum).PumpNomVolFlowRate;
    1564              :             }
    1565              :         }
    1566              : 
    1567         6957 :         state.dataWaterData->GroundwaterWell(WellNum).VdotDelivered = VdotDelivered;
    1568         6957 :         state.dataWaterData->GroundwaterWell(WellNum).VolDelivered = VdotDelivered * TimeStepSysSec;
    1569         6957 :         state.dataWaterData->GroundwaterWell(WellNum).PumpPower = PumpPower;
    1570         6957 :         state.dataWaterData->GroundwaterWell(WellNum).PumpEnergy = PumpPower * TimeStepSysSec;
    1571         6957 :     }
    1572              : 
    1573      3895454 :     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      3895454 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataWaterManager->MyEnvrnFlag) {
    1596         6066 :             for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
    1597              : 
    1598           36 :                 state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).InitialVolume;
    1599           36 :                 state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).InitialVolume;
    1600              :             }
    1601         6030 :             if ((!state.dataGlobal->DoingSizing) && (!state.dataGlobal->KickOffSimulation) && state.dataWaterManager->MyTankDemandCheckFlag) {
    1602          800 :                 if (state.dataWaterData->NumWaterStorageTanks > 0) {
    1603           10 :                     for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
    1604            5 :                         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          800 :                 state.dataWaterManager->MyTankDemandCheckFlag = false;
    1612              :             }
    1613              : 
    1614         6030 :             state.dataWaterManager->MyEnvrnFlag = false;
    1615         6030 :             state.dataWaterManager->MyWarmupFlag = true;
    1616              :         } // end environmental inits
    1617      3895454 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    1618      3879341 :             state.dataWaterManager->MyEnvrnFlag = true;
    1619              :         }
    1620              : 
    1621      3895454 :         if (state.dataWaterManager->MyWarmupFlag && (!state.dataGlobal->WarmupFlag)) { // do environment inits.  just went out of warmup mode
    1622         2660 :             for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
    1623           14 :                 state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).InitialVolume;
    1624           14 :                 state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume = state.dataWaterData->WaterStorage(TankNum).InitialVolume;
    1625           14 :                 state.dataWaterData->WaterStorage(TankNum).LastTimeStepTemp = state.dataWaterData->WaterStorage(TankNum).InitialTankTemp;
    1626              :             }
    1627         2646 :             state.dataWaterManager->MyWarmupFlag = false;
    1628              :         }
    1629              : 
    1630      3909493 :         for (TankNum = 1; TankNum <= state.dataWaterData->NumWaterStorageTanks; ++TankNum) {
    1631              :             // main location for inits for new timestep.
    1632        14039 :             state.dataWaterData->WaterStorage(TankNum).LastTimeStepVolume = max(state.dataWaterData->WaterStorage(TankNum).ThisTimeStepVolume, 0.0);
    1633        14039 :             state.dataWaterData->WaterStorage(TankNum).MainsDrawVdot = 0.0;
    1634        14039 :             state.dataWaterData->WaterStorage(TankNum).MainsDrawVol = 0.0;
    1635        14039 :             state.dataWaterData->WaterStorage(TankNum).NetVdot = 0.0;
    1636        14039 :             state.dataWaterData->WaterStorage(TankNum).VdotFromTank = 0.0;
    1637        14039 :             state.dataWaterData->WaterStorage(TankNum).VdotToTank = 0.0;
    1638        14039 :             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        14039 :                 state.dataWaterData->WaterStorage(TankNum).VdotAvailDemand = 0.0;
    1643              :             }
    1644        14039 :             state.dataWaterData->WaterStorage(TankNum).VdotOverflow = 0.0;
    1645        14039 :             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         7943 :                 state.dataWaterData->WaterStorage(TankNum).VdotAvailSupply = 0.0;
    1649              :             }
    1650        28078 :             if ((state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatValve) ||
    1651        14039 :                 (state.dataWaterData->WaterStorage(TankNum).ControlSupply == ControlSupplyType::WellFloatMainsBackup)) {
    1652         7943 :                 if (allocated(state.dataWaterData->GroundwaterWell)) {
    1653         7943 :                     state.dataWaterData->GroundwaterWell(state.dataWaterData->WaterStorage(TankNum).GroundWellID).VdotRequest = 0.0;
    1654              :                 }
    1655              :             }
    1656              :         } // tank loop
    1657              : 
    1658      3903397 :         for (RainColNum = 1; RainColNum <= state.dataWaterData->NumRainCollectors; ++RainColNum) {
    1659              : 
    1660         7943 :             state.dataWaterData->RainCollector(RainColNum).VdotAvail = 0.0;
    1661         7943 :             state.dataWaterData->RainCollector(RainColNum).VolCollected = 0.0;
    1662              :         }
    1663              : 
    1664      3903397 :         for (WellNum = 1; WellNum <= state.dataWaterData->NumGroundWaterWells; ++WellNum) {
    1665         7943 :             state.dataWaterData->GroundwaterWell(WellNum).VdotRequest = 0.0;
    1666         7943 :             state.dataWaterData->GroundwaterWell(WellNum).VdotDelivered = 0.0;
    1667         7943 :             state.dataWaterData->GroundwaterWell(WellNum).VolDelivered = 0.0;
    1668         7943 :             state.dataWaterData->GroundwaterWell(WellNum).PumpPower = 0.0;
    1669         7943 :             state.dataWaterData->GroundwaterWell(WellNum).PumpEnergy = 0.0;
    1670              :         }
    1671      3895454 :     }
    1672              : 
    1673          799 :     void ReportRainfall(EnergyPlusData &state)
    1674              :     {
    1675          799 :         constexpr std::array<std::string_view, 12> Months{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    1676        10387 :         for (int i = 0; i < 12; i++) {
    1677        19176 :             OutputReportPredefined::PreDefTableEntry(state,
    1678         9588 :                                                      state.dataOutRptPredefined->pdchMonthlyTotalPrecInWeather,
    1679         9588 :                                                      Months[i],
    1680         9588 :                                                      state.dataWaterData->RainFall.MonthlyTotalPrecInWeather[i]);
    1681         9588 :             OutputReportPredefined::PreDefTableEntry(
    1682         9588 :                 state, state.dataOutRptPredefined->pdchMonthlyTotalHrRain, Months[i], state.dataWaterData->RainFall.numRainyHoursInWeather[i]);
    1683              :         }
    1684              :         // report site:precipitation
    1685          799 :         if (state.dataWaterData->RainFall.ModeID == RainfallMode::RainSchedDesign) {
    1686           52 :             for (int i = 0; i < 12; i++) {
    1687           96 :                 OutputReportPredefined::PreDefTableEntry(state,
    1688           48 :                                                          state.dataOutRptPredefined->pdchMonthlyTotalPrecInSitePrec,
    1689           48 :                                                          Months[i],
    1690           48 :                                                          state.dataWaterData->RainFall.MonthlyTotalPrecInSitePrec[i]);
    1691              :             }
    1692              :         }
    1693              :         // report rain collector
    1694          799 :         if (state.dataWaterData->NumWaterStorageTanks > 0) {
    1695           65 :             for (int i = 0; i < 12; i++) {
    1696           60 :                 Real64 accVolCollectedMonthly = 0.0;
    1697           84 :                 for (int Item = 1; Item <= state.dataWaterData->NumRainCollectors; Item++) {
    1698           24 :                     accVolCollectedMonthly += state.dataWaterData->RainCollector(Item).VolCollectedMonthly[i];
    1699              :                 }
    1700          120 :                 OutputReportPredefined::PreDefTableEntry(
    1701           60 :                     state, state.dataOutRptPredefined->pdchMonthlyTotalRainCol, Months[i], accVolCollectedMonthly);
    1702              :             }
    1703              :         }
    1704              :         // report eco roof
    1705         6848 :         for (auto const &c : state.dataConstruction->Construct) {
    1706         6053 :             if (c.TypeIsEcoRoof) {
    1707           52 :                 for (int i = 0; i < 12; i++) {
    1708           96 :                     OutputReportPredefined::PreDefTableEntry(
    1709           48 :                         state, state.dataOutRptPredefined->pdchMonthlyTotalIrrDep, Months[i], state.dataEcoRoofMgr->MonthlyIrrigation[i]);
    1710              :                 }
    1711            4 :                 break;
    1712              :             }
    1713              :         }
    1714          799 :     }
    1715              : 
    1716              : } // namespace WaterManager
    1717              : 
    1718              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1