LCOV - code coverage report
Current view: top level - EnergyPlus - WeatherManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 3694 5466 67.6 %
Date: 2023-01-17 19:17:23 Functions: 77 85 90.6 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <array>
      50             : #include <cmath>
      51             : #include <cstdio>
      52             : #include <map>
      53             : 
      54             : // ObjexxFCL Headers
      55             : #include <ObjexxFCL/Array.functions.hh>
      56             : #include <ObjexxFCL/ArrayS.functions.hh>
      57             : #include <ObjexxFCL/Fmath.hh>
      58             : #include <ObjexxFCL/string.functions.hh>
      59             : #include <ObjexxFCL/time.hh>
      60             : 
      61             : // EnergyPlus Headers
      62             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      63             : #include <EnergyPlus/DataEnvironment.hh>
      64             : #include <EnergyPlus/DataHeatBalance.hh>
      65             : #include <EnergyPlus/DataIPShortCuts.hh>
      66             : #include <EnergyPlus/DataPrecisionGlobals.hh>
      67             : #include <EnergyPlus/DataReportingFlags.hh>
      68             : #include <EnergyPlus/DataSurfaces.hh>
      69             : #include <EnergyPlus/DataSystemVariables.hh>
      70             : #include <EnergyPlus/DataWater.hh>
      71             : #include <EnergyPlus/DisplayRoutines.hh>
      72             : #include <EnergyPlus/EMSManager.hh>
      73             : #include <EnergyPlus/FileSystem.hh>
      74             : #include <EnergyPlus/General.hh>
      75             : #include <EnergyPlus/GlobalNames.hh>
      76             : #include <EnergyPlus/GroundTemperatureModeling/GroundTemperatureModelManager.hh>
      77             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      78             : #include <EnergyPlus/OutputProcessor.hh>
      79             : #include <EnergyPlus/OutputReportPredefined.hh>
      80             : #include <EnergyPlus/OutputReportTabular.hh>
      81             : #include <EnergyPlus/Psychrometrics.hh>
      82             : #include <EnergyPlus/ScheduleManager.hh>
      83             : #include <EnergyPlus/StringUtilities.hh>
      84             : #include <EnergyPlus/SurfaceGeometry.hh>
      85             : #include <EnergyPlus/ThermalComfort.hh>
      86             : #include <EnergyPlus/UtilityRoutines.hh>
      87             : #include <EnergyPlus/Vectors.hh>
      88             : #include <EnergyPlus/WaterManager.hh>
      89             : #include <EnergyPlus/WeatherManager.hh>
      90             : 
      91             : namespace EnergyPlus {
      92             : 
      93             : namespace WeatherManager {
      94             : 
      95             :     // MODULE INFORMATION:
      96             :     //       AUTHOR         Rick Strand
      97             :     //       DATE WRITTEN   May 1997
      98             :     //       MODIFIED       December 1998, FW; December 1999, LKL.
      99             : 
     100             :     // PURPOSE OF THIS MODULE:
     101             :     // This module contains all of the weather handling routines for
     102             :     // EnergyPlus.  That includes getting user input, defining design day
     103             :     // weather, retrieving data from weather files, and supplying the
     104             :     // outdoor environment for each time step.
     105             : 
     106             :     constexpr std::array<std::string_view, static_cast<int>(EpwHeaderType::Num)> epwHeaders({"LOCATION",
     107             :                                                                                              "DESIGN CONDITIONS",
     108             :                                                                                              "TYPICAL/EXTREME PERIODS",
     109             :                                                                                              "GROUND TEMPERATURES",
     110             :                                                                                              "HOLIDAYS/DAYLIGHT SAVING",
     111             :                                                                                              "COMMENTS 1",
     112             :                                                                                              "COMMENTS 2",
     113             :                                                                                              "DATA PERIODS"});
     114             : 
     115             :     static constexpr std::array<std::string_view, static_cast<int>(WaterMainsTempCalcMethod::Num)> waterMainsCalcMethodNames{
     116             :         "Schedule", "Correlation", "CorrelationFromWeatherFile", "FixedDefault"};
     117             : 
     118             :     static constexpr std::array<std::string_view, static_cast<int>(WaterMainsTempCalcMethod::Num)> waterMainsCalcMethodNamesUC{
     119             :         "SCHEDULE", "CORRELATION", "CORRELATIONFROMWEATHERFILE", "FIXEDDEFAULT"};
     120             : 
     121             :     static constexpr std::array<std::string_view, static_cast<int>(SkyTempCalcType::Num)> SkyTempModelInputNamesUC{
     122             :         "CLARKALLEN", "SCHEDULEVALUE", "DIFFERENCESCHEDULEDRYBULBVALUE", "DIFFERENCESCHEDULEDEWPOINTVALUE", "BRUNT", "IDSO", "BERDAHLMARTIN"};
     123             : 
     124             :     static constexpr std::array<std::string_view, static_cast<int>(SkyTempCalcType::Num)> SkyTempModelNames{"Clark and Allen",
     125             :                                                                                                             "Schedule Value",
     126             :                                                                                                             "DryBulb Difference Schedule Value",
     127             :                                                                                                             "Dewpoint Difference Schedule Value",
     128             :                                                                                                             "Brunt",
     129             :                                                                                                             "Idso",
     130             :                                                                                                             "Berdahl and Martin"};
     131             : 
     132     2661169 :     void ManageWeather(EnergyPlusData &state)
     133             :     {
     134             : 
     135             :         // SUBROUTINE INFORMATION:
     136             :         //       AUTHOR         Rick Strand
     137             :         //       DATE WRITTEN   May 1997
     138             :         //       MODIFIED       June 1997 (general clean-up)
     139             : 
     140             :         // PURPOSE OF THIS SUBROUTINE:
     141             :         // This subroutine is the main driver of the weather manager module.
     142             :         // It controls the assignment of weather related global variables as
     143             :         // well as the reads and writes for weather information.
     144             : 
     145     2661169 :         InitializeWeather(state, state.dataWeatherManager->PrintEnvrnStamp);
     146             : 
     147     2661169 :         bool anyEMSRan = false;
     148             :         // Cannot call this during sizing, because EMS will not initialize properly until after simulation kickoff
     149     2661169 :         if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation) {
     150     1776480 :             EMSManager::ManageEMS(state,
     151             :                                   EMSManager::EMSCallFrom::BeginZoneTimestepBeforeSetCurrentWeather,
     152             :                                   anyEMSRan,
     153     3552960 :                                   ObjexxFCL::Optional_int_const()); // calling point
     154             :         }
     155     2661169 :         SetCurrentWeather(state);
     156             : 
     157     2661169 :         ReportWeatherAndTimeInformation(state, state.dataWeatherManager->PrintEnvrnStamp);
     158     2661169 :     }
     159             : 
     160        2728 :     void ResetEnvironmentCounter(EnergyPlusData &state)
     161             :     {
     162        2728 :         state.dataWeatherManager->Envrn = 0;
     163        2728 :     }
     164             : 
     165         769 :     bool CheckIfAnyUnderwaterBoundaries(EnergyPlusData &state)
     166             :     {
     167         769 :         bool errorsFound = false;
     168         769 :         int NumAlpha = 0, NumNumber = 0, IOStat = 0;
     169         769 :         state.dataIPShortCut->cCurrentModuleObject = "SurfaceProperty:Underwater";
     170         769 :         int Num = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
     171         770 :         for (int i = 1; i <= Num; i++) {
     172           8 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     173           1 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
     174             :                                                                      i,
     175           1 :                                                                      state.dataIPShortCut->cAlphaArgs,
     176             :                                                                      NumAlpha,
     177           1 :                                                                      state.dataIPShortCut->rNumericArgs,
     178             :                                                                      NumNumber,
     179             :                                                                      IOStat,
     180           1 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
     181           1 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     182           1 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     183           1 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     184           1 :             state.dataWeatherManager->underwaterBoundaries.emplace_back();
     185           1 :             auto &underwaterBoundary{state.dataWeatherManager->underwaterBoundaries[i - 1]};
     186           1 :             underwaterBoundary.Name = state.dataIPShortCut->cAlphaArgs(1);
     187           1 :             underwaterBoundary.distanceFromLeadingEdge = state.dataIPShortCut->rNumericArgs(1);
     188           1 :             underwaterBoundary.OSCMIndex = UtilityRoutines::FindItemInList(underwaterBoundary.Name, state.dataSurface->OSCM);
     189           1 :             if (underwaterBoundary.OSCMIndex <= 0) {
     190           0 :                 ShowSevereError(state, "Could not match underwater boundary condition object with an Other Side Conditions Model input object.");
     191           0 :                 errorsFound = true;
     192             :             }
     193           1 :             underwaterBoundary.WaterTempScheduleIndex = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     194           1 :             if (underwaterBoundary.WaterTempScheduleIndex == 0) {
     195           0 :                 ShowSevereError(state,
     196           0 :                                 R"(Water temperature schedule for "SurfaceProperty:Underwater" named ")" + underwaterBoundary.Name + "\" not found");
     197           0 :                 errorsFound = true;
     198             :             }
     199           1 :             if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
     200             :                 // that's OK, we can have a blank schedule, the water will just have no free stream velocity
     201           0 :                 underwaterBoundary.VelocityScheduleIndex = 0;
     202             :             } else {
     203           1 :                 underwaterBoundary.VelocityScheduleIndex = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3));
     204           1 :                 if (underwaterBoundary.WaterTempScheduleIndex == 0) {
     205           0 :                     ShowSevereError(state,
     206           0 :                                     R"(Free stream velocity schedule for "SurfaceProperty:Underwater" named ")" + underwaterBoundary.Name +
     207             :                                         "\" not found");
     208           0 :                     errorsFound = true;
     209             :                 }
     210             :             }
     211           1 :             if (errorsFound) break;
     212             :         }
     213         769 :         if (errorsFound) {
     214           0 :             ShowFatalError(state, "Previous input problems cause program termination");
     215             :         }
     216         769 :         return (Num > 0);
     217             :     }
     218             : 
     219             :     Real64
     220        1343 :     calculateWaterBoundaryConvectionCoefficient(Real64 const curWaterTemp, Real64 const freeStreamVelocity, Real64 const distanceFromLeadingEdge)
     221             :     {
     222        1343 :         Real64 constexpr waterKinematicViscosity = 1e-6; // m2/s
     223        1343 :         Real64 constexpr waterPrandtlNumber = 6;         // -
     224        1343 :         Real64 constexpr waterThermalConductivity = 0.6; // W/mK
     225             :         // do some calculation for forced convection from the leading edge of the ship
     226        1343 :         Real64 const localReynoldsNumber = freeStreamVelocity * distanceFromLeadingEdge / waterKinematicViscosity;
     227        1343 :         Real64 const localNusseltNumber = 0.0296 * pow(localReynoldsNumber, 0.8) * pow(waterPrandtlNumber, 1.0 / 3.0);
     228        1343 :         Real64 const localConvectionCoeff = localNusseltNumber * waterThermalConductivity / distanceFromLeadingEdge;
     229             : 
     230             :         // do some calculations for natural convection from the bottom of the ship
     231        1343 :         Real64 constexpr distanceFromBottomOfHull = 12; // meters, assumed for now
     232             :                                                         // this Prandtl correction is from Incropera & Dewitt, Intro to HT, eq 9.20
     233        1343 :         Real64 const prandtlCorrection =
     234             :             (0.75 * pow(waterPrandtlNumber, 0.5)) / pow(0.609 + 1.221 * pow(waterPrandtlNumber, 0.5) + 1.238 * waterPrandtlNumber, 0.25);
     235             :         // calculate the Grashof number
     236        1343 :         Real64 constexpr gravity = 9.81;          // m/s2
     237        1343 :         Real64 constexpr beta = 0.000214;         // water thermal expansion coefficient, from engineeringtoolbox.com, 1/C
     238        1343 :         Real64 constexpr assumedSurfaceTemp = 25; // Grashof requires a surface temp, this should suffice
     239             :         Real64 const localGrashofNumber =
     240        1343 :             (gravity * beta * (assumedSurfaceTemp - curWaterTemp) * pow(distanceFromBottomOfHull, 3)) / pow(waterKinematicViscosity, 2);
     241        1343 :         Real64 const localNusseltFreeConvection = pow(localGrashofNumber / 4, 0.25) * prandtlCorrection;
     242        1343 :         Real64 const localConvectionCoeffFreeConv = localNusseltFreeConvection * waterThermalConductivity / distanceFromBottomOfHull;
     243        1343 :         return max(localConvectionCoeff, localConvectionCoeffFreeConv);
     244             :     }
     245             : 
     246        1343 :     void UpdateUnderwaterBoundaries(EnergyPlusData &state)
     247             :     {
     248        2686 :         for (auto &thisBoundary : state.dataWeatherManager->underwaterBoundaries) {
     249        1343 :             Real64 const curWaterTemp = ScheduleManager::GetCurrentScheduleValue(state, thisBoundary.WaterTempScheduleIndex); // C
     250        1343 :             Real64 freeStreamVelocity = 0;
     251        1343 :             if (thisBoundary.VelocityScheduleIndex > 0) {
     252        1343 :                 freeStreamVelocity = ScheduleManager::GetCurrentScheduleValue(state, thisBoundary.VelocityScheduleIndex); // m/s
     253             :             }
     254        1343 :             state.dataSurface->OSCM(thisBoundary.OSCMIndex).TConv = curWaterTemp;
     255        1343 :             state.dataSurface->OSCM(thisBoundary.OSCMIndex).HConv =
     256        1343 :                 WeatherManager::calculateWaterBoundaryConvectionCoefficient(curWaterTemp, freeStreamVelocity, thisBoundary.distanceFromLeadingEdge);
     257        1343 :             state.dataSurface->OSCM(thisBoundary.OSCMIndex).TRad = curWaterTemp;
     258        1343 :             state.dataSurface->OSCM(thisBoundary.OSCMIndex).HRad = 0.0;
     259             :         }
     260        1343 :     }
     261             : 
     262         769 :     void ReadVariableLocationOrientation(EnergyPlusData &state)
     263             :     {
     264         769 :         int NumAlpha = 0, NumNumber = 0, IOStat = 0;
     265         769 :         state.dataIPShortCut->cCurrentModuleObject = "Site:VariableLocation";
     266         769 :         if (state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject) == 0) return;
     267           8 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     268           1 :                                                                  state.dataIPShortCut->cCurrentModuleObject,
     269             :                                                                  1,
     270           1 :                                                                  state.dataIPShortCut->cAlphaArgs,
     271             :                                                                  NumAlpha,
     272           1 :                                                                  state.dataIPShortCut->rNumericArgs,
     273             :                                                                  NumNumber,
     274             :                                                                  IOStat,
     275           1 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     276           1 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     277           1 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     278           1 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     279           1 :         state.dataEnvrn->varyingLocationSchedIndexLat = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(1));
     280           1 :         state.dataEnvrn->varyingLocationSchedIndexLong = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     281           1 :         state.dataEnvrn->varyingOrientationSchedIndex = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3));
     282             :     }
     283             : 
     284        1344 :     void UpdateLocationAndOrientation(EnergyPlusData &state)
     285             :     {
     286        1344 :         if (state.dataEnvrn->varyingLocationSchedIndexLat > 0) {
     287        1344 :             state.dataEnvrn->Latitude = ScheduleManager::GetCurrentScheduleValue(state, state.dataEnvrn->varyingLocationSchedIndexLat);
     288             :         }
     289        1344 :         if (state.dataEnvrn->varyingLocationSchedIndexLong > 0) {
     290        1344 :             state.dataEnvrn->Longitude = ScheduleManager::GetCurrentScheduleValue(state, state.dataEnvrn->varyingLocationSchedIndexLong);
     291             :         }
     292        1344 :         CheckLocationValidity(state);
     293        1344 :         if (state.dataEnvrn->varyingOrientationSchedIndex > 0) {
     294        1344 :             state.dataHeatBal->BuildingAzimuth =
     295        1344 :                 mod(ScheduleManager::GetCurrentScheduleValue(state, state.dataEnvrn->varyingOrientationSchedIndex), 360.0);
     296        1344 :             state.dataSurfaceGeometry->CosBldgRelNorth =
     297        1344 :                 std::cos(-(state.dataHeatBal->BuildingAzimuth + state.dataHeatBal->BuildingRotationAppendixG) * DataGlobalConstants::DegToRadians);
     298        1344 :             state.dataSurfaceGeometry->SinBldgRelNorth =
     299        1344 :                 std::sin(-(state.dataHeatBal->BuildingAzimuth + state.dataHeatBal->BuildingRotationAppendixG) * DataGlobalConstants::DegToRadians);
     300        8064 :             for (size_t SurfNum = 1; SurfNum < state.dataSurface->Surface.size(); ++SurfNum) {
     301       33600 :                 for (int n = 1; n <= state.dataSurface->Surface(SurfNum).Sides; ++n) {
     302       26880 :                     Real64 Xb = state.dataSurface->Surface(SurfNum).Vertex(n).x;
     303       26880 :                     Real64 Yb = state.dataSurface->Surface(SurfNum).Vertex(n).y;
     304       26880 :                     state.dataSurface->Surface(SurfNum).NewVertex(n).x =
     305       26880 :                         Xb * state.dataSurfaceGeometry->CosBldgRelNorth - Yb * state.dataSurfaceGeometry->SinBldgRelNorth;
     306       26880 :                     state.dataSurface->Surface(SurfNum).NewVertex(n).y =
     307       26880 :                         Xb * state.dataSurfaceGeometry->SinBldgRelNorth + Yb * state.dataSurfaceGeometry->CosBldgRelNorth;
     308       26880 :                     state.dataSurface->Surface(SurfNum).NewVertex(n).z = state.dataSurface->Surface(SurfNum).Vertex(n).z;
     309             :                 }
     310       13440 :                 Vectors::CreateNewellSurfaceNormalVector(state.dataSurface->Surface(SurfNum).NewVertex,
     311        6720 :                                                          state.dataSurface->Surface(SurfNum).Sides,
     312        6720 :                                                          state.dataSurface->Surface(SurfNum).NewellSurfaceNormalVector);
     313        6720 :                 Real64 SurfWorldAz = 0.0;
     314        6720 :                 Real64 SurfTilt = 0.0;
     315       40320 :                 Vectors::DetermineAzimuthAndTilt(state.dataSurface->Surface(SurfNum).NewVertex,
     316        6720 :                                                  state.dataSurface->Surface(SurfNum).Sides,
     317             :                                                  SurfWorldAz,
     318             :                                                  SurfTilt,
     319        6720 :                                                  state.dataSurface->Surface(SurfNum).lcsx,
     320        6720 :                                                  state.dataSurface->Surface(SurfNum).lcsy,
     321        6720 :                                                  state.dataSurface->Surface(SurfNum).lcsz,
     322        6720 :                                                  state.dataSurface->Surface(SurfNum).GrossArea,
     323        6720 :                                                  state.dataSurface->Surface(SurfNum).NewellSurfaceNormalVector);
     324        6720 :                 state.dataSurface->Surface(SurfNum).Azimuth = SurfWorldAz;
     325        6720 :                 state.dataSurface->Surface(SurfNum).SinAzim = std::sin(SurfWorldAz * DataGlobalConstants::DegToRadians);
     326        6720 :                 state.dataSurface->Surface(SurfNum).CosAzim = std::cos(SurfWorldAz * DataGlobalConstants::DegToRadians);
     327        6720 :                 state.dataSurface->Surface(SurfNum).OutNormVec = state.dataSurface->Surface(SurfNum).NewellSurfaceNormalVector;
     328             :             }
     329             :         }
     330        1344 :     }
     331             : 
     332       10855 :     bool GetNextEnvironment(EnergyPlusData &state, bool &Available, bool &ErrorsFound)
     333             :     {
     334             : 
     335             :         // SUBROUTINE INFORMATION:
     336             :         //       AUTHOR         Linda Lawrie
     337             :         //       DATE WRITTEN   August 2000
     338             :         //       MODIFIED       na
     339             :         //       RE-ENGINEERED  na
     340             : 
     341             :         // PURPOSE OF THIS SUBROUTINE:
     342             :         // This subroutine is called from the outer simulation manager and determines
     343             :         // if another environment is available in the "run list" or if the end has been
     344             :         // reached.
     345             : 
     346             :         static constexpr std::string_view RoutineName("GetNextEnvironment: ");
     347             :         static constexpr std::string_view EnvNameFormat("Environment,{},{},{},{},{},{},{},{},{},{},{},{},{}\n");
     348             :         static constexpr std::string_view EnvDSTNFormat("Environment:Daylight Saving,No,{}\n");
     349             :         static constexpr std::string_view EnvDSTYFormat("Environment:Daylight Saving,Yes,{},{},{}\n");
     350             :         static constexpr std::string_view DateFormat("{:02}/{:02}");
     351             :         static constexpr std::string_view DateFormatWithYear("{:02}/{:02}/{:04}");
     352       21710 :         std::string StDate;
     353       21710 :         std::string EnDate;
     354             :         int DSTActStMon;
     355             :         int DSTActStDay;
     356             :         int DSTActEnMon;
     357             :         int DSTActEnDay;
     358             : 
     359       10855 :         if (state.dataGlobal->BeginSimFlag && state.dataWeatherManager->GetEnvironmentFirstCall) {
     360             : 
     361         771 :             state.dataReportFlag->PrintEndDataDictionary = true;
     362             : 
     363         771 :             ReportOutputFileHeaders(state); // Write the output file header information
     364             : 
     365             :             // Setup Output Variables, CurrentModuleObject='All Simulations'
     366             : 
     367        2313 :             SetupOutputVariable(state,
     368             :                                 "Site Outdoor Air Drybulb Temperature",
     369             :                                 OutputProcessor::Unit::C,
     370         771 :                                 state.dataEnvrn->OutDryBulbTemp,
     371             :                                 OutputProcessor::SOVTimeStepType::Zone,
     372             :                                 OutputProcessor::SOVStoreType::Average,
     373        1542 :                                 "Environment");
     374        2313 :             SetupOutputVariable(state,
     375             :                                 "Site Outdoor Air Dewpoint Temperature",
     376             :                                 OutputProcessor::Unit::C,
     377         771 :                                 state.dataEnvrn->OutDewPointTemp,
     378             :                                 OutputProcessor::SOVTimeStepType::Zone,
     379             :                                 OutputProcessor::SOVStoreType::Average,
     380        1542 :                                 "Environment");
     381        2313 :             SetupOutputVariable(state,
     382             :                                 "Site Outdoor Air Wetbulb Temperature",
     383             :                                 OutputProcessor::Unit::C,
     384         771 :                                 state.dataEnvrn->OutWetBulbTemp,
     385             :                                 OutputProcessor::SOVTimeStepType::Zone,
     386             :                                 OutputProcessor::SOVStoreType::Average,
     387        1542 :                                 "Environment");
     388        2313 :             SetupOutputVariable(state,
     389             :                                 "Site Outdoor Air Humidity Ratio",
     390             :                                 OutputProcessor::Unit::kgWater_kgDryAir,
     391         771 :                                 state.dataEnvrn->OutHumRat,
     392             :                                 OutputProcessor::SOVTimeStepType::Zone,
     393             :                                 OutputProcessor::SOVStoreType::Average,
     394        1542 :                                 "Environment");
     395        2313 :             SetupOutputVariable(state,
     396             :                                 "Site Outdoor Air Relative Humidity",
     397             :                                 OutputProcessor::Unit::Perc,
     398         771 :                                 state.dataEnvrn->OutRelHum,
     399             :                                 OutputProcessor::SOVTimeStepType::Zone,
     400             :                                 OutputProcessor::SOVStoreType::Average,
     401        1542 :                                 "Environment");
     402        2313 :             SetupOutputVariable(state,
     403             :                                 "Site Outdoor Air Barometric Pressure",
     404             :                                 OutputProcessor::Unit::Pa,
     405         771 :                                 state.dataEnvrn->OutBaroPress,
     406             :                                 OutputProcessor::SOVTimeStepType::Zone,
     407             :                                 OutputProcessor::SOVStoreType::Average,
     408        1542 :                                 "Environment");
     409        2313 :             SetupOutputVariable(state,
     410             :                                 "Site Wind Speed",
     411             :                                 OutputProcessor::Unit::m_s,
     412         771 :                                 state.dataEnvrn->WindSpeed,
     413             :                                 OutputProcessor::SOVTimeStepType::Zone,
     414             :                                 OutputProcessor::SOVStoreType::Average,
     415        1542 :                                 "Environment");
     416        2313 :             SetupOutputVariable(state,
     417             :                                 "Site Wind Direction",
     418             :                                 OutputProcessor::Unit::deg,
     419         771 :                                 state.dataEnvrn->WindDir,
     420             :                                 OutputProcessor::SOVTimeStepType::Zone,
     421             :                                 OutputProcessor::SOVStoreType::Average,
     422        1542 :                                 "Environment");
     423        2313 :             SetupOutputVariable(state,
     424             :                                 "Site Sky Temperature",
     425             :                                 OutputProcessor::Unit::C,
     426         771 :                                 state.dataEnvrn->SkyTemp,
     427             :                                 OutputProcessor::SOVTimeStepType::Zone,
     428             :                                 OutputProcessor::SOVStoreType::Average,
     429        1542 :                                 "Environment");
     430        2313 :             SetupOutputVariable(state,
     431             :                                 "Site Horizontal Infrared Radiation Rate per Area",
     432             :                                 OutputProcessor::Unit::W_m2,
     433         771 :                                 state.dataWeatherManager->HorizIRSky,
     434             :                                 OutputProcessor::SOVTimeStepType::Zone,
     435             :                                 OutputProcessor::SOVStoreType::Average,
     436        1542 :                                 "Environment");
     437        2313 :             SetupOutputVariable(state,
     438             :                                 "Site Diffuse Solar Radiation Rate per Area",
     439             :                                 OutputProcessor::Unit::W_m2,
     440         771 :                                 state.dataEnvrn->DifSolarRad,
     441             :                                 OutputProcessor::SOVTimeStepType::Zone,
     442             :                                 OutputProcessor::SOVStoreType::Average,
     443        1542 :                                 "Environment");
     444        2313 :             SetupOutputVariable(state,
     445             :                                 "Site Direct Solar Radiation Rate per Area",
     446             :                                 OutputProcessor::Unit::W_m2,
     447         771 :                                 state.dataEnvrn->BeamSolarRad,
     448             :                                 OutputProcessor::SOVTimeStepType::Zone,
     449             :                                 OutputProcessor::SOVStoreType::Average,
     450        1542 :                                 "Environment");
     451        2313 :             SetupOutputVariable(state,
     452             :                                 "Liquid Precipitation Depth",
     453             :                                 OutputProcessor::Unit::m,
     454         771 :                                 state.dataEnvrn->LiquidPrecipitation,
     455             :                                 OutputProcessor::SOVTimeStepType::Zone,
     456             :                                 OutputProcessor::SOVStoreType::Summed,
     457        1542 :                                 "Environment");
     458        2313 :             SetupOutputVariable(state,
     459             :                                 "Site Precipitation Rate",
     460             :                                 OutputProcessor::Unit::m_s,
     461         771 :                                 state.dataWaterData->RainFall.CurrentRate,
     462             :                                 OutputProcessor::SOVTimeStepType::Zone,
     463             :                                 OutputProcessor::SOVStoreType::Average,
     464        1542 :                                 "Environment");
     465        2313 :             SetupOutputVariable(state,
     466             :                                 "Site Precipitation Depth",
     467             :                                 OutputProcessor::Unit::m,
     468         771 :                                 state.dataWaterData->RainFall.CurrentAmount,
     469             :                                 OutputProcessor::SOVTimeStepType::Zone,
     470             :                                 OutputProcessor::SOVStoreType::Summed,
     471        1542 :                                 "Environment");
     472        2313 :             SetupOutputVariable(state,
     473             :                                 "Site Ground Reflected Solar Radiation Rate per Area",
     474             :                                 OutputProcessor::Unit::W_m2,
     475         771 :                                 state.dataEnvrn->GndSolarRad,
     476             :                                 OutputProcessor::SOVTimeStepType::Zone,
     477             :                                 OutputProcessor::SOVStoreType::Average,
     478        1542 :                                 "Environment");
     479        2313 :             SetupOutputVariable(state,
     480             :                                 "Site Ground Temperature",
     481             :                                 OutputProcessor::Unit::C,
     482         771 :                                 state.dataEnvrn->GroundTemp,
     483             :                                 OutputProcessor::SOVTimeStepType::Zone,
     484             :                                 OutputProcessor::SOVStoreType::Average,
     485        1542 :                                 "Environment");
     486        2313 :             SetupOutputVariable(state,
     487             :                                 "Site Surface Ground Temperature",
     488             :                                 OutputProcessor::Unit::C,
     489         771 :                                 state.dataEnvrn->GroundTemp_Surface,
     490             :                                 OutputProcessor::SOVTimeStepType::Zone,
     491             :                                 OutputProcessor::SOVStoreType::Average,
     492        1542 :                                 "Environment");
     493        2313 :             SetupOutputVariable(state,
     494             :                                 "Site Deep Ground Temperature",
     495             :                                 OutputProcessor::Unit::C,
     496         771 :                                 state.dataEnvrn->GroundTemp_Deep,
     497             :                                 OutputProcessor::SOVTimeStepType::Zone,
     498             :                                 OutputProcessor::SOVStoreType::Average,
     499        1542 :                                 "Environment");
     500        2313 :             SetupOutputVariable(state,
     501             :                                 "Site Simple Factor Model Ground Temperature",
     502             :                                 OutputProcessor::Unit::C,
     503         771 :                                 state.dataEnvrn->GroundTempFC,
     504             :                                 OutputProcessor::SOVTimeStepType::Zone,
     505             :                                 OutputProcessor::SOVStoreType::Average,
     506        1542 :                                 "Environment");
     507        2313 :             SetupOutputVariable(state,
     508             :                                 "Site Total Sky Cover",
     509             :                                 OutputProcessor::Unit::None,
     510         771 :                                 state.dataEnvrn->TotalCloudCover,
     511             :                                 OutputProcessor::SOVTimeStepType::Zone,
     512             :                                 OutputProcessor::SOVStoreType::Average,
     513        1542 :                                 "Environment");
     514        2313 :             SetupOutputVariable(state,
     515             :                                 "Site Opaque Sky Cover",
     516             :                                 OutputProcessor::Unit::None,
     517         771 :                                 state.dataEnvrn->OpaqueCloudCover,
     518             :                                 OutputProcessor::SOVTimeStepType::Zone,
     519             :                                 OutputProcessor::SOVStoreType::Average,
     520        1542 :                                 "Environment");
     521        2313 :             SetupOutputVariable(state,
     522             :                                 "Site Outdoor Air Enthalpy",
     523             :                                 OutputProcessor::Unit::J_kg,
     524         771 :                                 state.dataEnvrn->OutEnthalpy,
     525             :                                 OutputProcessor::SOVTimeStepType::Zone,
     526             :                                 OutputProcessor::SOVStoreType::Average,
     527        1542 :                                 "Environment");
     528        2313 :             SetupOutputVariable(state,
     529             :                                 "Site Outdoor Air Density",
     530             :                                 OutputProcessor::Unit::kg_m3,
     531         771 :                                 state.dataEnvrn->OutAirDensity,
     532             :                                 OutputProcessor::SOVTimeStepType::Zone,
     533             :                                 OutputProcessor::SOVStoreType::Average,
     534        1542 :                                 "Environment");
     535        2313 :             SetupOutputVariable(state,
     536             :                                 "Site Solar Azimuth Angle",
     537             :                                 OutputProcessor::Unit::deg,
     538         771 :                                 state.dataWeatherManager->SolarAzimuthAngle,
     539             :                                 OutputProcessor::SOVTimeStepType::Zone,
     540             :                                 OutputProcessor::SOVStoreType::Average,
     541        1542 :                                 "Environment");
     542        2313 :             SetupOutputVariable(state,
     543             :                                 "Site Solar Altitude Angle",
     544             :                                 OutputProcessor::Unit::deg,
     545         771 :                                 state.dataWeatherManager->SolarAltitudeAngle,
     546             :                                 OutputProcessor::SOVTimeStepType::Zone,
     547             :                                 OutputProcessor::SOVStoreType::Average,
     548        1542 :                                 "Environment");
     549        2313 :             SetupOutputVariable(state,
     550             :                                 "Site Solar Hour Angle",
     551             :                                 OutputProcessor::Unit::deg,
     552         771 :                                 state.dataWeatherManager->HrAngle,
     553             :                                 OutputProcessor::SOVTimeStepType::Zone,
     554             :                                 OutputProcessor::SOVStoreType::Average,
     555        1542 :                                 "Environment");
     556        2313 :             SetupOutputVariable(state,
     557             :                                 "Site Rain Status",
     558             :                                 OutputProcessor::Unit::None,
     559         771 :                                 state.dataWeatherManager->RptIsRain,
     560             :                                 OutputProcessor::SOVTimeStepType::Zone,
     561             :                                 OutputProcessor::SOVStoreType::Average,
     562        1542 :                                 "Environment");
     563        2313 :             SetupOutputVariable(state,
     564             :                                 "Site Snow on Ground Status",
     565             :                                 OutputProcessor::Unit::None,
     566         771 :                                 state.dataWeatherManager->RptIsSnow,
     567             :                                 OutputProcessor::SOVTimeStepType::Zone,
     568             :                                 OutputProcessor::SOVStoreType::Average,
     569        1542 :                                 "Environment");
     570        2313 :             SetupOutputVariable(state,
     571             :                                 "Site Exterior Horizontal Sky Illuminance",
     572             :                                 OutputProcessor::Unit::lux,
     573         771 :                                 state.dataEnvrn->HISKF,
     574             :                                 OutputProcessor::SOVTimeStepType::Zone,
     575             :                                 OutputProcessor::SOVStoreType::Average,
     576        1542 :                                 "Environment");
     577        2313 :             SetupOutputVariable(state,
     578             :                                 "Site Exterior Horizontal Beam Illuminance",
     579             :                                 OutputProcessor::Unit::lux,
     580         771 :                                 state.dataEnvrn->HISUNF,
     581             :                                 OutputProcessor::SOVTimeStepType::Zone,
     582             :                                 OutputProcessor::SOVStoreType::Average,
     583        1542 :                                 "Environment");
     584        2313 :             SetupOutputVariable(state,
     585             :                                 "Site Exterior Beam Normal Illuminance",
     586             :                                 OutputProcessor::Unit::lux,
     587         771 :                                 state.dataEnvrn->HISUNFnorm,
     588             :                                 OutputProcessor::SOVTimeStepType::Zone,
     589             :                                 OutputProcessor::SOVStoreType::Average,
     590        1542 :                                 "Environment");
     591        2313 :             SetupOutputVariable(state,
     592             :                                 "Site Sky Diffuse Solar Radiation Luminous Efficacy",
     593             :                                 OutputProcessor::Unit::lum_W,
     594         771 :                                 state.dataEnvrn->PDIFLW,
     595             :                                 OutputProcessor::SOVTimeStepType::Zone,
     596             :                                 OutputProcessor::SOVStoreType::Average,
     597        1542 :                                 "Environment");
     598        2313 :             SetupOutputVariable(state,
     599             :                                 "Site Beam Solar Radiation Luminous Efficacy",
     600             :                                 OutputProcessor::Unit::lum_W,
     601         771 :                                 state.dataEnvrn->PDIRLW,
     602             :                                 OutputProcessor::SOVTimeStepType::Zone,
     603             :                                 OutputProcessor::SOVStoreType::Average,
     604        1542 :                                 "Environment");
     605        2313 :             SetupOutputVariable(state,
     606             :                                 "Site Daylighting Model Sky Clearness",
     607             :                                 OutputProcessor::Unit::None,
     608         771 :                                 state.dataEnvrn->SkyClearness,
     609             :                                 OutputProcessor::SOVTimeStepType::Zone,
     610             :                                 OutputProcessor::SOVStoreType::Average,
     611        1542 :                                 "Environment");
     612        2313 :             SetupOutputVariable(state,
     613             :                                 "Site Daylighting Model Sky Brightness",
     614             :                                 OutputProcessor::Unit::None,
     615         771 :                                 state.dataEnvrn->SkyBrightness,
     616             :                                 OutputProcessor::SOVTimeStepType::Zone,
     617             :                                 OutputProcessor::SOVStoreType::Average,
     618        1542 :                                 "Environment");
     619        2313 :             SetupOutputVariable(state,
     620             :                                 "Site Daylight Saving Time Status",
     621             :                                 OutputProcessor::Unit::None,
     622         771 :                                 state.dataEnvrn->DSTIndicator,
     623             :                                 OutputProcessor::SOVTimeStepType::Zone,
     624             :                                 OutputProcessor::SOVStoreType::State,
     625        1542 :                                 "Environment");
     626        2313 :             SetupOutputVariable(state,
     627             :                                 "Site Day Type Index",
     628             :                                 OutputProcessor::Unit::None,
     629         771 :                                 state.dataWeatherManager->RptDayType,
     630             :                                 OutputProcessor::SOVTimeStepType::Zone,
     631             :                                 OutputProcessor::SOVStoreType::State,
     632        1542 :                                 "Environment");
     633        2313 :             SetupOutputVariable(state,
     634             :                                 "Site Mains Water Temperature",
     635             :                                 OutputProcessor::Unit::C,
     636         771 :                                 state.dataEnvrn->WaterMainsTemp,
     637             :                                 OutputProcessor::SOVTimeStepType::Zone,
     638             :                                 OutputProcessor::SOVStoreType::Average,
     639        1542 :                                 "Environment");
     640             : 
     641         771 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     642         213 :                 SetupEMSActuator(state,
     643             :                                  "Weather Data",
     644             :                                  "Environment",
     645             :                                  "Outdoor Dry Bulb",
     646             :                                  "[C]",
     647          71 :                                  state.dataEnvrn->EMSOutDryBulbOverrideOn,
     648         142 :                                  state.dataEnvrn->EMSOutDryBulbOverrideValue);
     649         213 :                 SetupEMSActuator(state,
     650             :                                  "Weather Data",
     651             :                                  "Environment",
     652             :                                  "Outdoor Dew Point",
     653             :                                  "[C]",
     654          71 :                                  state.dataEnvrn->EMSOutDewPointTempOverrideOn,
     655         142 :                                  state.dataEnvrn->EMSOutDewPointTempOverrideValue);
     656         213 :                 SetupEMSActuator(state,
     657             :                                  "Weather Data",
     658             :                                  "Environment",
     659             :                                  "Outdoor Relative Humidity",
     660             :                                  "[%]",
     661          71 :                                  state.dataEnvrn->EMSOutRelHumOverrideOn,
     662         142 :                                  state.dataEnvrn->EMSOutRelHumOverrideValue);
     663         213 :                 SetupEMSActuator(state,
     664             :                                  "Weather Data",
     665             :                                  "Environment",
     666             :                                  "Diffuse Solar",
     667             :                                  "[W/m2]",
     668          71 :                                  state.dataEnvrn->EMSDifSolarRadOverrideOn,
     669         142 :                                  state.dataEnvrn->EMSDifSolarRadOverrideValue);
     670         213 :                 SetupEMSActuator(state,
     671             :                                  "Weather Data",
     672             :                                  "Environment",
     673             :                                  "Direct Solar",
     674             :                                  "[W/m2]",
     675          71 :                                  state.dataEnvrn->EMSBeamSolarRadOverrideOn,
     676         142 :                                  state.dataEnvrn->EMSBeamSolarRadOverrideValue);
     677         213 :                 SetupEMSActuator(state,
     678             :                                  "Weather Data",
     679             :                                  "Environment",
     680             :                                  "Wind Speed",
     681             :                                  "[m/s]",
     682          71 :                                  state.dataEnvrn->EMSWindSpeedOverrideOn,
     683         142 :                                  state.dataEnvrn->EMSWindSpeedOverrideValue);
     684         213 :                 SetupEMSActuator(state,
     685             :                                  "Weather Data",
     686             :                                  "Environment",
     687             :                                  "Wind Direction",
     688             :                                  "[deg]",
     689          71 :                                  state.dataEnvrn->EMSWindDirOverrideOn,
     690         142 :                                  state.dataEnvrn->EMSWindDirOverrideValue);
     691             :             }
     692         771 :             state.dataWeatherManager->GetEnvironmentFirstCall = false;
     693             : 
     694             :         } // ... end of DataGlobals::BeginSimFlag IF-THEN block.
     695             : 
     696       10855 :         if (state.dataWeatherManager->GetBranchInputOneTimeFlag) {
     697             : 
     698         771 :             SetupInterpolationValues(state);
     699         771 :             state.dataWeatherManager->TimeStepFraction = 1.0 / double(state.dataGlobal->NumOfTimeStepInHour);
     700         771 :             state.dataEnvrn->rhoAirSTP = Psychrometrics::PsyRhoAirFnPbTdbW(
     701         771 :                 state, DataEnvironment::StdPressureSeaLevel, DataPrecisionGlobals::constant_twenty, DataPrecisionGlobals::constant_zero);
     702         771 :             OpenWeatherFile(state, ErrorsFound); // moved here because of possibility of special days on EPW file
     703         771 :             CloseWeatherFile(state);
     704         771 :             ReadUserWeatherInput(state);
     705         771 :             AllocateWeatherData(state);
     706         771 :             if (state.dataWeatherManager->NumIntervalsPerHour != 1) {
     707           0 :                 if (state.dataWeatherManager->NumIntervalsPerHour != state.dataGlobal->NumOfTimeStepInHour) {
     708           0 :                     ShowSevereError(state,
     709           0 :                                     std::string{RoutineName} +
     710             :                                         "Number of intervals per hour on Weather file does not match specified number of Time Steps Per Hour");
     711           0 :                     ErrorsFound = true;
     712             :                 }
     713             :             }
     714         771 :             state.dataWeatherManager->GetBranchInputOneTimeFlag = false;
     715         771 :             state.dataWeatherManager->Envrn = 0;
     716         771 :             if (state.dataWeatherManager->NumOfEnvrn > 0) {
     717         771 :                 ResolveLocationInformation(state, ErrorsFound); // Obtain weather related info from input file
     718         771 :                 CheckLocationValidity(state);
     719        1542 :                 if ((state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).KindOfEnvrn !=
     720        1518 :                      DataGlobalConstants::KindOfSim::DesignDay) &&
     721         747 :                     (state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).KindOfEnvrn !=
     722             :                      DataGlobalConstants::KindOfSim::HVACSizeDesignDay)) {
     723         747 :                     CheckWeatherFileValidity(state);
     724             :                 }
     725         771 :                 if (ErrorsFound) {
     726           0 :                     ShowSevereError(state, std::string{RoutineName} + "No location specified, program will terminate.");
     727             :                 }
     728             :             } else {
     729           0 :                 ErrorsFound = true;
     730           0 :                 ShowSevereError(state, std::string{RoutineName} + "No Design Days or Run Period(s) specified, program will terminate.");
     731             :             }
     732         771 :             if (state.dataSysVars->DDOnly && state.dataEnvrn->TotDesDays == 0) {
     733           0 :                 ErrorsFound = true;
     734           0 :                 ShowSevereError(state,
     735           0 :                                 std::string{RoutineName} +
     736             :                                     "Requested Design Days only (DataSystemVariables::DDOnly) but no Design Days specified, program will terminate.");
     737             :             }
     738         771 :             if (state.dataSysVars->ReverseDD && state.dataEnvrn->TotDesDays == 1) {
     739           0 :                 ErrorsFound = true;
     740           0 :                 ShowSevereError(
     741             :                     state,
     742           0 :                     std::string{RoutineName} +
     743             :                         "Requested Reverse Design Days (DataSystemVariables::ReverseDD) but only 1 Design Day specified, program will terminate.");
     744             :             }
     745             : 
     746             :             // Throw a Fatal now that we have said it'll terminalte
     747         771 :             if (ErrorsFound) {
     748           0 :                 CloseWeatherFile(state); // will only close if opened.
     749           0 :                 ShowFatalError(state, std::string{RoutineName} + "Errors found in Weather Data Input. Program terminates.");
     750             :             }
     751             : 
     752         771 :             state.dataEnvrn->CurrentOverallSimDay = 0;
     753         771 :             state.dataEnvrn->TotalOverallSimDays = 0;
     754         771 :             state.dataEnvrn->MaxNumberSimYears = 1;
     755        3544 :             for (int i = 1; i <= state.dataWeatherManager->NumOfEnvrn; ++i) {
     756        2773 :                 state.dataEnvrn->TotalOverallSimDays += state.dataWeatherManager->Environment(i).TotalDays;
     757        2773 :                 if (state.dataWeatherManager->Environment(i).KindOfEnvrn == DataGlobalConstants::KindOfSim::RunPeriodWeather) {
     758        1154 :                     state.dataEnvrn->MaxNumberSimYears =
     759        1154 :                         max(state.dataEnvrn->MaxNumberSimYears, state.dataWeatherManager->Environment(i).NumSimYears);
     760             :                 }
     761             :             }
     762         771 :             DisplaySimDaysProgress(state, state.dataEnvrn->CurrentOverallSimDay, state.dataEnvrn->TotalOverallSimDays);
     763             :         }
     764             : 
     765       10855 :         CloseWeatherFile(state); // will only close if opened.
     766       10855 :         ++state.dataWeatherManager->Envrn;
     767       10855 :         state.dataWeatherManager->DatesShouldBeReset = false;
     768       10855 :         if (state.dataWeatherManager->Envrn > state.dataWeatherManager->NumOfEnvrn) {
     769        1537 :             Available = false;
     770        1537 :             state.dataWeatherManager->Envrn = 0;
     771        1537 :             state.dataEnvrn->CurEnvirNum = 0;
     772             :         } else {
     773        9318 :             state.dataGlobal->KindOfSim = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).KindOfEnvrn;
     774        9318 :             state.dataEnvrn->DayOfYear = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartJDay;
     775        9318 :             state.dataEnvrn->DayOfMonth = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDay;
     776        9318 :             state.dataGlobal->CalendarYear = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartYear;
     777        9318 :             state.dataGlobal->CalendarYearChr = fmt::to_string(state.dataGlobal->CalendarYear);
     778        9318 :             state.dataEnvrn->Month = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartMonth;
     779        9318 :             state.dataGlobal->NumOfDayInEnvrn =
     780        9318 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).TotalDays; // Set day loop maximum from DataGlobals
     781        9318 :             if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation) {
     782        2892 :                 if (state.dataHeatBal->AdaptiveComfortRequested_ASH55 || state.dataHeatBal->AdaptiveComfortRequested_CEN15251) {
     783          13 :                     if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::DesignDay) {
     784           8 :                         if (state.dataGlobal->DoDesDaySim) {
     785           8 :                             ShowWarningError(state, std::string{RoutineName} + "Adaptive Comfort being reported during design day.");
     786          16 :                             Real64 GrossApproxAvgDryBulb = (state.dataWeatherManager->DesDayInput(state.dataWeatherManager->Envrn).MaxDryBulb +
     787          16 :                                                             (state.dataWeatherManager->DesDayInput(state.dataWeatherManager->Envrn).MaxDryBulb -
     788          16 :                                                              state.dataWeatherManager->DesDayInput(state.dataWeatherManager->Envrn).DailyDBRange)) /
     789           8 :                                                            2.0;
     790           8 :                             if (state.dataHeatBal->AdaptiveComfortRequested_ASH55)
     791           8 :                                 ThermalComfort::CalcThermalComfortAdaptiveASH55(state, true, false, GrossApproxAvgDryBulb);
     792           8 :                             if (state.dataHeatBal->AdaptiveComfortRequested_CEN15251)
     793           2 :                                 ThermalComfort::CalcThermalComfortAdaptiveCEN15251(state, true, false, GrossApproxAvgDryBulb);
     794             :                         }
     795             :                     } else {
     796           5 :                         if (state.dataGlobal->DoWeathSim || state.dataGlobal->DoDesDaySim) {
     797           5 :                             if (state.dataHeatBal->AdaptiveComfortRequested_ASH55)
     798           5 :                                 ThermalComfort::CalcThermalComfortAdaptiveASH55(state, true, true, 0.0);
     799           5 :                             if (state.dataHeatBal->AdaptiveComfortRequested_CEN15251)
     800           1 :                                 ThermalComfort::CalcThermalComfortAdaptiveCEN15251(state, true, true, 0.0);
     801             :                         }
     802             :                     }
     803             :                 }
     804             :             }
     805        9318 :             if (state.dataWeatherManager->Envrn > state.dataEnvrn->TotDesDays && state.dataWeatherManager->WeatherFileExists) {
     806        3608 :                 OpenEPlusWeatherFile(state, ErrorsFound, false);
     807             :             }
     808        9318 :             Available = true;
     809       12819 :             if ((state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) &&
     810        3533 :                 (!state.dataWeatherManager->WeatherFileExists && state.dataGlobal->DoWeathSim)) {
     811           0 :                 if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation) {
     812           0 :                     ShowSevereError(state, "Weather Simulation requested, but no weather file attached.");
     813           0 :                     ErrorsFound = true;
     814             :                 }
     815           0 :                 if (!state.dataGlobal->DoingHVACSizingSimulations) state.dataWeatherManager->Envrn = 0;
     816           0 :                 Available = false;
     817       12851 :             } else if ((state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) &&
     818        3533 :                        (!state.dataWeatherManager->WeatherFileExists && !state.dataGlobal->DoWeathSim)) {
     819          32 :                 Available = false;
     820          32 :                 if (!state.dataGlobal->DoingHVACSizingSimulations) state.dataWeatherManager->Envrn = 0;
     821        9286 :             } else if ((state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) && state.dataGlobal->DoingSizing) {
     822        1147 :                 Available = false;
     823        1147 :                 state.dataWeatherManager->Envrn = 0;
     824             :             }
     825             : 
     826        9318 :             if (!ErrorsFound && Available && state.dataWeatherManager->Envrn > 0) {
     827        8139 :                 state.dataEnvrn->EnvironmentName = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).Title;
     828        8139 :                 state.dataEnvrn->CurEnvirNum = state.dataWeatherManager->Envrn;
     829        8139 :                 state.dataEnvrn->RunPeriodStartDayOfWeek = 0;
     830       16282 :                 if ((state.dataGlobal->DoDesDaySim && (state.dataGlobal->KindOfSim != DataGlobalConstants::KindOfSim::RunPeriodWeather)) ||
     831        4668 :                     ((state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) && state.dataGlobal->DoWeathSim)) {
     832        5797 :                     if (state.dataWeatherManager->PrntEnvHeaders && state.dataReportFlag->DoWeatherInitReporting) {
     833             :                         static constexpr std::string_view EnvironFormat(
     834             :                             "! <Environment>,Environment Name,Environment Type, Start Date, End Date, Start DayOfWeek, Duration {#days}, "
     835             :                             "Source:Start DayOfWeek,  Use Daylight Saving, Use Holidays, Apply Weekend Holiday Rule,  Use Rain Values, Use Snow "
     836             :                             "Values, Sky Temperature Model\n! <Environment:Special Days>, Special Day Name, Special Day Type, Source, Start Date, "
     837             :                             "Duration {#days}\n! "
     838             :                             "<Environment:Daylight Saving>, Daylight Saving Indicator, Source, Start Date, End Date\n! <Environment:WarmupDays>, "
     839             :                             "NumberofWarmupDays");
     840         769 :                         print(state.files.eio, "{}\n", EnvironFormat);
     841         769 :                         state.dataWeatherManager->PrntEnvHeaders = false;
     842             :                     }
     843             : 
     844       11590 :                     if ((state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather) ||
     845        5793 :                         (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodDesign)) {
     846          52 :                         std::string kindOfRunPeriod = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).cKindOfEnvrn;
     847          26 :                         state.dataEnvrn->RunPeriodEnvironment = state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather;
     848          52 :                         Array1D_int ActEndDayOfMonth(12);
     849          26 :                         ActEndDayOfMonth = state.dataWeatherManager->EndDayOfMonth;
     850          26 :                         state.dataEnvrn->CurrentYearIsLeapYear = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).IsLeapYear;
     851          26 :                         if (state.dataEnvrn->CurrentYearIsLeapYear && state.dataWeatherManager->WFAllowsLeapYears) {
     852           2 :                             state.dataWeatherManager->LeapYearAdd = 1;
     853             :                         } else {
     854          24 :                             state.dataWeatherManager->LeapYearAdd = 0;
     855             :                         }
     856          26 :                         if (state.dataEnvrn->CurrentYearIsLeapYear) {
     857           2 :                             ActEndDayOfMonth(2) = state.dataWeatherManager->EndDayOfMonth(2) + state.dataWeatherManager->LeapYearAdd;
     858             :                         }
     859          26 :                         state.dataWeatherManager->UseDaylightSaving = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseDST;
     860          26 :                         state.dataWeatherManager->UseSpecialDays = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseHolidays;
     861          26 :                         state.dataWeatherManager->UseRainValues = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseRain;
     862          26 :                         state.dataWeatherManager->UseSnowValues = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseSnow;
     863             : 
     864          26 :                         bool missingLeap(false); // Defer acting on anything found here until after the other range checks (see below)
     865          26 :                         if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).ActualWeather &&
     866           0 :                             !state.dataWeatherManager->WFAllowsLeapYears) {
     867           0 :                             for (int year = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartYear;
     868           0 :                                  year <= state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndYear;
     869             :                                  year++) {
     870           0 :                                 if (isLeapYear(year)) {
     871           0 :                                     ShowSevereError(state,
     872           0 :                                                     format("{}Weatherfile does not support leap years but runperiod includes a leap year ({})",
     873             :                                                            RoutineName,
     874           0 :                                                            year));
     875           0 :                                     missingLeap = true;
     876             :                                 }
     877             :                             }
     878             :                         }
     879             : 
     880          26 :                         bool OkRun = false;
     881             : 
     882          26 :                         if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).ActualWeather) {
     883             :                             // Actual weather
     884           0 :                             for (auto &dataperiod : state.dataWeatherManager->DataPeriods) {
     885           0 :                                 int runStartJulian = dataperiod.DataStJDay;
     886           0 :                                 int runEndJulian = dataperiod.DataEnJDay;
     887           0 :                                 if (!dataperiod.HasYearData) {
     888           0 :                                     ShowSevereError(state,
     889           0 :                                                     std::string{RoutineName} +
     890             :                                                         "Actual weather runperiod has been entered but weatherfile DATA PERIOD "
     891             :                                                         "does not have year included in start/end date.");
     892           0 :                                     ShowContinueError(state, "...to match the RunPeriod, the DATA PERIOD should be mm/dd/yyyy for both, or");
     893           0 :                                     ShowContinueError(state, R"(...set "Treat Weather as Actual" to "No".)");
     894             :                                 }
     895           0 :                                 if (!General::BetweenDates(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDate,
     896             :                                                            runStartJulian,
     897             :                                                            runEndJulian))
     898           0 :                                     continue;
     899           0 :                                 if (!General::BetweenDates(
     900           0 :                                         state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndDate, runStartJulian, runEndJulian))
     901           0 :                                     continue;
     902           0 :                                 OkRun = true;
     903           0 :                                 break;
     904             :                             }
     905             :                         } else {
     906             :                             // Typical (or just non-actual) weather
     907          26 :                             for (auto &dataperiod : state.dataWeatherManager->DataPeriods) {
     908             :                                 // Since this is not actual weather, there may be issues with this calculation
     909             :                                 // Assume the weather data starts the same year as the simulation, so LeapYearAdd is what
     910             :                                 // should be used.
     911          26 :                                 int runStartOrdinal = General::OrdinalDay(dataperiod.StMon, dataperiod.StDay, state.dataWeatherManager->LeapYearAdd);
     912             :                                 // This one is harder, leave as is for now. What about multiple years of data?
     913          26 :                                 int runEndOrdinal = General::OrdinalDay(dataperiod.EnMon, dataperiod.EnDay, state.dataWeatherManager->LeapYearAdd);
     914          26 :                                 if (runStartOrdinal == 1 && (runEndOrdinal == 366 || runEndOrdinal == 365)) {
     915             :                                     // Complete year(s) of weather data, will wrap around
     916          26 :                                     OkRun = true;
     917          26 :                                     break;
     918             :                                 }
     919           0 :                                 if (!General::BetweenDates(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartJDay,
     920             :                                                            runStartOrdinal,
     921             :                                                            runEndOrdinal))
     922           0 :                                     continue;
     923           0 :                                 if (!General::BetweenDates(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndJDay,
     924             :                                                            runStartOrdinal,
     925             :                                                            runEndOrdinal))
     926           0 :                                     continue;
     927           0 :                                 OkRun = true;
     928             :                             }
     929             :                         }
     930             : 
     931          26 :                         if (!OkRun) {
     932           0 :                             if (!state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).ActualWeather) {
     933           0 :                                 StDate = format(DateFormat,
     934           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartMonth,
     935           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDay);
     936           0 :                                 EnDate = format(DateFormat,
     937           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndMonth,
     938           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndDay);
     939           0 :                                 ShowSevereError(state,
     940           0 :                                                 std::string{RoutineName} + "Runperiod [mm/dd] (Start=" + StDate + ",End=" + EnDate +
     941             :                                                     ") requested not within Data Period(s) from Weather File");
     942             :                             } else {
     943           0 :                                 StDate = format(DateFormatWithYear,
     944           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartMonth,
     945           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDay,
     946           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartYear);
     947           0 :                                 EnDate = format(DateFormatWithYear,
     948           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndMonth,
     949           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndDay,
     950           0 :                                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndYear);
     951           0 :                                 ShowSevereError(state,
     952           0 :                                                 std::string{RoutineName} + "Runperiod [mm/dd/yyyy] (Start=" + StDate + ",End=" + EnDate +
     953             :                                                     ") requested not within Data Period(s) from Weather File");
     954             :                             }
     955           0 :                             StDate =
     956           0 :                                 format(DateFormat, state.dataWeatherManager->DataPeriods(1).StMon, state.dataWeatherManager->DataPeriods(1).StDay);
     957           0 :                             EnDate =
     958           0 :                                 format(DateFormat, state.dataWeatherManager->DataPeriods(1).EnMon, state.dataWeatherManager->DataPeriods(1).EnDay);
     959           0 :                             if (state.dataWeatherManager->DataPeriods(1).StYear > 0) {
     960           0 :                                 StDate += format("/{}", state.dataWeatherManager->DataPeriods(1).StYear);
     961             :                             } else {
     962           0 :                                 StDate += "/<noyear>";
     963             :                             }
     964           0 :                             if (state.dataWeatherManager->DataPeriods(1).EnYear > 0) {
     965           0 :                                 EnDate += format("/{}", state.dataWeatherManager->DataPeriods(1).EnYear);
     966             :                             } else {
     967           0 :                                 EnDate += "/<noyear>";
     968             :                             }
     969           0 :                             if (state.dataWeatherManager->NumDataPeriods == 1) {
     970           0 :                                 ShowContinueError(state, "Weather Data Period (Start=" + StDate + ",End=" + EnDate + ')');
     971             :                             } else {
     972           0 :                                 ShowContinueError(state, "Multiple Weather Data Periods 1st (Start=" + StDate + ",End=" + EnDate + ')');
     973             :                             }
     974           0 :                             ShowFatalError(state, std::string{RoutineName} + "Program terminates due to preceding condition.");
     975             :                         }
     976             : 
     977          26 :                         if (missingLeap) {
     978             :                             // Bail out now if we still need to
     979           0 :                             ShowFatalError(state, std::string{RoutineName} + "Program terminates due to preceding condition.");
     980             :                         }
     981             : 
     982             :                         // Following builds Environment start/end for ASHRAE 55 warnings
     983          52 :                         StDate = format(DateFormat,
     984          26 :                                         state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartMonth,
     985          26 :                                         state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDay);
     986          52 :                         EnDate = format(DateFormat,
     987          26 :                                         state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndMonth,
     988          26 :                                         state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndDay);
     989          26 :                         if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).KindOfEnvrn ==
     990             :                             DataGlobalConstants::KindOfSim::RunPeriodWeather) {
     991           4 :                             StDate += format("/{}", state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartYear);
     992           4 :                             EnDate += format("/{}", state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndYear);
     993             :                         }
     994          26 :                         state.dataEnvrn->EnvironmentStartEnd = StDate + " - " + EnDate;
     995          26 :                         state.dataEnvrn->StartYear = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartYear;
     996          26 :                         state.dataEnvrn->EndYear = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndYear;
     997             : 
     998          26 :                         int TWeekDay = (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).DayOfWeek == 0)
     999          52 :                                            ? 1
    1000          52 :                                            : state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).DayOfWeek;
    1001          26 :                         auto const &MonWeekDay = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).MonWeekDay;
    1002             : 
    1003          26 :                         if (state.dataReportFlag->DoWeatherInitReporting) {
    1004             :                             std::string const AlpUseDST =
    1005          14 :                                 (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseDST) ? "Yes" : "No";
    1006             :                             std::string const AlpUseSpec =
    1007          14 :                                 (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseHolidays) ? "Yes" : "No";
    1008             :                             std::string const ApWkRule =
    1009          14 :                                 (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).ApplyWeekendRule) ? "Yes" : "No";
    1010             :                             std::string const AlpUseRain =
    1011          14 :                                 (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseRain) ? "Yes" : "No";
    1012             :                             std::string const AlpUseSnow =
    1013          14 :                                 (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseSnow) ? "Yes" : "No";
    1014             : 
    1015           7 :                             print(state.files.eio,
    1016             :                                   EnvNameFormat,
    1017           7 :                                   state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).Title,
    1018             :                                   kindOfRunPeriod,
    1019             :                                   StDate,
    1020             :                                   EnDate,
    1021           7 :                                   ScheduleManager::dayTypeNames[TWeekDay],
    1022          14 :                                   fmt::to_string(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).TotalDays),
    1023             :                                   "Use RunPeriod Specified Day",
    1024             :                                   AlpUseDST,
    1025             :                                   AlpUseSpec,
    1026             :                                   ApWkRule,
    1027             :                                   AlpUseRain,
    1028             :                                   AlpUseSnow,
    1029             :                                   SkyTempModelNames[static_cast<int>(
    1030           7 :                                       state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel)]);
    1031             :                         }
    1032             : 
    1033          26 :                         if (!state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation) {
    1034           7 :                             if ((state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::RunPeriodWeather && state.dataGlobal->DoWeathSim)) {
    1035           2 :                                 if (state.dataHeatBal->AdaptiveComfortRequested_ASH55 || state.dataHeatBal->AdaptiveComfortRequested_CEN15251) {
    1036           0 :                                     if (state.dataWeatherManager->WFAllowsLeapYears) {
    1037           0 :                                         ShowSevereError(state,
    1038           0 :                                                         std::string{RoutineName} +
    1039             :                                                             "AdaptiveComfort Reporting does not work correctly with leap years in weather files.");
    1040           0 :                                         ErrorsFound = true;
    1041             :                                     }
    1042           0 :                                     if (state.dataWeatherManager->NumDataPeriods != 1) {
    1043           0 :                                         ShowSevereError(
    1044             :                                             state,
    1045           0 :                                             std::string{RoutineName} +
    1046             :                                                 "AdaptiveComfort Reporting does not work correctly with multiple dataperiods in weather files.");
    1047           0 :                                         ErrorsFound = true;
    1048             :                                     }
    1049           0 :                                     if (state.dataWeatherManager->DataPeriods(1).StMon == 1 && state.dataWeatherManager->DataPeriods(1).StDay == 1) {
    1050           0 :                                         int RunStJDay = General::OrdinalDay(state.dataWeatherManager->DataPeriods(1).StMon,
    1051           0 :                                                                             state.dataWeatherManager->DataPeriods(1).StDay,
    1052           0 :                                                                             state.dataWeatherManager->LeapYearAdd);
    1053           0 :                                         int RunEnJDay = General::OrdinalDay(state.dataWeatherManager->DataPeriods(1).EnMon,
    1054           0 :                                                                             state.dataWeatherManager->DataPeriods(1).EnDay,
    1055           0 :                                                                             state.dataWeatherManager->LeapYearAdd);
    1056           0 :                                         if (RunEnJDay - RunStJDay + 1 != 365) {
    1057           0 :                                             ShowSevereError(state,
    1058           0 :                                                             std::string{RoutineName} +
    1059             :                                                                 "AdaptiveComfort Reporting does not work correctly with weather files "
    1060             :                                                                 "that do not contain 365 days.");
    1061           0 :                                             ErrorsFound = true;
    1062             :                                         }
    1063             :                                     } else {
    1064           0 :                                         ShowSevereError(state,
    1065           0 :                                                         std::string{RoutineName} +
    1066             :                                                             "AdaptiveComfort Reporting does not work correctly with weather files that "
    1067             :                                                             "do not start on 1 January.");
    1068           0 :                                         ErrorsFound = true;
    1069             :                                     }
    1070           0 :                                     if (state.dataWeatherManager->NumIntervalsPerHour != 1) {
    1071           0 :                                         ShowSevereError(state,
    1072           0 :                                                         std::string{RoutineName} +
    1073             :                                                             "AdaptiveComfort Reporting does not work correctly with weather files that "
    1074             :                                                             "have multiple interval records per hour.");
    1075           0 :                                         ErrorsFound = true;
    1076             :                                     }
    1077             :                                 }
    1078             :                             }
    1079             :                         }
    1080             : 
    1081             :                         // Only need to set Week days for Run Days
    1082          26 :                         state.dataEnvrn->RunPeriodStartDayOfWeek = TWeekDay;
    1083          26 :                         state.dataWeatherManager->WeekDayTypes = 0;
    1084          52 :                         int JDay5Start = General::OrdinalDay(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartMonth,
    1085          26 :                                                              state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDay,
    1086          52 :                                                              state.dataWeatherManager->LeapYearAdd);
    1087          52 :                         int JDay5End = General::OrdinalDay(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndMonth,
    1088          26 :                                                            state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).EndDay,
    1089          52 :                                                            state.dataWeatherManager->LeapYearAdd);
    1090             : 
    1091          26 :                         state.dataWeatherManager->curSimDayForEndOfRunPeriod =
    1092          26 :                             state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).TotalDays;
    1093             : 
    1094             :                         {
    1095          26 :                             int i = JDay5Start;
    1096             :                             while (true) {
    1097        3178 :                                 state.dataWeatherManager->WeekDayTypes(i) = TWeekDay;
    1098        1602 :                                 TWeekDay = mod(TWeekDay, 7) + 1;
    1099        1602 :                                 ++i;
    1100        1602 :                                 if (i > 366) i = 1;
    1101        1602 :                                 if (i == JDay5End) break;
    1102             :                             }
    1103             :                         }
    1104             : 
    1105          26 :                         if (state.dataWeatherManager->UseDaylightSaving) {
    1106           4 :                             if (state.dataWeatherManager->EPWDaylightSaving) {
    1107           2 :                                 state.dataWeatherManager->DaylightSavingIsActive = true;
    1108             :                             }
    1109             :                         } else {
    1110          22 :                             state.dataWeatherManager->DaylightSavingIsActive = false;
    1111             :                         }
    1112          26 :                         if (state.dataWeatherManager->IDFDaylightSaving) {
    1113           0 :                             state.dataWeatherManager->DaylightSavingIsActive = true;
    1114             :                         }
    1115          26 :                         state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SetWeekDays = false;
    1116             : 
    1117          26 :                         if (state.dataWeatherManager->DaylightSavingIsActive) {
    1118           4 :                             SetDSTDateRanges(
    1119           2 :                                 state, MonWeekDay, state.dataWeatherManager->DSTIndex, DSTActStMon, DSTActStDay, DSTActEnMon, DSTActEnDay);
    1120             :                         }
    1121             : 
    1122          26 :                         SetSpecialDayDates(state, MonWeekDay);
    1123             : 
    1124          39 :                         if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartMonth != 1 ||
    1125          13 :                             state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDay != 1) {
    1126          22 :                             state.dataWeatherManager->StartDatesCycleShouldBeReset = true;
    1127          22 :                             state.dataWeatherManager->Jan1DatesShouldBeReset = true;
    1128             :                         }
    1129             : 
    1130          39 :                         if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartMonth == 1 &&
    1131          13 :                             state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDay == 1) {
    1132           4 :                             state.dataWeatherManager->StartDatesCycleShouldBeReset = false;
    1133           4 :                             state.dataWeatherManager->Jan1DatesShouldBeReset = true;
    1134             :                         }
    1135             : 
    1136          26 :                         if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).ActualWeather) {
    1137           0 :                             state.dataWeatherManager->StartDatesCycleShouldBeReset = false;
    1138           0 :                             state.dataWeatherManager->Jan1DatesShouldBeReset = true;
    1139             :                         }
    1140             : 
    1141             :                         // Report Actual Dates for Daylight Saving and Special Days
    1142          26 :                         if (!state.dataGlobal->KickOffSimulation) {
    1143          38 :                             std::string Source;
    1144          19 :                             if (state.dataWeatherManager->UseDaylightSaving) {
    1145           2 :                                 if (state.dataWeatherManager->EPWDaylightSaving) {
    1146           1 :                                     Source = "WeatherFile";
    1147             :                                 }
    1148             :                             } else {
    1149          17 :                                 Source = "RunPeriod Object";
    1150             :                             }
    1151          19 :                             if (state.dataWeatherManager->IDFDaylightSaving) {
    1152           0 :                                 Source = "InputFile";
    1153             :                             }
    1154          19 :                             if (state.dataWeatherManager->DaylightSavingIsActive && state.dataReportFlag->DoWeatherInitReporting) {
    1155           1 :                                 StDate = format(DateFormat, DSTActStMon, DSTActStDay);
    1156           1 :                                 EnDate = format(DateFormat, DSTActEnMon, DSTActEnDay);
    1157           1 :                                 print(state.files.eio, EnvDSTYFormat, Source, StDate, EnDate);
    1158          18 :                             } else if (state.dataGlobal->DoOutputReporting) {
    1159           6 :                                 print(state.files.eio, EnvDSTNFormat, Source);
    1160             :                             }
    1161          40 :                             for (int i = 1; i <= state.dataWeatherManager->NumSpecialDays; ++i) {
    1162             :                                 static constexpr std::string_view EnvSpDyFormat("Environment:Special Days,{},{},{},{},{:3}\n");
    1163          32 :                                 if (state.dataWeatherManager->SpecialDays(i).WthrFile && state.dataWeatherManager->UseSpecialDays &&
    1164          11 :                                     state.dataReportFlag->DoWeatherInitReporting) {
    1165          22 :                                     StDate = format(DateFormat,
    1166          11 :                                                     state.dataWeatherManager->SpecialDays(i).ActStMon,
    1167          11 :                                                     state.dataWeatherManager->SpecialDays(i).ActStDay);
    1168          22 :                                     print(state.files.eio,
    1169             :                                           EnvSpDyFormat,
    1170          11 :                                           state.dataWeatherManager->SpecialDays(i).Name,
    1171          11 :                                           ScheduleManager::dayTypeNames[state.dataWeatherManager->SpecialDays(i).DayType],
    1172             :                                           "WeatherFile",
    1173             :                                           StDate,
    1174          11 :                                           state.dataWeatherManager->SpecialDays(i).Duration);
    1175             :                                 }
    1176          21 :                                 if (!state.dataWeatherManager->SpecialDays(i).WthrFile && state.dataReportFlag->DoWeatherInitReporting) {
    1177          20 :                                     StDate = format(DateFormat,
    1178          10 :                                                     state.dataWeatherManager->SpecialDays(i).ActStMon,
    1179          10 :                                                     state.dataWeatherManager->SpecialDays(i).ActStDay);
    1180          20 :                                     print(state.files.eio,
    1181             :                                           EnvSpDyFormat,
    1182          10 :                                           state.dataWeatherManager->SpecialDays(i).Name,
    1183          10 :                                           ScheduleManager::dayTypeNames[state.dataWeatherManager->SpecialDays(i).DayType],
    1184             :                                           "InputFile",
    1185             :                                           StDate,
    1186          10 :                                           state.dataWeatherManager->SpecialDays(i).Duration);
    1187             :                                 }
    1188             :                             }
    1189             :                         }
    1190             : 
    1191        5888 :                     } else if (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::DesignDay ||
    1192         117 :                                state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeDesignDay) { // Design Day
    1193        5770 :                         state.dataEnvrn->RunPeriodEnvironment = false;
    1194       11540 :                         StDate = format(
    1195             :                             DateFormat,
    1196        5770 :                             state.dataWeatherManager->DesDayInput(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).DesignDayNum)
    1197             :                                 .Month,
    1198        5770 :                             state.dataWeatherManager->DesDayInput(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).DesignDayNum)
    1199             :                                 .DayOfMonth);
    1200        5770 :                         EnDate = StDate;
    1201        5770 :                         if (state.dataReportFlag->DoWeatherInitReporting) {
    1202        1786 :                             print(
    1203             :                                 state.files.eio,
    1204             :                                 EnvNameFormat,
    1205        1786 :                                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).Title,
    1206             :                                 "SizingPeriod:DesignDay",
    1207             :                                 StDate,
    1208             :                                 EnDate,
    1209             :                                 ScheduleManager::dayTypeNames[state.dataWeatherManager
    1210        3572 :                                                                   ->DesDayInput(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn)
    1211        3572 :                                                                                     .DesignDayNum)
    1212        1786 :                                                                   .DayType],
    1213             :                                 "1",
    1214             :                                 "N/A",
    1215             :                                 "N/A",
    1216             :                                 "N/A",
    1217             :                                 "N/A",
    1218             :                                 "N/A",
    1219             :                                 "N/A",
    1220             :                                 SkyTempModelNames[static_cast<int>(
    1221        1786 :                                     state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel)]);
    1222             :                         }
    1223       11540 :                         if (state.dataWeatherManager->DesDayInput(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).DesignDayNum)
    1224       11540 :                                     .DSTIndicator == 0 &&
    1225        5770 :                             state.dataReportFlag->DoWeatherInitReporting) {
    1226        1786 :                             print(state.files.eio, EnvDSTNFormat, "SizingPeriod:DesignDay");
    1227        3984 :                         } else if (state.dataReportFlag->DoWeatherInitReporting) {
    1228           0 :                             print(state.files.eio, EnvDSTYFormat, "SizingPeriod:DesignDay", StDate, EnDate);
    1229             :                         }
    1230             :                     }
    1231             :                 }
    1232             :             } // ErrorsFound
    1233             :         }
    1234             : 
    1235       10855 :         if (ErrorsFound && !state.dataGlobal->DoingSizing && !state.dataGlobal->KickOffSimulation) {
    1236           0 :             ShowSevereError(state, std::string{RoutineName} + "Errors found in getting a new environment");
    1237           0 :             Available = false;
    1238       10855 :         } else if (ErrorsFound) {
    1239           0 :             Available = false;
    1240             :         }
    1241       21710 :         return Available && !ErrorsFound;
    1242             :     }
    1243             : 
    1244          16 :     void AddDesignSetToEnvironmentStruct(EnergyPlusData &state, int const HVACSizingIterCount)
    1245             :     {
    1246          16 :         int OrigNumOfEnvrn{state.dataWeatherManager->NumOfEnvrn};
    1247             : 
    1248          79 :         for (int i = 1; i <= OrigNumOfEnvrn; ++i) {
    1249          63 :             if (state.dataWeatherManager->Environment(i).KindOfEnvrn == DataGlobalConstants::KindOfSim::DesignDay) {
    1250          32 :                 state.dataWeatherManager->Environment.redimension(++state.dataWeatherManager->NumOfEnvrn);
    1251          32 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn) =
    1252          32 :                     state.dataWeatherManager->Environment(i); // copy over seed data from current array element
    1253          32 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).SeedEnvrnNum = i;
    1254          32 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).KindOfEnvrn =
    1255             :                     DataGlobalConstants::KindOfSim::HVACSizeDesignDay;
    1256          64 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).Title =
    1257          96 :                     format("{} HVAC Sizing Pass {}", state.dataWeatherManager->Environment(i).Title, HVACSizingIterCount);
    1258          32 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).HVACSizingIterationNum = HVACSizingIterCount;
    1259          31 :             } else if (state.dataWeatherManager->Environment(i).KindOfEnvrn == DataGlobalConstants::KindOfSim::RunPeriodDesign) {
    1260           0 :                 state.dataWeatherManager->Environment.redimension(++state.dataWeatherManager->NumOfEnvrn);
    1261           0 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn) =
    1262           0 :                     state.dataWeatherManager->Environment(i); // copy over seed data
    1263           0 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).SeedEnvrnNum = i;
    1264           0 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).KindOfEnvrn =
    1265             :                     DataGlobalConstants::KindOfSim::HVACSizeRunPeriodDesign;
    1266           0 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).Title =
    1267           0 :                     format("{} HVAC Sizing Pass {}", state.dataWeatherManager->Environment(i).Title, HVACSizingIterCount);
    1268           0 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).HVACSizingIterationNum = HVACSizingIterCount;
    1269             :             }
    1270             :         } // for each loop over Environment data strucure
    1271          16 :     }
    1272             : 
    1273        1920 :     void SetupWeekDaysByMonth(EnergyPlusData &state, int const StMon, int const StDay, int const StWeekDay, Array1D_int &WeekDays)
    1274             :     {
    1275             : 
    1276             :         // SUBROUTINE INFORMATION:
    1277             :         //       AUTHOR         Linda Lawrie
    1278             :         //       DATE WRITTEN   August 2000
    1279             :         //       MODIFIED       na
    1280             :         //       RE-ENGINEERED  na
    1281             : 
    1282             :         // PURPOSE OF THIS SUBROUTINE:
    1283             :         // This subroutine calculates the weekday for each month based on the start date and
    1284             :         // weekday specified for that date.
    1285             : 
    1286             :         // Argument array dimensioning
    1287        1920 :         EP_SIZE_CHECK(WeekDays, 12); // NOLINT(misc-static-assert)
    1288             : 
    1289             :         // Set 1st day of Start Month
    1290        1920 :         int CurWeekDay{StWeekDay};
    1291        8046 :         for (int i = 1; i <= StDay - 1; ++i) {
    1292        6126 :             --CurWeekDay;
    1293        6126 :             if (CurWeekDay == 0) CurWeekDay = 7;
    1294             :         }
    1295             : 
    1296        1920 :         WeekDays(StMon) = CurWeekDay;
    1297       20293 :         for (int i = StMon + 1; i <= 12; ++i) {
    1298             : 
    1299       18373 :             if (i == 2) {
    1300        1424 :                 CurWeekDay += state.dataWeatherManager->EndDayOfMonth(1);
    1301       12840 :                 while (CurWeekDay > 7) {
    1302        5708 :                     CurWeekDay -= 7;
    1303             :                 }
    1304        1424 :                 WeekDays(i) = CurWeekDay;
    1305       16949 :             } else if (i == 3) {
    1306        1439 :                 CurWeekDay += state.dataWeatherManager->EndDayOfMonth(i - 1) + state.dataWeatherManager->LeapYearAdd;
    1307       12951 :                 while (CurWeekDay > 7) {
    1308        5756 :                     CurWeekDay -= 7;
    1309             :                 }
    1310        1439 :                 WeekDays(i) = CurWeekDay;
    1311       15510 :             } else if ((i >= 4) && (i <= 12)) {
    1312       15510 :                 CurWeekDay += state.dataWeatherManager->EndDayOfMonth(i - 1);
    1313      151038 :                 while (CurWeekDay > 7) {
    1314       67764 :                     CurWeekDay -= 7;
    1315             :                 }
    1316       15510 :                 WeekDays(i) = CurWeekDay;
    1317             :             }
    1318             :         }
    1319             : 
    1320        1920 :         if (any_eq(WeekDays, 0)) {
    1321             :             // need to start at StMon and go backwards.
    1322             :             // EndDayOfMonth is also "days" in month.  (without leapyear day in February)
    1323         495 :             CurWeekDay = StWeekDay;
    1324        3104 :             for (int i = 1; i <= StDay - 1; ++i) {
    1325        2609 :                 --CurWeekDay;
    1326        2609 :                 if (CurWeekDay == 0) CurWeekDay = 7;
    1327             :             }
    1328             : 
    1329        3236 :             for (int i = StMon - 1; i >= 1; --i) {
    1330             : 
    1331        2741 :                 if (i == 1) {
    1332         495 :                     CurWeekDay -= state.dataWeatherManager->EndDayOfMonth(1);
    1333        5003 :                     while (CurWeekDay <= 0) {
    1334        2254 :                         CurWeekDay += 7;
    1335             :                     }
    1336         495 :                     WeekDays(i) = CurWeekDay;
    1337        2246 :                 } else if (i == 2) {
    1338         480 :                     CurWeekDay = CurWeekDay - state.dataWeatherManager->EndDayOfMonth(2) + state.dataWeatherManager->LeapYearAdd;
    1339        4320 :                     while (CurWeekDay <= 0) {
    1340        1920 :                         CurWeekDay += 7;
    1341             :                     }
    1342         480 :                     WeekDays(i) = CurWeekDay;
    1343        1766 :                 } else if ((i >= 3) && (i <= 12)) {
    1344        1766 :                     CurWeekDay -= state.dataWeatherManager->EndDayOfMonth(i);
    1345       17092 :                     while (CurWeekDay <= 0) {
    1346        7663 :                         CurWeekDay += 7;
    1347             :                     }
    1348        1766 :                     WeekDays(i) = CurWeekDay;
    1349             :                 }
    1350             :             }
    1351             :         }
    1352        1920 :     }
    1353             : #pragma clang diagnostic pop
    1354             : 
    1355           0 :     void ResetWeekDaysByMonth(EnergyPlusData &state,
    1356             :                               Array1D_int &WeekDays,
    1357             :                               int const AddLeapYear,
    1358             :                               int const StartMonth,
    1359             :                               int const StartMonthDay,
    1360             :                               int const EndMonth,
    1361             :                               int const EndMonthDay,
    1362             :                               bool const Rollover,
    1363             :                               bool const MidSimReset)
    1364             :     {
    1365             : 
    1366             :         // SUBROUTINE INFORMATION:
    1367             :         //       AUTHOR         Linda Lawrie
    1368             :         //       DATE WRITTEN   March 2012
    1369             :         //       MODIFIED       na
    1370             :         //       RE-ENGINEERED  na
    1371             : 
    1372             :         // PURPOSE OF THIS SUBROUTINE:
    1373             :         // This subroutine resets the weekday for each month based on the current weekday
    1374             :         // and previous weekdays per month.
    1375             : 
    1376           0 :         EP_SIZE_CHECK(WeekDays, 12); // NOLINT(misc-static-assert)
    1377             : 
    1378           0 :         Array1D_int WeekDaysCopy(12);
    1379             :         int CurWeekDay;
    1380             : 
    1381           0 :         WeekDaysCopy = WeekDays;
    1382           0 :         if (!MidSimReset) {
    1383           0 :             if (Rollover) {
    1384           0 :                 if (StartMonth == 1) {
    1385           0 :                     CurWeekDay = WeekDays(12) + state.dataWeatherManager->EndDayOfMonth(12) + StartMonthDay - 1;
    1386             :                 } else {
    1387           0 :                     CurWeekDay = WeekDays(EndMonth) + EndMonthDay;
    1388             :                 }
    1389             :             } else { // restart at same as before
    1390           0 :                 CurWeekDay = WeekDays(StartMonth);
    1391             :             }
    1392           0 :             while (CurWeekDay > 7) {
    1393           0 :                 CurWeekDay -= 7;
    1394             :             }
    1395             : 
    1396           0 :             WeekDays = 0;
    1397           0 :             WeekDays(StartMonth) = CurWeekDay;
    1398           0 :             for (int i = StartMonth + 1; i <= 12; ++i) {
    1399           0 :                 if (i == 2) {
    1400           0 :                     CurWeekDay += state.dataWeatherManager->EndDayOfMonth(1);
    1401           0 :                     while (CurWeekDay > 7) {
    1402           0 :                         CurWeekDay -= 7;
    1403             :                     }
    1404           0 :                     WeekDays(i) = CurWeekDay;
    1405           0 :                 } else if (i == 3) {
    1406           0 :                     CurWeekDay += state.dataWeatherManager->EndDayOfMonth(i - 1) + AddLeapYear;
    1407           0 :                     while (CurWeekDay > 7) {
    1408           0 :                         CurWeekDay -= 7;
    1409             :                     }
    1410           0 :                     WeekDays(i) = CurWeekDay;
    1411           0 :                 } else if ((i >= 4) && (i <= 12)) {
    1412           0 :                     CurWeekDay += state.dataWeatherManager->EndDayOfMonth(i - 1);
    1413           0 :                     while (CurWeekDay > 7) {
    1414           0 :                         CurWeekDay -= 7;
    1415             :                     }
    1416           0 :                     WeekDays(i) = CurWeekDay;
    1417             :                 }
    1418             :             }
    1419             : 
    1420           0 :             if (any_eq(WeekDays, 0)) {
    1421             :                 // need to start at StMon and go backwards.
    1422             :                 // EndDayOfMonth is also "days" in month.  (without leapyear day in February)
    1423           0 :                 CurWeekDay = WeekDays(StartMonth);
    1424           0 :                 for (int i = 1; i <= StartMonthDay - 1; ++i) {
    1425           0 :                     --CurWeekDay;
    1426           0 :                     if (CurWeekDay == 0) CurWeekDay = 7;
    1427             :                 }
    1428             : 
    1429           0 :                 for (int i = StartMonth - 1; i >= 1; --i) {
    1430             : 
    1431           0 :                     if (i == 1) {
    1432           0 :                         CurWeekDay -= state.dataWeatherManager->EndDayOfMonth(1);
    1433           0 :                         while (CurWeekDay <= 0) {
    1434           0 :                             CurWeekDay += 7;
    1435             :                         }
    1436           0 :                         WeekDays(i) = CurWeekDay;
    1437           0 :                     } else if (i == 2) {
    1438           0 :                         CurWeekDay = CurWeekDay - state.dataWeatherManager->EndDayOfMonth(2) + AddLeapYear;
    1439           0 :                         while (CurWeekDay <= 0) {
    1440           0 :                             CurWeekDay += 7;
    1441             :                         }
    1442           0 :                         WeekDays(i) = CurWeekDay;
    1443           0 :                     } else if ((i >= 3) && (i <= 12)) {
    1444           0 :                         CurWeekDay -= state.dataWeatherManager->EndDayOfMonth(i);
    1445           0 :                         while (CurWeekDay <= 0) {
    1446           0 :                             CurWeekDay += 7;
    1447             :                         }
    1448           0 :                         WeekDays(i) = CurWeekDay;
    1449             :                     }
    1450             :                 }
    1451             :             }
    1452             : 
    1453             :         } else {
    1454           0 :             if (Rollover) {
    1455           0 :                 if (StartMonth == 1) {
    1456           0 :                     CurWeekDay = WeekDays(12) + state.dataWeatherManager->EndDayOfMonth(12) + StartMonthDay - 1;
    1457             :                 } else {
    1458           0 :                     CurWeekDay = WeekDays(EndMonth) + EndMonthDay;
    1459             :                 }
    1460             :             } else { // restart at same as before
    1461           0 :                 CurWeekDay = WeekDays(StartMonth);
    1462             :             }
    1463           0 :             while (CurWeekDay > 7) {
    1464           0 :                 CurWeekDay -= 7;
    1465             :             }
    1466           0 :             WeekDays = 0;
    1467           0 :             if (StartMonth != 1) {
    1468           0 :                 CurWeekDay = WeekDaysCopy(12) + state.dataWeatherManager->EndDayOfMonth(12);
    1469           0 :                 while (CurWeekDay > 7) {
    1470           0 :                     CurWeekDay -= 7;
    1471             :                 }
    1472           0 :                 WeekDays(1) = CurWeekDay;
    1473           0 :                 CurWeekDay += state.dataWeatherManager->EndDayOfMonth(1);
    1474           0 :                 while (CurWeekDay > 7) {
    1475           0 :                     CurWeekDay -= 7;
    1476             :                 }
    1477           0 :                 WeekDays(2) = CurWeekDay;
    1478           0 :                 CurWeekDay += state.dataWeatherManager->EndDayOfMonth(2) + AddLeapYear;
    1479           0 :                 while (CurWeekDay > 7) {
    1480           0 :                     CurWeekDay -= 7;
    1481             :                 }
    1482           0 :                 WeekDays(3) = CurWeekDay;
    1483           0 :                 for (int i = 4; i <= 12; ++i) {
    1484           0 :                     CurWeekDay += state.dataWeatherManager->EndDayOfMonth(i - 1);
    1485           0 :                     while (CurWeekDay > 7) {
    1486           0 :                         CurWeekDay -= 7;
    1487             :                     }
    1488           0 :                     WeekDays(i) = CurWeekDay;
    1489             :                 }
    1490             :             } else {
    1491           0 :                 WeekDays = 0;
    1492           0 :                 WeekDays(StartMonth) = CurWeekDay;
    1493           0 :                 for (int i = StartMonth + 1; i <= 12; ++i) {
    1494           0 :                     if (i == 2) {
    1495           0 :                         CurWeekDay += state.dataWeatherManager->EndDayOfMonth(1);
    1496           0 :                         while (CurWeekDay > 7) {
    1497           0 :                             CurWeekDay -= 7;
    1498             :                         }
    1499           0 :                         WeekDays(i) = CurWeekDay;
    1500           0 :                     } else if (i == 3) {
    1501           0 :                         CurWeekDay += state.dataWeatherManager->EndDayOfMonth(i - 1) + AddLeapYear;
    1502           0 :                         while (CurWeekDay > 7) {
    1503           0 :                             CurWeekDay -= 7;
    1504             :                         }
    1505           0 :                         WeekDays(i) = CurWeekDay;
    1506           0 :                     } else if ((i >= 4) && (i <= 12)) {
    1507           0 :                         CurWeekDay += state.dataWeatherManager->EndDayOfMonth(i - 1);
    1508           0 :                         while (CurWeekDay > 7) {
    1509           0 :                             CurWeekDay -= 7;
    1510             :                         }
    1511           0 :                         WeekDays(i) = CurWeekDay;
    1512             :                     }
    1513             :                 }
    1514             : 
    1515           0 :                 if (any_eq(WeekDays, 0)) {
    1516             :                     // need to start at StMon and go backwards.
    1517             :                     // EndDayOfMonth is also "days" in month.  (without leapyear day in February)
    1518           0 :                     CurWeekDay = WeekDays(StartMonth);
    1519           0 :                     for (int i = 1; i <= StartMonthDay - 1; ++i) {
    1520           0 :                         --CurWeekDay;
    1521           0 :                         if (CurWeekDay == 0) CurWeekDay = 7;
    1522             :                     }
    1523             : 
    1524           0 :                     for (int i = StartMonth - 1; i >= 1; --i) {
    1525             : 
    1526           0 :                         if (i == 1) {
    1527           0 :                             CurWeekDay -= state.dataWeatherManager->EndDayOfMonth(1);
    1528           0 :                             while (CurWeekDay <= 0) {
    1529           0 :                                 CurWeekDay += 7;
    1530             :                             }
    1531           0 :                             WeekDays(i) = CurWeekDay;
    1532           0 :                         } else if (i == 2) {
    1533           0 :                             CurWeekDay = CurWeekDay - state.dataWeatherManager->EndDayOfMonth(2) + AddLeapYear;
    1534           0 :                             while (CurWeekDay <= 0) {
    1535           0 :                                 CurWeekDay += 7;
    1536             :                             }
    1537           0 :                             WeekDays(i) = CurWeekDay;
    1538           0 :                         } else if ((i >= 3) && (i <= 12)) {
    1539           0 :                             CurWeekDay -= state.dataWeatherManager->EndDayOfMonth(i);
    1540           0 :                             while (CurWeekDay <= 0) {
    1541           0 :                                 CurWeekDay += 7;
    1542             :                             }
    1543           0 :                             WeekDays(i) = CurWeekDay;
    1544             :                         }
    1545             :                     }
    1546             :                 }
    1547             :             }
    1548             :         }
    1549           0 :     }
    1550             : 
    1551           3 :     void SetDSTDateRanges(EnergyPlusData &state,
    1552             :                           Array1D_int const &MonWeekDay, // Weekday of each day 1 of month
    1553             :                           Array1D_int &DSTIdx,           // DST Index for each julian day (1:366)
    1554             :                           Optional_int DSTActStMon,
    1555             :                           Optional_int DSTActStDay,
    1556             :                           Optional_int DSTActEnMon,
    1557             :                           Optional_int DSTActEnDay)
    1558             :     {
    1559             : 
    1560             :         // SUBROUTINE INFORMATION:
    1561             :         //       AUTHOR         Linda Lawrie
    1562             :         //       DATE WRITTEN   March 2012
    1563             :         //       MODIFIED       na
    1564             :         //       RE-ENGINEERED  na
    1565             : 
    1566             :         // PURPOSE OF THIS SUBROUTINE:
    1567             :         // With multiple year weather files (or repeating weather files that rollover day),
    1568             :         // need to set DST (Daylight Saving Time) dates at start of environment or year.
    1569             :         // DST is only projected for one year.
    1570             : 
    1571             :         static constexpr std::string_view RoutineName("SetDSTDateRanges: ");
    1572             : 
    1573             :         int ActStartMonth; // Actual Start Month
    1574             :         int ActStartDay;   // Actual Start Day of Month
    1575             :         int ActEndMonth;   // Actual End Month
    1576             :         int ActEndDay;     // Actual End Day of Month
    1577           6 :         Array1D_int ActEndDayOfMonth(12);
    1578             : 
    1579           3 :         bool ErrorsFound = false;
    1580           3 :         ActEndDayOfMonth = state.dataWeatherManager->EndDayOfMonth;
    1581           3 :         ActEndDayOfMonth(2) = state.dataWeatherManager->EndDayOfMonth(2) + state.dataWeatherManager->LeapYearAdd;
    1582           3 :         if (state.dataWeatherManager->DST.StDateType == DateType::MonthDay) {
    1583           0 :             ActStartMonth = state.dataWeatherManager->DST.StMon;
    1584           0 :             ActStartDay = state.dataWeatherManager->DST.StDay;
    1585           3 :         } else if (state.dataWeatherManager->DST.StDateType == DateType::NthDayInMonth) {
    1586           3 :             int ThisDay = state.dataWeatherManager->DST.StWeekDay - MonWeekDay(state.dataWeatherManager->DST.StMon) + 1;
    1587           9 :             while (ThisDay <= 0) {
    1588           3 :                 ThisDay += 7;
    1589             :             }
    1590           3 :             ThisDay += 7 * (state.dataWeatherManager->DST.StDay - 1);
    1591           3 :             if (ThisDay > ActEndDayOfMonth(state.dataWeatherManager->DST.StMon)) {
    1592           0 :                 ShowSevereError(state, std::string{RoutineName} + "Determining DST: DST Start Date, Nth Day of Month, not enough Nths");
    1593           0 :                 ErrorsFound = true;
    1594             :             } else {
    1595           3 :                 ActStartMonth = state.dataWeatherManager->DST.StMon;
    1596           3 :                 ActStartDay = ThisDay;
    1597             :             }
    1598             :         } else { // LastWeekDayInMonth
    1599           0 :             int ThisDay = state.dataWeatherManager->DST.StWeekDay - MonWeekDay(state.dataWeatherManager->DST.StMon) + 1;
    1600           0 :             while (ThisDay + 7 <= ActEndDayOfMonth(state.dataWeatherManager->DST.StMon)) {
    1601           0 :                 ThisDay += 7;
    1602             :             }
    1603           0 :             ActStartMonth = state.dataWeatherManager->DST.StMon;
    1604           0 :             ActStartDay = ThisDay;
    1605             :         }
    1606             : 
    1607           3 :         if (state.dataWeatherManager->DST.EnDateType == DateType::MonthDay) {
    1608           0 :             ActEndMonth = state.dataWeatherManager->DST.EnMon;
    1609           0 :             ActEndDay = state.dataWeatherManager->DST.EnDay;
    1610           3 :         } else if (state.dataWeatherManager->DST.EnDateType == DateType::NthDayInMonth) {
    1611           3 :             int ThisDay = state.dataWeatherManager->DST.EnWeekDay - MonWeekDay(state.dataWeatherManager->DST.EnMon) + 1;
    1612           9 :             while (ThisDay <= 0) {
    1613           3 :                 ThisDay += 7;
    1614             :             }
    1615           3 :             ThisDay += 7 * (state.dataWeatherManager->DST.EnDay - 1);
    1616           3 :             if (ThisDay > ActEndDayOfMonth(state.dataWeatherManager->DST.EnMon)) {
    1617           0 :                 ActEndMonth = 0; // Suppress uninitialized warning
    1618           0 :                 ActEndDay = 0;   // Suppress uninitialized warning
    1619           0 :                 ShowSevereError(state, std::string{RoutineName} + "Determining DST: DST End Date, Nth Day of Month, not enough Nths");
    1620           0 :                 ErrorsFound = true;
    1621             :             } else {
    1622           3 :                 ActEndMonth = state.dataWeatherManager->DST.EnMon;
    1623           3 :                 ActEndDay = ThisDay;
    1624             :             }
    1625             :         } else { // LastWeekDayInMonth
    1626           0 :             int ThisDay = state.dataWeatherManager->DST.EnWeekDay - MonWeekDay(state.dataWeatherManager->DST.EnMon) + 1;
    1627           0 :             while (ThisDay + 7 <= ActEndDayOfMonth(state.dataWeatherManager->DST.EnMon)) {
    1628           0 :                 ThisDay += 7;
    1629             :             }
    1630           0 :             ActEndMonth = state.dataWeatherManager->DST.EnMon;
    1631           0 :             ActEndDay = ThisDay;
    1632             :         }
    1633             : 
    1634           3 :         if (ErrorsFound) {
    1635           0 :             ShowFatalError(state, std::string{RoutineName} + "Program terminates due to preceding condition(s).");
    1636             :         }
    1637             : 
    1638           3 :         if (present(DSTActStMon)) {
    1639           2 :             DSTActStMon = ActStartMonth;
    1640           2 :             DSTActStDay = ActStartDay;
    1641           2 :             DSTActEnMon = ActEndMonth;
    1642           2 :             DSTActEnDay = ActEndDay;
    1643             :         }
    1644             : 
    1645           3 :         DSTIdx = 0;
    1646           3 :         int JDay = General::OrdinalDay(ActStartMonth, ActStartDay, state.dataWeatherManager->LeapYearAdd);
    1647           3 :         int JDay1 = General::OrdinalDay(ActEndMonth, ActEndDay, state.dataWeatherManager->LeapYearAdd);
    1648           3 :         if (JDay1 >= JDay) {
    1649           3 :             DSTIdx({JDay, JDay1}) = 1;
    1650             :         } else {
    1651           0 :             DSTIdx({JDay, 366}) = 1;
    1652           0 :             DSTIdx({1, JDay1}) = 1;
    1653             :         }
    1654           3 :     }
    1655             : 
    1656          28 :     void SetSpecialDayDates(EnergyPlusData &state, Array1D_int const &MonWeekDay) // Weekday of each day 1 of month
    1657             :     {
    1658             : 
    1659             :         // SUBROUTINE INFORMATION:
    1660             :         //       AUTHOR         Linda Lawrie
    1661             :         //       DATE WRITTEN   March 2012
    1662             :         //       MODIFIED       na
    1663             :         //       RE-ENGINEERED  na
    1664             : 
    1665             :         // PURPOSE OF THIS SUBROUTINE:
    1666             :         // With multiple year weather files (or repeating weather files that rollover day),
    1667             :         // need to set Special Day dates at start of environment or year.
    1668             :         // Special Days are only projected for one year.
    1669             : 
    1670             :         static constexpr std::string_view RoutineName("SetSpecialDayDates: ");
    1671             : 
    1672             :         int JDay;
    1673          56 :         Array1D_int ActEndDayOfMonth(12);
    1674             : 
    1675          28 :         bool ErrorsFound = false;
    1676          28 :         ActEndDayOfMonth = state.dataWeatherManager->EndDayOfMonth;
    1677          28 :         ActEndDayOfMonth(2) = state.dataWeatherManager->EndDayOfMonth(2) + state.dataWeatherManager->LeapYearAdd;
    1678          28 :         state.dataWeatherManager->SpecialDayTypes = 0;
    1679          91 :         for (int i = 1; i <= state.dataWeatherManager->NumSpecialDays; ++i) {
    1680          63 :             if (state.dataWeatherManager->SpecialDays(i).WthrFile && !state.dataWeatherManager->UseSpecialDays) continue;
    1681          63 :             if (state.dataWeatherManager->SpecialDays(i).DateType <= DateType::MonthDay) {
    1682          60 :                 JDay = General::OrdinalDay(state.dataWeatherManager->SpecialDays(i).Month,
    1683          30 :                                            state.dataWeatherManager->SpecialDays(i).Day,
    1684          30 :                                            state.dataWeatherManager->LeapYearAdd);
    1685          60 :                 if (state.dataWeatherManager->SpecialDays(i).Duration == 1 &&
    1686          30 :                     state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).ApplyWeekendRule) {
    1687          18 :                     if (state.dataWeatherManager->WeekDayTypes(JDay) == static_cast<int>(ScheduleManager::DayType::Sunday)) {
    1688             :                         // Sunday, must go to Monday
    1689           6 :                         ++JDay;
    1690           6 :                         if (JDay == 366 && state.dataWeatherManager->LeapYearAdd == 0) JDay = 1;
    1691          12 :                     } else if (state.dataWeatherManager->WeekDayTypes(JDay) == static_cast<int>(ScheduleManager::DayType::Saturday)) {
    1692           0 :                         ++JDay;
    1693           0 :                         if (JDay == 366 && state.dataWeatherManager->LeapYearAdd == 0) JDay = 1;
    1694           0 :                         ++JDay;
    1695           0 :                         if (JDay == 366 && state.dataWeatherManager->LeapYearAdd == 0) JDay = 1;
    1696             :                     }
    1697             :                 }
    1698          90 :                 General::InvOrdinalDay(JDay,
    1699          30 :                                        state.dataWeatherManager->SpecialDays(i).ActStMon,
    1700          30 :                                        state.dataWeatherManager->SpecialDays(i).ActStDay,
    1701          30 :                                        state.dataWeatherManager->LeapYearAdd);
    1702          33 :             } else if (state.dataWeatherManager->SpecialDays(i).DateType == DateType::NthDayInMonth) {
    1703          27 :                 int ThisDay = state.dataWeatherManager->SpecialDays(i).WeekDay - MonWeekDay(state.dataWeatherManager->SpecialDays(i).Month) + 1;
    1704          27 :                 if (state.dataWeatherManager->SpecialDays(i).WeekDay < MonWeekDay(state.dataWeatherManager->SpecialDays(i).Month)) {
    1705          18 :                     ThisDay += 7;
    1706             :                 }
    1707          27 :                 ThisDay += 7 * (state.dataWeatherManager->SpecialDays(i).Day - 1);
    1708          27 :                 if (ThisDay > ActEndDayOfMonth(state.dataWeatherManager->SpecialDays(i).Month)) {
    1709           0 :                     ShowSevereError(state,
    1710           0 :                                     std::string{RoutineName} + "Special Day Date, Nth Day of Month, not enough Nths, for SpecialDay=" +
    1711           0 :                                         state.dataWeatherManager->SpecialDays(i).Name);
    1712           0 :                     ErrorsFound = true;
    1713           0 :                     continue;
    1714             :                 }
    1715          27 :                 state.dataWeatherManager->SpecialDays(i).ActStMon = state.dataWeatherManager->SpecialDays(i).Month;
    1716          27 :                 state.dataWeatherManager->SpecialDays(i).ActStDay = ThisDay;
    1717          27 :                 JDay = General::OrdinalDay(state.dataWeatherManager->SpecialDays(i).Month, ThisDay, state.dataWeatherManager->LeapYearAdd);
    1718             :             } else { // LastWeekDayInMonth
    1719           6 :                 int ThisDay = state.dataWeatherManager->SpecialDays(i).WeekDay - MonWeekDay(state.dataWeatherManager->SpecialDays(i).Month) + 1;
    1720          60 :                 while (ThisDay + 7 <= ActEndDayOfMonth(state.dataWeatherManager->SpecialDays(i).Month)) {
    1721          27 :                     ThisDay += 7;
    1722             :                 }
    1723           6 :                 state.dataWeatherManager->SpecialDays(i).ActStMon = state.dataWeatherManager->SpecialDays(i).Month;
    1724           6 :                 state.dataWeatherManager->SpecialDays(i).ActStDay = ThisDay;
    1725           6 :                 JDay = General::OrdinalDay(state.dataWeatherManager->SpecialDays(i).Month, ThisDay, state.dataWeatherManager->LeapYearAdd);
    1726             :             }
    1727          63 :             if (state.dataWeatherManager->SpecialDayTypes(JDay) != 0) {
    1728           0 :                 ShowWarningError(state,
    1729           0 :                                  std::string{RoutineName} + "Special Day definition (" + state.dataWeatherManager->SpecialDays(i).Name +
    1730             :                                      ") is overwriting previously entered special day period");
    1731           0 :                 if (state.dataWeatherManager->UseSpecialDays) {
    1732           0 :                     ShowContinueError(state, "...This could be caused by definitions on the Weather File.");
    1733             :                 }
    1734           0 :                 ShowContinueError(state, "...This could be caused by duplicate definitions in the Input File.");
    1735             :             }
    1736          63 :             int JDay1 = JDay - 1;
    1737         126 :             for (int j = 0; j <= state.dataWeatherManager->SpecialDays(i).Duration - 1; ++j) {
    1738          63 :                 ++JDay1;
    1739          63 :                 if (JDay1 == 366 && state.dataWeatherManager->LeapYearAdd == 0) JDay1 = 1;
    1740          63 :                 if (JDay1 == 367) JDay1 = 1;
    1741          63 :                 state.dataWeatherManager->SpecialDayTypes(JDay1) = state.dataWeatherManager->SpecialDays(i).DayType;
    1742             :             }
    1743             :         }
    1744             : 
    1745          28 :         if (ErrorsFound) {
    1746           0 :             ShowFatalError(state, std::string{RoutineName} + "Program terminates due to preceding condition(s).");
    1747             :         }
    1748          28 :     }
    1749             : 
    1750     2661169 :     void InitializeWeather(EnergyPlusData &state, bool &printEnvrnStamp) // Set to true when the environment header should be printed
    1751             :     {
    1752             : 
    1753             :         // SUBROUTINE INFORMATION:
    1754             :         //       AUTHOR         Rick Strand
    1755             :         //       DATE WRITTEN   June 1997
    1756             :         //       MODIFIED       na
    1757             :         //       RE-ENGINEERED  na
    1758             : 
    1759             :         // PURPOSE OF THIS SUBROUTINE:
    1760             :         // This subroutine is the main driver of the weather initializations.
    1761             :         // Most of the weather handling can be described as "initializations"
    1762             :         // so most of the work is done via this subroutine.
    1763             : 
    1764     2661169 :         if (state.dataGlobal->BeginSimFlag && state.dataWeatherManager->FirstCall) {
    1765             : 
    1766         771 :             state.dataWeatherManager->FirstCall = false;
    1767         771 :             state.dataEnvrn->EndMonthFlag = false;
    1768             : 
    1769             :         } // ... end of DataGlobals::BeginSimFlag IF-THEN block.
    1770             : 
    1771     2661169 :         auto &thisEnvrn = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn);
    1772     2661169 :         if (state.dataGlobal->BeginEnvrnFlag) {
    1773             : 
    1774             :             // Call and setup the Design Day environment
    1775        6902 :             if (thisEnvrn.KindOfEnvrn != DataGlobalConstants::KindOfSim::RunPeriodWeather) {
    1776        5739 :                 if (thisEnvrn.DesignDayNum > 0) {
    1777        5716 :                     SetUpDesignDay(state, thisEnvrn.DesignDayNum);
    1778        5716 :                     state.dataEnvrn->EnvironmentName = thisEnvrn.Title;
    1779             :                 }
    1780             :             }
    1781             : 
    1782             :             // Only used in Weather file environments
    1783             :             // Start over missing values with each environment
    1784        6902 :             state.dataWeatherManager->Missing.StnPres = state.dataEnvrn->StdBaroPress; // Initial "missing" value
    1785        6902 :             state.dataWeatherManager->Missing.DryBulb = 6.0;                           // Initial "missing" value
    1786        6902 :             state.dataWeatherManager->Missing.DewPoint = 3.0;                          // Initial "missing" value
    1787        6902 :             state.dataWeatherManager->Missing.RelHumid = 50.0;                         // Initial "missing" value
    1788        6902 :             state.dataWeatherManager->Missing.WindSpd = 2.5;                           // Initial "missing" value
    1789        6902 :             state.dataWeatherManager->Missing.WindDir = 180;                           // Initial "missing" value
    1790        6902 :             state.dataWeatherManager->Missing.TotSkyCvr = 5;                           // Initial "missing" value
    1791        6902 :             state.dataWeatherManager->Missing.OpaqSkyCvr = 5;                          // Initial "missing" value
    1792        6902 :             state.dataWeatherManager->Missing.Visibility = 777.7;                      // Initial "missing" value
    1793        6902 :             state.dataWeatherManager->Missing.Ceiling = 77777;                         // Initial "missing" value
    1794        6902 :             state.dataWeatherManager->Missing.PrecipWater = 0;                         // Initial "missing" value
    1795        6902 :             state.dataWeatherManager->Missing.AerOptDepth = 0.0;                       // Initial "missing" value
    1796        6902 :             state.dataWeatherManager->Missing.SnowDepth = 0;                           // Initial "missing" value
    1797        6902 :             state.dataWeatherManager->Missing.DaysLastSnow = 88;                       // Initial "missing" value
    1798        6902 :             state.dataWeatherManager->Missing.Albedo = 0.0;                            // Initial "missing" value
    1799        6902 :             state.dataWeatherManager->Missing.LiquidPrecip = 0.0;                      // Initial "missing" value
    1800             :             // Counts set to 0 for each environment
    1801        6902 :             state.dataWeatherManager->Missed.StnPres = 0;
    1802        6902 :             state.dataWeatherManager->Missed.DryBulb = 0;
    1803        6902 :             state.dataWeatherManager->Missed.DewPoint = 0;
    1804        6902 :             state.dataWeatherManager->Missed.RelHumid = 0;
    1805        6902 :             state.dataWeatherManager->Missed.WindSpd = 0;
    1806        6902 :             state.dataWeatherManager->Missed.WindDir = 0;
    1807        6902 :             state.dataWeatherManager->Missed.TotSkyCvr = 0;
    1808        6902 :             state.dataWeatherManager->Missed.OpaqSkyCvr = 0;
    1809        6902 :             state.dataWeatherManager->Missed.Visibility = 0;
    1810        6902 :             state.dataWeatherManager->Missed.Ceiling = 0;
    1811        6902 :             state.dataWeatherManager->Missed.PrecipWater = 0;
    1812        6902 :             state.dataWeatherManager->Missed.AerOptDepth = 0;
    1813        6902 :             state.dataWeatherManager->Missed.SnowDepth = 0;
    1814        6902 :             state.dataWeatherManager->Missed.DaysLastSnow = 0;
    1815        6902 :             state.dataWeatherManager->Missed.Albedo = 0;
    1816        6902 :             state.dataWeatherManager->Missed.LiquidPrecip = 0;
    1817        6902 :             state.dataWeatherManager->Missed.WeathCodes = 0;
    1818        6902 :             state.dataWeatherManager->Missed.DirectRad = 0;
    1819        6902 :             state.dataWeatherManager->Missed.DiffuseRad = 0;
    1820             :             // Counts set to 0 for each environment
    1821        6902 :             state.dataWeatherManager->OutOfRange.StnPres = 0;
    1822        6902 :             state.dataWeatherManager->OutOfRange.DryBulb = 0;
    1823        6902 :             state.dataWeatherManager->OutOfRange.DewPoint = 0;
    1824        6902 :             state.dataWeatherManager->OutOfRange.RelHumid = 0;
    1825        6902 :             state.dataWeatherManager->OutOfRange.WindSpd = 0;
    1826        6902 :             state.dataWeatherManager->OutOfRange.WindDir = 0;
    1827        6902 :             state.dataWeatherManager->OutOfRange.DirectRad = 0;
    1828        6902 :             state.dataWeatherManager->OutOfRange.DiffuseRad = 0;
    1829        6902 :             state.dataWeatherManager->IsRainThreshold = 0.8 / double(state.dataGlobal->NumOfTimeStepInHour); // [mm]
    1830             : 
    1831        6902 :             if (!state.dataWeatherManager->RPReadAllWeatherData) {
    1832        6901 :                 printEnvrnStamp = true; // Set this to true so that on first non-warmup day (only) the environment header will print out
    1833             :             }
    1834             : 
    1835       22520 :             for (int i = 1; i <= state.dataWeatherManager->NumSpecialDays; ++i) {
    1836       15618 :                 state.dataWeatherManager->SpecialDays(i).Used = false;
    1837             :             }
    1838             : 
    1839        8162 :             if ((state.dataGlobal->KindOfSim != DataGlobalConstants::KindOfSim::DesignDay) &&
    1840        1260 :                 (state.dataGlobal->KindOfSim != DataGlobalConstants::KindOfSim::HVACSizeDesignDay)) {
    1841        1186 :                 ReadWeatherForDay(state, 1, state.dataWeatherManager->Envrn, false); // Read first day's weather
    1842             :             } else {
    1843        5716 :                 state.dataWeatherManager->TomorrowVariables = state.dataWeatherManager->DesignDay(thisEnvrn.DesignDayNum);
    1844             :             }
    1845             : 
    1846             :         } // ... end of DataGlobals::BeginEnvrnFlag IF-THEN block.
    1847             : 
    1848     2661169 :         if (state.dataGlobal->BeginDayFlag) {
    1849             : 
    1850             :             // Check Holidays, Daylight Saving Time, Ground Temperatures, etc.
    1851             : 
    1852       24476 :             UpdateWeatherData(state); // Update daily weather info
    1853             : 
    1854             :             // Read tomorrow's weather only if necessary.  This means that the
    1855             :             // simulation is out of warmup, is using a weather tape for this
    1856             :             // environment, and is not on the last day (day after last day is
    1857             :             // assumed to be equal to last day).
    1858             : 
    1859             :             // Following code checks whether the present day of simulation matches the start month and start day.
    1860             :             // In a multi year simulation with run period less than 365, we need to position the weather line
    1861             :             // appropriately.
    1862             : 
    1863       25694 :             if ((!state.dataGlobal->WarmupFlag) && ((thisEnvrn.KindOfEnvrn != DataGlobalConstants::KindOfSim::DesignDay) &&
    1864        1218 :                                                     (thisEnvrn.KindOfEnvrn != DataGlobalConstants::KindOfSim::HVACSizeDesignDay))) {
    1865        1186 :                 if (state.dataGlobal->DayOfSim < state.dataGlobal->NumOfDayInEnvrn) {
    1866        1171 :                     if (state.dataGlobal->DayOfSim == state.dataWeatherManager->curSimDayForEndOfRunPeriod) {
    1867           0 :                         state.dataWeatherManager->curSimDayForEndOfRunPeriod += thisEnvrn.RawSimDays;
    1868           0 :                         if (state.dataWeatherManager->StartDatesCycleShouldBeReset) {
    1869           0 :                             ResetWeekDaysByMonth(state,
    1870             :                                                  thisEnvrn.MonWeekDay,
    1871           0 :                                                  state.dataWeatherManager->LeapYearAdd,
    1872             :                                                  thisEnvrn.StartMonth,
    1873             :                                                  thisEnvrn.StartDay,
    1874             :                                                  thisEnvrn.EndMonth,
    1875             :                                                  thisEnvrn.EndDay,
    1876           0 :                                                  thisEnvrn.RollDayTypeOnRepeat);
    1877           0 :                             if (state.dataWeatherManager->DaylightSavingIsActive) {
    1878           0 :                                 SetDSTDateRanges(state, thisEnvrn.MonWeekDay, state.dataWeatherManager->DSTIndex);
    1879             :                             }
    1880           0 :                             SetSpecialDayDates(state, thisEnvrn.MonWeekDay);
    1881             :                         }
    1882           0 :                         ++state.dataWeatherManager->YearOfSim;
    1883           0 :                         ReadWeatherForDay(state, 1, state.dataWeatherManager->Envrn, false); // Read tomorrow's weather
    1884             :                     } else {
    1885        1171 :                         ReadWeatherForDay(state, state.dataGlobal->DayOfSim + 1, state.dataWeatherManager->Envrn, false); // Read tomorrow's weather
    1886             :                     }
    1887             :                 }
    1888             :             }
    1889             : 
    1890       24476 :             state.dataEnvrn->EndYearFlag = false;
    1891       24476 :             if (state.dataEnvrn->DayOfMonth == state.dataWeatherManager->EndDayOfMonth(state.dataEnvrn->Month)) {
    1892          43 :                 state.dataEnvrn->EndMonthFlag = true;
    1893          43 :                 state.dataEnvrn->EndYearFlag = (state.dataEnvrn->Month == 12);
    1894             :             }
    1895             : 
    1896             :             // Set Tomorrow's date data
    1897       24476 :             state.dataEnvrn->MonthTomorrow = state.dataWeatherManager->TomorrowVariables.Month;
    1898       24476 :             state.dataEnvrn->DayOfMonthTomorrow = state.dataWeatherManager->TomorrowVariables.DayOfMonth;
    1899       24476 :             state.dataEnvrn->DayOfWeekTomorrow = state.dataWeatherManager->TomorrowVariables.DayOfWeek;
    1900       24476 :             state.dataEnvrn->HolidayIndexTomorrow = state.dataWeatherManager->TomorrowVariables.HolidayIndex;
    1901       24476 :             state.dataEnvrn->YearTomorrow = state.dataWeatherManager->TomorrowVariables.Year;
    1902             : 
    1903       24476 :             if (thisEnvrn.KindOfEnvrn == DataGlobalConstants::KindOfSim::RunPeriodWeather) {
    1904        1904 :                 if (state.dataEnvrn->Month == 1 && state.dataEnvrn->DayOfMonth == 1 && thisEnvrn.ActualWeather) {
    1905           0 :                     if (state.dataWeatherManager->DatesShouldBeReset) {
    1906           0 :                         if (thisEnvrn.TreatYearsAsConsecutive) {
    1907           0 :                             ++thisEnvrn.CurrentYear;
    1908           0 :                             thisEnvrn.IsLeapYear = isLeapYear(thisEnvrn.CurrentYear);
    1909           0 :                             state.dataEnvrn->CurrentYearIsLeapYear = thisEnvrn.IsLeapYear;
    1910           0 :                             if (state.dataEnvrn->CurrentYearIsLeapYear) {
    1911           0 :                                 if (state.dataWeatherManager->WFAllowsLeapYears) {
    1912           0 :                                     state.dataWeatherManager->LeapYearAdd = 1;
    1913             :                                 } else {
    1914           0 :                                     state.dataWeatherManager->LeapYearAdd = 0;
    1915             :                                 }
    1916             :                             } else {
    1917           0 :                                 state.dataWeatherManager->LeapYearAdd = 0;
    1918             :                             }
    1919             :                             // need to reset MonWeekDay and WeekDayTypes
    1920           0 :                             int JDay5Start = General::OrdinalDay(thisEnvrn.StartMonth, thisEnvrn.StartDay, state.dataWeatherManager->LeapYearAdd);
    1921           0 :                             int JDay5End = General::OrdinalDay(thisEnvrn.EndMonth, thisEnvrn.EndDay, state.dataWeatherManager->LeapYearAdd);
    1922           0 :                             if (!thisEnvrn.ActualWeather)
    1923           0 :                                 state.dataWeatherManager->curSimDayForEndOfRunPeriod =
    1924           0 :                                     state.dataGlobal->DayOfSim + thisEnvrn.RawSimDays + state.dataWeatherManager->LeapYearAdd - 1;
    1925             : 
    1926             :                             {
    1927           0 :                                 int i = JDay5Start;
    1928           0 :                                 int TWeekDay = state.dataEnvrn->DayOfWeek;
    1929             :                                 while (true) {
    1930           0 :                                     state.dataWeatherManager->WeekDayTypes(i) = TWeekDay;
    1931           0 :                                     TWeekDay = mod(TWeekDay, 7) + 1;
    1932           0 :                                     ++i;
    1933           0 :                                     if (i > 366) i = 1;
    1934           0 :                                     if (i == JDay5End) break;
    1935             :                                 }
    1936             :                             }
    1937           0 :                             ResetWeekDaysByMonth(state,
    1938             :                                                  thisEnvrn.MonWeekDay,
    1939           0 :                                                  state.dataWeatherManager->LeapYearAdd,
    1940             :                                                  thisEnvrn.StartMonth,
    1941             :                                                  thisEnvrn.StartDay,
    1942             :                                                  thisEnvrn.EndMonth,
    1943             :                                                  thisEnvrn.EndDay,
    1944           0 :                                                  thisEnvrn.RollDayTypeOnRepeat);
    1945           0 :                             if (state.dataWeatherManager->DaylightSavingIsActive) {
    1946           0 :                                 SetDSTDateRanges(state, thisEnvrn.MonWeekDay, state.dataWeatherManager->DSTIndex);
    1947             :                             }
    1948           0 :                             SetSpecialDayDates(state, thisEnvrn.MonWeekDay);
    1949             :                         }
    1950             :                     }
    1951        1904 :                 } else if ((state.dataEnvrn->Month == 1 && state.dataEnvrn->DayOfMonth == 1) && state.dataWeatherManager->DatesShouldBeReset &&
    1952           0 :                            (state.dataWeatherManager->Jan1DatesShouldBeReset)) {
    1953           0 :                     if (thisEnvrn.TreatYearsAsConsecutive) {
    1954           0 :                         ++thisEnvrn.CurrentYear;
    1955           0 :                         thisEnvrn.IsLeapYear = isLeapYear(thisEnvrn.CurrentYear);
    1956           0 :                         state.dataEnvrn->CurrentYearIsLeapYear = thisEnvrn.IsLeapYear;
    1957           0 :                         if (state.dataEnvrn->CurrentYearIsLeapYear && !state.dataWeatherManager->WFAllowsLeapYears)
    1958           0 :                             state.dataEnvrn->CurrentYearIsLeapYear = false;
    1959           0 :                         if (state.dataGlobal->DayOfSim < state.dataWeatherManager->curSimDayForEndOfRunPeriod &&
    1960           0 :                             state.dataEnvrn->CurrentYearIsLeapYear)
    1961           0 :                             ++state.dataWeatherManager->curSimDayForEndOfRunPeriod;
    1962             :                     }
    1963           0 :                     if (state.dataEnvrn->CurrentYearIsLeapYear) {
    1964           0 :                         if (state.dataWeatherManager->WFAllowsLeapYears) {
    1965           0 :                             state.dataWeatherManager->LeapYearAdd = 1;
    1966             :                         } else {
    1967           0 :                             state.dataWeatherManager->LeapYearAdd = 0;
    1968             :                         }
    1969             :                     } else {
    1970           0 :                         state.dataWeatherManager->LeapYearAdd = 0;
    1971             :                     }
    1972             : 
    1973           0 :                     if (state.dataGlobal->DayOfSim < state.dataWeatherManager->curSimDayForEndOfRunPeriod) {
    1974           0 :                         ResetWeekDaysByMonth(state,
    1975             :                                              thisEnvrn.MonWeekDay,
    1976           0 :                                              state.dataWeatherManager->LeapYearAdd,
    1977             :                                              thisEnvrn.StartMonth,
    1978             :                                              thisEnvrn.StartDay,
    1979             :                                              thisEnvrn.EndMonth,
    1980             :                                              thisEnvrn.EndDay,
    1981           0 :                                              thisEnvrn.RollDayTypeOnRepeat,
    1982           0 :                                              thisEnvrn.RollDayTypeOnRepeat || state.dataEnvrn->CurrentYearIsLeapYear);
    1983           0 :                         if (state.dataWeatherManager->DaylightSavingIsActive) {
    1984           0 :                             SetDSTDateRanges(state, thisEnvrn.MonWeekDay, state.dataWeatherManager->DSTIndex);
    1985             :                         }
    1986           0 :                         SetSpecialDayDates(state, thisEnvrn.MonWeekDay);
    1987             :                     }
    1988             :                 }
    1989             :             }
    1990             : 
    1991             :             // at the end of each day find the min/max weather used for DOAS sizing
    1992       24476 :             if (state.dataGlobal->AirLoopHVACDOASUsedInSim) {
    1993          70 :                 if (thisEnvrn.KindOfEnvrn == DataGlobalConstants::KindOfSim::RunPeriodDesign ||
    1994          35 :                     thisEnvrn.KindOfEnvrn == DataGlobalConstants::KindOfSim::DesignDay) {
    1995        4930 :                     for (size_t i = 0; i < state.dataWeatherManager->TodayOutDryBulbTemp.size(); ++i) {
    1996        4896 :                         if (state.dataWeatherManager->TodayOutDryBulbTemp[i] > thisEnvrn.maxCoolingOATSizing) {
    1997           9 :                             thisEnvrn.maxCoolingOATSizing = state.dataWeatherManager->TodayOutDryBulbTemp[i];
    1998           9 :                             thisEnvrn.maxCoolingOADPSizing = state.dataWeatherManager->TodayOutDewPointTemp[i];
    1999             :                         }
    2000        4896 :                         if (state.dataWeatherManager->TodayOutDryBulbTemp[i] < thisEnvrn.minHeatingOATSizing) {
    2001           8 :                             thisEnvrn.minHeatingOATSizing = state.dataWeatherManager->TodayOutDryBulbTemp[i];
    2002           8 :                             thisEnvrn.minHeatingOADPSizing = state.dataWeatherManager->TodayOutDewPointTemp[i];
    2003             :                         }
    2004             :                     }
    2005             :                 }
    2006             :             }
    2007             : 
    2008             :         } // ... end of DataGlobals::BeginDayFlag IF-THEN block.
    2009             : 
    2010     8461023 :         if (!state.dataGlobal->BeginDayFlag && !state.dataGlobal->WarmupFlag &&
    2011      931603 :             (state.dataEnvrn->Month != state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartMonth ||
    2012      518392 :              state.dataEnvrn->DayOfMonth != state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).StartDay) &&
    2013     2769478 :             !state.dataWeatherManager->DatesShouldBeReset &&
    2014       19528 :             state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).KindOfEnvrn == DataGlobalConstants::KindOfSim::RunPeriodWeather) {
    2015           2 :             state.dataWeatherManager->DatesShouldBeReset = true;
    2016             :         }
    2017             : 
    2018     5329239 :         if (state.dataGlobal->EndEnvrnFlag &&
    2019     2662429 :             (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).KindOfEnvrn != DataGlobalConstants::KindOfSim::DesignDay) &&
    2020        1260 :             (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).KindOfEnvrn !=
    2021             :              DataGlobalConstants::KindOfSim::HVACSizeDesignDay)) {
    2022        1186 :             state.files.inputWeatherFile.rewind();
    2023        1186 :             SkipEPlusWFHeader(state);
    2024        1186 :             ReportMissing_RangeData(state);
    2025             :         }
    2026             : 
    2027             :         // set the EndDesignDayEnvrnsFlag (dataGlobal)
    2028             :         // True at the end of the last design day environment (last time step of last hour of last day of environ which is a design day)
    2029     2661169 :         state.dataGlobal->EndDesignDayEnvrnsFlag = false;
    2030     2661169 :         if (state.dataGlobal->EndEnvrnFlag) {
    2031        6901 :             if (state.dataWeatherManager->Envrn < state.dataWeatherManager->NumOfEnvrn) {
    2032       12160 :                 if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).KindOfEnvrn !=
    2033        6080 :                     state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn + 1).KindOfEnvrn) {
    2034        2692 :                     state.dataGlobal->EndDesignDayEnvrnsFlag = true;
    2035             :                 }
    2036             :             } else {
    2037             :                 // if the last environment set the flag to true.
    2038         821 :                 state.dataGlobal->EndDesignDayEnvrnsFlag = true;
    2039             :             }
    2040             :         }
    2041             : 
    2042     2661169 :         if (state.dataWeatherManager->WaterMainsParameterReport) {
    2043             :             // this is done only once
    2044         771 :             if (state.dataWeatherManager->WaterMainsTempsMethod == WaterMainsTempCalcMethod::CorrelationFromWeatherFile) {
    2045           0 :                 if (!state.dataWeatherManager->OADryBulbAverage.OADryBulbWeatherDataProcessed) {
    2046           0 :                     state.dataWeatherManager->OADryBulbAverage.CalcAnnualAndMonthlyDryBulbTemp(state);
    2047             :                 }
    2048             :             }
    2049             :             // reports to eio file
    2050         771 :             ReportWaterMainsTempParameters(state);
    2051         771 :             state.dataWeatherManager->WaterMainsParameterReport = false;
    2052             :         }
    2053     2661169 :     }
    2054             : 
    2055       24476 :     void UpdateWeatherData(EnergyPlusData &state)
    2056             :     {
    2057             : 
    2058             :         // SUBROUTINE INFORMATION:
    2059             :         //       AUTHOR         Rick Strand
    2060             :         //       DATE WRITTEN   June 1997
    2061             :         //       MODIFIED       na
    2062             :         //       RE-ENGINEERED  na
    2063             : 
    2064             :         // PURPOSE OF THIS SUBROUTINE:
    2065             :         // This subroutine updates all of the daily weather data in the local
    2066             :         // module level variables and the global variables.
    2067             :         // This subroutine will temporarily transfer the weather data for the
    2068             :         // current day to the old data structure contained in envdat.inc until
    2069             :         // enough reengineering has taken place to eliminate the need for this
    2070             :         // include.
    2071             : 
    2072       24476 :         state.dataWeatherManager->TodayVariables =
    2073       24476 :             state.dataWeatherManager->TomorrowVariables; // Transfer Tomorrow's Daily Weather Variables to Today
    2074             : 
    2075       24476 :         if (state.dataGlobal->BeginEnvrnFlag) {
    2076        6902 :             state.dataGlobal->PreviousHour = 24;
    2077             :         }
    2078             : 
    2079       24476 :         state.dataWeatherManager->TodayIsRain = state.dataWeatherManager->TomorrowIsRain;
    2080       24476 :         state.dataWeatherManager->TodayIsSnow = state.dataWeatherManager->TomorrowIsSnow;
    2081       24476 :         state.dataWeatherManager->TodayOutDryBulbTemp = state.dataWeatherManager->TomorrowOutDryBulbTemp;
    2082       24476 :         state.dataWeatherManager->TodayOutDewPointTemp = state.dataWeatherManager->TomorrowOutDewPointTemp;
    2083       24476 :         state.dataWeatherManager->TodayOutBaroPress = state.dataWeatherManager->TomorrowOutBaroPress;
    2084       24476 :         state.dataWeatherManager->TodayOutRelHum = state.dataWeatherManager->TomorrowOutRelHum;
    2085       24476 :         state.dataWeatherManager->TodayWindSpeed = state.dataWeatherManager->TomorrowWindSpeed;
    2086       24476 :         state.dataWeatherManager->TodayWindDir = state.dataWeatherManager->TomorrowWindDir;
    2087       24476 :         state.dataWeatherManager->TodaySkyTemp = state.dataWeatherManager->TomorrowSkyTemp;
    2088       24476 :         state.dataWeatherManager->TodayHorizIRSky = state.dataWeatherManager->TomorrowHorizIRSky;
    2089       24476 :         state.dataWeatherManager->TodayBeamSolarRad = state.dataWeatherManager->TomorrowBeamSolarRad;
    2090       24476 :         state.dataWeatherManager->TodayDifSolarRad = state.dataWeatherManager->TomorrowDifSolarRad;
    2091       24476 :         state.dataWeatherManager->TodayLiquidPrecip = state.dataWeatherManager->TomorrowLiquidPrecip;
    2092       24476 :         state.dataWeatherManager->TodayTotalSkyCover = state.dataWeatherManager->TomorrowTotalSkyCover;
    2093       24476 :         state.dataWeatherManager->TodayOpaqueSkyCover = state.dataWeatherManager->TomorrowOpaqueSkyCover;
    2094             : 
    2095             :         // Update Global Data
    2096             : 
    2097       24476 :         state.dataEnvrn->DayOfYear = state.dataWeatherManager->TodayVariables.DayOfYear;
    2098       24476 :         state.dataEnvrn->Year = state.dataWeatherManager->TodayVariables.Year;
    2099       24476 :         state.dataEnvrn->Month = state.dataWeatherManager->TodayVariables.Month;
    2100       24476 :         state.dataEnvrn->DayOfMonth = state.dataWeatherManager->TodayVariables.DayOfMonth;
    2101       24476 :         state.dataEnvrn->DayOfWeek = state.dataWeatherManager->TodayVariables.DayOfWeek;
    2102       24476 :         state.dataEnvrn->HolidayIndex = state.dataWeatherManager->TodayVariables.HolidayIndex;
    2103       24476 :         if (state.dataEnvrn->HolidayIndex > 0) {
    2104       21880 :             state.dataWeatherManager->RptDayType = state.dataEnvrn->HolidayIndex;
    2105             :         } else {
    2106        2596 :             state.dataWeatherManager->RptDayType = state.dataEnvrn->DayOfWeek;
    2107             :         }
    2108       24476 :         state.dataEnvrn->DSTIndicator = state.dataWeatherManager->TodayVariables.DaylightSavingIndex;
    2109       24476 :         state.dataEnvrn->EquationOfTime = state.dataWeatherManager->TodayVariables.EquationOfTime;
    2110       24476 :         state.dataEnvrn->CosSolarDeclinAngle = state.dataWeatherManager->TodayVariables.CosSolarDeclinAngle;
    2111       24476 :         state.dataEnvrn->SinSolarDeclinAngle = state.dataWeatherManager->TodayVariables.SinSolarDeclinAngle;
    2112       24476 :     }
    2113             : 
    2114     2661169 :     void SetCurrentWeather(EnergyPlusData &state)
    2115             :     {
    2116             : 
    2117             :         // SUBROUTINE INFORMATION:
    2118             :         //       AUTHOR         Russ Taylor
    2119             :         //       DATE WRITTEN   March 1990
    2120             :         //       MODIFIED       Aug94 (LKL) Fixed improper weighting
    2121             :         //                      Nov98 (FCW) Added call to get exterior illuminances
    2122             :         //                      Jan02 (FCW) Changed how ground reflectance for daylighting is set
    2123             :         //                      Mar12 (LKL) Changed settings for leap years/ current years.
    2124             :         //       RE-ENGINEERED  Apr97,May97 (RKS)
    2125             : 
    2126             :         // PURPOSE OF THIS SUBROUTINE:
    2127             :         // The purpose of this subroutine is to interpolate the hourly
    2128             :         // environment data for the sub-hourly time steps in EnergyPlus.  In
    2129             :         // other words, this subroutine puts the current weather conditions
    2130             :         // into the proper variables.  Rather than using the same data for
    2131             :         // each time step, environment data is interpolated as a continuum
    2132             :         // throughout the day.
    2133             : 
    2134             :         // METHODOLOGY EMPLOYED:
    2135             :         // The current hour (DataGlobals::HourOfDay) as well as the next hour are used
    2136             :         // to come up with environment data per time step interval.  Method
    2137             :         // used is to assign a weighting for the current hour's data and
    2138             :         // (1-that weighting) to the next hour's data.  Actual method is:  if
    2139             :         // the current time step is 15 minutes into hour, the interpolated dry
    2140             :         // bulb temperature should be 3/4*dry bulb temperature of current hour
    2141             :         // and 1/4*dry bulb temperature of next environment hourly data.  At
    2142             :         // day boundary (current hour = 24), the next hour is hour 1 of next
    2143             :         // weather data day (Tomorrow%).
    2144             : 
    2145             :         static constexpr std::string_view RoutineName("SetCurrentWeather");
    2146             : 
    2147     2661169 :         state.dataWeatherManager->NextHour = state.dataGlobal->HourOfDay + 1;
    2148             : 
    2149     2661169 :         if (state.dataGlobal->HourOfDay == 24) { // Should investigate whether EndDayFlag is always set here and use that instead
    2150      114109 :             state.dataWeatherManager->NextHour = 1;
    2151             :         }
    2152             : 
    2153     2661169 :         if (state.dataGlobal->HourOfDay == 1) { // Should investigate whether DataGlobals::BeginDayFlag is always set here and use that instead
    2154      117798 :             state.dataEnvrn->DayOfYear_Schedule = General::OrdinalDay(state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, 1);
    2155             :         }
    2156             : 
    2157     2661169 :         ScheduleManager::UpdateScheduleValues(state);
    2158             : 
    2159    10644676 :         state.dataEnvrn->CurMnDyHr = fmt::format(
    2160    10644676 :             "{:02d}/{:02d} {:02d}", state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, (unsigned short)(state.dataGlobal->HourOfDay - 1));
    2161     5322338 :         state.dataEnvrn->CurMnDy = fmt::format("{:02d}/{:02d}", state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth);
    2162     5322338 :         state.dataEnvrn->CurMnDyYr =
    2163     7983507 :             fmt::format("{:02d}/{:02d}/{:04d}", state.dataEnvrn->Month, state.dataEnvrn->DayOfMonth, state.dataGlobal->CalendarYear);
    2164             : 
    2165     2661169 :         state.dataGlobal->WeightNow = state.dataWeatherManager->Interpolation(state.dataGlobal->TimeStep);
    2166     2661169 :         state.dataGlobal->WeightPreviousHour = 1.0 - state.dataGlobal->WeightNow;
    2167             : 
    2168     2661169 :         state.dataGlobal->CurrentTime = (state.dataGlobal->HourOfDay - 1) + state.dataGlobal->TimeStep * (state.dataWeatherManager->TimeStepFraction);
    2169     7983507 :         state.dataGlobal->SimTimeSteps = (state.dataGlobal->DayOfSim - 1) * 24 * state.dataGlobal->NumOfTimeStepInHour +
    2170     5322338 :                                          (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->NumOfTimeStepInHour + state.dataGlobal->TimeStep;
    2171             : 
    2172     2661169 :         state.dataEnvrn->GroundTemp =
    2173     2661169 :             state.dataWeatherManager->siteBuildingSurfaceGroundTempsPtr->getGroundTempAtTimeInMonths(state, 0, state.dataEnvrn->Month);
    2174     2661169 :         state.dataEnvrn->GroundTempKelvin = state.dataEnvrn->GroundTemp + DataGlobalConstants::KelvinConv;
    2175     2661169 :         state.dataEnvrn->GroundTempFC =
    2176     2661169 :             state.dataWeatherManager->siteFCFactorMethodGroundTempsPtr->getGroundTempAtTimeInMonths(state, 0, state.dataEnvrn->Month);
    2177     2661169 :         state.dataEnvrn->GroundTemp_Surface =
    2178     2661169 :             state.dataWeatherManager->siteShallowGroundTempsPtr->getGroundTempAtTimeInMonths(state, 0, state.dataEnvrn->Month);
    2179     2661169 :         state.dataEnvrn->GroundTemp_Deep =
    2180     2661169 :             state.dataWeatherManager->siteDeepGroundTempsPtr->getGroundTempAtTimeInMonths(state, 0, state.dataEnvrn->Month);
    2181     2661169 :         state.dataEnvrn->GndReflectance = state.dataWeatherManager->GroundReflectances(state.dataEnvrn->Month);
    2182     2661169 :         state.dataEnvrn->GndReflectanceForDayltg = state.dataEnvrn->GndReflectance;
    2183             : 
    2184     2661169 :         CalcWaterMainsTemp(state);
    2185             : 
    2186             :         // Determine if Sun is up or down, set Solar Cosine values for time step.
    2187     2661169 :         DetermineSunUpDown(state, state.dataEnvrn->SOLCOS);
    2188     2661169 :         if (state.dataEnvrn->SunIsUp && state.dataWeatherManager->SolarAltitudeAngle < 0.0) {
    2189           0 :             ShowFatalError(state, "SetCurrentWeather: At " + state.dataEnvrn->CurMnDyHr + " Sun is Up but Solar Altitude Angle is < 0.0");
    2190             :         }
    2191             : 
    2192     2661169 :         state.dataEnvrn->OutDryBulbTemp = state.dataWeatherManager->TodayOutDryBulbTemp(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2193     2661169 :         if (state.dataEnvrn->EMSOutDryBulbOverrideOn) state.dataEnvrn->OutDryBulbTemp = state.dataEnvrn->EMSOutDryBulbOverrideValue;
    2194     2661169 :         state.dataEnvrn->OutBaroPress = state.dataWeatherManager->TodayOutBaroPress(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2195     2661169 :         state.dataEnvrn->OutDewPointTemp = state.dataWeatherManager->TodayOutDewPointTemp(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2196     2661169 :         if (state.dataEnvrn->EMSOutDewPointTempOverrideOn) state.dataEnvrn->OutDewPointTemp = state.dataEnvrn->EMSOutDewPointTempOverrideValue;
    2197     2661169 :         state.dataEnvrn->OutRelHum = state.dataWeatherManager->TodayOutRelHum(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2198     2661169 :         state.dataEnvrn->OutRelHumValue = state.dataEnvrn->OutRelHum / 100.0;
    2199     2661169 :         if (state.dataEnvrn->EMSOutRelHumOverrideOn) {
    2200           0 :             state.dataEnvrn->OutRelHumValue = state.dataEnvrn->EMSOutRelHumOverrideValue / 100.0;
    2201           0 :             state.dataEnvrn->OutRelHum = state.dataEnvrn->EMSOutRelHumOverrideValue;
    2202             :         }
    2203             : 
    2204             :         // Humidity Ratio and Wet Bulb are derived
    2205     7983507 :         state.dataEnvrn->OutHumRat = Psychrometrics::PsyWFnTdbRhPb(
    2206     7983507 :             state, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutRelHumValue, state.dataEnvrn->OutBaroPress, RoutineName);
    2207     2661169 :         state.dataEnvrn->OutWetBulbTemp =
    2208     5322338 :             Psychrometrics::PsyTwbFnTdbWPb(state, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    2209     2661169 :         if (state.dataEnvrn->OutDryBulbTemp < state.dataEnvrn->OutWetBulbTemp) {
    2210      918977 :             state.dataEnvrn->OutWetBulbTemp = state.dataEnvrn->OutDryBulbTemp;
    2211     3675908 :             Real64 TempVal = Psychrometrics::PsyWFnTdbTwbPb(
    2212     3675908 :                 state, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutWetBulbTemp, state.dataEnvrn->OutBaroPress);
    2213      918977 :             state.dataEnvrn->OutDewPointTemp = Psychrometrics::PsyTdpFnWPb(state, TempVal, state.dataEnvrn->OutBaroPress);
    2214             :         }
    2215             : 
    2216     2661169 :         if (state.dataEnvrn->OutDewPointTemp > state.dataEnvrn->OutWetBulbTemp) {
    2217      969350 :             state.dataEnvrn->OutDewPointTemp = state.dataEnvrn->OutWetBulbTemp;
    2218             :         }
    2219             : 
    2220     2796064 :         if ((state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::DesignDay) ||
    2221      134895 :             (state.dataGlobal->KindOfSim == DataGlobalConstants::KindOfSim::HVACSizeDesignDay)) {
    2222     2555968 :             state.dataWeatherManager->SPSiteDryBulbRangeModScheduleValue = -999.0;   // N/A Drybulb Temperature Range Modifier Schedule Value
    2223     2555968 :             state.dataWeatherManager->SPSiteHumidityConditionScheduleValue = -999.0; // N/A Humidity Condition Schedule Value
    2224     2555968 :             state.dataWeatherManager->SPSiteBeamSolarScheduleValue = -999.0;         // N/A Beam Solar Schedule Value
    2225     2555968 :             state.dataWeatherManager->SPSiteDiffuseSolarScheduleValue = -999.0;      // N/A Diffuse Solar Schedule Value
    2226     2555968 :             state.dataWeatherManager->SPSiteSkyTemperatureScheduleValue = -999.0;    // N/A SkyTemperature Modifier Schedule Value
    2227             : 
    2228     2555968 :             int const envrnDayNum(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).DesignDayNum);
    2229     2555968 :             if (state.dataWeatherManager->DesDayInput(envrnDayNum).DBTempRangeType != DDDBRangeType::Default) {
    2230        9234 :                 state.dataWeatherManager->SPSiteDryBulbRangeModScheduleValue(envrnDayNum) =
    2231        9234 :                     state.dataWeatherManager->DDDBRngModifier(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, envrnDayNum);
    2232             :             }
    2233     2555968 :             DDHumIndType const &humIndType{state.dataWeatherManager->DesDayInput(envrnDayNum).HumIndType};
    2234     5101811 :             if (humIndType == DDHumIndType::WBProfDef || humIndType == DDHumIndType::WBProfDif || humIndType == DDHumIndType::WBProfMul ||
    2235     2545843 :                 humIndType == DDHumIndType::RelHumSch) {
    2236       15606 :                 state.dataWeatherManager->SPSiteHumidityConditionScheduleValue(envrnDayNum) =
    2237       15606 :                     state.dataWeatherManager->DDHumIndModifier(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, envrnDayNum);
    2238             :             }
    2239     2555968 :             if (state.dataWeatherManager->DesDayInput(envrnDayNum).SolarModel == DesignDaySolarModel::SolarModel_Schedule) {
    2240        5289 :                 state.dataWeatherManager->SPSiteBeamSolarScheduleValue(envrnDayNum) =
    2241        5289 :                     state.dataWeatherManager->DDBeamSolarValues(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, envrnDayNum);
    2242        5289 :                 state.dataWeatherManager->SPSiteDiffuseSolarScheduleValue(envrnDayNum) =
    2243        5289 :                     state.dataWeatherManager->DDDiffuseSolarValues(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, envrnDayNum);
    2244             :             }
    2245     7666077 :             if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::ScheduleValue ||
    2246     5110109 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::DryBulbDelta ||
    2247     2554141 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::DewPointDelta) {
    2248        1827 :                 state.dataWeatherManager->SPSiteSkyTemperatureScheduleValue(envrnDayNum) =
    2249        1827 :                     state.dataWeatherManager->DDSkyTempScheduleValues(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay, envrnDayNum);
    2250             :             }
    2251      105201 :         } else if (state.dataEnvrn->TotDesDays > 0) {
    2252      105201 :             state.dataWeatherManager->SPSiteDryBulbRangeModScheduleValue = -999.0;   // N/A Drybulb Temperature Range Modifier Schedule Value
    2253      105201 :             state.dataWeatherManager->SPSiteHumidityConditionScheduleValue = -999.0; // N/A Humidity Condition Schedule Value
    2254      105201 :             state.dataWeatherManager->SPSiteBeamSolarScheduleValue = -999.0;         // N/A Beam Solar Schedule Value
    2255      105201 :             state.dataWeatherManager->SPSiteDiffuseSolarScheduleValue = -999.0;      // N/A Diffuse Solar Schedule Value
    2256      105201 :             state.dataWeatherManager->SPSiteSkyTemperatureScheduleValue = -999.0;    // N/A SkyTemperature Modifier Schedule Value
    2257             :         }
    2258             : 
    2259     2661169 :         state.dataEnvrn->WindSpeed = state.dataWeatherManager->TodayWindSpeed(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2260     2661169 :         if (state.dataEnvrn->EMSWindSpeedOverrideOn) state.dataEnvrn->WindSpeed = state.dataEnvrn->EMSWindSpeedOverrideValue;
    2261     2661169 :         state.dataEnvrn->WindDir = state.dataWeatherManager->TodayWindDir(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2262     2661169 :         if (state.dataEnvrn->EMSWindDirOverrideOn) state.dataEnvrn->WindDir = state.dataEnvrn->EMSWindDirOverrideValue;
    2263     2661169 :         state.dataWeatherManager->HorizIRSky = state.dataWeatherManager->TodayHorizIRSky(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2264     2661169 :         state.dataEnvrn->SkyTemp = state.dataWeatherManager->TodaySkyTemp(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2265     2661169 :         state.dataEnvrn->SkyTempKelvin = state.dataEnvrn->SkyTemp + DataGlobalConstants::KelvinConv;
    2266     2661169 :         state.dataEnvrn->DifSolarRad = state.dataWeatherManager->TodayDifSolarRad(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2267     2661169 :         if (state.dataEnvrn->EMSDifSolarRadOverrideOn) state.dataEnvrn->DifSolarRad = state.dataEnvrn->EMSDifSolarRadOverrideValue;
    2268     2661169 :         state.dataEnvrn->BeamSolarRad = state.dataWeatherManager->TodayBeamSolarRad(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2269     2661169 :         if (state.dataEnvrn->EMSBeamSolarRadOverrideOn) state.dataEnvrn->BeamSolarRad = state.dataEnvrn->EMSBeamSolarRadOverrideValue;
    2270     2661169 :         state.dataEnvrn->LiquidPrecipitation =
    2271     2661169 :             state.dataWeatherManager->TodayLiquidPrecip(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay) / 1000.0; // convert from mm to m
    2272     2661169 :         if ((state.dataEnvrn->RunPeriodEnvironment) && (!state.dataGlobal->WarmupFlag)) {
    2273       70176 :             int month = state.dataEnvrn->Month;
    2274       70176 :             state.dataWaterData->RainFall.MonthlyTotalPrecInWeather.at(month - 1) += state.dataEnvrn->LiquidPrecipitation * 1000.0;
    2275       70176 :             if ((state.dataEnvrn->LiquidPrecipitation > 0) && (state.dataGlobal->TimeStep == 1)) {
    2276         253 :                 state.dataWaterData->RainFall.numRainyHoursInWeather.at(month - 1) += 1;
    2277             :             }
    2278             :         }
    2279             : 
    2280     2661169 :         WaterManager::UpdatePrecipitation(state);
    2281             : 
    2282     2661169 :         state.dataEnvrn->TotalCloudCover = state.dataWeatherManager->TodayTotalSkyCover(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2283     2661169 :         state.dataEnvrn->OpaqueCloudCover = state.dataWeatherManager->TodayOpaqueSkyCover(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2284             : 
    2285     2661169 :         if (state.dataWeatherManager->UseRainValues) {
    2286             :             // It is set as LiquidPrecipitation >= .8 mm here: state.dataWeatherManager->TomorrowLiquidPrecip(ts, hour) >=
    2287             :             // state.dataWeatherManager->IsRainThreshold;
    2288     2627122 :             state.dataEnvrn->IsRain = state.dataWeatherManager->TodayIsRain(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2289     2627122 :             if (state.dataWaterData->RainFall.ModeID == DataWater::RainfallMode::RainSchedDesign && state.dataEnvrn->RunPeriodEnvironment) {
    2290             :                 // CurrentAmount unit: m
    2291           0 :                 state.dataEnvrn->IsRain = state.dataWaterData->RainFall.CurrentAmount >= (state.dataWeatherManager->IsRainThreshold / 1000.0);
    2292             :             }
    2293             :         } else {
    2294       34047 :             state.dataEnvrn->IsRain = false;
    2295             :         }
    2296     2661169 :         if (state.dataWeatherManager->UseSnowValues) {
    2297     2627122 :             state.dataEnvrn->IsSnow = state.dataWeatherManager->TodayIsSnow(state.dataGlobal->TimeStep, state.dataGlobal->HourOfDay);
    2298             :         } else {
    2299       34047 :             state.dataEnvrn->IsSnow = false;
    2300             :         }
    2301             : 
    2302     2661169 :         if (state.dataEnvrn->IsSnow) {
    2303           0 :             state.dataEnvrn->GndReflectance = max(min(state.dataEnvrn->GndReflectance * state.dataWeatherManager->SnowGndRefModifier, 1.0), 0.0);
    2304           0 :             state.dataEnvrn->GndReflectanceForDayltg =
    2305           0 :                 max(min(state.dataEnvrn->GndReflectanceForDayltg * state.dataWeatherManager->SnowGndRefModifierForDayltg, 1.0), 0.0);
    2306             :         }
    2307             : 
    2308     2661169 :         state.dataEnvrn->GndSolarRad =
    2309     2661169 :             max((state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad) * state.dataEnvrn->GndReflectance, 0.0);
    2310             : 
    2311     2661169 :         if (!state.dataEnvrn->SunIsUp) {
    2312     1326427 :             state.dataEnvrn->DifSolarRad = 0.0;
    2313     1326427 :             state.dataEnvrn->BeamSolarRad = 0.0;
    2314     1326427 :             state.dataEnvrn->GndSolarRad = 0.0;
    2315             :         }
    2316             : 
    2317     2661169 :         state.dataEnvrn->OutEnthalpy = Psychrometrics::PsyHFnTdbW(state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
    2318     2661169 :         state.dataEnvrn->OutAirDensity =
    2319     5322338 :             Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
    2320             : 
    2321     2661169 :         if (state.dataEnvrn->OutDryBulbTemp < state.dataEnvrn->OutWetBulbTemp) state.dataEnvrn->OutWetBulbTemp = state.dataEnvrn->OutDryBulbTemp;
    2322     2661169 :         if (state.dataEnvrn->OutDewPointTemp > state.dataEnvrn->OutWetBulbTemp) state.dataEnvrn->OutDewPointTemp = state.dataEnvrn->OutWetBulbTemp;
    2323             : 
    2324     2661169 :         DayltgCurrentExtHorizIllum(state);
    2325             : 
    2326     2661169 :         if (!state.dataEnvrn->IsRain) {
    2327     2660381 :             state.dataWeatherManager->RptIsRain = 0;
    2328             :         } else {
    2329         788 :             state.dataWeatherManager->RptIsRain = 1;
    2330             :         }
    2331             : 
    2332     2661169 :         if (!state.dataEnvrn->IsSnow) {
    2333     2661169 :             state.dataWeatherManager->RptIsSnow = 0;
    2334             :         } else {
    2335           0 :             state.dataWeatherManager->RptIsSnow = 1;
    2336             :         }
    2337     2661169 :     }
    2338             : 
    2339        2357 :     void ReadWeatherForDay(EnergyPlusData &state,
    2340             :                            int const DayToRead,          // =1 when starting out, otherwise signifies next day
    2341             :                            int const Environ,            // Environment being simulated
    2342             :                            bool const BackSpaceAfterRead // True if weather file is to be backspaced after read
    2343             :     )
    2344             :     {
    2345             : 
    2346             :         // SUBROUTINE INFORMATION:
    2347             :         //       AUTHOR         Linda K. Lawrie
    2348             :         //       DATE WRITTEN   April 1999
    2349             :         //       MODIFIED       na
    2350             :         //       RE-ENGINEERED  na
    2351             : 
    2352             :         // PURPOSE OF THIS SUBROUTINE:
    2353             :         // This subroutine is the driving routine behind reading the weather data.
    2354             :         // Theoretically, several kinds of weather files could be read here.  As
    2355             :         // distributed only EPW files are allowed.
    2356             : 
    2357        2357 :         ReadEPlusWeatherForDay(state, DayToRead, Environ, BackSpaceAfterRead);
    2358        2357 :     }
    2359             : 
    2360        2357 :     void ReadEPlusWeatherForDay(EnergyPlusData &state,
    2361             :                                 int const DayToRead,          // =1 when starting out, otherwise signifies next day
    2362             :                                 int const Environ,            // Environment being simulated
    2363             :                                 bool const BackSpaceAfterRead // True if weather file is to be backspaced after read
    2364             :     )
    2365             :     {
    2366             : 
    2367             :         // SUBROUTINE INFORMATION:
    2368             :         //       AUTHOR         Linda K. Lawrie
    2369             :         //       DATE WRITTEN   April 1999
    2370             :         //       MODIFIED       March 2012; add actual weather read.
    2371             :         //       RE-ENGINEERED  na
    2372             : 
    2373             :         // PURPOSE OF THIS SUBROUTINE:
    2374             :         // This subroutine reads the appropriate day of EPW weather data.
    2375             : 
    2376             :         int WYear;
    2377             :         int WMonth;
    2378             :         int WDay;
    2379             :         int WHour;
    2380             :         int WMinute;
    2381             :         Real64 DryBulb;
    2382             :         Real64 DewPoint;
    2383             :         Real64 RelHum;
    2384             :         Real64 AtmPress;
    2385             :         Real64 ETHoriz;
    2386             :         Real64 ETDirect;
    2387             :         Real64 IRHoriz;
    2388             :         Real64 GLBHoriz;
    2389             :         Real64 DirectRad;
    2390             :         Real64 DiffuseRad;
    2391             :         Real64 GLBHorizIllum;
    2392             :         Real64 DirectNrmIllum;
    2393             :         Real64 DiffuseHorizIllum;
    2394             :         Real64 ZenLum;
    2395             :         Real64 WindDir;
    2396             :         Real64 WindSpeed;
    2397             :         Real64 TotalSkyCover;
    2398             :         Real64 OpaqueSkyCover;
    2399             :         Real64 Visibility;
    2400             :         Real64 CeilHeight;
    2401             :         Real64 PrecipWater;
    2402             :         Real64 AerosolOptDepth;
    2403             :         Real64 SnowDepth;
    2404             :         Real64 DaysSinceLastSnow;
    2405             :         Real64 Albedo;
    2406             :         Real64 LiquidPrecip;
    2407             :         int PresWeathObs;
    2408        4714 :         Array1D_int PresWeathConds(9);
    2409             : 
    2410        2357 :         struct HourlyWeatherData
    2411             :         {
    2412             :             // Members
    2413             :             Array1D_bool IsRain;             // Rain indicator, true=rain
    2414             :             Array1D_bool IsSnow;             // Snow indicator, true=snow
    2415             :             Array1D<Real64> OutDryBulbTemp;  // Hourly dry bulb temperature of outside air
    2416             :             Array1D<Real64> OutDewPointTemp; // Hourly Dew Point Temperature of outside air
    2417             :             Array1D<Real64> OutBaroPress;    // Hourly barometric pressure of outside air
    2418             :             Array1D<Real64> OutRelHum;       // Hourly relative humidity
    2419             :             Array1D<Real64> WindSpeed;       // Hourly wind speed of outside air
    2420             :             Array1D<Real64> WindDir;         // Hourly wind direction of outside air
    2421             :             Array1D<Real64> SkyTemp;         // Hourly sky temperature
    2422             :             Array1D<Real64> HorizIRSky;      // Hourly Horizontal Infrared Radiation Intensity
    2423             :             Array1D<Real64> BeamSolarRad;    // Hourly direct normal solar irradiance
    2424             :             Array1D<Real64> DifSolarRad;     // Hourly sky diffuse horizontal solar irradiance
    2425             :             Array1D<Real64> Albedo;          // Albedo
    2426             :             Array1D<Real64> LiquidPrecip;    // Liquid Precipitation
    2427             :             Array1D<Real64> TotalSkyCover;   // Total Sky Cover
    2428             :             Array1D<Real64> OpaqueSkyCover;  // Opaque Sky Cover
    2429             : 
    2430             :             // Default Constructor
    2431        2357 :             HourlyWeatherData()
    2432        2357 :                 : IsRain(24, false), IsSnow(24, false), OutDryBulbTemp(24, 0.0), OutDewPointTemp(24, 0.0), OutBaroPress(24, 0.0), OutRelHum(24, 0.0),
    2433             :                   WindSpeed(24, 0.0), WindDir(24, 0.0), SkyTemp(24, 0.0), HorizIRSky(24, 0.0), BeamSolarRad(24, 0.0), DifSolarRad(24, 0.0),
    2434        2357 :                   Albedo(24, 0.0), LiquidPrecip(24, 0.0), TotalSkyCover(24, 0.0), OpaqueSkyCover(24, 0.0)
    2435             :             {
    2436        2357 :             }
    2437             :         };
    2438             : 
    2439        4714 :         HourlyWeatherData Wthr;
    2440             : 
    2441        2357 :         if (DayToRead == 1) {
    2442             : 
    2443             :             // Checks whether Weather file contains just one year of data. If yes then rewind and position to first
    2444             :             // day of weather file. The rest of code appropriately positions to the start day.
    2445             : 
    2446        1186 :             bool Ready = false;
    2447        1186 :             int NumRewinds = 0;
    2448             :             //     Must position file to proper day
    2449             :             //     File already position to first data record
    2450             :             //          Set Current Day of Week to "start of Data Period"
    2451        1186 :             state.dataWeatherManager->ReadEPlusWeatherCurTime = 1.0 / double(state.dataWeatherManager->NumIntervalsPerHour);
    2452        1186 :             state.dataWeatherManager->CurDayOfWeek = state.dataWeatherManager->DataPeriods(1).WeekDay - 1;
    2453        1186 :             WYear = 0;
    2454        1186 :             WMonth = 0;
    2455        1186 :             WDay = 0;
    2456        1186 :             WHour = 0;
    2457        1186 :             WMinute = 0;
    2458        1186 :             state.dataWeatherManager->LastHourSet = false;
    2459        2372 :             InputFile::ReadResult<std::string> WeatherDataLine{"", true, false};
    2460      187002 :             while (!Ready) {
    2461       92908 :                 WeatherDataLine.update(state.files.inputWeatherFile.readLine());
    2462       92908 :                 if (WeatherDataLine.good) {
    2463             :                     bool ErrorFound;
    2464       92908 :                     InterpretWeatherDataLine(state,
    2465             :                                              WeatherDataLine.data,
    2466             :                                              ErrorFound,
    2467             :                                              WYear,
    2468             :                                              WMonth,
    2469             :                                              WDay,
    2470             :                                              WHour,
    2471             :                                              WMinute,
    2472             :                                              DryBulb,
    2473             :                                              DewPoint,
    2474             :                                              RelHum,
    2475             :                                              AtmPress,
    2476             :                                              ETHoriz,
    2477             :                                              ETDirect,
    2478             :                                              IRHoriz,
    2479             :                                              GLBHoriz,
    2480             :                                              DirectRad,
    2481             :                                              DiffuseRad,
    2482             :                                              GLBHorizIllum,
    2483             :                                              DirectNrmIllum,
    2484             :                                              DiffuseHorizIllum,
    2485             :                                              ZenLum,
    2486             :                                              WindDir,
    2487             :                                              WindSpeed,
    2488             :                                              TotalSkyCover,
    2489             :                                              OpaqueSkyCover,
    2490             :                                              Visibility,
    2491             :                                              CeilHeight,
    2492             :                                              PresWeathObs,
    2493             :                                              PresWeathConds,
    2494             :                                              PrecipWater,
    2495             :                                              AerosolOptDepth,
    2496             :                                              SnowDepth,
    2497             :                                              DaysSinceLastSnow,
    2498             :                                              Albedo,
    2499             :                                              LiquidPrecip);
    2500           0 :                 } else if (WeatherDataLine.eof) {
    2501           0 :                     if (NumRewinds > 0) {
    2502           0 :                         std::string date = fmt::to_string(state.dataWeatherManager->Environment(Environ).StartMonth) + '/' +
    2503           0 :                                            fmt::to_string(state.dataWeatherManager->Environment(Environ).StartDay);
    2504           0 :                         if (state.dataWeatherManager->Environment(Environ).MatchYear) {
    2505           0 :                             date += '/' + fmt::to_string(state.dataWeatherManager->Environment(Environ).StartYear);
    2506             :                         }
    2507           0 :                         ShowSevereError(state, "Multiple rewinds on EPW while searching for first day " + date);
    2508             :                     } else {
    2509           0 :                         state.files.inputWeatherFile.rewind();
    2510           0 :                         ++NumRewinds;
    2511           0 :                         SkipEPlusWFHeader(state);
    2512           0 :                         WeatherDataLine.update(state.files.inputWeatherFile.readLine());
    2513             :                         bool ErrorFound;
    2514           0 :                         InterpretWeatherDataLine(state,
    2515             :                                                  WeatherDataLine.data,
    2516             :                                                  ErrorFound,
    2517             :                                                  WYear,
    2518             :                                                  WMonth,
    2519             :                                                  WDay,
    2520             :                                                  WHour,
    2521             :                                                  WMinute,
    2522             :                                                  DryBulb,
    2523             :                                                  DewPoint,
    2524             :                                                  RelHum,
    2525             :                                                  AtmPress,
    2526             :                                                  ETHoriz,
    2527             :                                                  ETDirect,
    2528             :                                                  IRHoriz,
    2529             :                                                  GLBHoriz,
    2530             :                                                  DirectRad,
    2531             :                                                  DiffuseRad,
    2532             :                                                  GLBHorizIllum,
    2533             :                                                  DirectNrmIllum,
    2534             :                                                  DiffuseHorizIllum,
    2535             :                                                  ZenLum,
    2536             :                                                  WindDir,
    2537             :                                                  WindSpeed,
    2538             :                                                  TotalSkyCover,
    2539             :                                                  OpaqueSkyCover,
    2540             :                                                  Visibility,
    2541             :                                                  CeilHeight,
    2542             :                                                  PresWeathObs,
    2543             :                                                  PresWeathConds,
    2544             :                                                  PrecipWater,
    2545             :                                                  AerosolOptDepth,
    2546             :                                                  SnowDepth,
    2547             :                                                  DaysSinceLastSnow,
    2548             :                                                  Albedo,
    2549             :                                                  LiquidPrecip);
    2550             :                     }
    2551             :                 }
    2552       92908 :                 if (!WeatherDataLine.good) {
    2553           0 :                     ShowFatalError(state,
    2554           0 :                                    format("Error occurred on EPW while searching for first day, stopped at {}/{}/{} {}:{} IO Error='{}'",
    2555             :                                           WYear,
    2556             :                                           WMonth,
    2557             :                                           WDay,
    2558             :                                           WHour,
    2559             :                                           WMinute,
    2560           0 :                                           state.files.inputWeatherFile.error_state_to_string()),
    2561           0 :                                    OptionalOutputFileRef{state.files.eso});
    2562             :                 }
    2563       92908 :                 if (state.dataWeatherManager->CurDayOfWeek <= 7) {
    2564       92908 :                     state.dataWeatherManager->CurDayOfWeek = mod(state.dataWeatherManager->CurDayOfWeek, 7) + 1;
    2565             :                 }
    2566             :                 bool RecordDateMatch =
    2567      100592 :                     (WMonth == state.dataWeatherManager->Environment(Environ).StartMonth &&
    2568      187002 :                      WDay == state.dataWeatherManager->Environment(Environ).StartDay && !state.dataWeatherManager->Environment(Environ).MatchYear) ||
    2569       98220 :                     (WMonth == state.dataWeatherManager->Environment(Environ).StartMonth &&
    2570        6498 :                      WDay == state.dataWeatherManager->Environment(Environ).StartDay && state.dataWeatherManager->Environment(Environ).MatchYear &&
    2571       92908 :                      WYear == state.dataWeatherManager->Environment(Environ).StartYear);
    2572       92908 :                 if (RecordDateMatch) {
    2573        1186 :                     state.files.inputWeatherFile.backspace();
    2574        1186 :                     Ready = true;
    2575        1186 :                     if (state.dataWeatherManager->CurDayOfWeek <= 7) {
    2576        1186 :                         --state.dataWeatherManager->CurDayOfWeek;
    2577             :                     }
    2578             :                     // Do the range checks on the first set of fields -- no others.
    2579        1186 :                     bool ErrorsFound = false;
    2580        1186 :                     if (DryBulb >= 99.9)
    2581           0 :                         state.dataInputProcessing->inputProcessor->rangeCheck(state,
    2582             :                                                                               ErrorsFound,
    2583             :                                                                               "DryBulb Temperature",
    2584             :                                                                               "WeatherFile",
    2585             :                                                                               "Severe",
    2586             :                                                                               ">= -90",
    2587             :                                                                               (DryBulb >= -90.0),
    2588             :                                                                               "<= 70",
    2589             :                                                                               (DryBulb <= 70.0),
    2590           0 :                                                                               format("{:.2R}", DryBulb),
    2591           0 :                                                                               state.dataEnvrn->WeatherFileLocationTitle);
    2592        1186 :                     if (DewPoint < 99.9)
    2593        3558 :                         state.dataInputProcessing->inputProcessor->rangeCheck(state,
    2594             :                                                                               ErrorsFound,
    2595             :                                                                               "DewPoint Temperature",
    2596             :                                                                               "WeatherFile",
    2597             :                                                                               "Severe",
    2598             :                                                                               ">= -90",
    2599             :                                                                               (DewPoint >= -90.0),
    2600             :                                                                               "<= 70",
    2601             :                                                                               (DewPoint <= 70.0),
    2602        2372 :                                                                               format("{:.2R}", DewPoint),
    2603        1186 :                                                                               state.dataEnvrn->WeatherFileLocationTitle);
    2604        1186 :                     if (RelHum < 999.0)
    2605        3558 :                         state.dataInputProcessing->inputProcessor->rangeCheck(state,
    2606             :                                                                               ErrorsFound,
    2607             :                                                                               "Relative Humidity",
    2608             :                                                                               "WeatherFile",
    2609             :                                                                               "Severe",
    2610             :                                                                               "> 0",
    2611             :                                                                               (RelHum >= 0.0),
    2612             :                                                                               "<= 110",
    2613             :                                                                               (RelHum <= 110.0),
    2614        2372 :                                                                               format("{:.0R}", RelHum),
    2615        1186 :                                                                               state.dataEnvrn->WeatherFileLocationTitle);
    2616        1186 :                     if (AtmPress < 999999.0)
    2617        3558 :                         state.dataInputProcessing->inputProcessor->rangeCheck(state,
    2618             :                                                                               ErrorsFound,
    2619             :                                                                               "Atmospheric Pressure",
    2620             :                                                                               "WeatherFile",
    2621             :                                                                               "Severe",
    2622             :                                                                               "> 31000",
    2623             :                                                                               (AtmPress > 31000.0),
    2624             :                                                                               "<=120000",
    2625             :                                                                               (AtmPress <= 120000.0),
    2626        2372 :                                                                               format("{:.0R}", AtmPress),
    2627        1186 :                                                                               state.dataEnvrn->WeatherFileLocationTitle);
    2628        1186 :                     if (DirectRad < 9999.0)
    2629        3558 :                         state.dataInputProcessing->inputProcessor->lowerRangeCheck(state,
    2630             :                                                                                    ErrorsFound,
    2631             :                                                                                    "Direct Radiation",
    2632             :                                                                                    "WeatherFile",
    2633             :                                                                                    "Severe",
    2634             :                                                                                    ">= 0",
    2635             :                                                                                    (DirectRad >= 0.0),
    2636             :                                                                                    {},
    2637        2372 :                                                                                    state.dataEnvrn->WeatherFileLocationTitle);
    2638        1186 :                     if (DiffuseRad < 9999.0)
    2639        3558 :                         state.dataInputProcessing->inputProcessor->lowerRangeCheck(state,
    2640             :                                                                                    ErrorsFound,
    2641             :                                                                                    "Diffuse Radiation",
    2642             :                                                                                    "WeatherFile",
    2643             :                                                                                    "Severe",
    2644             :                                                                                    ">= 0",
    2645             :                                                                                    (DiffuseRad >= 0.0),
    2646             :                                                                                    {},
    2647        2372 :                                                                                    state.dataEnvrn->WeatherFileLocationTitle);
    2648        1186 :                     if (WindDir < 999.0)
    2649        3558 :                         state.dataInputProcessing->inputProcessor->rangeCheck(state,
    2650             :                                                                               ErrorsFound,
    2651             :                                                                               "Wind Direction",
    2652             :                                                                               "WeatherFile",
    2653             :                                                                               "Severe",
    2654             :                                                                               ">=0",
    2655             :                                                                               (WindDir >= 0.0),
    2656             :                                                                               "<=360",
    2657             :                                                                               (WindDir <= 360.0),
    2658        2372 :                                                                               format("{:.0R}", WindDir),
    2659        1186 :                                                                               state.dataEnvrn->WeatherFileLocationTitle);
    2660        1186 :                     if (WindSpeed < 999.0)
    2661        3558 :                         state.dataInputProcessing->inputProcessor->rangeCheck(state,
    2662             :                                                                               ErrorsFound,
    2663             :                                                                               "Wind Speed",
    2664             :                                                                               "WeatherFile",
    2665             :                                                                               "Severe",
    2666             :                                                                               ">=0",
    2667             :                                                                               (WindSpeed >= 0.0),
    2668             :                                                                               "<=40",
    2669             :                                                                               (WindSpeed <= 40.0),
    2670        2372 :                                                                               format("{:.2R}", WindSpeed),
    2671        1186 :                                                                               state.dataEnvrn->WeatherFileLocationTitle);
    2672        1186 :                     if (ErrorsFound) {
    2673           0 :                         ShowSevereError(state, "Out of Range errors found with initial day of WeatherFile");
    2674             :                     }
    2675             :                 } else {
    2676             :                     //  Must skip this day
    2677       91722 :                     for (int i = 2; i <= state.dataWeatherManager->NumIntervalsPerHour; ++i) {
    2678           0 :                         WeatherDataLine.update(state.files.inputWeatherFile.readLine());
    2679           0 :                         if (!WeatherDataLine.good) {
    2680           0 :                             readList(WeatherDataLine.data, WYear, WMonth, WDay, WHour, WMinute);
    2681           0 :                             ShowFatalError(state,
    2682           0 :                                            format("Error occurred on EPW while searching for first day, stopped at {}/{}/{} {}:{} IO Error='{}'",
    2683             :                                                   WYear,
    2684             :                                                   WMonth,
    2685             :                                                   WDay,
    2686             :                                                   WHour,
    2687             :                                                   WMinute,
    2688           0 :                                                   state.files.inputWeatherFile.error_state_to_string()),
    2689           0 :                                            OptionalOutputFileRef{state.files.eso});
    2690             :                         }
    2691             :                     }
    2692     2201328 :                     for (int i = 1; i <= 23 * state.dataWeatherManager->NumIntervalsPerHour; ++i) {
    2693     2109606 :                         WeatherDataLine.update(state.files.inputWeatherFile.readLine());
    2694     2109606 :                         if (!WeatherDataLine.good) {
    2695           0 :                             readList(WeatherDataLine.data, WYear, WMonth, WDay, WHour, WMinute);
    2696           0 :                             ShowFatalError(state,
    2697           0 :                                            format("Error occurred on EPW while searching for first day, stopped at {}/{}/{} {}:{} IO Error='{}'",
    2698             :                                                   WYear,
    2699             :                                                   WMonth,
    2700             :                                                   WDay,
    2701             :                                                   WHour,
    2702             :                                                   WMinute,
    2703           0 :                                                   state.files.inputWeatherFile.error_state_to_string()),
    2704           0 :                                            OptionalOutputFileRef{state.files.eso});
    2705             :                         }
    2706             :                     }
    2707             :                 }
    2708             :             }
    2709             : 
    2710             :             // Positioned to proper day
    2711        1193 :             if (!state.dataGlobal->KickOffSimulation && !state.dataGlobal->DoingSizing &&
    2712           7 :                 state.dataWeatherManager->Environment(Environ).KindOfEnvrn == DataGlobalConstants::KindOfSim::RunPeriodWeather) {
    2713           2 :                 ++state.dataWeatherManager->Environment(Environ).CurrentCycle;
    2714           2 :                 if (!state.dataWeatherManager->Environment(Environ).RollDayTypeOnRepeat) {
    2715           0 :                     SetDayOfWeekInitialValues(state.dataWeatherManager->Environment(Environ).DayOfWeek, state.dataWeatherManager->CurDayOfWeek);
    2716           0 :                     if (state.dataWeatherManager->DaylightSavingIsActive) {
    2717           0 :                         SetDSTDateRanges(state,
    2718           0 :                                          state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).MonWeekDay,
    2719           0 :                                          state.dataWeatherManager->DSTIndex);
    2720             :                     }
    2721           0 :                     SetSpecialDayDates(state, state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).MonWeekDay);
    2722           2 :                 } else if (state.dataWeatherManager->Environment(Environ).CurrentCycle == 1) {
    2723           2 :                     SetDayOfWeekInitialValues(state.dataWeatherManager->Environment(Environ).DayOfWeek, state.dataWeatherManager->CurDayOfWeek);
    2724           2 :                     state.dataWeatherManager->Environment(Environ).SetWeekDays = true;
    2725           2 :                     if (state.dataWeatherManager->DaylightSavingIsActive) {
    2726           3 :                         SetDSTDateRanges(state,
    2727           1 :                                          state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).MonWeekDay,
    2728           1 :                                          state.dataWeatherManager->DSTIndex);
    2729             :                     }
    2730           2 :                     SetSpecialDayDates(state, state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).MonWeekDay);
    2731             :                 } else {
    2732           0 :                     state.dataWeatherManager->CurDayOfWeek = state.dataEnvrn->DayOfWeekTomorrow;
    2733             :                 }
    2734             :             } else {
    2735        1184 :                 SetDayOfWeekInitialValues(state.dataWeatherManager->Environment(Environ).DayOfWeek, state.dataWeatherManager->CurDayOfWeek);
    2736             :             }
    2737             :         }
    2738             : 
    2739        2357 :         bool TryAgain = true;
    2740        2357 :         bool SkipThisDay = false;
    2741             : 
    2742        7071 :         while (TryAgain) {
    2743             : 
    2744        2357 :             TryAgain = false;
    2745             : 
    2746        2357 :             state.dataWeatherManager->TomorrowOutDryBulbTemp = 0.0;
    2747        2357 :             state.dataWeatherManager->TomorrowOutDewPointTemp = 0.0;
    2748        2357 :             state.dataWeatherManager->TomorrowOutBaroPress = 0.0;
    2749        2357 :             state.dataWeatherManager->TomorrowOutRelHum = 0.0;
    2750        2357 :             state.dataWeatherManager->TomorrowWindSpeed = 0.0;
    2751        2357 :             state.dataWeatherManager->TomorrowWindDir = 0.0;
    2752        2357 :             state.dataWeatherManager->TomorrowSkyTemp = 0.0;
    2753        2357 :             state.dataWeatherManager->TomorrowHorizIRSky = 0.0;
    2754        2357 :             state.dataWeatherManager->TomorrowBeamSolarRad = 0.0;
    2755        2357 :             state.dataWeatherManager->TomorrowDifSolarRad = 0.0;
    2756        2357 :             state.dataWeatherManager->TomorrowAlbedo = 0.0;
    2757        2357 :             state.dataWeatherManager->TomorrowLiquidPrecip = 0.0;
    2758        2357 :             state.dataWeatherManager->TomorrowIsRain = false;
    2759        2357 :             state.dataWeatherManager->TomorrowIsSnow = false;
    2760             : 
    2761       58925 :             for (int hour = 1; hour <= 24; ++hour) {
    2762      113136 :                 for (int CurTimeStep = 1; CurTimeStep <= state.dataWeatherManager->NumIntervalsPerHour; ++CurTimeStep) {
    2763      113136 :                     auto WeatherDataLine = state.files.inputWeatherFile.readLine();
    2764       56568 :                     if (!WeatherDataLine.good) WeatherDataLine.data.clear();
    2765       56568 :                     if (WeatherDataLine.data.empty()) {
    2766           0 :                         if (hour == 1) {
    2767           0 :                             WeatherDataLine.eof = true;
    2768           0 :                             WeatherDataLine.good = false;
    2769             :                         } else {
    2770           0 :                             WeatherDataLine.good = false;
    2771             :                         }
    2772             :                     }
    2773       56568 :                     if (WeatherDataLine.good) {
    2774             :                         bool ErrorFound;
    2775       56568 :                         InterpretWeatherDataLine(state,
    2776             :                                                  WeatherDataLine.data,
    2777             :                                                  ErrorFound,
    2778             :                                                  WYear,
    2779             :                                                  WMonth,
    2780             :                                                  WDay,
    2781             :                                                  WHour,
    2782             :                                                  WMinute,
    2783             :                                                  DryBulb,
    2784             :                                                  DewPoint,
    2785             :                                                  RelHum,
    2786             :                                                  AtmPress,
    2787             :                                                  ETHoriz,
    2788             :                                                  ETDirect,
    2789             :                                                  IRHoriz,
    2790             :                                                  GLBHoriz,
    2791             :                                                  DirectRad,
    2792             :                                                  DiffuseRad,
    2793             :                                                  GLBHorizIllum,
    2794             :                                                  DirectNrmIllum,
    2795             :                                                  DiffuseHorizIllum,
    2796             :                                                  ZenLum,
    2797             :                                                  WindDir,
    2798             :                                                  WindSpeed,
    2799             :                                                  TotalSkyCover,
    2800             :                                                  OpaqueSkyCover,
    2801             :                                                  Visibility,
    2802             :                                                  CeilHeight,
    2803             :                                                  PresWeathObs,
    2804             :                                                  PresWeathConds,
    2805             :                                                  PrecipWater,
    2806             :                                                  AerosolOptDepth,
    2807             :                                                  SnowDepth,
    2808             :                                                  DaysSinceLastSnow,
    2809             :                                                  Albedo,
    2810             :                                                  LiquidPrecip);
    2811             :                     } else { // ReadStatus /=0
    2812           0 :                         if (WeatherDataLine.eof &&
    2813           0 :                             state.dataWeatherManager->NumDataPeriods == 1) { // Standard End-of-file, rewind and position to first day...
    2814           0 :                             if (state.dataWeatherManager->DataPeriods(1).NumDays >= state.dataWeatherManager->NumDaysInYear) {
    2815           0 :                                 state.files.inputWeatherFile.rewind();
    2816           0 :                                 SkipEPlusWFHeader(state);
    2817           0 :                                 WeatherDataLine.update(state.files.inputWeatherFile.readLine());
    2818             :                                 bool ErrorFound;
    2819           0 :                                 InterpretWeatherDataLine(state,
    2820             :                                                          WeatherDataLine.data,
    2821             :                                                          ErrorFound,
    2822             :                                                          WYear,
    2823             :                                                          WMonth,
    2824             :                                                          WDay,
    2825             :                                                          WHour,
    2826             :                                                          WMinute,
    2827             :                                                          DryBulb,
    2828             :                                                          DewPoint,
    2829             :                                                          RelHum,
    2830             :                                                          AtmPress,
    2831             :                                                          ETHoriz,
    2832             :                                                          ETDirect,
    2833             :                                                          IRHoriz,
    2834             :                                                          GLBHoriz,
    2835             :                                                          DirectRad,
    2836             :                                                          DiffuseRad,
    2837             :                                                          GLBHorizIllum,
    2838             :                                                          DirectNrmIllum,
    2839             :                                                          DiffuseHorizIllum,
    2840             :                                                          ZenLum,
    2841             :                                                          WindDir,
    2842             :                                                          WindSpeed,
    2843             :                                                          TotalSkyCover,
    2844             :                                                          OpaqueSkyCover,
    2845             :                                                          Visibility,
    2846             :                                                          CeilHeight,
    2847             :                                                          PresWeathObs,
    2848             :                                                          PresWeathConds,
    2849             :                                                          PrecipWater,
    2850             :                                                          AerosolOptDepth,
    2851             :                                                          SnowDepth,
    2852             :                                                          DaysSinceLastSnow,
    2853             :                                                          Albedo,
    2854             :                                                          LiquidPrecip);
    2855             :                             } else {
    2856           0 :                                 ShowFatalError(state,
    2857           0 :                                                format("End-of-File encountered after {}/{}/{} {}:{}, starting from first day of Weather File would "
    2858             :                                                       "not be \"next day\"",
    2859             :                                                       WYear,
    2860             :                                                       WMonth,
    2861             :                                                       WDay,
    2862             :                                                       WHour,
    2863           0 :                                                       WMinute));
    2864             :                             }
    2865             :                         } else {
    2866           0 :                             ShowFatalError(state,
    2867           0 :                                            format("Unexpected error condition in middle of reading EPW file, stopped at {}/{}/{} {}:{}",
    2868             :                                                   WYear,
    2869             :                                                   WMonth,
    2870             :                                                   WDay,
    2871             :                                                   WHour,
    2872           0 :                                                   WMinute),
    2873           0 :                                            OptionalOutputFileRef{state.files.eso});
    2874             :                         }
    2875             :                     }
    2876             : 
    2877       56568 :                     if (hour != WHour) {
    2878           0 :                         ShowFatalError(state,
    2879           0 :                                        format("Unexpected error condition in middle of reading EPW file, stopped at {}/{}/{} {}:{}",
    2880             :                                               WYear,
    2881             :                                               WMonth,
    2882             :                                               WDay,
    2883             :                                               WHour,
    2884           0 :                                               WMinute),
    2885           0 :                                        OptionalOutputFileRef{state.files.eso});
    2886             :                     }
    2887             : 
    2888             :                     //         Set possible missing values
    2889       56568 :                     if (ETHoriz < 0.0) ETHoriz = 9999.0;
    2890       56568 :                     if (ETDirect < 0.0) ETDirect = 9999.0;
    2891       56568 :                     if (IRHoriz <= 0.0) IRHoriz = 9999.0;
    2892       56568 :                     if (GLBHoriz < 0.0) GLBHoriz = 9999.0;
    2893       56568 :                     if (state.dataEnvrn->DisplayWeatherMissingDataWarnings) {
    2894           0 :                         if (DirectRad >= 9999.0) {
    2895           0 :                             ++state.dataWeatherManager->Missed.DirectRad;
    2896             :                         }
    2897           0 :                         if (DiffuseRad >= 9999.0) {
    2898           0 :                             state.dataWeatherManager->Missed.DiffuseRad = state.dataWeatherManager->Missed.DirectRad + 1;
    2899             :                         }
    2900           0 :                         if (DirectRad < 0.0) {
    2901           0 :                             DirectRad = 9999.0;
    2902           0 :                             ++state.dataWeatherManager->OutOfRange.DirectRad;
    2903             :                         }
    2904           0 :                         if (DiffuseRad < 0.0) {
    2905           0 :                             DiffuseRad = 9999.0;
    2906           0 :                             ++state.dataWeatherManager->OutOfRange.DiffuseRad;
    2907             :                         }
    2908             :                     }
    2909       56568 :                     if (GLBHorizIllum < 0.0) GLBHorizIllum = 999999.0;
    2910       56568 :                     if (DirectNrmIllum < 0.0) DirectNrmIllum = 999999.0;
    2911       56568 :                     if (DiffuseHorizIllum < 0.0) DiffuseHorizIllum = 999999.0;
    2912       56568 :                     if (ZenLum < 0.0) ZenLum = 99999.0;
    2913       56568 :                     if (AtmPress < 0.0) AtmPress = 999999.0;
    2914       56568 :                     if (WindSpeed < 0.0) WindSpeed = 999.0;
    2915       56568 :                     if (WindDir < -360.0 || WindDir > 360.0) WindDir = 999.0;
    2916       56568 :                     if (TotalSkyCover < 0.0) TotalSkyCover = 99.0;
    2917       56568 :                     if (RelHum < 0.0) RelHum = 999.0;
    2918       56568 :                     if (OpaqueSkyCover < 0.0) OpaqueSkyCover = 99.0;
    2919       56568 :                     if (Visibility < 0.0) Visibility = 9999.0;
    2920       56568 :                     if (CeilHeight < 0.0) CeilHeight = 9999.0;
    2921       56568 :                     if (PresWeathObs < 0) PresWeathObs = 9;
    2922       56568 :                     if (PrecipWater < 0.0) PrecipWater = 999.0;
    2923       56568 :                     if (AerosolOptDepth < 0.0) AerosolOptDepth = 999.0;
    2924       56568 :                     if (SnowDepth < 0.0) SnowDepth = 999.0;
    2925       56568 :                     if (DaysSinceLastSnow < 0.0) DaysSinceLastSnow = 99.0;
    2926       56568 :                     if (Albedo < 0.0) Albedo = 999.0;
    2927       56568 :                     if (LiquidPrecip < 0.0) LiquidPrecip = 999.0;
    2928             : 
    2929       56568 :                     if (hour == 1 && CurTimeStep == 1) {
    2930        2357 :                         if (WMonth == 2 && WDay == 29 && (!state.dataEnvrn->CurrentYearIsLeapYear || !state.dataWeatherManager->WFAllowsLeapYears)) {
    2931           0 :                             state.dataWeatherManager->EndDayOfMonth(2) = 28;
    2932           0 :                             SkipThisDay = true;
    2933           0 :                             TryAgain = true;
    2934           0 :                             ShowWarningError(state, "ReadEPlusWeatherForDay: Feb29 data encountered but will not be processed.");
    2935           0 :                             if (!state.dataWeatherManager->WFAllowsLeapYears) {
    2936           0 :                                 ShowContinueError(
    2937             :                                     state, "...WeatherFile does not allow Leap Years. HOLIDAYS/DAYLIGHT SAVINGS header must indicate \"Yes\".");
    2938             :                             }
    2939           0 :                             continue;
    2940             :                         } else {
    2941        2357 :                             TryAgain = false;
    2942        2357 :                             SkipThisDay = false;
    2943             :                         }
    2944             : 
    2945        2357 :                         if (state.dataWeatherManager->Environment(Environ).ActualWeather && state.dataEnvrn->CurrentYearIsLeapYear) {
    2946           0 :                             if (WMonth == 3 && WDay == 1 && state.dataEnvrn->Month == 2 && state.dataEnvrn->DayOfMonth == 28) {
    2947           0 :                                 ShowFatalError(state, "ReadEPlusWeatherForDay: Current year is a leap year, but Feb29 data is missing.");
    2948             :                             }
    2949             :                         }
    2950             : 
    2951        2357 :                         state.dataWeatherManager->TomorrowVariables.Year = WYear;
    2952        2357 :                         state.dataWeatherManager->TomorrowVariables.Month = WMonth;
    2953        2357 :                         state.dataWeatherManager->TomorrowVariables.DayOfMonth = WDay;
    2954        2357 :                         state.dataWeatherManager->TomorrowVariables.DayOfYear =
    2955        2357 :                             General::OrdinalDay(WMonth, WDay, state.dataWeatherManager->LeapYearAdd);
    2956        2357 :                         state.dataWeatherManager->TomorrowVariables.DayOfYear_Schedule = General::OrdinalDay(WMonth, WDay, 1);
    2957             :                         Real64 A;
    2958             :                         Real64 B;
    2959             :                         Real64 C;
    2960             :                         Real64 AVSC;
    2961        9428 :                         CalculateDailySolarCoeffs(state,
    2962        2357 :                                                   state.dataWeatherManager->TomorrowVariables.DayOfYear,
    2963             :                                                   A,
    2964             :                                                   B,
    2965             :                                                   C,
    2966             :                                                   AVSC,
    2967        2357 :                                                   state.dataWeatherManager->TomorrowVariables.EquationOfTime,
    2968        2357 :                                                   state.dataWeatherManager->TomorrowVariables.SinSolarDeclinAngle,
    2969        2357 :                                                   state.dataWeatherManager->TomorrowVariables.CosSolarDeclinAngle);
    2970        2357 :                         if (state.dataWeatherManager->CurDayOfWeek <= 7) {
    2971        2257 :                             state.dataWeatherManager->CurDayOfWeek = mod(state.dataWeatherManager->CurDayOfWeek, 7) + 1;
    2972             :                         }
    2973        2357 :                         state.dataWeatherManager->TomorrowVariables.DayOfWeek = state.dataWeatherManager->CurDayOfWeek;
    2974        2357 :                         state.dataWeatherManager->TomorrowVariables.DaylightSavingIndex =
    2975        2357 :                             state.dataWeatherManager->DSTIndex(state.dataWeatherManager->TomorrowVariables.DayOfYear);
    2976        2357 :                         state.dataWeatherManager->TomorrowVariables.HolidayIndex =
    2977        2357 :                             state.dataWeatherManager->SpecialDayTypes(state.dataWeatherManager->TomorrowVariables.DayOfYear);
    2978             :                     }
    2979             : 
    2980       56568 :                     if (SkipThisDay) continue;
    2981             : 
    2982             :                     // Check out missing values
    2983             : 
    2984       56568 :                     if (DryBulb >= 99.9) {
    2985           0 :                         DryBulb = state.dataWeatherManager->Missing.DryBulb;
    2986           0 :                         ++state.dataWeatherManager->Missed.DryBulb;
    2987             :                     }
    2988       56568 :                     if (DryBulb < -90.0 || DryBulb > 70.0) {
    2989           0 :                         ++state.dataWeatherManager->OutOfRange.DryBulb;
    2990             :                     }
    2991             : 
    2992       56568 :                     if (DewPoint >= 99.9) {
    2993           0 :                         DewPoint = state.dataWeatherManager->Missing.DewPoint;
    2994           0 :                         ++state.dataWeatherManager->Missed.DewPoint;
    2995             :                     }
    2996       56568 :                     if (DewPoint < -90.0 || DewPoint > 70.0) {
    2997           0 :                         ++state.dataWeatherManager->OutOfRange.DewPoint;
    2998             :                     }
    2999             : 
    3000       56568 :                     if (RelHum >= 999.0) {
    3001           0 :                         RelHum = state.dataWeatherManager->Missing.RelHumid;
    3002           0 :                         ++state.dataWeatherManager->Missed.RelHumid;
    3003             :                     }
    3004       56568 :                     if (RelHum < 0.0 || RelHum > 110.0) {
    3005           0 :                         ++state.dataWeatherManager->OutOfRange.RelHumid;
    3006             :                     }
    3007             : 
    3008       56568 :                     if (AtmPress >= 999999.0) {
    3009           0 :                         AtmPress = state.dataWeatherManager->Missing.StnPres;
    3010           0 :                         ++state.dataWeatherManager->Missed.StnPres;
    3011             :                     }
    3012       56568 :                     if (AtmPress <= 31000.0 || AtmPress > 120000.0) {
    3013           0 :                         ++state.dataWeatherManager->OutOfRange.StnPres;
    3014           0 :                         AtmPress = state.dataWeatherManager->Missing.StnPres;
    3015             :                     }
    3016             : 
    3017       56568 :                     if (WindDir >= 999.0) {
    3018           0 :                         WindDir = state.dataWeatherManager->Missing.WindDir;
    3019           0 :                         ++state.dataWeatherManager->Missed.WindDir;
    3020             :                     }
    3021       56568 :                     if (WindDir < 0.0 || WindDir > 360.0) {
    3022           0 :                         ++state.dataWeatherManager->OutOfRange.WindDir;
    3023             :                     }
    3024             : 
    3025       56568 :                     if (WindSpeed >= 999.0) {
    3026           0 :                         WindSpeed = state.dataWeatherManager->Missing.WindSpd;
    3027           0 :                         ++state.dataWeatherManager->Missed.WindSpd;
    3028             :                     }
    3029       56568 :                     if (WindSpeed < 0.0 || WindSpeed > 40.0) {
    3030           0 :                         ++state.dataWeatherManager->OutOfRange.WindSpd;
    3031             :                     }
    3032             : 
    3033       56568 :                     if (TotalSkyCover >= 99.0) {
    3034           0 :                         TotalSkyCover = state.dataWeatherManager->Missing.TotSkyCvr;
    3035           0 :                         ++state.dataWeatherManager->Missed.TotSkyCvr;
    3036             :                     }
    3037             : 
    3038       56568 :                     if (OpaqueSkyCover >= 99.0) {
    3039           0 :                         OpaqueSkyCover = state.dataWeatherManager->Missing.OpaqSkyCvr;
    3040           0 :                         ++state.dataWeatherManager->Missed.OpaqSkyCvr;
    3041             :                     }
    3042             : 
    3043       56568 :                     if (SnowDepth >= 999.0) {
    3044          72 :                         SnowDepth = state.dataWeatherManager->Missing.SnowDepth;
    3045          72 :                         ++state.dataWeatherManager->Missed.SnowDepth;
    3046             :                     }
    3047             : 
    3048       56568 :                     if (Albedo >= 999.0) {
    3049       41064 :                         Albedo = state.dataWeatherManager->Missing.Albedo;
    3050       41064 :                         ++state.dataWeatherManager->Missed.Albedo;
    3051             :                     }
    3052             : 
    3053       56568 :                     if (LiquidPrecip >= 999.0) {
    3054       41723 :                         LiquidPrecip = state.dataWeatherManager->Missing.LiquidPrecip;
    3055       41723 :                         ++state.dataWeatherManager->Missed.LiquidPrecip;
    3056             :                     }
    3057             : 
    3058       56568 :                     state.dataWeatherManager->TomorrowOutDryBulbTemp(CurTimeStep, hour) = DryBulb;
    3059       56568 :                     state.dataWeatherManager->TomorrowOutDewPointTemp(CurTimeStep, hour) = DewPoint;
    3060       56568 :                     state.dataWeatherManager->TomorrowOutBaroPress(CurTimeStep, hour) = AtmPress;
    3061       56568 :                     state.dataWeatherManager->TomorrowOutRelHum(CurTimeStep, hour) = RelHum;
    3062       56568 :                     RelHum *= 0.01;
    3063       56568 :                     state.dataWeatherManager->TomorrowWindSpeed(CurTimeStep, hour) = WindSpeed;
    3064       56568 :                     state.dataWeatherManager->TomorrowWindDir(CurTimeStep, hour) = WindDir;
    3065       56568 :                     state.dataWeatherManager->TomorrowLiquidPrecip(CurTimeStep, hour) = LiquidPrecip;
    3066       56568 :                     state.dataWeatherManager->TomorrowTotalSkyCover(CurTimeStep, hour) = TotalSkyCover;
    3067       56568 :                     state.dataWeatherManager->TomorrowOpaqueSkyCover(CurTimeStep, hour) = OpaqueSkyCover;
    3068             : 
    3069      113136 :                     calcSky(state,
    3070       56568 :                             state.dataWeatherManager->TomorrowHorizIRSky(CurTimeStep, hour),
    3071       56568 :                             state.dataWeatherManager->TomorrowSkyTemp(CurTimeStep, hour),
    3072             :                             OpaqueSkyCover,
    3073             :                             DryBulb,
    3074             :                             DewPoint,
    3075             :                             RelHum,
    3076             :                             IRHoriz);
    3077             : 
    3078       56568 :                     if (ETHoriz >= 9999.0) ETHoriz = 0.0;
    3079       56568 :                     if (ETDirect >= 9999.0) ETDirect = 0.0;
    3080       56568 :                     if (GLBHoriz >= 9999.0) GLBHoriz = 0.0;
    3081       56568 :                     if (DirectRad >= 9999.0) DirectRad = 0.0;
    3082       56568 :                     if (DiffuseRad >= 9999.0) DiffuseRad = 0.0;
    3083       56568 :                     if (GLBHorizIllum >= 999900.0) GLBHorizIllum = 0.0;
    3084       56568 :                     if (DirectNrmIllum >= 999900.0) DirectNrmIllum = 0.0;
    3085       56568 :                     if (DiffuseHorizIllum >= 999900.0) DiffuseHorizIllum = 0.0;
    3086       56568 :                     if (ZenLum >= 99990.0) ZenLum = 0.0;
    3087       56568 :                     if (state.dataEnvrn->IgnoreSolarRadiation) {
    3088           0 :                         GLBHoriz = 0.0;
    3089           0 :                         DirectRad = 0.0;
    3090           0 :                         DiffuseRad = 0.0;
    3091             :                     }
    3092       56568 :                     if (state.dataEnvrn->IgnoreBeamRadiation) {
    3093           0 :                         DirectRad = 0.0;
    3094             :                     }
    3095       56568 :                     if (state.dataEnvrn->IgnoreDiffuseRadiation) {
    3096           0 :                         DiffuseRad = 0.0;
    3097             :                     }
    3098             : 
    3099       56568 :                     state.dataWeatherManager->TomorrowBeamSolarRad(CurTimeStep, hour) = DirectRad;
    3100       56568 :                     state.dataWeatherManager->TomorrowDifSolarRad(CurTimeStep, hour) = DiffuseRad;
    3101             : 
    3102       56568 :                     state.dataWeatherManager->TomorrowIsRain(CurTimeStep, hour) = false;
    3103       56568 :                     if (PresWeathObs == 0) {
    3104         144 :                         if (PresWeathConds(1) < 9 || PresWeathConds(2) < 9 || PresWeathConds(3) < 9)
    3105           0 :                             state.dataWeatherManager->TomorrowIsRain(CurTimeStep, hour) = true;
    3106             :                     } else {
    3107       56424 :                         state.dataWeatherManager->TomorrowIsRain(CurTimeStep, hour) = false;
    3108             :                     }
    3109       56568 :                     state.dataWeatherManager->TomorrowIsSnow(CurTimeStep, hour) = (SnowDepth > 0.0);
    3110             : 
    3111             :                     // default if rain but none on weather file
    3112       56568 :                     if (state.dataWeatherManager->TomorrowIsRain(CurTimeStep, hour) &&
    3113           0 :                         state.dataWeatherManager->TomorrowLiquidPrecip(CurTimeStep, hour) == 0.0)
    3114           0 :                         state.dataWeatherManager->TomorrowLiquidPrecip(CurTimeStep, hour) = 2.0; // 2mm in an hour ~ .08 inch
    3115             : 
    3116       56568 :                     state.dataWeatherManager->Missing.DryBulb = DryBulb;
    3117       56568 :                     state.dataWeatherManager->Missing.DewPoint = DewPoint;
    3118       56568 :                     state.dataWeatherManager->Missing.RelHumid = static_cast<int>(std::round(RelHum * 100.0));
    3119       56568 :                     state.dataWeatherManager->Missing.StnPres = AtmPress;
    3120       56568 :                     state.dataWeatherManager->Missing.WindDir = WindDir;
    3121       56568 :                     state.dataWeatherManager->Missing.WindSpd = WindSpeed;
    3122       56568 :                     state.dataWeatherManager->Missing.TotSkyCvr = TotalSkyCover;
    3123       56568 :                     state.dataWeatherManager->Missing.OpaqSkyCvr = OpaqueSkyCover;
    3124       56568 :                     state.dataWeatherManager->Missing.Visibility = Visibility;
    3125       56568 :                     state.dataWeatherManager->Missing.Ceiling = CeilHeight;
    3126       56568 :                     state.dataWeatherManager->Missing.PrecipWater = PrecipWater;
    3127       56568 :                     state.dataWeatherManager->Missing.AerOptDepth = AerosolOptDepth;
    3128       56568 :                     state.dataWeatherManager->Missing.SnowDepth = SnowDepth;
    3129       56568 :                     state.dataWeatherManager->Missing.DaysLastSnow = DaysSinceLastSnow;
    3130       56568 :                     state.dataWeatherManager->Missing.Albedo = Albedo;
    3131             : 
    3132             :                 } // CurTimeStep Loop
    3133             : 
    3134             :             } // Hour Loop
    3135             : 
    3136             :         } // Try Again While Loop
    3137             : 
    3138        2357 :         if (BackSpaceAfterRead) {
    3139           0 :             state.files.inputWeatherFile.backspace();
    3140             :         }
    3141             : 
    3142        2357 :         if (state.dataWeatherManager->NumIntervalsPerHour == 1 && state.dataGlobal->NumOfTimeStepInHour > 1) {
    3143             :             // Create interpolated weather for timestep orientation
    3144             :             // First copy ts=1 (hourly) from data arrays to Wthr structure
    3145       49550 :             for (int hour = 1; hour <= 24; ++hour) {
    3146       47568 :                 Wthr.OutDryBulbTemp(hour) = state.dataWeatherManager->TomorrowOutDryBulbTemp(1, hour);
    3147       47568 :                 Wthr.OutDewPointTemp(hour) = state.dataWeatherManager->TomorrowOutDewPointTemp(1, hour);
    3148       47568 :                 Wthr.OutBaroPress(hour) = state.dataWeatherManager->TomorrowOutBaroPress(1, hour);
    3149       47568 :                 Wthr.OutRelHum(hour) = state.dataWeatherManager->TomorrowOutRelHum(1, hour);
    3150       47568 :                 Wthr.WindSpeed(hour) = state.dataWeatherManager->TomorrowWindSpeed(1, hour);
    3151       47568 :                 Wthr.WindDir(hour) = state.dataWeatherManager->TomorrowWindDir(1, hour);
    3152       47568 :                 Wthr.SkyTemp(hour) = state.dataWeatherManager->TomorrowSkyTemp(1, hour);
    3153       47568 :                 Wthr.HorizIRSky(hour) = state.dataWeatherManager->TomorrowHorizIRSky(1, hour);
    3154       47568 :                 Wthr.BeamSolarRad(hour) = state.dataWeatherManager->TomorrowBeamSolarRad(1, hour);
    3155       47568 :                 Wthr.DifSolarRad(hour) = state.dataWeatherManager->TomorrowDifSolarRad(1, hour);
    3156       47568 :                 Wthr.IsRain(hour) = state.dataWeatherManager->TomorrowIsRain(1, hour);
    3157       47568 :                 Wthr.IsSnow(hour) = state.dataWeatherManager->TomorrowIsSnow(1, hour);
    3158       47568 :                 Wthr.Albedo(hour) = state.dataWeatherManager->TomorrowAlbedo(1, hour);
    3159       47568 :                 Wthr.LiquidPrecip(hour) = state.dataWeatherManager->TomorrowLiquidPrecip(1, hour);
    3160       47568 :                 Wthr.TotalSkyCover(hour) = state.dataWeatherManager->TomorrowTotalSkyCover(1, hour);
    3161       47568 :                 Wthr.OpaqueSkyCover(hour) = state.dataWeatherManager->TomorrowOpaqueSkyCover(1, hour);
    3162             :             }
    3163             : 
    3164        1982 :             if (!state.dataWeatherManager->LastHourSet) {
    3165             :                 // For first day of weather, all time steps of the first hour will be
    3166             :                 // equal to the first hour's value.
    3167             :                 // 2021-06: An additional input is added to here to allow the user to have chosen which hour to use
    3168        1175 :                 int HrUsedtoInterp = state.dataWeatherManager->Environment(Environ).firstHrInterpUseHr1 ? 1 : 24;
    3169             : 
    3170        1175 :                 state.dataWeatherManager->LastHrOutDryBulbTemp = Wthr.OutDryBulbTemp(HrUsedtoInterp);
    3171        1175 :                 state.dataWeatherManager->LastHrOutDewPointTemp = Wthr.OutDewPointTemp(HrUsedtoInterp);
    3172        1175 :                 state.dataWeatherManager->LastHrOutBaroPress = Wthr.OutBaroPress(HrUsedtoInterp);
    3173        1175 :                 state.dataWeatherManager->LastHrOutRelHum = Wthr.OutRelHum(HrUsedtoInterp);
    3174        1175 :                 state.dataWeatherManager->LastHrWindSpeed = Wthr.WindSpeed(HrUsedtoInterp);
    3175        1175 :                 state.dataWeatherManager->LastHrWindDir = Wthr.WindDir(HrUsedtoInterp);
    3176        1175 :                 state.dataWeatherManager->LastHrSkyTemp = Wthr.SkyTemp(HrUsedtoInterp);
    3177        1175 :                 state.dataWeatherManager->LastHrHorizIRSky = Wthr.HorizIRSky(HrUsedtoInterp);
    3178        1175 :                 state.dataWeatherManager->LastHrBeamSolarRad = Wthr.BeamSolarRad(HrUsedtoInterp);
    3179        1175 :                 state.dataWeatherManager->LastHrDifSolarRad = Wthr.DifSolarRad(HrUsedtoInterp);
    3180        1175 :                 state.dataWeatherManager->LastHrAlbedo = Wthr.Albedo(HrUsedtoInterp);
    3181        1175 :                 state.dataWeatherManager->LastHrLiquidPrecip = Wthr.LiquidPrecip(HrUsedtoInterp);
    3182        1175 :                 state.dataWeatherManager->LastHrTotalSkyCover = Wthr.TotalSkyCover(HrUsedtoInterp);
    3183        1175 :                 state.dataWeatherManager->LastHrOpaqueSkyCover = Wthr.OpaqueSkyCover(HrUsedtoInterp);
    3184             : 
    3185        1175 :                 state.dataWeatherManager->LastHourSet = true;
    3186             :             }
    3187             : 
    3188       49550 :             for (int hour = 1; hour <= 24; ++hour) {
    3189             : 
    3190       47568 :                 int NxtHour = hour + 1;
    3191       47568 :                 if (hour == 24) {
    3192        1982 :                     NxtHour = 1;
    3193             :                 }
    3194       47568 :                 state.dataWeatherManager->NextHrBeamSolarRad = Wthr.BeamSolarRad(NxtHour);
    3195       47568 :                 state.dataWeatherManager->NextHrDifSolarRad = Wthr.DifSolarRad(NxtHour);
    3196       47568 :                 state.dataWeatherManager->NextHrLiquidPrecip = Wthr.LiquidPrecip(NxtHour);
    3197             : 
    3198      283584 :                 for (int ts = 1; ts <= state.dataGlobal->NumOfTimeStepInHour; ++ts) {
    3199             : 
    3200      236016 :                     Real64 WtNow = state.dataWeatherManager->Interpolation(ts);
    3201      236016 :                     Real64 WtPrevHour = 1.0 - WtNow;
    3202             : 
    3203             :                     // Do Solar "weighting"
    3204             : 
    3205      236016 :                     Real64 WgtHourNow = state.dataWeatherManager->SolarInterpolation(ts);
    3206             :                     Real64 WgtPrevHour;
    3207             :                     Real64 WgtNextHour;
    3208             : 
    3209      236016 :                     if (state.dataGlobal->NumOfTimeStepInHour == 1) {
    3210           0 :                         WgtNextHour = 1.0 - WgtHourNow;
    3211           0 :                         WgtPrevHour = 0.0;
    3212             :                     } else {
    3213      236016 :                         if (WgtHourNow == 1.0) {
    3214             :                             //  It's at the half hour
    3215       47568 :                             WgtNextHour = 0.0;
    3216       47568 :                             WgtPrevHour = 0.0;
    3217      188448 :                         } else if (ts * state.dataWeatherManager->TimeStepFraction < 0.5) {
    3218       70440 :                             WgtNextHour = 0.0;
    3219       70440 :                             WgtPrevHour = 1.0 - WgtHourNow;
    3220             :                         } else { // After the half hour
    3221      118008 :                             WgtPrevHour = 0.0;
    3222      118008 :                             WgtNextHour = 1.0 - WgtHourNow;
    3223             :                         }
    3224             :                     }
    3225             : 
    3226      236016 :                     state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour) =
    3227      236016 :                         state.dataWeatherManager->LastHrOutDryBulbTemp * WtPrevHour + Wthr.OutDryBulbTemp(hour) * WtNow;
    3228      236016 :                     state.dataWeatherManager->TomorrowOutBaroPress(ts, hour) =
    3229      236016 :                         state.dataWeatherManager->LastHrOutBaroPress * WtPrevHour + Wthr.OutBaroPress(hour) * WtNow;
    3230      236016 :                     state.dataWeatherManager->TomorrowOutDewPointTemp(ts, hour) =
    3231      236016 :                         state.dataWeatherManager->LastHrOutDewPointTemp * WtPrevHour + Wthr.OutDewPointTemp(hour) * WtNow;
    3232      236016 :                     state.dataWeatherManager->TomorrowOutRelHum(ts, hour) =
    3233      236016 :                         state.dataWeatherManager->LastHrOutRelHum * WtPrevHour + Wthr.OutRelHum(hour) * WtNow;
    3234      236016 :                     state.dataWeatherManager->TomorrowWindSpeed(ts, hour) =
    3235      236016 :                         state.dataWeatherManager->LastHrWindSpeed * WtPrevHour + Wthr.WindSpeed(hour) * WtNow;
    3236      236016 :                     state.dataWeatherManager->TomorrowWindDir(ts, hour) =
    3237      236016 :                         interpolateWindDirection(state.dataWeatherManager->LastHrWindDir, Wthr.WindDir(hour), WtNow);
    3238      236016 :                     state.dataWeatherManager->TomorrowTotalSkyCover(ts, hour) =
    3239      236016 :                         state.dataWeatherManager->LastHrTotalSkyCover * WtPrevHour + Wthr.TotalSkyCover(hour) * WtNow;
    3240      236016 :                     state.dataWeatherManager->TomorrowOpaqueSkyCover(ts, hour) =
    3241      236016 :                         state.dataWeatherManager->LastHrOpaqueSkyCover * WtPrevHour + Wthr.OpaqueSkyCover(hour) * WtNow;
    3242             :                     // Sky emissivity now takes interpolated timestep inputs rather than interpolated calculation esky results
    3243     1416096 :                     calcSky(state,
    3244      236016 :                             state.dataWeatherManager->TomorrowHorizIRSky(ts, hour),
    3245      236016 :                             state.dataWeatherManager->TomorrowSkyTemp(ts, hour),
    3246      236016 :                             state.dataWeatherManager->TomorrowOpaqueSkyCover(ts, hour),
    3247      236016 :                             state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    3248      236016 :                             state.dataWeatherManager->TomorrowOutDewPointTemp(ts, hour),
    3249      236016 :                             state.dataWeatherManager->TomorrowOutRelHum(ts, hour) * 0.01,
    3250      236016 :                             state.dataWeatherManager->LastHrHorizIRSky * WtPrevHour + Wthr.HorizIRSky(hour) * WtNow);
    3251             : 
    3252      708048 :                     state.dataWeatherManager->TomorrowDifSolarRad(ts, hour) = state.dataWeatherManager->LastHrDifSolarRad * WgtPrevHour +
    3253      472032 :                                                                               Wthr.DifSolarRad(hour) * WgtHourNow +
    3254      236016 :                                                                               state.dataWeatherManager->NextHrDifSolarRad * WgtNextHour;
    3255      708048 :                     state.dataWeatherManager->TomorrowBeamSolarRad(ts, hour) = state.dataWeatherManager->LastHrBeamSolarRad * WgtPrevHour +
    3256      472032 :                                                                                Wthr.BeamSolarRad(hour) * WgtHourNow +
    3257      236016 :                                                                                state.dataWeatherManager->NextHrBeamSolarRad * WgtNextHour;
    3258             : 
    3259      236016 :                     state.dataWeatherManager->TomorrowLiquidPrecip(ts, hour) =
    3260      236016 :                         state.dataWeatherManager->LastHrLiquidPrecip * WtPrevHour + Wthr.LiquidPrecip(hour) * WtNow;
    3261      236016 :                     state.dataWeatherManager->TomorrowLiquidPrecip(ts, hour) /= double(state.dataGlobal->NumOfTimeStepInHour);
    3262      236016 :                     state.dataWeatherManager->TomorrowIsRain(ts, hour) =
    3263      236016 :                         state.dataWeatherManager->TomorrowLiquidPrecip(ts, hour) >= state.dataWeatherManager->IsRainThreshold; // Wthr%IsRain(Hour)
    3264      236016 :                     state.dataWeatherManager->TomorrowIsSnow(ts, hour) = Wthr.IsSnow(hour);
    3265             :                 } // End of TS Loop
    3266             : 
    3267       47568 :                 state.dataWeatherManager->LastHrOutDryBulbTemp = Wthr.OutDryBulbTemp(hour);
    3268       47568 :                 state.dataWeatherManager->LastHrOutDewPointTemp = Wthr.OutDewPointTemp(hour);
    3269       47568 :                 state.dataWeatherManager->LastHrOutBaroPress = Wthr.OutBaroPress(hour);
    3270       47568 :                 state.dataWeatherManager->LastHrOutRelHum = Wthr.OutRelHum(hour);
    3271       47568 :                 state.dataWeatherManager->LastHrWindSpeed = Wthr.WindSpeed(hour);
    3272       47568 :                 state.dataWeatherManager->LastHrWindDir = Wthr.WindDir(hour);
    3273       47568 :                 state.dataWeatherManager->LastHrHorizIRSky = Wthr.HorizIRSky(hour);
    3274       47568 :                 state.dataWeatherManager->LastHrSkyTemp = Wthr.SkyTemp(hour);
    3275       47568 :                 state.dataWeatherManager->LastHrBeamSolarRad = Wthr.BeamSolarRad(hour);
    3276       47568 :                 state.dataWeatherManager->LastHrDifSolarRad = Wthr.DifSolarRad(hour);
    3277       47568 :                 state.dataWeatherManager->LastHrAlbedo = Wthr.Albedo(hour);
    3278       47568 :                 state.dataWeatherManager->LastHrLiquidPrecip = Wthr.LiquidPrecip(hour);
    3279       47568 :                 state.dataWeatherManager->LastHrTotalSkyCover = Wthr.TotalSkyCover(hour);
    3280       47568 :                 state.dataWeatherManager->LastHrOpaqueSkyCover = Wthr.OpaqueSkyCover(hour);
    3281             :             } // End of Hour Loop
    3282             :         }
    3283             : 
    3284        2357 :         if (state.dataWeatherManager->Environment(Environ).WP_Type1 != 0) {
    3285           0 :             switch (state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(Environ).WP_Type1).CalculationType) {
    3286           0 :             case SkyTempCalcType::ScheduleValue:
    3287           0 :                 ScheduleManager::GetScheduleValuesForDay(
    3288             :                     state,
    3289           0 :                     state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(Environ).WP_Type1).SchedulePtr,
    3290           0 :                     state.dataWeatherManager->TomorrowSkyTemp,
    3291           0 :                     state.dataWeatherManager->TomorrowVariables.DayOfYear_Schedule,
    3292           0 :                     state.dataWeatherManager->CurDayOfWeek);
    3293           0 :                 break;
    3294           0 :             case SkyTempCalcType::DryBulbDelta:
    3295           0 :                 ScheduleManager::GetScheduleValuesForDay(
    3296             :                     state,
    3297           0 :                     state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(Environ).WP_Type1).SchedulePtr,
    3298           0 :                     state.dataWeatherManager->TomorrowSkyTemp,
    3299           0 :                     state.dataWeatherManager->TomorrowVariables.DayOfYear_Schedule,
    3300           0 :                     state.dataWeatherManager->CurDayOfWeek);
    3301           0 :                 for (int hour = 1; hour <= 24; ++hour) {
    3302           0 :                     for (int ts = 1; ts <= state.dataGlobal->NumOfTimeStepInHour; ++ts) {
    3303           0 :                         state.dataWeatherManager->TomorrowSkyTemp(ts, hour) =
    3304           0 :                             state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour) - state.dataWeatherManager->TomorrowSkyTemp(ts, hour);
    3305             :                     }
    3306           0 :                 }
    3307           0 :                 break;
    3308           0 :             case SkyTempCalcType::DewPointDelta:
    3309           0 :                 ScheduleManager::GetScheduleValuesForDay(
    3310             :                     state,
    3311           0 :                     state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(Environ).WP_Type1).SchedulePtr,
    3312           0 :                     state.dataWeatherManager->TomorrowSkyTemp,
    3313           0 :                     state.dataWeatherManager->TomorrowVariables.DayOfYear_Schedule,
    3314           0 :                     state.dataWeatherManager->CurDayOfWeek);
    3315           0 :                 for (int hour = 1; hour <= 24; ++hour) {
    3316           0 :                     for (int ts = 1; ts <= state.dataGlobal->NumOfTimeStepInHour; ++ts) {
    3317           0 :                         state.dataWeatherManager->TomorrowSkyTemp(ts, hour) =
    3318           0 :                             state.dataWeatherManager->TomorrowOutDewPointTemp(ts, hour) - state.dataWeatherManager->TomorrowSkyTemp(ts, hour);
    3319             :                     }
    3320           0 :                 }
    3321           0 :                 break;
    3322           0 :             default:
    3323           0 :                 break;
    3324             :             }
    3325             :         }
    3326        2357 :     }
    3327             : 
    3328      236016 :     Real64 interpolateWindDirection(Real64 const prevHrWindDir, Real64 const curHrWindDir, Real64 const curHrWeight)
    3329             :     {
    3330             :         // adapted from http://stackoverflow.com/questions/2708476/rotation-interpolation
    3331      236016 :         Real64 curAng = curHrWindDir;
    3332      236016 :         Real64 prevAng = prevHrWindDir;
    3333      236016 :         Real64 diff = std::abs(curAng - prevAng);
    3334      236016 :         if (diff > 180.) {
    3335       22696 :             if (curAng > prevAng) {
    3336        9916 :                 prevAng += 360.;
    3337             :             } else {
    3338       12780 :                 curAng += 360.;
    3339             :             }
    3340             :         }
    3341      236016 :         Real64 interpAng = prevAng + (curAng - prevAng) * curHrWeight;
    3342      236016 :         return (fmod(interpAng, 360.)); // fmod is float modulus function
    3343             :     }
    3344             : 
    3345      748656 :     Real64 CalcSkyEmissivity(EnergyPlusData &state,
    3346             :                              SkyTempCalcType const ESkyCalcType,
    3347             :                              Real64 const OSky,
    3348             :                              Real64 const DryBulb,
    3349             :                              Real64 const DewPoint,
    3350             :                              Real64 const RelHum)
    3351             :     {
    3352             :         // Calculate Sky Emissivity
    3353             :         // References:
    3354             :         // M. Li, Y. Jiang and C. F. M. Coimbra,
    3355             :         // "On the determination of atmospheric longwave irradiance under all-sky conditions,"
    3356             :         // Solar Energy 144, 2017, pp. 40–48,
    3357             :         // G. Clark and C. Allen, "The Estimation of Atmospheric Radiation for Clear and
    3358             :         // Cloudy Skies," Proc. 2nd National Passive Solar Conference (AS/ISES), 1978, pp. 675-678.
    3359             : 
    3360             :         Real64 ESky;
    3361             : 
    3362      748656 :         if (ESkyCalcType == SkyTempCalcType::BruntModel) {
    3363           0 :             double const PartialPress = RelHum * Psychrometrics::PsyPsatFnTemp(state, DryBulb) * 0.01;
    3364           0 :             ESky = 0.618 + 0.056 * pow(PartialPress, 0.5);
    3365      748656 :         } else if (ESkyCalcType == SkyTempCalcType::IdsoModel) {
    3366           0 :             double const PartialPress = RelHum * Psychrometrics::PsyPsatFnTemp(state, DryBulb) * 0.01;
    3367           0 :             ESky = 0.685 + 0.000032 * PartialPress * exp(1699 / (DryBulb + DataGlobalConstants::KelvinConv));
    3368      748656 :         } else if (ESkyCalcType == SkyTempCalcType::BerdahlMartinModel) {
    3369           0 :             double const TDewC = min(DryBulb, DewPoint);
    3370           0 :             ESky = 0.758 + 0.521 * (TDewC / 100) + 0.625 * pow_2(TDewC / 100);
    3371             :         } else {
    3372      748656 :             ESky = 0.787 + 0.764 * std::log((min(DryBulb, DewPoint) + DataGlobalConstants::KelvinConv) / DataGlobalConstants::KelvinConv);
    3373             :         }
    3374      748656 :         ESky = ESky * (1.0 + 0.0224 * OSky - 0.0035 * pow_2(OSky) + 0.00028 * pow_3(OSky));
    3375      748656 :         return ESky;
    3376             :     }
    3377             : 
    3378        1186 :     void SetDayOfWeekInitialValues(int const EnvironDayOfWeek, // Starting Day of Week for the (Weather) RunPeriod (User Input)
    3379             :                                    int &currentDayOfWeek       // Current Day of Week
    3380             :     )
    3381             :     {
    3382             : 
    3383             :         // SUBROUTINE INFORMATION:
    3384             :         //       AUTHOR         Linda Lawrie
    3385             :         //       DATE WRITTEN   March 2012
    3386             :         //       MODIFIED       na
    3387             :         //       RE-ENGINEERED  na
    3388             : 
    3389             :         // PURPOSE OF THIS SUBROUTINE:
    3390             :         // Set of begin day of week for an environment.  Similar sets but slightly different
    3391             :         // conditions.  Improve code readability by having three routine calls instead of three
    3392             :         // IF blocks.
    3393             : 
    3394        1186 :         if (EnvironDayOfWeek != 0) {
    3395        1186 :             if (EnvironDayOfWeek <= 7) {
    3396        1164 :                 currentDayOfWeek = EnvironDayOfWeek - 1;
    3397             :             } else {
    3398          22 :                 currentDayOfWeek = EnvironDayOfWeek;
    3399             :             }
    3400             :         }
    3401        1186 :     }
    3402             : 
    3403           0 :     void ErrorInterpretWeatherDataLine(EnergyPlusData &state,
    3404             :                                        int const WYear,
    3405             :                                        int const WMonth,
    3406             :                                        int const WDay,
    3407             :                                        int const WHour,
    3408             :                                        int const WMinute,
    3409             :                                        std::string_view SaveLine,
    3410             :                                        std::string_view Line)
    3411             :     {
    3412           0 :         ShowSevereError(state, fmt::format("Invalid Weather Line at date={:4}/{:2}/{:2} Hour#={:2} Min#={:2}", WYear, WMonth, WDay, WHour, WMinute));
    3413           0 :         ShowContinueError(state, fmt::format("Full Data Line={}", SaveLine));
    3414           0 :         ShowContinueError(state, fmt::format("Remainder of line={}", Line));
    3415           0 :         ShowFatalError(state, "Error in Reading Weather Data");
    3416           0 :     }
    3417             : 
    3418      228316 :     void InterpretWeatherDataLine(EnergyPlusData &state,
    3419             :                                   std::string_view Line,
    3420             :                                   bool &ErrorFound, // True if an error is found, false otherwise
    3421             :                                   int &WYear,
    3422             :                                   int &WMonth,
    3423             :                                   int &WDay,
    3424             :                                   int &WHour,
    3425             :                                   int &WMinute,
    3426             :                                   Real64 &DryBulb,
    3427             :                                   Real64 &DewPoint,
    3428             :                                   Real64 &RelHum,
    3429             :                                   Real64 &AtmPress,
    3430             :                                   Real64 &ETHoriz,
    3431             :                                   Real64 &ETDirect,
    3432             :                                   Real64 &IRHoriz,
    3433             :                                   Real64 &GLBHoriz,
    3434             :                                   Real64 &DirectRad,
    3435             :                                   Real64 &DiffuseRad,
    3436             :                                   Real64 &GLBHorizIllum,
    3437             :                                   Real64 &DirectNrmIllum,
    3438             :                                   Real64 &DiffuseHorizIllum,
    3439             :                                   Real64 &ZenLum,
    3440             :                                   Real64 &WindDir,
    3441             :                                   Real64 &WindSpeed,
    3442             :                                   Real64 &TotalSkyCover,
    3443             :                                   Real64 &OpaqueSkyCover,
    3444             :                                   Real64 &Visibility,
    3445             :                                   Real64 &CeilHeight,
    3446             :                                   int &WObs,              // PresWeathObs
    3447             :                                   Array1D_int &WCodesArr, // PresWeathConds
    3448             :                                   Real64 &PrecipWater,
    3449             :                                   Real64 &AerosolOptDepth,
    3450             :                                   Real64 &SnowDepth,
    3451             :                                   Real64 &DaysSinceLastSnow,
    3452             :                                   Real64 &Albedo,
    3453             :                                   Real64 &LiquidPrecip)
    3454             :     {
    3455             : 
    3456             :         // SUBROUTINE INFORMATION:
    3457             :         //       AUTHOR         Linda Lawrie
    3458             :         //       DATE WRITTEN   April 2001
    3459             :         //       MODIFIED       na
    3460             :         //       RE-ENGINEERED  na
    3461             : 
    3462             :         // PURPOSE OF THIS SUBROUTINE:
    3463             :         // This subroutine interprets the EPW weather data line because comma delimited fields
    3464             :         // may cause problems with some compilers.  (Particularly character variables in
    3465             :         // comma delimited lines.
    3466             : 
    3467             :         // METHODOLOGY EMPLOYED:
    3468             :         // Field by field interpretation, eliminating the "data source field" which is also
    3469             :         // likely to contain blanks.  Note that the "Weatherconditions" must be a 9 character
    3470             :         // alpha field with no intervening blanks.
    3471             : 
    3472      228316 :         EP_SIZE_CHECK(WCodesArr, 9); // NOLINT(misc-static-assert)
    3473             : 
    3474             :         static constexpr std::string_view ValidDigits("0123456789");
    3475             : 
    3476      228316 :         std::string_view::size_type pos = 0;
    3477      228316 :         std::string_view current_line = Line;
    3478             : 
    3479      228316 :         ErrorFound = false;
    3480             : 
    3481             :         // Do the first five.  (To get to the DataSource field)
    3482             :         {
    3483      228316 :             auto nth_pos = nth_occurrence(current_line, ',', 5);
    3484      228316 :             const bool succeeded = readList(current_line.substr(pos, nth_pos), WYear, WMonth, WDay, WHour, WMinute);
    3485      228316 :             if (!succeeded) {
    3486           0 :                 ShowSevereError(state, "Invalid Date info in Weather Line");
    3487           0 :                 ShowContinueError(state, fmt::format("Entire Data Line={}", Line));
    3488           0 :                 ShowFatalError(state, "Error in Reading Weather Data");
    3489             :             }
    3490             :         }
    3491             : 
    3492      228316 :         bool DateInError = false;
    3493      228316 :         if (WMonth >= 1 && WMonth <= 12) {
    3494             :             // Month number is valid
    3495      456632 :             if (WMonth != 2) {
    3496      205805 :                 if (WDay > state.dataWeatherManager->EndDayOfMonth(WMonth)) {
    3497           0 :                     DateInError = true;
    3498             :                 }
    3499       22511 :             } else if (WDay > state.dataWeatherManager->EndDayOfMonth(WMonth) + 1) { // Whether actually used is determined by calling routine.
    3500           0 :                 DateInError = true;
    3501             :             }
    3502             :         } else {
    3503           0 :             DateInError = true;
    3504             :         }
    3505             : 
    3506      228316 :         if (DateInError) {
    3507           0 :             ShowSevereError(state, format("Reading Weather Data Line, Invalid Date, Year={}, Month={}, Day={}", WYear, WMonth, WDay));
    3508           0 :             ShowFatalError(state, "Program terminates due to previous condition.");
    3509             :         }
    3510             : 
    3511      228316 :         pos = index(Line, ','); // WYear
    3512      228316 :         if (pos == std::string::npos) {
    3513           0 :             ShowSevereError(
    3514           0 :                 state, format("Invalid Weather Line (no commas) at date={:4}/{:2}/{:2} Hour#={:2} Min#={:2}", WYear, WMonth, WDay, WHour, WMinute));
    3515           0 :             ShowContinueError(state, fmt::format("Full Data Line={}", Line));
    3516           0 :             ShowFatalError(state, "Error in Reading Weather Data");
    3517             :         }
    3518      228316 :         current_line.remove_prefix(nth_occurrence(Line, ',', 6)); // remove WYear,WMonth,WDay,WHour,WMinute,Data Source/Integrity
    3519             : 
    3520             :         // Now read more numerics with List Directed I/O (note there is another "character" field lurking)
    3521             :         Real64 RField21;
    3522             :         {
    3523      228316 :             auto nth_pos = nth_occurrence(current_line, ',', 21);
    3524             : 
    3525      228316 :             const bool succeeded = readList(current_line.substr(0, nth_pos),
    3526             :                                             DryBulb,
    3527             :                                             DewPoint,
    3528             :                                             RelHum,
    3529             :                                             AtmPress,
    3530             :                                             ETHoriz,
    3531             :                                             ETDirect,
    3532             :                                             IRHoriz,
    3533             :                                             GLBHoriz,
    3534             :                                             DirectRad,
    3535             :                                             DiffuseRad,
    3536             :                                             GLBHorizIllum,
    3537             :                                             DirectNrmIllum,
    3538             :                                             DiffuseHorizIllum,
    3539             :                                             ZenLum,
    3540             :                                             WindDir,
    3541             :                                             WindSpeed,
    3542             :                                             TotalSkyCover,
    3543             :                                             OpaqueSkyCover,
    3544             :                                             Visibility,
    3545             :                                             CeilHeight,
    3546      228316 :                                             RField21);
    3547             : 
    3548      228316 :             if (!succeeded) ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3549      228316 :             current_line.remove_prefix(nth_pos + 1);
    3550             :         }
    3551      228316 :         pos = index(current_line, ',');
    3552      456632 :         std::string PresWeathCodes;
    3553      228316 :         if (pos != std::string::npos && pos != 0) {
    3554      228316 :             PresWeathCodes = current_line.substr(0, pos);
    3555             :         } else {
    3556           0 :             PresWeathCodes = "999999999";
    3557             :         }
    3558      228316 :         current_line.remove_prefix(pos + 1);
    3559      228316 :         pos = index(current_line, ',');
    3560      228316 :         if (pos != std::string::npos) {
    3561      228316 :             if (pos != 0) {
    3562      228316 :                 bool error = false;
    3563      228316 :                 PrecipWater = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3564      228316 :                 if (error) {
    3565           0 :                     ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3566             :                 }
    3567             :             } else {
    3568           0 :                 PrecipWater = 999.0;
    3569             :             }
    3570      228316 :             current_line.remove_prefix(pos + 1);
    3571      228316 :             pos = index(current_line, ',');
    3572      228316 :             if (pos != std::string::npos) {
    3573      228291 :                 if (pos != 0) {
    3574      228291 :                     bool error = false;
    3575      228291 :                     AerosolOptDepth = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3576      228291 :                     if (error) {
    3577           0 :                         ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3578             :                     }
    3579             :                 } else {
    3580           0 :                     AerosolOptDepth = 999.0;
    3581             :                 }
    3582      228291 :                 current_line.remove_prefix(pos + 1);
    3583      228291 :                 pos = index(current_line, ',');
    3584      228291 :                 if (pos != std::string::npos) {
    3585      228291 :                     if (pos != 0) {
    3586      228291 :                         bool error = false;
    3587      228291 :                         SnowDepth = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3588      228291 :                         if (error) {
    3589           0 :                             ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3590             :                         }
    3591             :                     } else {
    3592           0 :                         SnowDepth = 999.0;
    3593             :                     }
    3594      228291 :                     current_line.remove_prefix(pos + 1);
    3595      228291 :                     pos = index(current_line, ',');
    3596      228291 :                     if (pos != std::string::npos) {
    3597      228291 :                         if (pos != 0) {
    3598      228291 :                             bool error = false;
    3599      228291 :                             DaysSinceLastSnow = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3600      228291 :                             if (error) {
    3601           0 :                                 ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3602             :                             }
    3603             :                         } else {
    3604           0 :                             DaysSinceLastSnow = 999.0;
    3605             :                         }
    3606      228291 :                         current_line.remove_prefix(pos + 1);
    3607      228291 :                         pos = index(current_line, ',');
    3608      228291 :                         if (pos != std::string::npos) {
    3609      228291 :                             if (pos != 0) {
    3610      228291 :                                 bool error = false;
    3611      228291 :                                 Albedo = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3612      228291 :                                 if (error) {
    3613           0 :                                     ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3614             :                                 }
    3615             :                             } else {
    3616           0 :                                 Albedo = 999.0;
    3617             :                             }
    3618      228291 :                             current_line.remove_prefix(pos + 1);
    3619      228291 :                             pos = index(current_line, ',');
    3620      228291 :                             if (pos != std::string::npos) {
    3621      228291 :                                 if (pos != 0) {
    3622      228291 :                                     bool error = false;
    3623      228291 :                                     LiquidPrecip = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3624      228291 :                                     if (error) {
    3625           0 :                                         ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3626             :                                     }
    3627             :                                 } else {
    3628           0 :                                     LiquidPrecip = 999.0;
    3629             :                                 }
    3630      228291 :                                 current_line.remove_prefix(pos + 1);
    3631      228291 :                                 pos = index(current_line, ',');
    3632             :                             } else {
    3633           0 :                                 LiquidPrecip = 999.0;
    3634             :                             }
    3635             :                         } else {
    3636           0 :                             Albedo = 999.0;
    3637           0 :                             LiquidPrecip = 999.0;
    3638             :                         }
    3639             :                     } else {
    3640           0 :                         bool error = false;
    3641           0 :                         DaysSinceLastSnow = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3642           0 :                         if (error) {
    3643           0 :                             ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3644             :                         }
    3645           0 :                         Albedo = 999.0;
    3646           0 :                         LiquidPrecip = 999.0;
    3647             :                     }
    3648             :                 } else {
    3649           0 :                     bool error = false;
    3650           0 :                     SnowDepth = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3651           0 :                     if (error) {
    3652           0 :                         ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3653             :                     }
    3654           0 :                     DaysSinceLastSnow = 999.0;
    3655           0 :                     Albedo = 999.0;
    3656           0 :                     LiquidPrecip = 999.0;
    3657             :                 }
    3658             :             } else {
    3659          25 :                 bool error = false;
    3660          25 :                 AerosolOptDepth = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3661          25 :                 if (error) {
    3662           0 :                     ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3663             :                 }
    3664          25 :                 SnowDepth = 999.0;
    3665          25 :                 DaysSinceLastSnow = 999.0;
    3666          25 :                 Albedo = 999.0;
    3667          25 :                 LiquidPrecip = 999.0;
    3668             :             }
    3669             :         } else {
    3670           0 :             bool error = false;
    3671           0 :             PrecipWater = UtilityRoutines::ProcessNumber(current_line.substr(0, pos), error);
    3672           0 :             if (error) {
    3673           0 :                 ErrorInterpretWeatherDataLine(state, WYear, WMonth, WDay, WHour, WMinute, Line, current_line);
    3674             :             }
    3675           0 :             AerosolOptDepth = 999.0;
    3676           0 :             SnowDepth = 999.0;
    3677           0 :             DaysSinceLastSnow = 999.0;
    3678           0 :             Albedo = 999.0;
    3679           0 :             LiquidPrecip = 999.0;
    3680             :         }
    3681             : 
    3682      228316 :         WObs = nint(RField21);
    3683      228316 :         if (WObs == 0) { // Obs Indicator indicates Weather Codes valid
    3684             :             // Check for miscellaneous characters
    3685         350 :             pos = index(PresWeathCodes, '\'');
    3686         350 :             while (pos != std::string::npos) {
    3687           0 :                 PresWeathCodes[pos] = ' ';
    3688           0 :                 pos = index(PresWeathCodes, '\'');
    3689             :             }
    3690         350 :             pos = index(PresWeathCodes, '"');
    3691         350 :             while (pos != std::string::npos) {
    3692           0 :                 PresWeathCodes[pos] = ' ';
    3693           0 :                 pos = index(PresWeathCodes, '"');
    3694             :             }
    3695         350 :             strip(PresWeathCodes);
    3696         350 :             if (len(PresWeathCodes) == 9) {
    3697           0 :                 for (pos = 0; pos < 9; ++pos) {
    3698           0 :                     if (!has(ValidDigits, PresWeathCodes[pos])) PresWeathCodes[pos] = '9';
    3699             :                 }
    3700             : 
    3701             :                 // we are trying to read a string of 9 integers with no spaces, each
    3702             :                 // into its own integer, like:
    3703             :                 // "123456789"
    3704             :                 // becomes
    3705             :                 // std::vector<int>{1,2,3,4,5,6,7,8,9};
    3706           0 :                 auto reader = stringReader(PresWeathCodes);
    3707           0 :                 for (auto &value : WCodesArr) {
    3708           0 :                     char c[2]{};          // a string of 2 characters, init both to 0
    3709           0 :                     reader >> c[0];       // read next char into the first byte
    3710           0 :                     value = std::atoi(c); // convert this short string into the appropriate int to read
    3711             :                 }
    3712             :             } else {
    3713         350 :                 ++state.dataWeatherManager->Missed.WeathCodes;
    3714         350 :                 WCodesArr = 9;
    3715             :             }
    3716             :         } else {
    3717      227966 :             WCodesArr = 9;
    3718             :         }
    3719      228316 :     }
    3720             : 
    3721        5716 :     void SetUpDesignDay(EnergyPlusData &state, int const EnvrnNum) // Environment number passed into the routine
    3722             :     {
    3723             : 
    3724             :         // SUBROUTINE INFORMATION:
    3725             :         //       AUTHOR         Linda Lawrie
    3726             :         //       DATE WRITTEN   February 1977
    3727             :         //       MODIFIED       June 1997 (RKS); May 2013 (LKL) add temperature profile for drybulb.
    3728             :         //       RE-ENGINEERED  August 2003;LKL -- to generate timestep weather for design days.
    3729             : 
    3730             :         // PURPOSE OF THIS SUBROUTINE:
    3731             :         // This purpose of this subroutine is to convert the user supplied input
    3732             :         // values for the design day parameters into an entire weather day
    3733             :         // record.  This now bypasses any file I/O by keeping all of the
    3734             :         // weather day record information in the local module level derived type
    3735             :         // called DesignDay.
    3736             : 
    3737        5716 :         constexpr Real64 GlobalSolarConstant(1367.0);
    3738        5716 :         constexpr Real64 ZHGlobalSolarConstant(1355.0);
    3739             : 
    3740        5716 :         Real64 constexpr ZhangHuangModCoeff_C0(0.5598);   // 37.6865d0
    3741        5716 :         Real64 constexpr ZhangHuangModCoeff_C1(0.4982);   // 13.9263d0
    3742        5716 :         Real64 constexpr ZhangHuangModCoeff_C2(-0.6762);  // -20.2354d0
    3743        5716 :         Real64 constexpr ZhangHuangModCoeff_C3(0.02842);  // 0.9695d0
    3744        5716 :         Real64 constexpr ZhangHuangModCoeff_C4(-0.00317); // -0.2046d0
    3745        5716 :         Real64 constexpr ZhangHuangModCoeff_C5(0.014);    // -0.0980d0
    3746        5716 :         Real64 constexpr ZhangHuangModCoeff_D(-17.853);   // -10.8568d0
    3747        5716 :         Real64 constexpr ZhangHuangModCoeff_K(0.843);     // 49.3112d0
    3748             :         static constexpr std::string_view RoutineNamePsyWFnTdbTwbPb("SetUpDesignDay:PsyWFnTdbTwbPb");
    3749             :         static constexpr std::string_view RoutineNamePsyWFnTdpPb("SetUpDesignDay:PsyWFnTdpPb");
    3750             :         static constexpr std::string_view RoutineNamePsyWFnTdbH("SetUpDesignDay:PsyWFnTdbH");
    3751             :         static constexpr std::string_view WeatherManager("WeatherManager");
    3752             :         static constexpr std::string_view RoutineNameLong("WeatherManager.cc subroutine SetUpDesignDay");
    3753             : 
    3754       11432 :         std::string StringOut;
    3755             :         //     For reporting purposes, set year to current system year
    3756             : 
    3757        5716 :         struct HourlyWeatherData
    3758             :         {
    3759             :             // Members
    3760             :             Array1D<Real64> BeamSolarRad; // Hourly direct normal solar irradiance
    3761             :             Array1D<Real64> DifSolarRad;  // Hourly sky diffuse horizontal solar irradiance
    3762             : 
    3763             :             // Default Constructor
    3764        5716 :             HourlyWeatherData() : BeamSolarRad(24, 0.0), DifSolarRad(24, 0.0)
    3765             :             {
    3766        5716 :             }
    3767             :         };
    3768             : 
    3769             :         // Object Data
    3770       11432 :         HourlyWeatherData Wthr;
    3771             : 
    3772        5716 :         bool SaveWarmupFlag = state.dataGlobal->WarmupFlag;
    3773        5716 :         state.dataGlobal->WarmupFlag = true;
    3774             : 
    3775       11432 :         Array1D_int Date0(8);
    3776        5716 :         date_and_time(_, _, _, Date0);
    3777        5716 :         int CurrentYear = Date0(1);
    3778             : 
    3779        5716 :         if (state.dataGlobal->BeginSimFlag) {
    3780         771 :             state.dataWeatherManager->PrintDDHeader = true;
    3781             :         }
    3782             : 
    3783        5716 :         state.dataWeatherManager->DesignDay(EnvrnNum).Year = CurrentYear; // f90 date_and_time implemented. full 4 digit year !+ 1900
    3784        5716 :         state.dataWeatherManager->DesignDay(EnvrnNum).Month = state.dataWeatherManager->DesDayInput(EnvrnNum).Month;
    3785        5716 :         state.dataWeatherManager->DesignDay(EnvrnNum).DayOfMonth = state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth;
    3786        5716 :         state.dataWeatherManager->DesignDay(EnvrnNum).DayOfYear =
    3787        5716 :             General::OrdinalDay(state.dataWeatherManager->DesignDay(EnvrnNum).Month, state.dataWeatherManager->DesignDay(EnvrnNum).DayOfMonth, 0);
    3788             :         static constexpr std::string_view MnDyFmt("{:02}/{:02}");
    3789       11432 :         state.dataEnvrn->CurMnDy =
    3790       17148 :             format(MnDyFmt, state.dataWeatherManager->DesDayInput(EnvrnNum).Month, state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth);
    3791             :         // EnvironmentName = DesDayInput( EnvrnNum ).Title;
    3792        5716 :         state.dataEnvrn->RunPeriodEnvironment = false;
    3793             :         // Following builds Environment start/end for ASHRAE 55 warnings
    3794        5716 :         state.dataEnvrn->EnvironmentStartEnd = state.dataEnvrn->CurMnDy + " - " + state.dataEnvrn->CurMnDy;
    3795             : 
    3796             :         // Check that barometric pressure is within range
    3797        5716 :         if (state.dataWeatherManager->DesDayInput(EnvrnNum).PressureEntered) {
    3798       17076 :             if (std::abs((state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom - state.dataEnvrn->StdBaroPress) /
    3799       11384 :                          state.dataEnvrn->StdBaroPress) > 0.1) { // 10% off
    3800         162 :                 ShowWarningError(state,
    3801         216 :                                  format("SetUpDesignDay: Entered DesignDay Barometric Pressure={:.0R} differs by more than 10% from Standard "
    3802             :                                         "Barometric Pressure={:.0R}.",
    3803          54 :                                         state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom,
    3804         108 :                                         state.dataEnvrn->StdBaroPress));
    3805         162 :                 ShowContinueError(
    3806         108 :                     state, "...occurs in DesignDay=" + state.dataEnvrn->EnvironmentName + ", Standard Pressure (based on elevation) will be used.");
    3807          54 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom = state.dataEnvrn->StdBaroPress;
    3808             :             }
    3809             :         } else {
    3810          24 :             state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom = state.dataEnvrn->StdBaroPress;
    3811             :         }
    3812             : 
    3813             :         // verify that design WB or DP <= design DB
    3814        5741 :         if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::DewPoint &&
    3815          25 :             state.dataWeatherManager->DesDayInput(EnvrnNum).DewPointNeedsSet) {
    3816             :             // dew-point
    3817           0 :             Real64 testval = Psychrometrics::PsyWFnTdbRhPb(
    3818           0 :                 state, state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb, 1.0, state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    3819           0 :             state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue =
    3820           0 :                 Psychrometrics::PsyTdpFnWPb(state, testval, state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    3821             :         }
    3822             : 
    3823             :         // Day of week defaults to Monday, if day type specified, then that is used.
    3824        5716 :         state.dataWeatherManager->DesignDay(EnvrnNum).DayOfWeek = 2;
    3825        5716 :         if (state.dataWeatherManager->DesDayInput(EnvrnNum).DayType <= 7)
    3826          52 :             state.dataWeatherManager->DesignDay(EnvrnNum).DayOfWeek = state.dataWeatherManager->DesDayInput(EnvrnNum).DayType;
    3827             : 
    3828             :         // set Holiday as indicated by user input
    3829        5716 :         state.dataWeatherManager->DesignDay(EnvrnNum).HolidayIndex = 0;
    3830        5716 :         if (state.dataWeatherManager->DesDayInput(EnvrnNum).DayType > 7)
    3831        5664 :             state.dataWeatherManager->DesignDay(EnvrnNum).HolidayIndex = state.dataWeatherManager->DesDayInput(EnvrnNum).DayType;
    3832             : 
    3833        5716 :         state.dataWeatherManager->DesignDay(EnvrnNum).DaylightSavingIndex = state.dataWeatherManager->DesDayInput(EnvrnNum).DSTIndicator;
    3834             : 
    3835             :         //  Set up Solar parameters for day
    3836             :         Real64 A;    // Apparent solar irradiation at air mass = 0
    3837             :         Real64 B;    // Atmospheric extinction coefficient
    3838             :         Real64 C;    // ASHRAE diffuse radiation factor
    3839             :         Real64 AVSC; // Annual variation in the solar constant
    3840       22864 :         CalculateDailySolarCoeffs(state,
    3841        5716 :                                   state.dataWeatherManager->DesignDay(EnvrnNum).DayOfYear,
    3842             :                                   A,
    3843             :                                   B,
    3844             :                                   C,
    3845             :                                   AVSC,
    3846        5716 :                                   state.dataWeatherManager->DesignDay(EnvrnNum).EquationOfTime,
    3847        5716 :                                   state.dataWeatherManager->DesignDay(EnvrnNum).SinSolarDeclinAngle,
    3848        5716 :                                   state.dataWeatherManager->DesignDay(EnvrnNum).CosSolarDeclinAngle);
    3849             : 
    3850        5716 :         if (state.dataWeatherManager->PrintDDHeader && state.dataReportFlag->DoWeatherInitReporting) {
    3851             :             static constexpr std::string_view EnvDDHdFormat(
    3852             :                 "! <Environment:Design Day Data>, Max Dry-Bulb Temp {C}, Temp Range {dC}, Temp Range Ind Type, "
    3853             :                 "Hum Ind Type, Hum Ind Value at Max Temp, Hum Ind Units, Pressure {Pa}, Wind Direction {deg CW from N}, Wind "
    3854             :                 "Speed {m/s}, Clearness, Rain, Snow");
    3855         767 :             print(state.files.eio, "{}\n", EnvDDHdFormat);
    3856             :             static constexpr std::string_view DDayMiscHdFormat(
    3857             :                 "! <Environment:Design Day Misc>,DayOfYear,ASHRAE A Coeff,ASHRAE B Coeff,ASHRAE C Coeff,Solar "
    3858             :                 "Constant-Annual Variation,Eq of Time {minutes}, Solar Declination Angle {deg}, Solar Model");
    3859         767 :             print(state.files.eio, "{}\n", DDayMiscHdFormat);
    3860         767 :             state.dataWeatherManager->PrintDDHeader = false;
    3861             :         }
    3862        5716 :         if (state.dataReportFlag->DoWeatherInitReporting) {
    3863        3424 :             std::string const AlpUseRain = (state.dataWeatherManager->DesDayInput(EnvrnNum).RainInd == 1) ? "Yes" : "No";
    3864        3424 :             std::string const AlpUseSnow = (state.dataWeatherManager->DesDayInput(EnvrnNum).SnowInd == 1) ? "Yes" : "No";
    3865        1712 :             print(state.files.eio, "Environment:Design Day Data,");
    3866        1712 :             print(state.files.eio, "{:.2R},", state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb);
    3867        1712 :             print(state.files.eio, "{:.2R},", state.dataWeatherManager->DesDayInput(EnvrnNum).DailyDBRange);
    3868             : 
    3869        1712 :             StringOut = ",";
    3870        1712 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType == DDDBRangeType::Default) {
    3871        1706 :                 StringOut = "DefaultMultipliers,";
    3872           6 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType == DDDBRangeType::Multiplier) {
    3873           3 :                 StringOut = "MultiplierSchedule,";
    3874           3 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType == DDDBRangeType::Profile) {
    3875           1 :                 StringOut = "TemperatureProfile,";
    3876           2 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType == DDDBRangeType::Difference) {
    3877           2 :                 StringOut = "DifferenceSchedule,";
    3878             :             }
    3879        1712 :             print(state.files.eio, "{}", StringOut);
    3880             : 
    3881             :             // Hum Ind Type, Hum Ind Value at Max Temp, Hum Ind Units
    3882        1712 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WetBulb) {
    3883        1686 :                 StringOut = format("Wetbulb,{:.2R},{{C}},", state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue);
    3884          26 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::DewPoint) {
    3885           5 :                 StringOut = format("Dewpoint,{:.2R},{{C}},", state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue);
    3886          21 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::Enthalpy) {
    3887           3 :                 StringOut = format("Enthalpy,{:.2R},{{J/kgDryAir}},", state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue);
    3888          18 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::HumRatio) {
    3889           0 :                 StringOut = format("HumidityRatio,{:.4R},{{kgWater/kgDryAir}},", state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue);
    3890          18 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::RelHumSch) {
    3891           3 :                 StringOut = "Schedule,<schedule values from 0.0 to 100.0>,{percent},";
    3892          15 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDef) {
    3893          24 :                 StringOut = format("WetBulbProfileDefaultMultipliers,{:.2R},{{C}},",
    3894          24 :                                    state.dataWeatherManager->DesDayInput(state.dataWeatherManager->Envrn).HumIndValue);
    3895           3 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDif) {
    3896           1 :                 StringOut = format("WetBulbProfileDifferenceSchedule,{:.2R},{{C}},", state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue);
    3897           2 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfMul) {
    3898           2 :                 StringOut = format("WetBulbProfileMultiplierSchedule,{:.2R},{{C}},", state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue);
    3899             :             }
    3900        1712 :             print(state.files.eio, "{}", StringOut);
    3901        1712 :             print(state.files.eio, "{:.0R},", state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    3902        1712 :             print(state.files.eio, "{:.0R},", state.dataWeatherManager->DesDayInput(EnvrnNum).WindDir);
    3903        1712 :             print(state.files.eio, "{:.1R},", state.dataWeatherManager->DesDayInput(EnvrnNum).WindSpeed);
    3904        1712 :             print(state.files.eio, "{:.2R},", state.dataWeatherManager->DesDayInput(EnvrnNum).SkyClear);
    3905             : 
    3906        1712 :             print(state.files.eio, "{},{}\n", AlpUseRain, AlpUseSnow);
    3907             : 
    3908             :             static constexpr std::string_view DDayMiscFormat("Environment:Design Day Misc,{:3},");
    3909        1712 :             print(state.files.eio, DDayMiscFormat, state.dataWeatherManager->DesignDay(EnvrnNum).DayOfYear);
    3910        1712 :             print(state.files.eio, "{:.1R},", A);
    3911        1712 :             print(state.files.eio, "{:.4R},", B);
    3912        1712 :             print(state.files.eio, "{:.4R},", C);
    3913        1712 :             print(state.files.eio, "{:.1R},", AVSC);
    3914        1712 :             print(state.files.eio, "{:.2R},", state.dataWeatherManager->DesignDay(EnvrnNum).EquationOfTime * 60.0);
    3915        1712 :             print(state.files.eio,
    3916             :                   "{:.1R},",
    3917        3424 :                   std::asin(state.dataWeatherManager->DesignDay(EnvrnNum).SinSolarDeclinAngle) / DataGlobalConstants::DegToRadians);
    3918             : 
    3919        1712 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel == DesignDaySolarModel::ASHRAE_ClearSky) {
    3920        1622 :                 StringOut = "ASHRAEClearSky";
    3921          90 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel == DesignDaySolarModel::Zhang_Huang) {
    3922           2 :                 StringOut = "ZhangHuang";
    3923          88 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel == DesignDaySolarModel::SolarModel_Schedule) {
    3924           3 :                 StringOut = "User supplied beam/diffuse from schedules";
    3925          85 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel == DesignDaySolarModel::ASHRAE_Tau) {
    3926          85 :                 StringOut = "ASHRAETau";
    3927           0 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel == DesignDaySolarModel::ASHRAE_Tau2017) {
    3928           0 :                 StringOut = "ASHRAETau2017";
    3929             :             } else {
    3930           0 :                 StringOut = "unknown";
    3931             :             }
    3932        1712 :             print(state.files.eio, "{}\n", StringOut);
    3933             :         }
    3934             : 
    3935             :         // Must set up weather values for Design Day.  User can specify the "humidity indicator" as
    3936             :         // Wetbulb, DewPoint or input the relative humidity schedule.  For both wetbulb and dewpoint indicators, the
    3937             :         // humidity for the day will be constant, using the drybulb (max) and humidity indicator temperature to
    3938             :         // set the values.  For the scheduled values, these are already set in the DDxxx array.
    3939             : 
    3940        5716 :         state.dataGlobal->CurrentTime = 25.0;
    3941             :         Real64 HumidityRatio; // Humidity Ratio -- when constant for day
    3942             :         bool ConstantHumidityRatio;
    3943             : 
    3944        5716 :         switch (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType) {
    3945        5640 :         case DDHumIndType::WetBulb:
    3946       16920 :             HumidityRatio = Psychrometrics::PsyWFnTdbTwbPb(state,
    3947        5640 :                                                            state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb,
    3948        5640 :                                                            state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue,
    3949        5640 :                                                            state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom,
    3950             :                                                            RoutineNamePsyWFnTdbTwbPb);
    3951        5640 :             ConstantHumidityRatio = true;
    3952        5640 :             break;
    3953          25 :         case DDHumIndType::DewPoint:
    3954          50 :             HumidityRatio = Psychrometrics::PsyWFnTdpPb(state,
    3955          25 :                                                         state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue,
    3956          25 :                                                         state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom,
    3957             :                                                         RoutineNamePsyWFnTdpPb);
    3958          25 :             ConstantHumidityRatio = true;
    3959          25 :             break;
    3960           0 :         case DDHumIndType::HumRatio:
    3961           0 :             HumidityRatio = state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue;
    3962           0 :             ConstantHumidityRatio = true;
    3963           0 :             break;
    3964          15 :         case DDHumIndType::Enthalpy:
    3965             :             // HumIndValue is already in J/kg, so no conversions needed
    3966          30 :             HumidityRatio = Psychrometrics::PsyWFnTdbH(state,
    3967          15 :                                                        state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb,
    3968          15 :                                                        state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue,
    3969             :                                                        RoutineNamePsyWFnTdbH);
    3970          15 :             ConstantHumidityRatio = true;
    3971          15 :             break;
    3972           6 :         case DDHumIndType::RelHumSch:
    3973             :             // nothing to do -- DDHumIndModifier already contains the scheduled Relative Humidity
    3974           6 :             ConstantHumidityRatio = false;
    3975           6 :             state.dataWeatherManager->TomorrowOutRelHum = state.dataWeatherManager->DDHumIndModifier(_, _, EnvrnNum);
    3976           6 :             break;
    3977          30 :         case DDHumIndType::WBProfDef:
    3978             :         case DDHumIndType::WBProfDif:
    3979             :         case DDHumIndType::WBProfMul:
    3980          30 :             ConstantHumidityRatio = false;
    3981          30 :             break;
    3982           0 :         default:
    3983           0 :             ShowSevereError(state, "SetUpDesignDay: Invalid Humidity Indicator type");
    3984           0 :             ShowContinueError(state, "Occurred in Design Day=" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title);
    3985           0 :             break;
    3986             :         }
    3987             : 
    3988             :         int OSky; // Opaque Sky Cover (tenths)
    3989        5716 :         if (state.dataWeatherManager->DesDayInput(EnvrnNum).RainInd != 0) {
    3990           0 :             state.dataWeatherManager->TomorrowIsRain(_, _) = true;
    3991           0 :             OSky = 10;
    3992           0 :             state.dataWeatherManager->TomorrowLiquidPrecip = 3.0;
    3993             :         } else {
    3994        5716 :             state.dataWeatherManager->TomorrowIsRain(_, _) = false;
    3995        5716 :             OSky = 0;
    3996        5716 :             state.dataWeatherManager->TomorrowLiquidPrecip = 0.0;
    3997             :         }
    3998             : 
    3999             :         Real64 GndReflet; // Ground Reflectivity
    4000        5716 :         if (state.dataWeatherManager->DesDayInput(EnvrnNum).SnowInd == 0) {
    4001        5716 :             state.dataWeatherManager->TomorrowIsSnow(_, _) = false;
    4002        5716 :             GndReflet = 0.2;
    4003             :         } else { // Snow
    4004           0 :             state.dataWeatherManager->TomorrowIsSnow(_, _) = true;
    4005           0 :             GndReflet = 0.7;
    4006             :         }
    4007             : 
    4008             :         // Some values are constant
    4009             : 
    4010        5716 :         state.dataWeatherManager->TomorrowOutBaroPress(_, _) = state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom;
    4011        5716 :         state.dataWeatherManager->TomorrowWindSpeed(_, _) = state.dataWeatherManager->DesDayInput(EnvrnNum).WindSpeed;
    4012        5716 :         state.dataWeatherManager->TomorrowWindDir(_, _) = state.dataWeatherManager->DesDayInput(EnvrnNum).WindDir;
    4013        5716 :         state.dataWeatherManager->TomorrowAlbedo = 0.0;
    4014             : 
    4015             :         // resolve daily ranges
    4016             :         Real64 DBRange; // working copy of dry-bulb daily range, C (or 1 if input is difference)
    4017        5716 :         if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType == DDDBRangeType::Difference) {
    4018           4 :             DBRange = 1.0; // use unscaled multiplier values if difference
    4019        5712 :         } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType == DDDBRangeType::Profile) {
    4020           2 :             DBRange = 0.0;
    4021             :         } else {
    4022        5710 :             DBRange = state.dataWeatherManager->DesDayInput(EnvrnNum).DailyDBRange;
    4023             :         }
    4024             :         Real64 WBRange; // working copy of wet-bulb daily range. C (or 1 if input is difference)
    4025        5716 :         if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDif) {
    4026           2 :             WBRange = 1.0; // use unscaled multiplier values if difference
    4027             :         } else {
    4028        5714 :             WBRange = state.dataWeatherManager->DesDayInput(EnvrnNum).DailyWBRange;
    4029             :         }
    4030             : 
    4031      142900 :         for (int hour = 1; hour <= 24; ++hour) {
    4032      885840 :             for (int ts = 1; ts <= state.dataGlobal->NumOfTimeStepInHour; ++ts) {
    4033             : 
    4034      748656 :                 if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType != DDDBRangeType::Profile) {
    4035             :                     // dry-bulb profile
    4036      748464 :                     state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour) =
    4037     1496928 :                         state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb -
    4038      748464 :                         state.dataWeatherManager->DDDBRngModifier(ts, hour, EnvrnNum) * DBRange;
    4039             :                 } else { // DesDayInput(EnvrnNum)%DBTempRangeType == DDDBRangeType::Profile
    4040         192 :                     state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour) = state.dataWeatherManager->DDDBRngModifier(ts, hour, EnvrnNum);
    4041             :                 }
    4042             : 
    4043             :                 // wet-bulb - generate from profile, humidity ratio, or dew point
    4044     2243664 :                 if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDef ||
    4045     1494816 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDif ||
    4046      746160 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfMul) {
    4047        2880 :                     Real64 WetBulb = state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue -
    4048        2880 :                                      state.dataWeatherManager->DDHumIndModifier(ts, hour, EnvrnNum) * WBRange;
    4049        2880 :                     WetBulb = min(WetBulb, state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour)); // WB must be <= DB
    4050        8640 :                     Real64 OutHumRat = Psychrometrics::PsyWFnTdbTwbPb(state,
    4051        2880 :                                                                       state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    4052             :                                                                       WetBulb,
    4053        5760 :                                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    4054        2880 :                     state.dataWeatherManager->TomorrowOutDewPointTemp(ts, hour) =
    4055        5760 :                         Psychrometrics::PsyTdpFnWPb(state, OutHumRat, state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    4056        2880 :                     state.dataWeatherManager->TomorrowOutRelHum(ts, hour) =
    4057        5760 :                         Psychrometrics::PsyRhFnTdbWPb(state,
    4058        2880 :                                                       state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    4059             :                                                       OutHumRat,
    4060        2880 :                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom,
    4061        2880 :                                                       WeatherManager) *
    4062             :                         100.0;
    4063      745776 :                 } else if (ConstantHumidityRatio) {
    4064             :                     //  Need Dew Point Temperature.  Use Relative Humidity to get Humidity Ratio, unless Humidity Ratio is constant
    4065             :                     // BG 9-26-07  moved following inside this IF statment; when HumIndType is 'Schedule' HumidityRatio wasn't being initialized
    4066     1490400 :                     Real64 WetBulb = Psychrometrics::PsyTwbFnTdbWPb(state,
    4067      745200 :                                                                     state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    4068             :                                                                     HumidityRatio,
    4069      745200 :                                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom,
    4070      745200 :                                                                     RoutineNameLong);
    4071             : 
    4072     2235600 :                     Real64 OutHumRat = Psychrometrics::PsyWFnTdpPb(state,
    4073      745200 :                                                                    state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    4074     1490400 :                                                                    state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    4075      745200 :                     if (HumidityRatio > OutHumRat) {
    4076      267701 :                         WetBulb = state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour);
    4077             :                     } else {
    4078      954998 :                         OutHumRat = Psychrometrics::PsyWFnTdbTwbPb(state,
    4079      477499 :                                                                    state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    4080             :                                                                    WetBulb,
    4081      477499 :                                                                    state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    4082             :                     }
    4083      745200 :                     state.dataWeatherManager->TomorrowOutDewPointTemp(ts, hour) =
    4084     1490400 :                         Psychrometrics::PsyTdpFnWPb(state, OutHumRat, state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    4085      745200 :                     state.dataWeatherManager->TomorrowOutRelHum(ts, hour) =
    4086     1490400 :                         Psychrometrics::PsyRhFnTdbWPb(state,
    4087      745200 :                                                       state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    4088             :                                                       OutHumRat,
    4089      745200 :                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom,
    4090      745200 :                                                       WeatherManager) *
    4091             :                         100.0;
    4092             :                 } else {
    4093        1728 :                     HumidityRatio = Psychrometrics::PsyWFnTdbRhPb(state,
    4094         576 :                                                                   state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    4095         576 :                                                                   state.dataWeatherManager->DDHumIndModifier(ts, hour, EnvrnNum) / 100.0,
    4096         576 :                                                                   state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    4097         576 :                     state.dataWeatherManager->TomorrowOutRelHum(ts, hour) =
    4098        1152 :                         Psychrometrics::PsyRhFnTdbWPb(state,
    4099         576 :                                                       state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour),
    4100             :                                                       HumidityRatio,
    4101         576 :                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom,
    4102         576 :                                                       WeatherManager) *
    4103             :                         100.0;
    4104             :                     // TomorrowOutRelHum values set earlier
    4105         576 :                     state.dataWeatherManager->TomorrowOutDewPointTemp(ts, hour) =
    4106        1152 :                         Psychrometrics::PsyTdpFnWPb(state, HumidityRatio, state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom);
    4107             :                 }
    4108             : 
    4109      748656 :                 double DryBulb = state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour);
    4110      748656 :                 double RelHum = state.dataWeatherManager->TomorrowOutRelHum(ts, hour) * 0.01;
    4111     1497312 :                 Real64 ESky = CalcSkyEmissivity(state,
    4112      748656 :                                                 state.dataWeatherManager->Environment(EnvrnNum).SkyTempModel,
    4113             :                                                 OSky,
    4114             :                                                 DryBulb,
    4115      748656 :                                                 state.dataWeatherManager->TomorrowOutDewPointTemp(ts, hour),
    4116      748656 :                                                 RelHum); // Emissivitity of Sky
    4117      748656 :                 state.dataWeatherManager->TomorrowHorizIRSky(ts, hour) =
    4118      748656 :                     ESky * state.dataWeatherManager->Sigma * pow_4(DryBulb + DataGlobalConstants::KelvinConv);
    4119             : 
    4120     2245968 :                 if (state.dataWeatherManager->Environment(EnvrnNum).SkyTempModel == SkyTempCalcType::BruntModel ||
    4121     1497312 :                     state.dataWeatherManager->Environment(EnvrnNum).SkyTempModel == SkyTempCalcType::IdsoModel ||
    4122     2245968 :                     state.dataWeatherManager->Environment(EnvrnNum).SkyTempModel == SkyTempCalcType::BerdahlMartinModel ||
    4123      748656 :                     state.dataWeatherManager->Environment(EnvrnNum).SkyTempModel == SkyTempCalcType::ClarkAllenModel) {
    4124             :                     // Design day not scheduled
    4125      748464 :                     state.dataWeatherManager->TomorrowSkyTemp(ts, hour) =
    4126      748464 :                         (DryBulb + DataGlobalConstants::KelvinConv) * root_4(ESky) - DataGlobalConstants::KelvinConv;
    4127             :                 }
    4128             :                 // Generate solar values for timestep
    4129             :                 //    working results = BeamRad and DiffRad
    4130             :                 //    stored to program globals at end of loop
    4131             :                 Real64 BeamRad;
    4132             :                 Real64 DiffRad;
    4133      748656 :                 if (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel == DesignDaySolarModel::SolarModel_Schedule) {
    4134             :                     // scheduled: set value unconditionally (whether sun up or not)
    4135         576 :                     BeamRad = state.dataWeatherManager->DDBeamSolarValues(ts, hour, EnvrnNum);
    4136         576 :                     DiffRad = state.dataWeatherManager->DDDiffuseSolarValues(ts, hour, EnvrnNum);
    4137             :                 } else {
    4138             : 
    4139             :                     // calc time = fractional hour of day
    4140             :                     Real64 CurTime;
    4141      748080 :                     if (state.dataGlobal->NumOfTimeStepInHour != 1) {
    4142      746784 :                         CurTime = double(hour - 1) + double(ts) * state.dataWeatherManager->TimeStepFraction;
    4143             :                     } else {
    4144        1296 :                         CurTime = double(hour) + state.dataEnvrn->TS1TimeOffset;
    4145             :                     }
    4146             : 
    4147     1496160 :                     Array1D<Real64> SUNCOS(3); // Sun direction cosines
    4148     2244240 :                     CalculateSunDirectionCosines(state,
    4149             :                                                  CurTime,
    4150      748080 :                                                  state.dataWeatherManager->DesignDay(EnvrnNum).EquationOfTime,
    4151      748080 :                                                  state.dataWeatherManager->DesignDay(EnvrnNum).SinSolarDeclinAngle,
    4152      748080 :                                                  state.dataWeatherManager->DesignDay(EnvrnNum).CosSolarDeclinAngle,
    4153             :                                                  SUNCOS);
    4154      748080 :                     Real64 CosZenith = SUNCOS(3); // Cosine of Zenith Angle of Sun
    4155      748080 :                     if (CosZenith < DataEnvironment::SunIsUpValue) {
    4156      371369 :                         BeamRad = 0.0;
    4157      371369 :                         DiffRad = 0.0;
    4158             :                     } else {
    4159      376711 :                         Real64 SinSolarAltitude = SUNCOS(3);
    4160             : 
    4161      376711 :                         switch (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel) {
    4162      356733 :                         case DesignDaySolarModel::ASHRAE_ClearSky: {
    4163      356733 :                             Real64 Exponent = B / CosZenith;
    4164             :                             Real64 TotHoriz; // Total Radiation on Horizontal Surface
    4165      356733 :                             if (Exponent > 700.0) {
    4166          10 :                                 TotHoriz = 0.0;
    4167             :                             } else {
    4168      356723 :                                 TotHoriz = state.dataWeatherManager->DesDayInput(EnvrnNum).SkyClear * A * (C + CosZenith) * std::exp(-B / CosZenith);
    4169             :                             }
    4170             :                             // Radiation on an extraterrestial horizontal surface
    4171      356733 :                             Real64 HO = GlobalSolarConstant * AVSC * CosZenith;
    4172      356733 :                             Real64 KT = TotHoriz / HO; // Radiation ratio
    4173      356733 :                             KT = min(KT, 0.75);
    4174      356733 :                             DiffRad = TotHoriz * (1.0045 + KT * (0.04349 + KT * (-3.5227 + 2.6313 * KT)));
    4175      356733 :                             if (state.dataWeatherManager->DesDayInput(EnvrnNum).SkyClear > 0.70) DiffRad = TotHoriz * C / (C + CosZenith);
    4176      356733 :                             BeamRad = (TotHoriz - DiffRad) / CosZenith;
    4177      356733 :                             DiffRad = max(0.0, DiffRad);
    4178      356733 :                             BeamRad = max(0.0, BeamRad);
    4179             : 
    4180      356733 :                         } break;
    4181       19788 :                         case DesignDaySolarModel::ASHRAE_Tau:
    4182             :                         case DesignDaySolarModel::ASHRAE_Tau2017: {
    4183       19788 :                             Real64 ETR = GlobalSolarConstant * AVSC; // radiation of an extraterrestrial normal surface, W/m2
    4184             :                             Real64 GloHorzRad;
    4185       59364 :                             ASHRAETauModel(state,
    4186       19788 :                                            state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel,
    4187             :                                            ETR,
    4188             :                                            CosZenith,
    4189       19788 :                                            state.dataWeatherManager->DesDayInput(EnvrnNum).TauB,
    4190       19788 :                                            state.dataWeatherManager->DesDayInput(EnvrnNum).TauD,
    4191             :                                            BeamRad,
    4192             :                                            DiffRad,
    4193       19788 :                                            GloHorzRad);
    4194       19788 :                         } break;
    4195         190 :                         case DesignDaySolarModel::Zhang_Huang: {
    4196         190 :                             int Hour3Ago = mod(hour + 20, 24) + 1; // hour 3 hours before
    4197         190 :                             Real64 const TotSkyCover = max(1.0 - state.dataWeatherManager->DesDayInput(EnvrnNum).SkyClear, 0.0);
    4198             :                             Real64 GloHorzRad =
    4199         380 :                                 (ZHGlobalSolarConstant * SinSolarAltitude *
    4200         380 :                                      (ZhangHuangModCoeff_C0 + ZhangHuangModCoeff_C1 * TotSkyCover + ZhangHuangModCoeff_C2 * pow_2(TotSkyCover) +
    4201         380 :                                       ZhangHuangModCoeff_C3 * (state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour) -
    4202         380 :                                                                state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, Hour3Ago)) +
    4203         380 :                                       ZhangHuangModCoeff_C4 * state.dataWeatherManager->TomorrowOutRelHum(ts, hour) +
    4204         380 :                                       ZhangHuangModCoeff_C5 * state.dataWeatherManager->TomorrowWindSpeed(ts, hour)) +
    4205             :                                  ZhangHuangModCoeff_D) /
    4206         190 :                                 ZhangHuangModCoeff_K;
    4207         190 :                             GloHorzRad = max(GloHorzRad, 0.0);
    4208         190 :                             Real64 ClearnessIndex_kt = GloHorzRad / (GlobalSolarConstant * SinSolarAltitude);
    4209             :                             //          ClearnessIndex_kt=DesDayInput(EnvrnNum)%SkyClear
    4210         190 :                             Real64 ClearnessIndex_ktc = 0.4268 + 0.1934 * SinSolarAltitude;
    4211             :                             Real64 ClearnessIndex_kds;
    4212         190 :                             if (ClearnessIndex_kt < ClearnessIndex_ktc) {
    4213          96 :                                 ClearnessIndex_kds = (3.996 - 3.862 * SinSolarAltitude + 1.54 * pow_2(SinSolarAltitude)) * pow_3(ClearnessIndex_kt);
    4214             :                             } else {
    4215         188 :                                 ClearnessIndex_kds = ClearnessIndex_kt - (1.107 + 0.03569 * SinSolarAltitude + 1.681 * pow_2(SinSolarAltitude)) *
    4216          94 :                                                                              pow_3(1.0 - ClearnessIndex_kt);
    4217             :                             }
    4218             :                             // Calculate direct normal radiation, W/m2
    4219         380 :                             BeamRad = ZHGlobalSolarConstant * SinSolarAltitude * ClearnessIndex_kds *
    4220         190 :                                       ((1.0 - ClearnessIndex_kt) / (1.0 - ClearnessIndex_kds));
    4221             :                             // Calculation diffuse horizontal radiation, W/m2
    4222         190 :                             DiffRad =
    4223         190 :                                 ZHGlobalSolarConstant * SinSolarAltitude * ((ClearnessIndex_kt - ClearnessIndex_kds) / (1.0 - ClearnessIndex_kds));
    4224             : 
    4225         190 :                         } break;
    4226           0 :                         default:
    4227           0 :                             break;
    4228             :                         }
    4229             :                     }
    4230             :                 }
    4231             : 
    4232             :                 // override result to 0 per environment var (for testing)
    4233      748656 :                 if (state.dataEnvrn->IgnoreSolarRadiation || state.dataEnvrn->IgnoreBeamRadiation) BeamRad = 0.0;
    4234      748656 :                 if (state.dataEnvrn->IgnoreSolarRadiation || state.dataEnvrn->IgnoreDiffuseRadiation) DiffRad = 0.0;
    4235             : 
    4236      748656 :                 state.dataWeatherManager->TomorrowBeamSolarRad(ts, hour) = BeamRad;
    4237      748656 :                 state.dataWeatherManager->TomorrowDifSolarRad(ts, hour) = DiffRad;
    4238             : 
    4239             :             } // Timestep (TS) Loop
    4240             :         }     // Hour Loop
    4241             : 
    4242             :         // back-fill hour values from timesteps
    4243             :         // hour values = integrated over hour ending at time of hour
    4244             :         // insurance: hourly values not known to be needed
    4245      142900 :         for (int hour = 1; hour <= 24; ++hour) {
    4246      137184 :             int Hour1Ago = mod(hour + 22, 24) + 1;
    4247      274368 :             Real64 BeamRad = (state.dataWeatherManager->TomorrowBeamSolarRad(state.dataGlobal->NumOfTimeStepInHour, Hour1Ago) +
    4248      137184 :                               state.dataWeatherManager->TomorrowBeamSolarRad(state.dataGlobal->NumOfTimeStepInHour, hour)) /
    4249      137184 :                              2.0;
    4250      274368 :             Real64 DiffRad = (state.dataWeatherManager->TomorrowDifSolarRad(state.dataGlobal->NumOfTimeStepInHour, Hour1Ago) +
    4251      137184 :                               state.dataWeatherManager->TomorrowDifSolarRad(state.dataGlobal->NumOfTimeStepInHour, hour)) /
    4252      137184 :                              2.0;
    4253      137184 :             if (state.dataGlobal->NumOfTimeStepInHour > 1) {
    4254      135888 :                 BeamRad += sum(state.dataWeatherManager->TomorrowBeamSolarRad({1, state.dataGlobal->NumOfTimeStepInHour - 1}, hour));
    4255      135888 :                 DiffRad += sum(state.dataWeatherManager->TomorrowDifSolarRad({1, state.dataGlobal->NumOfTimeStepInHour - 1}, hour));
    4256             :             }
    4257      137184 :             Wthr.BeamSolarRad(hour) = BeamRad / state.dataGlobal->NumOfTimeStepInHour;
    4258      137184 :             Wthr.DifSolarRad(hour) = DiffRad / state.dataGlobal->NumOfTimeStepInHour;
    4259             :         }
    4260             : 
    4261        5716 :         if (state.dataWeatherManager->Environment(EnvrnNum).WP_Type1 != 0) {
    4262             : 
    4263           2 :             switch (state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(EnvrnNum).WP_Type1).CalculationType) {
    4264           2 :             case SkyTempCalcType::ScheduleValue:
    4265           4 :                 ScheduleManager::GetSingleDayScheduleValues(
    4266             :                     state,
    4267           2 :                     state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(EnvrnNum).WP_Type1).SchedulePtr,
    4268           2 :                     state.dataWeatherManager->TomorrowSkyTemp);
    4269           2 :                 state.dataWeatherManager->DDSkyTempScheduleValues(_, _, EnvrnNum) = state.dataWeatherManager->TomorrowSkyTemp;
    4270           2 :                 break;
    4271           0 :             case SkyTempCalcType::DryBulbDelta:
    4272           0 :                 ScheduleManager::GetSingleDayScheduleValues(
    4273             :                     state,
    4274           0 :                     state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(EnvrnNum).WP_Type1).SchedulePtr,
    4275           0 :                     state.dataWeatherManager->TomorrowSkyTemp);
    4276           0 :                 state.dataWeatherManager->DDSkyTempScheduleValues(_, _, EnvrnNum) = state.dataWeatherManager->TomorrowSkyTemp;
    4277           0 :                 for (int hour = 1; hour <= 24; ++hour) {
    4278           0 :                     for (int ts = 1; ts <= state.dataGlobal->NumOfTimeStepInHour; ++ts) {
    4279           0 :                         state.dataWeatherManager->TomorrowSkyTemp(ts, hour) =
    4280           0 :                             state.dataWeatherManager->TomorrowOutDryBulbTemp(ts, hour) - state.dataWeatherManager->TomorrowSkyTemp(ts, hour);
    4281             :                     }
    4282           0 :                 }
    4283           0 :                 break;
    4284           0 :             case SkyTempCalcType::DewPointDelta:
    4285           0 :                 ScheduleManager::GetSingleDayScheduleValues(
    4286             :                     state,
    4287           0 :                     state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(EnvrnNum).WP_Type1).SchedulePtr,
    4288           0 :                     state.dataWeatherManager->TomorrowSkyTemp);
    4289           0 :                 state.dataWeatherManager->DDSkyTempScheduleValues(_, _, EnvrnNum) = state.dataWeatherManager->TomorrowSkyTemp;
    4290           0 :                 for (int hour = 1; hour <= 24; ++hour) {
    4291           0 :                     for (int ts = 1; ts <= state.dataGlobal->NumOfTimeStepInHour; ++ts) {
    4292           0 :                         state.dataWeatherManager->TomorrowSkyTemp(ts, hour) =
    4293           0 :                             state.dataWeatherManager->TomorrowOutDewPointTemp(ts, hour) - state.dataWeatherManager->TomorrowSkyTemp(ts, hour);
    4294             :                     }
    4295           0 :                 }
    4296           0 :                 break;
    4297           0 :             default:
    4298           0 :                 break;
    4299             :             }
    4300             :         }
    4301             : 
    4302        5716 :         state.dataGlobal->WarmupFlag = SaveWarmupFlag;
    4303        5716 :     }
    4304             : 
    4305       19788 :     Real64 AirMass(Real64 const CosZen) // COS( solar zenith), 0 - 1
    4306             :     {
    4307             : 
    4308             :         // SUBROUTINE INFORMATION:
    4309             :         //       AUTHOR         C Barnaby
    4310             :         //       DATE WRITTEN   Nov 2010
    4311             :         //       MODIFIED       na
    4312             :         //       RE-ENGINEERED  na
    4313             : 
    4314             :         // PURPOSE OF THIS SUBROUTINE:
    4315             :         // Calculate relative air mass using Kasten and Young approximation
    4316             : 
    4317             :         // METHODOLOGY EMPLOYED:
    4318             :         // Eqn (16), ASHRAE HOF 2009, p. 14.9
    4319             : 
    4320             :         // REFERENCES:
    4321             :         // ASHRAE HOF 2009 Chapter 14
    4322             :         // Kasten, F and T. Young.  1989.  Revised optical air mass tables
    4323             :         //   and approximating formula.  Applied Optics 28:4735-4738.
    4324             : 
    4325             :         Real64 AirMass;
    4326             :         Real64 SunAltD;
    4327             : 
    4328       19788 :         if (CosZen <= 0.001) {
    4329           6 :             AirMass = 37.07837343; // limit value calc'd with Excel
    4330             :                                    //  value increases little as CosZen -> 0
    4331       19782 :         } else if (CosZen >= 1.0) {
    4332           0 :             AirMass = 1.0;
    4333             :         } else {
    4334             :             // note: COS( Zen) = SIN( Alt)
    4335       19782 :             SunAltD = std::asin(CosZen) / DataGlobalConstants::DegToRadians; // altitude, degrees
    4336       19782 :             AirMass = 1.0 / (CosZen + 0.50572 * std::pow(6.07995 + SunAltD, -1.6364));
    4337             :         }
    4338       19788 :         return AirMass;
    4339             :     }
    4340             : 
    4341             :     //------------------------------------------------------------------------------
    4342             : 
    4343       19788 :     void ASHRAETauModel([[maybe_unused]] EnergyPlusData &state,
    4344             :                         DesignDaySolarModel const TauModelType, // ASHRAETau solar model type ASHRAE_Tau or ASHRAE_Tau2017
    4345             :                         Real64 const ETR,                       // extraterrestrial normal irradiance, W/m2
    4346             :                         Real64 const CosZen,                    // COS( solar zenith angle), 0 - 1
    4347             :                         Real64 const TauB,                      // beam tau factor
    4348             :                         Real64 const TauD,                      // dif tau factor
    4349             :                         Real64 &IDirN,                          // returned: direct (beam) irradiance on normal surface, W/m2
    4350             :                         Real64 &IDifH,                          // returned: diffuse irradiance on horiz surface, W/m2
    4351             :                         Real64 &IGlbH                           // returned: global irradiance on horiz surface, W/m2
    4352             :     )
    4353             :     {
    4354             : 
    4355             :         // SUBROUTINE INFORMATION:
    4356             :         //       AUTHOR         C Barnaby
    4357             :         //       DATE WRITTEN   Nov 2010
    4358             :         //       MODIFIED       na
    4359             :         //       RE-ENGINEERED  na
    4360             : 
    4361             :         // PURPOSE OF THIS SUBROUTINE:
    4362             :         // Calculate clear-sky direct and diffuse irradiance using ASHRAE "tau" model
    4363             : 
    4364             :         // METHODOLOGY EMPLOYED:
    4365             :         // Eqns (17-18), ASHRAE HOF 2009, p. 14.9
    4366             :         // Eqns (19-20), ASHRAE HOF 2013 p. 14.9 and 2017 p. 14.10
    4367             : 
    4368             :         // REFERENCES:
    4369             :         // ASHRAE HOF 2009 Chapter 14
    4370             : 
    4371             :         Real64 AB; // air mass exponents
    4372             :         Real64 AD;
    4373             :         Real64 M; // air mass
    4374             : 
    4375       19788 :         if (CosZen < DataEnvironment::SunIsUpValue || TauB <= 0.0 || TauD <= 0.0) {
    4376           0 :             IDirN = 0.0;
    4377           0 :             IDifH = 0.0;
    4378           0 :             IGlbH = 0.0;
    4379             :         } else {
    4380       19788 :             if (TauModelType == DesignDaySolarModel::ASHRAE_Tau) {
    4381       19788 :                 AB = 1.219 - 0.043 * TauB - 0.151 * TauD - 0.204 * TauB * TauD;
    4382       19788 :                 AD = 0.202 + 0.852 * TauB - 0.007 * TauD - 0.357 * TauB * TauD;
    4383             :             } else {
    4384             :                 // TauModelType == ASHRAE_Tau2017
    4385           0 :                 AB = 1.454 - 0.406 * TauB - 0.268 * TauD + 0.021 * TauB * TauD;
    4386           0 :                 AD = 0.507 + 0.205 * TauB - 0.080 * TauD - 0.190 * TauB * TauD;
    4387             :             }
    4388       19788 :             M = AirMass(CosZen);
    4389       19788 :             IDirN = ETR * std::exp(-TauB * std::pow(M, AB));
    4390       19788 :             IDifH = ETR * std::exp(-TauD * std::pow(M, AD));
    4391       19788 :             IGlbH = IDirN * CosZen + IDifH;
    4392             :         }
    4393       19788 :     }
    4394             : 
    4395         771 :     void AllocateWeatherData(EnergyPlusData &state)
    4396             :     {
    4397             : 
    4398             :         // SUBROUTINE INFORMATION:
    4399             :         //       AUTHOR         Linda Lawrie
    4400             :         //       DATE WRITTEN   December 2000
    4401             :         //       MODIFIED       na
    4402             :         //       RE-ENGINEERED  na
    4403             : 
    4404             :         // PURPOSE OF THIS SUBROUTINE:
    4405             :         // This subroutine allocates the weather data structures (Today, Tomorrow,
    4406             :         // Design Day) to the proper number of "time steps in hour" requested by the user.
    4407             :         // Interpolation of data is done later after either setting up the design day (hourly
    4408             :         // data) or reading in hourly weather data.
    4409             : 
    4410         771 :         state.dataWeatherManager->TodayIsRain.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4411         771 :         state.dataWeatherManager->TodayIsRain = false;
    4412         771 :         state.dataWeatherManager->TodayIsSnow.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4413         771 :         state.dataWeatherManager->TodayIsSnow = false;
    4414         771 :         state.dataWeatherManager->TodayOutDryBulbTemp.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4415         771 :         state.dataWeatherManager->TodayOutDryBulbTemp = 0.0;
    4416         771 :         state.dataWeatherManager->TodayOutDewPointTemp.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4417         771 :         state.dataWeatherManager->TodayOutDewPointTemp = 0.0;
    4418         771 :         state.dataWeatherManager->TodayOutBaroPress.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4419         771 :         state.dataWeatherManager->TodayOutBaroPress = 0.0;
    4420         771 :         state.dataWeatherManager->TodayOutRelHum.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4421         771 :         state.dataWeatherManager->TodayOutRelHum = 0.0;
    4422         771 :         state.dataWeatherManager->TodayWindSpeed.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4423         771 :         state.dataWeatherManager->TodayWindSpeed = 0.0;
    4424         771 :         state.dataWeatherManager->TodayWindDir.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4425         771 :         state.dataWeatherManager->TodayWindDir = 0.0;
    4426         771 :         state.dataWeatherManager->TodaySkyTemp.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4427         771 :         state.dataWeatherManager->TodaySkyTemp = 0.0;
    4428         771 :         state.dataWeatherManager->TodayHorizIRSky.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4429         771 :         state.dataWeatherManager->TodayHorizIRSky = 0.0;
    4430         771 :         state.dataWeatherManager->TodayBeamSolarRad.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4431         771 :         state.dataWeatherManager->TodayBeamSolarRad = 0.0;
    4432         771 :         state.dataWeatherManager->TodayDifSolarRad.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4433         771 :         state.dataWeatherManager->TodayDifSolarRad = 0.0;
    4434         771 :         state.dataWeatherManager->TodayAlbedo.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4435         771 :         state.dataWeatherManager->TodayAlbedo = 0.0;
    4436         771 :         state.dataWeatherManager->TodayLiquidPrecip.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4437         771 :         state.dataWeatherManager->TodayLiquidPrecip = 0.0;
    4438         771 :         state.dataWeatherManager->TodayTotalSkyCover.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4439         771 :         state.dataWeatherManager->TodayTotalSkyCover = 0.0;
    4440         771 :         state.dataWeatherManager->TodayOpaqueSkyCover.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4441         771 :         state.dataWeatherManager->TodayOpaqueSkyCover = 0.0;
    4442             : 
    4443         771 :         state.dataWeatherManager->TomorrowIsRain.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4444         771 :         state.dataWeatherManager->TomorrowIsRain = false;
    4445         771 :         state.dataWeatherManager->TomorrowIsSnow.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4446         771 :         state.dataWeatherManager->TomorrowIsSnow = false;
    4447         771 :         state.dataWeatherManager->TomorrowOutDryBulbTemp.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4448         771 :         state.dataWeatherManager->TomorrowOutDryBulbTemp = 0.0;
    4449         771 :         state.dataWeatherManager->TomorrowOutDewPointTemp.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4450         771 :         state.dataWeatherManager->TomorrowOutDewPointTemp = 0.0;
    4451         771 :         state.dataWeatherManager->TomorrowOutBaroPress.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4452         771 :         state.dataWeatherManager->TomorrowOutBaroPress = 0.0;
    4453         771 :         state.dataWeatherManager->TomorrowOutRelHum.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4454         771 :         state.dataWeatherManager->TomorrowOutRelHum = 0.0;
    4455         771 :         state.dataWeatherManager->TomorrowWindSpeed.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4456         771 :         state.dataWeatherManager->TomorrowWindSpeed = 0.0;
    4457         771 :         state.dataWeatherManager->TomorrowWindDir.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4458         771 :         state.dataWeatherManager->TomorrowWindDir = 0.0;
    4459         771 :         state.dataWeatherManager->TomorrowSkyTemp.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4460         771 :         state.dataWeatherManager->TomorrowSkyTemp = 0.0;
    4461         771 :         state.dataWeatherManager->TomorrowHorizIRSky.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4462         771 :         state.dataWeatherManager->TomorrowHorizIRSky = 0.0;
    4463         771 :         state.dataWeatherManager->TomorrowBeamSolarRad.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4464         771 :         state.dataWeatherManager->TomorrowBeamSolarRad = 0.0;
    4465         771 :         state.dataWeatherManager->TomorrowDifSolarRad.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4466         771 :         state.dataWeatherManager->TomorrowDifSolarRad = 0.0;
    4467         771 :         state.dataWeatherManager->TomorrowAlbedo.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4468         771 :         state.dataWeatherManager->TomorrowAlbedo = 0.0;
    4469         771 :         state.dataWeatherManager->TomorrowLiquidPrecip.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4470         771 :         state.dataWeatherManager->TomorrowLiquidPrecip = 0.0;
    4471         771 :         state.dataWeatherManager->TomorrowTotalSkyCover.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4472         771 :         state.dataWeatherManager->TomorrowTotalSkyCover = 0.0;
    4473         771 :         state.dataWeatherManager->TomorrowOpaqueSkyCover.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
    4474         771 :         state.dataWeatherManager->TomorrowOpaqueSkyCover = 0.0;
    4475         771 :     }
    4476             : 
    4477        8073 :     void CalculateDailySolarCoeffs(EnergyPlusData &state,
    4478             :                                    int const DayOfYear,           // Day of year (1 - 366)
    4479             :                                    Real64 &A,                     // ASHRAE "A" - Apparent solar irradiation at air mass = 0 [W/M**2]
    4480             :                                    Real64 &B,                     // ASHRAE "B" - Atmospheric extinction coefficient
    4481             :                                    Real64 &C,                     // ASHRAE "C" - Diffuse radiation factor
    4482             :                                    Real64 &AnnVarSolConstant,     // Annual variation in the solar constant
    4483             :                                    Real64 &EquationOfTime,        // Equation of Time
    4484             :                                    Real64 &SineSolarDeclination,  // Sine of Solar Declination
    4485             :                                    Real64 &CosineSolarDeclination // Cosine of Solar Declination
    4486             :     )
    4487             :     {
    4488             : 
    4489             :         // SUBROUTINE INFORMATION:
    4490             :         //       AUTHOR         George Walton
    4491             :         //       DATE WRITTEN   May 1985
    4492             :         //       MODIFIED       1999 for EnergyPlus
    4493             :         //       RE-ENGINEERED  2001; LKL; Remove need for English -> SI conversion
    4494             :         //                      Implement Tarp "fix" for Southern Hemisphere
    4495             : 
    4496             :         // PURPOSE OF THIS SUBROUTINE:
    4497             :         // This subroutine computes the daily solar coefficients used in other
    4498             :         // calculations.  Specifically, this routine computes values of the solar declination, equation
    4499             :         // of time, and ashrae sky coefficients a, b, and c for a given
    4500             :         // day of the year.
    4501             : 
    4502             :         // METHODOLOGY EMPLOYED:
    4503             :         // The method is the same as that recommended in the ASHRAE loads
    4504             :         // algorithms manual, except that the fourier series expressions
    4505             :         // have been extended by two terms for greater accuracy.
    4506             :         // coefficients for the new expressions were determined at USACERL
    4507             :         // using data from the cited references.
    4508             : 
    4509             :         // REFERENCES:
    4510             :         // J. L. Threlkeld, "Thermal Environmental Engineering", 1970,
    4511             :         // p.316, for declination and equation of time.
    4512             :         // "ASHRAE Handbook of Fundamentals", 1972, p.387 for sky
    4513             :         // coefficients a, b, and c.
    4514             :         // See SUN3 in SolarShading. See SUN2 in BLAST.  See SUN3 in Tarp.
    4515             : 
    4516        8073 :         Real64 const DayCorrection(DataGlobalConstants::Pi * 2.0 / 366.0);
    4517             : 
    4518             :         // Fitted coefficients of Fourier series | Sine of declination coefficients
    4519             :         static constexpr std::array<Real64, 9> SineSolDeclCoef = {
    4520             :             0.00561800, 0.0657911, -0.392779, 0.00064440, -0.00618495, -0.00010101, -0.00007951, -0.00011691, 0.00002096};
    4521             :         // Fitted coefficients of Fourier Series | Equation of Time coefficients
    4522             :         static constexpr std::array<Real64, 9> EqOfTimeCoef = {
    4523             :             0.00021971, -0.122649, 0.00762856, -0.156308, -0.0530028, -0.00388702, -0.00123978, -0.00270502, -0.00167992};
    4524             :         // Fitted coefficients of Fourier Series | ASHRAE A Factor coefficients
    4525             :         static constexpr std::array<Real64, 9> ASHRAE_A_Coef = {1161.6685, 1.1554, 77.3575, -0.5359, -3.7622, 0.9875, -3.3924, -1.7445, 1.1198};
    4526             :         // Fitted coefficients of Fourier Series | ASHRAE B Factor coefficients
    4527             :         static constexpr std::array<Real64, 9> ASHRAE_B_Coef = {
    4528             :             0.171631, -0.00400448, -0.0344923, 0.00000209, 0.00325428, -0.00085429, 0.00229562, 0.0009034, -0.0011867};
    4529             :         // Fitted coefficients of Fourier Series | ASHRAE C Factor coefficients
    4530             :         static constexpr std::array<Real64, 9> ASHRAE_C_Coef = {
    4531             :             0.0905151, -0.00322522, -0.0407966, 0.000104164, 0.00745899, -0.00086461, 0.0013111, 0.000808275, -0.00170515};
    4532             : 
    4533             :         // Day of Year in Radians (Computed from Input DayOfYear)
    4534        8073 :         Real64 X = DayCorrection * DayOfYear; // Convert Julian date (Day of Year) to angle X
    4535             : 
    4536             :         // Calculate sines and cosines of X
    4537        8073 :         Real64 SinX = std::sin(X);
    4538        8073 :         Real64 CosX = std::cos(X);
    4539             : 
    4540       24219 :         SineSolarDeclination = SineSolDeclCoef[0] + SineSolDeclCoef[1] * SinX + SineSolDeclCoef[2] * CosX + SineSolDeclCoef[3] * (SinX * CosX * 2.0) +
    4541       16146 :                                SineSolDeclCoef[4] * (pow_2(CosX) - pow_2(SinX)) +
    4542       16146 :                                SineSolDeclCoef[5] * (SinX * (pow_2(CosX) - pow_2(SinX)) + CosX * (SinX * CosX * 2.0)) +
    4543       16146 :                                SineSolDeclCoef[6] * (CosX * (pow_2(CosX) - pow_2(SinX)) - SinX * (SinX * CosX * 2.0)) +
    4544       16146 :                                SineSolDeclCoef[7] * (2.0 * (SinX * CosX * 2.0) * (pow_2(CosX) - pow_2(SinX))) +
    4545        8073 :                                SineSolDeclCoef[8] * (pow_2(pow_2(CosX) - pow_2(SinX)) - pow_2(SinX * CosX * 2.0));
    4546        8073 :         CosineSolarDeclination = std::sqrt(1.0 - pow_2(SineSolarDeclination));
    4547             : 
    4548       24219 :         EquationOfTime = EqOfTimeCoef[0] + EqOfTimeCoef[1] * SinX + EqOfTimeCoef[2] * CosX + EqOfTimeCoef[3] * (SinX * CosX * 2.0) +
    4549       16146 :                          EqOfTimeCoef[4] * (pow_2(CosX) - pow_2(SinX)) +
    4550       16146 :                          EqOfTimeCoef[5] * (SinX * (pow_2(CosX) - pow_2(SinX)) + CosX * (SinX * CosX * 2.0)) +
    4551       16146 :                          EqOfTimeCoef[6] * (CosX * (pow_2(CosX) - pow_2(SinX)) - SinX * (SinX * CosX * 2.0)) +
    4552       16146 :                          EqOfTimeCoef[7] * (2.0 * (SinX * CosX * 2.0) * (pow_2(CosX) - pow_2(SinX))) +
    4553        8073 :                          EqOfTimeCoef[8] * (pow_2(pow_2(CosX) - pow_2(SinX)) - pow_2(SinX * CosX * 2.0));
    4554             : 
    4555        8073 :         AnnVarSolConstant = 1.000047 + 0.000352615 * SinX + 0.0334454 * CosX;
    4556             : 
    4557       24219 :         A = ASHRAE_A_Coef[0] + ASHRAE_A_Coef[1] * SinX + ASHRAE_A_Coef[2] * CosX + ASHRAE_A_Coef[3] * (SinX * CosX * 2.0) +
    4558       24219 :             ASHRAE_A_Coef[4] * (pow_2(CosX) - pow_2(SinX)) + ASHRAE_A_Coef[5] * (SinX * (pow_2(CosX) - pow_2(SinX)) + CosX * (SinX * CosX * 2.0)) +
    4559       16146 :             ASHRAE_A_Coef[6] * (CosX * (pow_2(CosX) - pow_2(SinX)) - SinX * (SinX * CosX * 2.0)) +
    4560       16146 :             ASHRAE_A_Coef[7] * (2.0 * (SinX * CosX * 2.0) * (pow_2(CosX) - pow_2(SinX))) +
    4561        8073 :             ASHRAE_A_Coef[8] * (pow_2(pow_2(CosX) - pow_2(SinX)) - pow_2(SinX * CosX * 2.0));
    4562             : 
    4563             :         // Compute B and C coefficients
    4564             : 
    4565        8073 :         if (state.dataEnvrn->Latitude < 0.0) {
    4566             :             // If in southern hemisphere, compute B and C with a six month time shift.
    4567           0 :             X -= DataGlobalConstants::Pi;
    4568           0 :             SinX = std::sin(X);
    4569           0 :             CosX = std::cos(X);
    4570             :         }
    4571             : 
    4572       24219 :         B = ASHRAE_B_Coef[0] + ASHRAE_B_Coef[1] * SinX + ASHRAE_B_Coef[2] * CosX + ASHRAE_B_Coef[3] * (SinX * CosX * 2.0) +
    4573       24219 :             ASHRAE_B_Coef[4] * (pow_2(CosX) - pow_2(SinX)) + ASHRAE_B_Coef[5] * (SinX * (pow_2(CosX) - pow_2(SinX)) + CosX * (SinX * CosX * 2.0)) +
    4574       16146 :             ASHRAE_B_Coef[6] * (CosX * (pow_2(CosX) - pow_2(SinX)) - SinX * (SinX * CosX * 2.0)) +
    4575       16146 :             ASHRAE_B_Coef[7] * (2.0 * (SinX * CosX * 2.0) * (pow_2(CosX) - pow_2(SinX))) +
    4576        8073 :             ASHRAE_B_Coef[8] * (pow_2(pow_2(CosX) - pow_2(SinX)) - pow_2(SinX * CosX * 2.0));
    4577             : 
    4578       24219 :         C = ASHRAE_C_Coef[0] + ASHRAE_C_Coef[1] * SinX + ASHRAE_C_Coef[2] * CosX + ASHRAE_C_Coef[3] * (SinX * CosX * 2.0) +
    4579       24219 :             ASHRAE_C_Coef[4] * (pow_2(CosX) - pow_2(SinX)) + ASHRAE_C_Coef[5] * (SinX * (pow_2(CosX) - pow_2(SinX)) + CosX * (SinX * CosX * 2.0)) +
    4580       16146 :             ASHRAE_C_Coef[6] * (CosX * (pow_2(CosX) - pow_2(SinX)) - SinX * (SinX * CosX * 2.0)) +
    4581       16146 :             ASHRAE_C_Coef[7] * (2.0 * (SinX * CosX * 2.0) * (pow_2(CosX) - pow_2(SinX))) +
    4582        8073 :             ASHRAE_C_Coef[8] * (pow_2(pow_2(CosX) - pow_2(SinX)) - pow_2(SinX * CosX * 2.0));
    4583        8073 :     }
    4584             : 
    4585      748080 :     void CalculateSunDirectionCosines(EnergyPlusData &state,
    4586             :                                       Real64 const TimeValue,    // Current Time of Day
    4587             :                                       Real64 const EqOfTime,     // Equation of Time
    4588             :                                       Real64 const SinSolDeclin, // Sine of Solar Declination
    4589             :                                       Real64 const CosSolDeclin, // Cosine of Solar Declination
    4590             :                                       Array1D<Real64> &SUNCOS)
    4591             :     {
    4592             : 
    4593             :         // SUBROUTINE INFORMATION:
    4594             :         //       AUTHOR         George Walton
    4595             :         //       DATE WRITTEN   May 1975
    4596             :         //       MODIFIED       1999 for EnergyPlus
    4597             :         //       RE-ENGINEERED  na
    4598             : 
    4599             :         // PURPOSE OF THIS SUBROUTINE:
    4600             :         // This routine computes the solar direction cosines for hourly
    4601             :         // radiation calculations.
    4602             : 
    4603             :         // REFERENCES:
    4604             :         // "NECAP Engineering Manual", 1974, p.3-117
    4605             : 
    4606      748080 :         EP_SIZE_CHECK(SUNCOS, 3); // NOLINT(misc-static-assert)
    4607             : 
    4608             :         // COMPUTE THE HOUR ANGLE
    4609      748080 :         Real64 H = (15.0 * (12.0 - (TimeValue + EqOfTime)) + (state.dataEnvrn->TimeZoneMeridian - state.dataEnvrn->Longitude)) *
    4610      748080 :                    DataGlobalConstants::DegToRadians;
    4611      748080 :         Real64 COSH = std::cos(H);
    4612             :         // COMPUTE THE COSINE OF THE SOLAR ZENITH ANGLE.
    4613             :         // This is also the Sine of the Solar Altitude Angle
    4614             : 
    4615      748080 :         SUNCOS(3) = SinSolDeclin * state.dataEnvrn->SinLatitude + CosSolDeclin * state.dataEnvrn->CosLatitude * COSH;
    4616             : 
    4617      748080 :         if (SUNCOS(3) >= DataEnvironment::SunIsUpValue) { // If Sun above horizon, compute other direction cosines
    4618      376711 :             SUNCOS(2) = SinSolDeclin * state.dataEnvrn->CosLatitude - CosSolDeclin * state.dataEnvrn->SinLatitude * COSH;
    4619      376711 :             SUNCOS(1) = CosSolDeclin * std::sin(H);
    4620             :         } else { // Sun is down, set to 0.0
    4621      371369 :             SUNCOS(1) = 0.0;
    4622      371369 :             SUNCOS(2) = 0.0;
    4623             :         }
    4624      748080 :     }
    4625             : 
    4626     2661169 :     void DetermineSunUpDown(EnergyPlusData &state, Array1D<Real64> &SunDirectionCosines)
    4627             :     {
    4628             : 
    4629             :         // SUBROUTINE INFORMATION:
    4630             :         //       AUTHOR         Linda Lawrie
    4631             :         //       DATE WRITTEN   1999
    4632             :         //       MODIFIED       na
    4633             :         //       RE-ENGINEERED  na
    4634             : 
    4635             :         // PURPOSE OF THIS SUBROUTINE:
    4636             :         // This subroutine determines if the sun is up or down for the current
    4637             :         // hour/timestep.
    4638             : 
    4639             :         // REFERENCES:
    4640             :         // Sun routines from IBLAST, authored by Walton.
    4641             : 
    4642     2661169 :         EP_SIZE_CHECK(SunDirectionCosines, 3); // NOLINT(misc-static-assert)
    4643             : 
    4644             :         // COMPUTE THE HOUR ANGLE
    4645     2661169 :         if (state.dataGlobal->NumOfTimeStepInHour != 1) {
    4646     2648653 :             state.dataWeatherManager->HrAngle =
    4647     5297306 :                 (15.0 * (12.0 - (state.dataGlobal->CurrentTime + state.dataWeatherManager->TodayVariables.EquationOfTime)) +
    4648     2648653 :                  (state.dataEnvrn->TimeZoneMeridian - state.dataEnvrn->Longitude));
    4649             :         } else {
    4650       37548 :             state.dataWeatherManager->HrAngle = (15.0 * (12.0 - ((state.dataGlobal->CurrentTime + state.dataEnvrn->TS1TimeOffset) +
    4651       25032 :                                                                  state.dataWeatherManager->TodayVariables.EquationOfTime)) +
    4652       12516 :                                                  (state.dataEnvrn->TimeZoneMeridian - state.dataEnvrn->Longitude));
    4653             :         }
    4654     2661169 :         Real64 H = state.dataWeatherManager->HrAngle * DataGlobalConstants::DegToRadians;
    4655             : 
    4656             :         // Compute the Cosine of the Solar Zenith (Altitude) Angle.
    4657     2661169 :         Real64 CosZenith = state.dataEnvrn->SinLatitude * state.dataWeatherManager->TodayVariables.SinSolarDeclinAngle +
    4658     2661169 :                            state.dataEnvrn->CosLatitude * state.dataWeatherManager->TodayVariables.CosSolarDeclinAngle * std::cos(H);
    4659             : 
    4660     2661169 :         Real64 SolarZenith = std::acos(CosZenith);
    4661     2661169 :         Real64 SinAltitude = state.dataEnvrn->CosLatitude * state.dataWeatherManager->TodayVariables.CosSolarDeclinAngle * std::cos(H) +
    4662     2661169 :                              state.dataEnvrn->SinLatitude * state.dataWeatherManager->TodayVariables.SinSolarDeclinAngle;
    4663     2661169 :         Real64 SolarAltitude = std::asin(SinAltitude);
    4664     2661169 :         Real64 CosAzimuth = -(state.dataEnvrn->SinLatitude * CosZenith - state.dataWeatherManager->TodayVariables.SinSolarDeclinAngle) /
    4665     2661169 :                             (state.dataEnvrn->CosLatitude * std::sin(SolarZenith));
    4666             :         // Following because above can yield invalid cos value.  (e.g. at south pole)
    4667     2661169 :         CosAzimuth = max(CosAzimuth, -1.0);
    4668     2661169 :         CosAzimuth = min(1.0, CosAzimuth);
    4669     2661169 :         Real64 SolarAzimuth = std::acos(CosAzimuth);
    4670             : 
    4671     2661169 :         state.dataWeatherManager->SolarAltitudeAngle = SolarAltitude / DataGlobalConstants::DegToRadians;
    4672     2661169 :         state.dataWeatherManager->SolarAzimuthAngle = SolarAzimuth / DataGlobalConstants::DegToRadians;
    4673     2661169 :         if (state.dataWeatherManager->HrAngle < 0.0) {
    4674     1331383 :             state.dataWeatherManager->SolarAzimuthAngle = 360.0 - state.dataWeatherManager->SolarAzimuthAngle;
    4675             :         }
    4676             : 
    4677     2661169 :         SunDirectionCosines(3) = CosZenith;
    4678     2661169 :         state.dataEnvrn->SunIsUpPrevTS = state.dataEnvrn->SunIsUp;
    4679     2661169 :         if (CosZenith < DataEnvironment::SunIsUpValue) {
    4680     1326427 :             state.dataEnvrn->SunIsUp = false;
    4681     1326427 :             SunDirectionCosines(2) = 0.0;
    4682     1326427 :             SunDirectionCosines(1) = 0.0;
    4683             :         } else {
    4684     1334742 :             state.dataEnvrn->SunIsUp = true;
    4685     2669484 :             SunDirectionCosines(2) = state.dataWeatherManager->TodayVariables.SinSolarDeclinAngle * state.dataEnvrn->CosLatitude -
    4686     1334742 :                                      state.dataWeatherManager->TodayVariables.CosSolarDeclinAngle * state.dataEnvrn->SinLatitude * std::cos(H);
    4687     1334742 :             SunDirectionCosines(1) = state.dataWeatherManager->TodayVariables.CosSolarDeclinAngle * std::sin(H);
    4688             :         }
    4689     2661169 :     }
    4690             : 
    4691         771 :     void OpenWeatherFile(EnergyPlusData &state, bool &ErrorsFound)
    4692             :     {
    4693             : 
    4694             :         // SUBROUTINE INFORMATION:
    4695             :         //       AUTHOR         Linda Lawrie
    4696             :         //       DATE WRITTEN   June 1999
    4697             :         //       RE-ENGINEERED  na
    4698             : 
    4699             :         // PURPOSE OF THIS SUBROUTINE:
    4700             :         // This subroutine checks to see if a weather file and what kind of weather file
    4701             :         // exists in the working directory and calls appropriate routines to
    4702             :         // open the files and set up for use.
    4703             : 
    4704         771 :         state.dataWeatherManager->WeatherFileExists = FileSystem::fileExists(state.files.inputWeatherFilePath.filePath);
    4705         771 :         if (state.dataWeatherManager->WeatherFileExists) {
    4706         761 :             OpenEPlusWeatherFile(state, ErrorsFound, true);
    4707             :         }
    4708         771 :     }
    4709             : 
    4710        4369 :     void OpenEPlusWeatherFile(EnergyPlusData &state,
    4711             :                               bool &ErrorsFound,       // Will be set to true if errors found
    4712             :                               bool const ProcessHeader // Set to true when headers should be processed (rather than just read)
    4713             :     )
    4714             :     {
    4715             : 
    4716             :         // SUBROUTINE INFORMATION:
    4717             :         //       AUTHOR         Linda K. Lawrie
    4718             :         //       DATE WRITTEN   June 1999
    4719             : 
    4720             :         // PURPOSE OF THIS SUBROUTINE:
    4721             :         // This subroutine opens the EnergyPlus Weather File (in.epw) and processes
    4722             :         // the initial header records.
    4723             : 
    4724             :         // METHODOLOGY EMPLOYED:
    4725             :         // List directed reads, as possible.
    4726             : 
    4727        4369 :         state.files.inputWeatherFile.close();
    4728        4369 :         state.files.inputWeatherFile.filePath = state.files.inputWeatherFilePath.filePath;
    4729        4369 :         state.files.inputWeatherFile.open();
    4730        4369 :         if (!state.files.inputWeatherFile.good()) {
    4731           0 :             ShowFatalError(state, "OpenWeatherFile: Could not OPEN EPW Weather File", OptionalOutputFileRef(state.files.eso));
    4732             :         }
    4733             : 
    4734        4369 :         if (ProcessHeader) {
    4735             :             // Read in Header Information
    4736             : 
    4737             :             // Headers should come in order
    4738        6849 :             for (int typeNum = static_cast<int>(EpwHeaderType::Location); typeNum < static_cast<int>(EpwHeaderType::Num); ++typeNum) {
    4739       12176 :                 auto Line = state.files.inputWeatherFile.readLine();
    4740        6088 :                 if (Line.eof) {
    4741           0 :                     ShowFatalError(
    4742             :                         state,
    4743           0 :                         format("OpenWeatherFile: Unexpected End-of-File on EPW Weather file, while reading header information, looking for header={}",
    4744           0 :                                epwHeaders[typeNum]),
    4745           0 :                         OptionalOutputFileRef(state.files.eso));
    4746             :                 }
    4747             : 
    4748        6088 :                 int endcol = len(Line.data);
    4749        6088 :                 if (endcol > 0) {
    4750        6088 :                     if (int(Line.data[endcol - 1]) == DataSystemVariables::iUnicode_end) {
    4751           0 :                         ShowSevereError(state,
    4752             :                                         "OpenWeatherFile: EPW Weather File appears to be a Unicode or binary file.",
    4753           0 :                                         OptionalOutputFileRef(state.files.eso));
    4754           0 :                         ShowContinueError(state, "...This file cannot be read by this program. Please save as PC or Unix file and try again");
    4755           0 :                         ShowFatalError(state, "Program terminates due to previous condition.");
    4756             :                     }
    4757             :                 }
    4758        6088 :                 std::string::size_type const Pos = FindNonSpace(Line.data);
    4759        6088 :                 std::string::size_type const HdPos = index(Line.data, epwHeaders[typeNum]);
    4760        6088 :                 if (Pos != HdPos) continue;
    4761        6088 :                 ProcessEPWHeader(state, static_cast<EpwHeaderType>(typeNum), Line.data, ErrorsFound);
    4762             :             }
    4763             :         } else { // Header already processed, just read
    4764        3608 :             SkipEPlusWFHeader(state);
    4765             :         }
    4766        4369 :     }
    4767             : 
    4768       11626 :     void CloseWeatherFile(EnergyPlusData &state)
    4769             :     {
    4770       11626 :         state.files.inputWeatherFile.close();
    4771       11626 :     }
    4772             : 
    4773         771 :     void ResolveLocationInformation(EnergyPlusData &state, bool &ErrorsFound) // Set to true if no location evident
    4774             :     {
    4775             : 
    4776             :         // SUBROUTINE INFORMATION:
    4777             :         //       AUTHOR         Rick Strand
    4778             :         //       DATE WRITTEN   June 1997
    4779             :         //       MODIFIED       na
    4780             :         //       RE-ENGINEERED  na
    4781             : 
    4782             :         // PURPOSE OF THIS SUBROUTINE:
    4783             :         // This subroutine is currently the main interface between the old data
    4784             :         // structure on the BLAST Weather file and the new data structure contained
    4785             :         // in this module.  At some point, this subroutine will be converted
    4786             :         // to read information directly from the new input file.
    4787             : 
    4788        1542 :         if (state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).KindOfEnvrn ==
    4789        1518 :                 DataGlobalConstants::KindOfSim::RunPeriodWeather &&
    4790         747 :             state.dataWeatherManager->WeatherFileExists) {
    4791         737 :             if (state.dataWeatherManager->LocationGathered) {
    4792             :                 // See if "matching" location
    4793        2143 :                 if (std::abs(state.dataEnvrn->Latitude - state.dataWeatherManager->WeatherFileLatitude) > 1.0 ||
    4794        1366 :                     std::abs(state.dataEnvrn->Longitude - state.dataWeatherManager->WeatherFileLongitude) > 1.0 ||
    4795        2096 :                     std::abs(state.dataEnvrn->TimeZoneNumber - state.dataWeatherManager->WeatherFileTimeZone) > 0.0 ||
    4796         683 :                     std::abs(state.dataEnvrn->Elevation - state.dataWeatherManager->WeatherFileElevation) / max(state.dataEnvrn->Elevation, 1.0) >
    4797             :                         0.10) {
    4798          68 :                     ShowWarningError(state, "Weather file location will be used rather than entered (IDF) Location object.");
    4799          68 :                     ShowContinueError(state, "..Location object=" + state.dataWeatherManager->LocationTitle);
    4800          68 :                     ShowContinueError(state, "..Weather File Location=" + state.dataEnvrn->WeatherFileLocationTitle);
    4801         204 :                     ShowContinueError(
    4802             :                         state,
    4803         136 :                         format("..due to location differences, Latitude difference=[{:.2R}] degrees, Longitude difference=[{:.2R}] degrees.",
    4804         136 :                                std::abs(state.dataEnvrn->Latitude - state.dataWeatherManager->WeatherFileLatitude),
    4805         204 :                                std::abs(state.dataEnvrn->Longitude - state.dataWeatherManager->WeatherFileLongitude)));
    4806         204 :                     ShowContinueError(state,
    4807         136 :                                       format("..Time Zone difference=[{:.1R}] hour(s), Elevation difference=[{:.2R}] percent, [{:.2R}] meters.",
    4808         136 :                                              std::abs(state.dataEnvrn->TimeZoneNumber - state.dataWeatherManager->WeatherFileTimeZone),
    4809         204 :                                              std::abs((state.dataEnvrn->Elevation - state.dataWeatherManager->WeatherFileElevation) /
    4810          68 :                                                       max(state.dataEnvrn->Elevation, 1.0) * 100.0),
    4811         204 :                                              std::abs(state.dataEnvrn->Elevation - state.dataWeatherManager->WeatherFileElevation)));
    4812             :                 }
    4813             :             }
    4814             : 
    4815         737 :             state.dataWeatherManager->LocationTitle = state.dataEnvrn->WeatherFileLocationTitle;
    4816         737 :             state.dataEnvrn->Latitude = state.dataWeatherManager->WeatherFileLatitude;
    4817         737 :             state.dataEnvrn->Longitude = state.dataWeatherManager->WeatherFileLongitude;
    4818         737 :             state.dataEnvrn->TimeZoneNumber = state.dataWeatherManager->WeatherFileTimeZone;
    4819         737 :             state.dataEnvrn->Elevation = state.dataWeatherManager->WeatherFileElevation;
    4820          34 :         } else if (!state.dataWeatherManager->LocationGathered) {
    4821           0 :             state.dataWeatherManager->LocationTitle = "Not Entered";
    4822           0 :             ShowSevereError(state, "No Location given. Must have location information for simulation.");
    4823           0 :             ErrorsFound = true;
    4824             :         }
    4825             : 
    4826         771 :         if (!ErrorsFound) {
    4827         771 :             state.dataEnvrn->StdBaroPress = DataEnvironment::StdPressureSeaLevel * std::pow(1.0 - 2.25577e-05 * state.dataEnvrn->Elevation, 5.2559);
    4828         771 :             state.dataEnvrn->StdRhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(
    4829         771 :                 state, state.dataEnvrn->StdBaroPress, DataPrecisionGlobals::constant_twenty, DataPrecisionGlobals::constant_zero);
    4830             :             // Write Final Location Information to the initialization output file
    4831             :             static constexpr std::string_view LocHdFormat(
    4832             :                 "! <Site:Location>, Location Name, Latitude {N+/S- Deg}, Longitude {E+/W- Deg},  Time Zone Number "
    4833             :                 "{GMT+/-}, Elevation {m},  Standard Pressure at Elevation {Pa}, Standard RhoAir at Elevation\n");
    4834         771 :             print(state.files.eio, "{}", LocHdFormat);
    4835             : 
    4836             :             static constexpr std::string_view LocFormat("Site:Location,{},{:.2R},{:.2R},{:.2R},{:.2R},{:.0R},{:.4R}\n");
    4837        5397 :             print(state.files.eio,
    4838             :                   LocFormat,
    4839         771 :                   state.dataWeatherManager->LocationTitle,
    4840         771 :                   state.dataEnvrn->Latitude,
    4841         771 :                   state.dataEnvrn->Longitude,
    4842         771 :                   state.dataEnvrn->TimeZoneNumber,
    4843         771 :                   state.dataEnvrn->Elevation,
    4844         771 :                   state.dataEnvrn->StdBaroPress,
    4845         771 :                   state.dataEnvrn->StdRhoAir);
    4846             :         }
    4847         771 :     }
    4848             : 
    4849        2115 :     void CheckLocationValidity(EnergyPlusData &state)
    4850             :     {
    4851             : 
    4852             :         // SUBROUTINE INFORMATION:
    4853             :         //       AUTHOR         Rick Strand
    4854             :         //       DATE WRITTEN   June 1997
    4855             :         //       MODIFIED       na
    4856             :         //       RE-ENGINEERED  na
    4857             : 
    4858             :         // PURPOSE OF THIS SUBROUTINE:
    4859             :         // This subroutine is checks to see whether the user specified location
    4860             :         // or the weather file location (if one exists) is valid.  The standard
    4861             :         // time meridian is also calculated and compared to the user supplied
    4862             :         // or weather file time zone number.
    4863             : 
    4864        2115 :         bool LocationError = false; // Set to true if there is a problem detected
    4865             : 
    4866        2115 :         if ((state.dataEnvrn->Latitude == -999.0) && (state.dataEnvrn->Longitude == -999.0) && (state.dataEnvrn->TimeZoneNumber != -999.0)) {
    4867           0 :             ShowSevereError(state, "No location specified");
    4868           0 :             LocationError = true;
    4869             :         }
    4870             : 
    4871        2115 :         if ((state.dataEnvrn->Latitude < -90.0) || (state.dataEnvrn->Latitude > 90.0)) {
    4872           0 :             ShowSevereError(state, format("Latitude must be between -90 and 90; Entered={:.2R}", state.dataEnvrn->Latitude));
    4873           0 :             LocationError = true;
    4874             :         }
    4875             : 
    4876        2115 :         if ((state.dataEnvrn->Longitude < -180.0) || (state.dataEnvrn->Longitude > 180.0)) {
    4877           0 :             ShowSevereError(state, format("Longitude must be between -180 and 180; Entered={:.2R}", state.dataEnvrn->Longitude));
    4878           0 :             LocationError = true;
    4879             :         }
    4880             : 
    4881        2115 :         if ((state.dataEnvrn->TimeZoneNumber < -12.00) || (state.dataEnvrn->TimeZoneNumber > 14.00)) {
    4882           0 :             ShowSevereError(state, format("Time Zone must be between -12 and +14; Entered={:.2R}", state.dataEnvrn->TimeZoneNumber));
    4883           0 :             LocationError = true;
    4884             :         }
    4885             : 
    4886        2115 :         Real64 const StdTimeMerid = GetSTM(state.dataEnvrn->Longitude); // Standard time meridian.
    4887             : 
    4888             :         // Compare the standard time meridian with the time zone number.  If
    4889             :         // different, notify the user.  If StdTimeMerid couldn't be calculated,
    4890             :         // produce an error message.
    4891             : 
    4892        2115 :         if (state.dataEnvrn->varyingLocationSchedIndexLat > 0 || state.dataEnvrn->varyingLocationSchedIndexLong > 0) {
    4893             :             // don't do any warnings, the building is moving
    4894         771 :         } else if (StdTimeMerid >= -12.0 && StdTimeMerid <= 12.0) {
    4895         771 :             if (state.dataEnvrn->TimeZoneNumber != StdTimeMerid) {
    4896             :                 // Difference between Standard Time Meridian and TimeZone
    4897           9 :                 Real64 const DiffCalc = std::abs(state.dataEnvrn->TimeZoneNumber - StdTimeMerid);
    4898           9 :                 if (DiffCalc > 1.0 && DiffCalc < 24.0) {
    4899           0 :                     if (DiffCalc < 3.0) {
    4900           0 :                         ShowWarningError(state,
    4901           0 :                                          format("Standard Time Meridian and Time Zone differ by more than 1, Difference=\"{:.1R}\"", DiffCalc));
    4902           0 :                         ShowContinueError(state, "Solar Positions may be incorrect");
    4903             :                     } else {
    4904           0 :                         ShowSevereError(state, format("Standard Time Meridian and Time Zone differ by more than 2, Difference=\"{:.1R}\"", DiffCalc));
    4905           0 :                         ShowContinueError(state, "Solar Positions will be incorrect");
    4906             :                         //          LocationError=.TRUE.
    4907             :                     }
    4908             :                 }
    4909         771 :             }
    4910             :         } else {
    4911           0 :             ShowSevereError(state, "Unable to calculate the standard time meridian");
    4912           0 :             LocationError = true;
    4913             :         }
    4914             : 
    4915             :         // Error handling:  if there are any errors in the location information
    4916             :         // the simulation must be terminated
    4917             : 
    4918        2115 :         if (LocationError) {
    4919           0 :             ShowFatalError(state, "Due to previous error condition, simulation terminated");
    4920             :         }
    4921             : 
    4922        2115 :         if (state.dataEnvrn->TimeZoneNumber <= 12.00) {
    4923        2115 :             state.dataEnvrn->TimeZoneMeridian = state.dataEnvrn->TimeZoneNumber * 15.0;
    4924             :         } else {
    4925           0 :             state.dataEnvrn->TimeZoneMeridian = state.dataEnvrn->TimeZoneNumber * 15.0 - 360.0;
    4926             :         }
    4927        2115 :         state.dataEnvrn->SinLatitude = std::sin(DataGlobalConstants::DegToRadians * state.dataEnvrn->Latitude);
    4928        2115 :         state.dataEnvrn->CosLatitude = std::cos(DataGlobalConstants::DegToRadians * state.dataEnvrn->Latitude);
    4929             : 
    4930        2115 :         if (state.dataEnvrn->Latitude == 0.0 && state.dataEnvrn->Longitude == 0.0 && state.dataEnvrn->TimeZoneNumber == 0.0) {
    4931           0 :             ShowWarningError(state,
    4932             :                              "Did you realize that you have Latitude=0.0, Longitude=0.0 and TimeZone=0.0?  Your building site is in the middle of "
    4933             :                              "the Atlantic Ocean.");
    4934             :         }
    4935        2115 :     }
    4936             : 
    4937         747 :     void CheckWeatherFileValidity(EnergyPlusData &state)
    4938             :     {
    4939             : 
    4940             :         // SUBROUTINE INFORMATION:
    4941             :         //       AUTHOR         Linda Lawrie
    4942             :         //       DATE WRITTEN   February 1977
    4943             :         //       MODIFIED       June 1997 (RKS)
    4944             :         //       RE-ENGINEERED  na
    4945             : 
    4946             :         // PURPOSE OF THIS SUBROUTINE:
    4947             :         // This subroutine contains a portion of the legacy subroutine CKBLDE.
    4948             :         // The main purpose of this routine is to check the validity of the
    4949             :         // weather dates provided by the user and the attached weather file.
    4950             :         // These functions may eventually be pushed to an interface.  This
    4951             :         // routine also sends the weather file header information at the
    4952             :         // Environment derived type.
    4953             : 
    4954         747 :         if (!state.dataWeatherManager->WeatherFileExists) { // No weather file exists but the user requested one--print error message
    4955             : 
    4956          10 :             if (state.dataGlobal->DoWeathSim) {
    4957           0 :                 ShowSevereError(state, "GetNextEnvironment: Weather Environment(s) requested, but no weather file found");
    4958           0 :                 ShowFatalError(state, "Due to previous error condition, simulation terminated");
    4959             :             }
    4960             : 
    4961             :         } // ... end of WeatherFileExists IF-THEN
    4962         747 :     }
    4963             : 
    4964         771 :     void ReportOutputFileHeaders(EnergyPlusData &state)
    4965             :     {
    4966             : 
    4967             :         // SUBROUTINE INFORMATION:
    4968             :         //       AUTHOR         Rick Strand
    4969             :         //       DATE WRITTEN   June 1997
    4970             :         //       MODIFIED       December 2017; Jason DeGraw
    4971             :         //       RE-ENGINEERED  na
    4972             : 
    4973             :         // PURPOSE OF THIS SUBROUTINE:
    4974             :         // This subroutine prints out the necessary header information required
    4975             :         // by the EnergyPlus output file format.  This subroutine can be
    4976             :         // replicated in any other modules which must send data to the output
    4977             :         // file.
    4978             : 
    4979             :         // METHODOLOGY EMPLOYED:
    4980             :         // For each report, the report flag integer must be saved from the
    4981             :         // global report number counter.  Then, the report counter must be
    4982             :         // incremented.  Finally, the header information for the report must
    4983             :         // be sent to the output file.
    4984             : 
    4985             :         static constexpr std::string_view EnvironmentString(",5,Environment Title[],Latitude[deg],Longitude[deg],Time Zone[],Elevation[m]");
    4986             :         static constexpr std::string_view TimeStepString(
    4987             :             ",8,Day of Simulation[],Month[],Day of Month[],DST Indicator[1=yes 0=no],Hour[],StartMinute[],EndMinute[],DayType");
    4988             :         static constexpr std::string_view DailyString(
    4989             :             ",5,Cumulative Day of Simulation[],Month[],Day of Month[],DST Indicator[1=yes 0=no],DayType  ! When Daily ");
    4990             :         static constexpr std::string_view MonthlyString(",2,Cumulative Days of Simulation[],Month[]  ! When Monthly ");
    4991             :         static constexpr std::string_view RunPeriodString(",1,Cumulative Days of Simulation[] ! When Run Period ");
    4992             :         static constexpr std::string_view YearlyString(",1,Calendar Year of Simulation[] ! When Annual ");
    4993             : 
    4994         771 :         AssignReportNumber(state, state.dataWeatherManager->EnvironmentReportNbr);
    4995         771 :         if (state.dataWeatherManager->EnvironmentReportNbr != 1) { //  problem
    4996           0 :             ShowFatalError(state, "ReportOutputFileHeaders: Assigned report number for Environment title is not 1.  Contact Support.");
    4997             :         }
    4998         771 :         state.dataWeatherManager->EnvironmentReportChr = fmt::to_string(state.dataWeatherManager->EnvironmentReportNbr);
    4999         771 :         strip(state.dataWeatherManager->EnvironmentReportChr);
    5000         771 :         print(state.files.eso, "{}{}\n", state.dataWeatherManager->EnvironmentReportChr, EnvironmentString);
    5001         771 :         print(state.files.mtr, "{}{}\n", state.dataWeatherManager->EnvironmentReportChr, EnvironmentString);
    5002             : 
    5003         771 :         AssignReportNumber(state, state.dataOutputProcessor->TimeStepStampReportNbr);
    5004         771 :         state.dataOutputProcessor->TimeStepStampReportChr = fmt::to_string(state.dataOutputProcessor->TimeStepStampReportNbr);
    5005         771 :         strip(state.dataOutputProcessor->TimeStepStampReportChr);
    5006         771 :         print(state.files.eso, "{}{}\n", state.dataOutputProcessor->TimeStepStampReportChr, TimeStepString);
    5007         771 :         print(state.files.mtr, "{}{}\n", state.dataOutputProcessor->TimeStepStampReportChr, TimeStepString);
    5008             : 
    5009         771 :         AssignReportNumber(state, state.dataOutputProcessor->DailyStampReportNbr);
    5010         771 :         state.dataOutputProcessor->DailyStampReportChr = fmt::to_string(state.dataOutputProcessor->DailyStampReportNbr);
    5011         771 :         strip(state.dataOutputProcessor->DailyStampReportChr);
    5012         771 :         print(state.files.eso, "{}{}{}\n", state.dataOutputProcessor->DailyStampReportChr, DailyString, "Report Variables Requested");
    5013         771 :         print(state.files.mtr, "{}{}{}\n", state.dataOutputProcessor->DailyStampReportChr, DailyString, "Meters Requested");
    5014             : 
    5015         771 :         AssignReportNumber(state, state.dataOutputProcessor->MonthlyStampReportNbr);
    5016         771 :         state.dataOutputProcessor->MonthlyStampReportChr = fmt::to_string(state.dataOutputProcessor->MonthlyStampReportNbr);
    5017         771 :         strip(state.dataOutputProcessor->MonthlyStampReportChr);
    5018         771 :         print(state.files.eso, "{}{}{}\n", state.dataOutputProcessor->MonthlyStampReportChr, MonthlyString, "Report Variables Requested");
    5019         771 :         print(state.files.mtr, "{}{}{}\n", state.dataOutputProcessor->MonthlyStampReportChr, MonthlyString, "Meters Requested");
    5020             : 
    5021         771 :         AssignReportNumber(state, state.dataOutputProcessor->RunPeriodStampReportNbr);
    5022         771 :         state.dataOutputProcessor->RunPeriodStampReportChr = fmt::to_string(state.dataOutputProcessor->RunPeriodStampReportNbr);
    5023         771 :         strip(state.dataOutputProcessor->RunPeriodStampReportChr);
    5024         771 :         print(state.files.eso, "{}{}{}\n", state.dataOutputProcessor->RunPeriodStampReportChr, RunPeriodString, "Report Variables Requested");
    5025         771 :         print(state.files.mtr, "{}{}{}\n", state.dataOutputProcessor->RunPeriodStampReportChr, RunPeriodString, "Meters Requested");
    5026             : 
    5027         771 :         AssignReportNumber(state, state.dataOutputProcessor->YearlyStampReportNbr);
    5028         771 :         state.dataOutputProcessor->YearlyStampReportChr = fmt::to_string(state.dataOutputProcessor->YearlyStampReportNbr);
    5029         771 :         strip(state.dataOutputProcessor->YearlyStampReportChr);
    5030         771 :         print(state.files.eso, "{}{}{}\n", state.dataOutputProcessor->YearlyStampReportChr, YearlyString, "Report Variables Requested");
    5031         771 :         print(state.files.mtr, "{}{}{}\n", state.dataOutputProcessor->YearlyStampReportChr, YearlyString, "Meters Requested");
    5032         771 :     }
    5033             : 
    5034     2661169 :     void ReportWeatherAndTimeInformation(EnergyPlusData &state, bool &printEnvrnStamp) // Set to true when the environment header should be printed
    5035             :     {
    5036             : 
    5037             :         // SUBROUTINE INFORMATION:
    5038             :         //       AUTHOR         Rick Strand
    5039             :         //       DATE WRITTEN   June 1997
    5040             :         //       MODIFIED       na
    5041             :         //       RE-ENGINEERED  na
    5042             : 
    5043             :         // PURPOSE OF THIS SUBROUTINE:
    5044             :         // This subroutine is the main driver of the weather reporting.  This
    5045             :         // routine is also responsible for printing the time and environment
    5046             :         // stamps.
    5047             : 
    5048             :         // METHODOLOGY EMPLOYED:
    5049             :         // Reporting is only done for non-warmup days.  The environment stamp
    5050             :         // is only reported at the beginning of an environment, but after the
    5051             :         // warmup days (to allow all modules to print the report headers to the
    5052             :         // output file.  This is controlled by the PrintEnvrnStamp variable
    5053             :         // which is passed in and reset if necessary.
    5054             : 
    5055             :         // Report the time stamp and the current weather to the output file
    5056             : 
    5057     2661169 :         if (!state.dataGlobal->WarmupFlag && !state.dataWeatherManager->RPReadAllWeatherData) { // Write the required output information
    5058             : 
    5059             :             // The first time through in a non-warmup day, the environment header
    5060             :             // must be printed.  This must be done here and not in the generic
    5061             :             // DataGlobals::BeginEnvrnFlag block above because other modules in the simulation
    5062             :             // must also print out header information.  This can be done during
    5063             :             // the simulation warmup if the environment stamp printing is delayed
    5064             :             // until the warmup is completed.  The stamp should only be printed once
    5065             :             // per environment (set/reset of PrintEnvrnStamp).  In addition, before
    5066             :             // the first environment, the end of the header block flag must also be
    5067             :             // sent to the output file.
    5068             : 
    5069      497616 :             if (printEnvrnStamp) {
    5070             : 
    5071      200173 :                 if (state.dataReportFlag->PrintEndDataDictionary && state.dataGlobal->DoOutputReporting) {
    5072             :                     static constexpr std::string_view EndOfHeaderString("End of Data Dictionary"); // End of data dictionary marker
    5073         769 :                     print(state.files.eso, "{}\n", EndOfHeaderString);
    5074         769 :                     print(state.files.mtr, "{}\n", EndOfHeaderString);
    5075         769 :                     state.dataReportFlag->PrintEndDataDictionary = false;
    5076             :                 }
    5077      200173 :                 if (state.dataGlobal->DoOutputReporting) {
    5078        1645 :                     std::string const &Title(state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).Title);
    5079             :                     static constexpr std::string_view EnvironmentStampFormatStr(
    5080             :                         "{},{},{:7.2F},{:7.2F},{:7.2F},{:7.2F}\n"); // Format descriptor for environ stamp
    5081        8225 :                     print(state.files.eso,
    5082             :                           EnvironmentStampFormatStr,
    5083        1645 :                           state.dataWeatherManager->EnvironmentReportChr,
    5084             :                           Title,
    5085        1645 :                           state.dataEnvrn->Latitude,
    5086        1645 :                           state.dataEnvrn->Longitude,
    5087        1645 :                           state.dataEnvrn->TimeZoneNumber,
    5088        1645 :                           state.dataEnvrn->Elevation);
    5089        8225 :                     print(state.files.mtr,
    5090             :                           EnvironmentStampFormatStr,
    5091        1645 :                           state.dataWeatherManager->EnvironmentReportChr,
    5092             :                           Title,
    5093        1645 :                           state.dataEnvrn->Latitude,
    5094        1645 :                           state.dataEnvrn->Longitude,
    5095        1645 :                           state.dataEnvrn->TimeZoneNumber,
    5096        1645 :                           state.dataEnvrn->Elevation);
    5097        1645 :                     printEnvrnStamp = false;
    5098             :                 }
    5099             :             }
    5100             :         } // ... end of .NOT.WarmupFlag IF-THEN block.
    5101     2661169 :     }
    5102             : 
    5103         771 :     void ReadUserWeatherInput(EnergyPlusData &state)
    5104             :     {
    5105             : 
    5106             :         // SUBROUTINE INFORMATION:
    5107             :         //       AUTHOR         Richard Liesen
    5108             :         //       DATE WRITTEN   September 1997
    5109             :         //       MODIFIED
    5110             :         //       RE-ENGINEERED  na
    5111             : 
    5112             :         // PURPOSE OF THIS SUBROUTINE:
    5113             :         // This subroutine is the main driver of the weather manager module.
    5114             :         // It controls the assignment of weather related global variables as
    5115             :         // well as the reads and writes for retrieving weather information.
    5116             : 
    5117             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5118         771 :         bool ErrorsFound(false);
    5119             : 
    5120             :         // Get the number of design days and annual runs from user inpout
    5121         771 :         state.dataEnvrn->TotDesDays = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "SizingPeriod:DesignDay");
    5122         771 :         int RPD1 = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "SizingPeriod:WeatherFileDays");
    5123         771 :         int RPD2 = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "SizingPeriod:WeatherFileConditionType");
    5124         771 :         state.dataWeatherManager->TotRunPers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "RunPeriod");
    5125         771 :         state.dataWeatherManager->NumOfEnvrn = state.dataEnvrn->TotDesDays + state.dataWeatherManager->TotRunPers + RPD1 + RPD2;
    5126         771 :         state.dataGlobal->WeathSimReq = state.dataWeatherManager->TotRunPers > 0;
    5127         771 :         state.dataWeatherManager->TotReportPers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Output:Table:ReportPeriod");
    5128             : 
    5129         771 :         state.dataWeatherManager->SPSiteScheduleNamePtr.allocate(state.dataEnvrn->TotDesDays * 5);
    5130         771 :         state.dataWeatherManager->SPSiteScheduleUnits.allocate(state.dataEnvrn->TotDesDays * 5);
    5131             : 
    5132         771 :         state.dataWeatherManager->SPSiteScheduleNamePtr = 0;
    5133         771 :         state.dataWeatherManager->SPSiteScheduleUnits = "";
    5134             : 
    5135             :         // Allocate the Design Day and Environment array to the # of DD's or/and
    5136             :         // Annual runs on input file
    5137         771 :         state.dataWeatherManager->DesignDay.allocate(state.dataEnvrn->TotDesDays);
    5138         771 :         state.dataWeatherManager->Environment.allocate(state.dataWeatherManager->NumOfEnvrn);
    5139             : 
    5140             :         // Set all Environments to DesignDay and then the weather environment will be set
    5141             :         //  in the get annual run data subroutine
    5142        2385 :         for (int Env = 1; Env <= state.dataEnvrn->TotDesDays; ++Env) {
    5143        1614 :             state.dataWeatherManager->Environment(Env).KindOfEnvrn = DataGlobalConstants::KindOfSim::DesignDay;
    5144             :         }
    5145         776 :         for (int Env = 1; Env <= RPD1 + RPD2; ++Env) {
    5146           5 :             if (!state.dataSysVars->DDOnly) {
    5147           0 :                 state.dataWeatherManager->Environment(state.dataEnvrn->TotDesDays + Env).KindOfEnvrn =
    5148             :                     DataGlobalConstants::KindOfSim::RunPeriodDesign;
    5149             :             } else {
    5150           5 :                 state.dataWeatherManager->Environment(state.dataEnvrn->TotDesDays + Env).KindOfEnvrn =
    5151             :                     DataGlobalConstants::KindOfSim::RunPeriodWeather;
    5152             :             }
    5153             :         }
    5154        1925 :         for (int Env = 1; Env <= state.dataWeatherManager->TotRunPers; ++Env) {
    5155        1154 :             state.dataWeatherManager->Environment(state.dataEnvrn->TotDesDays + RPD1 + RPD2 + Env).KindOfEnvrn =
    5156             :                 DataGlobalConstants::KindOfSim::RunPeriodWeather;
    5157             :         }
    5158             : 
    5159         771 :         if (state.dataEnvrn->TotDesDays >= 1) {
    5160         771 :             GetDesignDayData(state, state.dataEnvrn->TotDesDays, ErrorsFound);
    5161             :         }
    5162             : 
    5163         771 :         if (RPD1 >= 1 || RPD2 >= 1) {
    5164           3 :             GetRunPeriodDesignData(state, ErrorsFound);
    5165             :         }
    5166             : 
    5167             :         // the last environment(s) is designated the weather environment if an annual run
    5168             :         // is selected.  All of the design systems is done from the design day info
    5169             :         // which will have to be completed to run the annual run.
    5170         771 :         if (state.dataWeatherManager->TotRunPers >= 1 || state.dataSysVars->FullAnnualRun) {
    5171         747 :             GetRunPeriodData(state, state.dataWeatherManager->TotRunPers, ErrorsFound);
    5172             :         }
    5173             : 
    5174         771 :         if (state.dataWeatherManager->TotReportPers > 0) {
    5175           4 :             GetReportPeriodData(state, state.dataWeatherManager->TotReportPers, ErrorsFound);
    5176           4 :             GroupReportPeriodByType(state, state.dataWeatherManager->TotReportPers);
    5177             :         }
    5178             : 
    5179         771 :         if (state.dataSysVars->FullAnnualRun) {
    5180             :             // GetRunPeriodData may have reset the value of TotRunPers
    5181           2 :             state.dataWeatherManager->NumOfEnvrn = state.dataEnvrn->TotDesDays + state.dataWeatherManager->TotRunPers + RPD1 + RPD2;
    5182             :         }
    5183             : 
    5184         771 :         if (RPD1 >= 1 || RPD2 >= 1 || state.dataWeatherManager->TotRunPers >= 1 || state.dataSysVars->FullAnnualRun) {
    5185         747 :             GetSpecialDayPeriodData(state, ErrorsFound);
    5186         747 :             GetDSTData(state, ErrorsFound);
    5187         747 :             if (state.dataWeatherManager->IDFDaylightSaving) {
    5188         174 :                 state.dataWeatherManager->DST = state.dataWeatherManager->IDFDST;
    5189             :             }
    5190             :         }
    5191             : 
    5192         771 :         GetLocationInfo(state, ErrorsFound);
    5193             : 
    5194         771 :         GetGroundTemps(state);
    5195             : 
    5196         771 :         GetGroundReflectances(state, ErrorsFound);
    5197             : 
    5198         771 :         GetSnowGroundRefModifiers(state, ErrorsFound);
    5199             : 
    5200         771 :         GetWaterMainsTemperatures(state, ErrorsFound);
    5201             : 
    5202         771 :         GetWeatherStation(state, ErrorsFound);
    5203             : 
    5204         771 :         SetupEnvironmentTypes(state);
    5205             : 
    5206         771 :         GetWeatherProperties(state, ErrorsFound);
    5207             : 
    5208             :         // Deallocate ones used for schedule pointers
    5209         771 :         state.dataWeatherManager->SPSiteScheduleNamePtr.deallocate();
    5210         771 :         state.dataWeatherManager->SPSiteScheduleUnits.deallocate();
    5211             : 
    5212         771 :         if (ErrorsFound) {
    5213           0 :             ShowFatalError(state, "GetWeatherInput: Above errors cause termination");
    5214             :         }
    5215         771 :     }
    5216             : 
    5217        1005 :     static int findYearForWeekday(int const month, int const day, ScheduleManager::DayType const weekday)
    5218             :     {
    5219             :         // Find a year that goes with a month/day and a weekday. A lookup table is used with the most recent year that includes
    5220             :         // the date with the weekday specified.
    5221             : 
    5222             :         // Tu, W, Th, F, Sa, Su, M, Tu, W, Th, F, Sa, Su
    5223             :         static std::array<int, 13> const defaultYear{{2013, 2014, 2015, 2010, 2011, 2017, 2007, 2013, 2014, 2015, 2010, 2011, 2017}};
    5224             : 
    5225        1005 :         int rem = calculateDayOfYear(month, day) % 7;
    5226        1005 :         return defaultYear[static_cast<int>(weekday) - rem + 5]; // static_cast<int>(weekday) - rem + 1 + 4
    5227             :     }
    5228             : 
    5229           0 :     static int findLeapYearForWeekday(int const month, int const day, ScheduleManager::DayType const weekday)
    5230             :     {
    5231             :         // Find a leap year that goes with a month/day and a weekday. A lookup table is used with the most recent year that includes
    5232             :         // the date with the weekday specified.
    5233             : 
    5234             :         // Tu, W, Th, F, Sa, Su, M, Tu, W, Th, F, Sa, Su
    5235             :         static std::array<int, 13> const defaultLeapYear{{2008, 1992, 2004, 2016, 2000, 2012, 1996, 2008, 1992, 2004, 2016, 2000, 2012}};
    5236             : 
    5237           0 :         int rem = calculateDayOfYear(month, day, true) % 7;
    5238           0 :         return defaultLeapYear[static_cast<int>(weekday) - rem + 5]; // static_cast<int>(weekday) - rem + 1 + 4
    5239             :     }
    5240             : 
    5241           4 :     void GetReportPeriodData(EnergyPlusData &state,
    5242             :                              int &nReportPeriods, // Total number of Report Periods requested
    5243             :                              bool &ErrorsFound)
    5244             :     {
    5245           4 :         state.dataWeatherManager->ReportPeriodInput.allocate(nReportPeriods);
    5246           4 :         state.dataWeatherManager->ReportPeriodInputUniqueNames.reserve(static_cast<unsigned>(nReportPeriods));
    5247             : 
    5248           4 :         state.dataIPShortCut->cCurrentModuleObject = "Output:Table:ReportPeriod";
    5249           4 :         int Count = 0;
    5250             :         int NumAlpha;   // Number of alphas being input
    5251             :         int NumNumeric; // Number of numbers being input
    5252             :         int IOStat;     // IO Status when calling get input subroutine
    5253          13 :         for (int i = 1; i <= nReportPeriods; ++i) {
    5254          72 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5255           9 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
    5256             :                                                                      i,
    5257           9 :                                                                      state.dataIPShortCut->cAlphaArgs,
    5258             :                                                                      NumAlpha,
    5259           9 :                                                                      state.dataIPShortCut->rNumericArgs,
    5260             :                                                                      NumNumeric,
    5261             :                                                                      IOStat,
    5262           9 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    5263           9 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    5264           9 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    5265           9 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    5266             : 
    5267             :             // A1, \field Name
    5268           9 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(1)) {
    5269          27 :                 GlobalNames::VerifyUniqueInterObjectName(state,
    5270           9 :                                                          state.dataWeatherManager->ReportPeriodInputUniqueNames,
    5271           9 :                                                          state.dataIPShortCut->cAlphaArgs(1),
    5272           9 :                                                          state.dataIPShortCut->cCurrentModuleObject,
    5273           9 :                                                          state.dataIPShortCut->cAlphaFieldNames(1),
    5274             :                                                          ErrorsFound);
    5275             :             }
    5276             : 
    5277           9 :             ++Count;
    5278             :             // Loop = RP + Ptr;
    5279             :             // Note JM 2018-11-20: IDD allows blank name, but input processor will create a name such as "ReportPeriod 1" anyways
    5280             :             // which is fine for our reporting below
    5281           9 :             state.dataWeatherManager->ReportPeriodInput(i).title = state.dataIPShortCut->cAlphaArgs(1);
    5282             :             // A2, \field Report Name
    5283           9 :             state.dataWeatherManager->ReportPeriodInput(i).reportName = state.dataIPShortCut->cAlphaArgs(2);
    5284             : 
    5285             :             // set the start and end day of month from user input
    5286             :             // N1, \field Begin Year
    5287             :             // N2, \field Begin Month
    5288             :             // N3, \field Begin Day of Month
    5289             :             // N4, \field Begin Hour of Day
    5290             :             // N5, \field End Year
    5291             :             // N6, \field End Month
    5292             :             // N7, \field End Day of Month
    5293             :             // N8; \field End Hour of Day
    5294           9 :             state.dataWeatherManager->ReportPeriodInput(i).startYear = int(state.dataIPShortCut->rNumericArgs(1));
    5295           9 :             state.dataWeatherManager->ReportPeriodInput(i).startMonth = int(state.dataIPShortCut->rNumericArgs(2));
    5296           9 :             state.dataWeatherManager->ReportPeriodInput(i).startDay = int(state.dataIPShortCut->rNumericArgs(3));
    5297           9 :             state.dataWeatherManager->ReportPeriodInput(i).startHour = int(state.dataIPShortCut->rNumericArgs(4));
    5298           9 :             state.dataWeatherManager->ReportPeriodInput(i).endYear = int(state.dataIPShortCut->rNumericArgs(5));
    5299           9 :             state.dataWeatherManager->ReportPeriodInput(i).endMonth = int(state.dataIPShortCut->rNumericArgs(6));
    5300           9 :             state.dataWeatherManager->ReportPeriodInput(i).endDay = int(state.dataIPShortCut->rNumericArgs(7));
    5301           9 :             state.dataWeatherManager->ReportPeriodInput(i).endHour = int(state.dataIPShortCut->rNumericArgs(8));
    5302             : 
    5303             :             // Validate year inputs
    5304           9 :             if (state.dataWeatherManager->ReportPeriodInput(i).startYear == 0) {
    5305           9 :                 if (state.dataWeatherManager->ReportPeriodInput(i).endYear != 0) { // Have to have an input start year to input an end year
    5306           0 :                     ShowSevereError(state,
    5307           0 :                                     state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->ReportPeriodInput(i).title +
    5308             :                                         ", end year cannot be specified if the start year is not.");
    5309           0 :                     ErrorsFound = true;
    5310             :                 }
    5311           0 :             } else if (state.dataWeatherManager->ReportPeriodInput(i).startYear < 1583) { // Bail on the proleptic Gregorian calendar
    5312           0 :                 ShowSevereError(state,
    5313           0 :                                 format("{}: object={}, start year ({}) is too early, please choose a date after 1582.",
    5314           0 :                                        state.dataIPShortCut->cCurrentModuleObject,
    5315           0 :                                        state.dataWeatherManager->ReportPeriodInput(i).title,
    5316           0 :                                        state.dataWeatherManager->ReportPeriodInput(i).startYear));
    5317           0 :                 ErrorsFound = true;
    5318             :             }
    5319             : 
    5320           9 :             if (state.dataWeatherManager->ReportPeriodInput(i).endYear != 0 &&
    5321           0 :                 state.dataWeatherManager->ReportPeriodInput(i).startYear > state.dataWeatherManager->ReportPeriodInput(i).endYear) {
    5322           0 :                 ShowSevereError(state,
    5323           0 :                                 format("{}: object={}, start year ({}) is after the end year ({}).",
    5324           0 :                                        state.dataIPShortCut->cCurrentModuleObject,
    5325           0 :                                        state.dataWeatherManager->ReportPeriodInput(i).title,
    5326           0 :                                        state.dataWeatherManager->ReportPeriodInput(i).startYear,
    5327           0 :                                        state.dataWeatherManager->ReportPeriodInput(i).endYear));
    5328           0 :                 ErrorsFound = true;
    5329             :             }
    5330             : 
    5331           9 :             state.dataWeatherManager->ReportPeriodInput(i).startJulianDate =
    5332          18 :                 computeJulianDate(state.dataWeatherManager->ReportPeriodInput(i).startYear,
    5333           9 :                                   state.dataWeatherManager->ReportPeriodInput(i).startMonth,
    5334           9 :                                   state.dataWeatherManager->ReportPeriodInput(i).startDay);
    5335          18 :             state.dataWeatherManager->ReportPeriodInput(i).endJulianDate = computeJulianDate(state.dataWeatherManager->ReportPeriodInput(i).endYear,
    5336           9 :                                                                                              state.dataWeatherManager->ReportPeriodInput(i).endMonth,
    5337           9 :                                                                                              state.dataWeatherManager->ReportPeriodInput(i).endDay);
    5338             :         }
    5339           4 :     }
    5340             : 
    5341          11 :     void CopyReportPeriodObject(const Array1D<WeatherManager::ReportPeriodData> &source,
    5342             :                                 const int sourceIdx,
    5343             :                                 Array1D<WeatherManager::ReportPeriodData> &target,
    5344             :                                 const int targetIdx)
    5345             :     // copy the content of one reporting period object to another.
    5346             :     // The aim is to transfer data of each reporting period object to its corresonding
    5347             :     // report time so the indexing works out
    5348             :     {
    5349          11 :         target(targetIdx).title = source(sourceIdx).title;
    5350          11 :         target(targetIdx).reportName = source(sourceIdx).reportName;
    5351          11 :         target(targetIdx).startYear = source(sourceIdx).startYear;
    5352          11 :         target(targetIdx).startMonth = source(sourceIdx).startMonth;
    5353          11 :         target(targetIdx).startDay = source(sourceIdx).startDay;
    5354          11 :         target(targetIdx).startHour = source(sourceIdx).startHour;
    5355          11 :         target(targetIdx).startJulianDate = source(sourceIdx).startJulianDate;
    5356          11 :         target(targetIdx).endYear = source(sourceIdx).endYear;
    5357          11 :         target(targetIdx).endMonth = source(sourceIdx).endMonth;
    5358          11 :         target(targetIdx).endDay = source(sourceIdx).endDay;
    5359          11 :         target(targetIdx).endHour = source(sourceIdx).endHour;
    5360          11 :         target(targetIdx).endJulianDate = source(sourceIdx).endJulianDate;
    5361          11 :     }
    5362             : 
    5363           4 :     void GroupReportPeriodByType(EnergyPlusData &state, const int nReportPeriods)
    5364             :     {
    5365             :         // transfer data from the reporting period object to the corresponding report period type arrays
    5366             :         // ThermalResilienceSummary, CO2ResilienceSummary, VisualResilienceSummary, and AllResilienceSummaries
    5367          13 :         for (int i = 1; i <= nReportPeriods; ++i) {
    5368           9 :             if (state.dataWeatherManager->ReportPeriodInput(i).reportName == "THERMALRESILIENCESUMMARY") {
    5369           4 :                 state.dataWeatherManager->TotThermalReportPers += 1;
    5370           5 :             } else if (state.dataWeatherManager->ReportPeriodInput(i).reportName == "CO2RESILIENCESUMMARY") {
    5371           2 :                 state.dataWeatherManager->TotCO2ReportPers += 1;
    5372           3 :             } else if (state.dataWeatherManager->ReportPeriodInput(i).reportName == "VISUALRESILIENCESUMMARY") {
    5373           2 :                 state.dataWeatherManager->TotVisualReportPers += 1;
    5374           1 :             } else if (state.dataWeatherManager->ReportPeriodInput(i).reportName == "ALLRESILIENCESUMMARIES") {
    5375           1 :                 state.dataWeatherManager->TotThermalReportPers += 1;
    5376           1 :                 state.dataWeatherManager->TotCO2ReportPers += 1;
    5377           1 :                 state.dataWeatherManager->TotVisualReportPers += 1;
    5378             :             }
    5379             :         }
    5380             : 
    5381           4 :         state.dataWeatherManager->ThermalReportPeriodInput.allocate(state.dataWeatherManager->TotThermalReportPers);
    5382           4 :         state.dataWeatherManager->CO2ReportPeriodInput.allocate(state.dataWeatherManager->TotCO2ReportPers);
    5383           4 :         state.dataWeatherManager->VisualReportPeriodInput.allocate(state.dataWeatherManager->TotVisualReportPers);
    5384             : 
    5385           4 :         int ThermalReportPeriodsIdx = 1;
    5386           4 :         int CO2ReportPeriodsIdx = 1;
    5387           4 :         int VisualReportPeriodsIdx = 1;
    5388          13 :         for (int i = 1; i <= nReportPeriods; ++i) {
    5389           9 :             if (state.dataWeatherManager->ReportPeriodInput(i).reportName == "THERMALRESILIENCESUMMARY") {
    5390           8 :                 CopyReportPeriodObject(
    5391           8 :                     state.dataWeatherManager->ReportPeriodInput, i, state.dataWeatherManager->ThermalReportPeriodInput, ThermalReportPeriodsIdx);
    5392           4 :                 ThermalReportPeriodsIdx += 1;
    5393           5 :             } else if (state.dataWeatherManager->ReportPeriodInput(i).reportName == "CO2RESILIENCESUMMARY") {
    5394           4 :                 CopyReportPeriodObject(
    5395           4 :                     state.dataWeatherManager->ReportPeriodInput, i, state.dataWeatherManager->CO2ReportPeriodInput, CO2ReportPeriodsIdx);
    5396           2 :                 CO2ReportPeriodsIdx += 1;
    5397           3 :             } else if (state.dataWeatherManager->ReportPeriodInput(i).reportName == "VISUALRESILIENCESUMMARY") {
    5398           4 :                 CopyReportPeriodObject(
    5399           4 :                     state.dataWeatherManager->ReportPeriodInput, i, state.dataWeatherManager->VisualReportPeriodInput, VisualReportPeriodsIdx);
    5400           2 :                 VisualReportPeriodsIdx += 1;
    5401           1 :             } else if (state.dataWeatherManager->ReportPeriodInput(i).reportName == "ALLRESILIENCESUMMARIES") {
    5402           2 :                 CopyReportPeriodObject(
    5403           2 :                     state.dataWeatherManager->ReportPeriodInput, i, state.dataWeatherManager->ThermalReportPeriodInput, ThermalReportPeriodsIdx);
    5404           1 :                 ThermalReportPeriodsIdx += 1;
    5405           2 :                 CopyReportPeriodObject(
    5406           2 :                     state.dataWeatherManager->ReportPeriodInput, i, state.dataWeatherManager->CO2ReportPeriodInput, CO2ReportPeriodsIdx);
    5407           1 :                 CO2ReportPeriodsIdx += 1;
    5408           2 :                 CopyReportPeriodObject(
    5409           2 :                     state.dataWeatherManager->ReportPeriodInput, i, state.dataWeatherManager->VisualReportPeriodInput, VisualReportPeriodsIdx);
    5410           1 :                 VisualReportPeriodsIdx += 1;
    5411             :             }
    5412             :         }
    5413           4 :     }
    5414             : 
    5415         747 :     void GetRunPeriodData(EnergyPlusData &state,
    5416             :                           int &nRunPeriods, // Total number of Run Periods requested
    5417             :                           bool &ErrorsFound)
    5418             :     {
    5419             : 
    5420             :         // SUBROUTINE INFORMATION:
    5421             :         //       AUTHOR         Richard Liesen
    5422             :         //       DATE WRITTEN   October 1997
    5423             :         //       MODIFIED       February 1999, Add multiple run periods, Change name.
    5424             :         //                      March 2012, LKL, Add features to object; New "actual weather" object;
    5425             :         //       RE-ENGINEERED  na
    5426             : 
    5427             :         // PURPOSE OF THIS SUBROUTINE:
    5428             :         // This subroutine gets the run period info from User input and the
    5429             :         //  simulation dates
    5430             : 
    5431             :         // Call Input Get routine to retrieve annual run data
    5432         747 :         state.dataWeatherManager->RunPeriodInput.allocate(nRunPeriods);
    5433         747 :         state.dataWeatherManager->RunPeriodInputUniqueNames.reserve(static_cast<unsigned>(nRunPeriods));
    5434             : 
    5435         747 :         state.dataIPShortCut->cCurrentModuleObject = "RunPeriod";
    5436         747 :         int Count = 0;
    5437             :         int NumAlpha;   // Number of alphas being input
    5438             :         int NumNumeric; // Number of numbers being input
    5439             :         int IOStat;     // IO Status when calling get input subroutine
    5440        1901 :         for (int i = 1; i <= nRunPeriods; ++i) {
    5441        9232 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5442        1154 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
    5443             :                                                                      i,
    5444        1154 :                                                                      state.dataIPShortCut->cAlphaArgs,
    5445             :                                                                      NumAlpha,
    5446        1154 :                                                                      state.dataIPShortCut->rNumericArgs,
    5447             :                                                                      NumNumeric,
    5448             :                                                                      IOStat,
    5449        1154 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    5450        1154 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    5451        1154 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    5452        1154 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    5453             : 
    5454             :             // A1, \field Name
    5455        1154 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(1)) {
    5456        3462 :                 GlobalNames::VerifyUniqueInterObjectName(state,
    5457        1154 :                                                          state.dataWeatherManager->RunPeriodInputUniqueNames,
    5458        1154 :                                                          state.dataIPShortCut->cAlphaArgs(1),
    5459        1154 :                                                          state.dataIPShortCut->cCurrentModuleObject,
    5460        1154 :                                                          state.dataIPShortCut->cAlphaFieldNames(1),
    5461             :                                                          ErrorsFound);
    5462             :             }
    5463             : 
    5464        1154 :             ++Count;
    5465             :             // Loop = RP + Ptr;
    5466             :             // Note JM 2018-11-20: IDD allows blank name, but input processor will create a name such as "RUNPERIOD 1" anyways
    5467             :             // which is fine for our reporting below
    5468        1154 :             state.dataWeatherManager->RunPeriodInput(i).title = state.dataIPShortCut->cAlphaArgs(1);
    5469             : 
    5470             :             // set the start and end day of month from user input
    5471             :             // N1 , \field Begin Month
    5472             :             // N2 , \field Begin Day of Month
    5473             :             // N3,  \field Start Year
    5474             :             // N4 , \field End Month
    5475             :             // N5 , \field End Day of Month
    5476             :             // N6,  \field End Year
    5477        1154 :             state.dataWeatherManager->RunPeriodInput(i).startMonth = int(state.dataIPShortCut->rNumericArgs(1));
    5478        1154 :             state.dataWeatherManager->RunPeriodInput(i).startDay = int(state.dataIPShortCut->rNumericArgs(2));
    5479        1154 :             state.dataWeatherManager->RunPeriodInput(i).startYear = int(state.dataIPShortCut->rNumericArgs(3));
    5480        1154 :             state.dataWeatherManager->RunPeriodInput(i).endMonth = int(state.dataIPShortCut->rNumericArgs(4));
    5481        1154 :             state.dataWeatherManager->RunPeriodInput(i).endDay = int(state.dataIPShortCut->rNumericArgs(5));
    5482        1154 :             state.dataWeatherManager->RunPeriodInput(i).endYear = int(state.dataIPShortCut->rNumericArgs(6));
    5483        1154 :             state.dataWeatherManager->RunPeriodInput(i).TreatYearsAsConsecutive = true;
    5484             : 
    5485        1154 :             if (state.dataSysVars->FullAnnualRun && i == 1) {
    5486           2 :                 state.dataWeatherManager->RunPeriodInput(i).startMonth = 1;
    5487           2 :                 state.dataWeatherManager->RunPeriodInput(i).startDay = 1;
    5488           2 :                 state.dataWeatherManager->RunPeriodInput(i).endMonth = 12;
    5489           2 :                 state.dataWeatherManager->RunPeriodInput(i).endDay = 31;
    5490             :             }
    5491             : 
    5492             :             // Validate year inputs
    5493        1154 :             if (state.dataWeatherManager->RunPeriodInput(i).startYear == 0) {
    5494        1148 :                 if (state.dataWeatherManager->RunPeriodInput(i).endYear != 0) { // Have to have an input start year to input an end year
    5495           0 :                     ShowSevereError(state,
    5496           0 :                                     state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->RunPeriodInput(i).title +
    5497             :                                         ", end year cannot be specified if the start year is not.");
    5498           0 :                     ErrorsFound = true;
    5499             :                 }
    5500           6 :             } else if (state.dataWeatherManager->RunPeriodInput(i).startYear < 1583) { // Bail on the proleptic Gregorian calendar
    5501           0 :                 ShowSevereError(state,
    5502           0 :                                 format("{}: object={}, start year ({}) is too early, please choose a date after 1582.",
    5503           0 :                                        state.dataIPShortCut->cCurrentModuleObject,
    5504           0 :                                        state.dataWeatherManager->RunPeriodInput(i).title,
    5505           0 :                                        state.dataWeatherManager->RunPeriodInput(i).startYear));
    5506           0 :                 ErrorsFound = true;
    5507             :             }
    5508             : 
    5509        1160 :             if (state.dataWeatherManager->RunPeriodInput(i).endYear != 0 &&
    5510           6 :                 state.dataWeatherManager->RunPeriodInput(i).startYear > state.dataWeatherManager->RunPeriodInput(i).endYear) {
    5511           0 :                 ShowSevereError(state,
    5512           0 :                                 format("{}: object={}, start year ({}) is after the end year ({}).",
    5513           0 :                                        state.dataIPShortCut->cCurrentModuleObject,
    5514           0 :                                        state.dataWeatherManager->RunPeriodInput(i).title,
    5515           0 :                                        state.dataWeatherManager->RunPeriodInput(i).startYear,
    5516           0 :                                        state.dataWeatherManager->RunPeriodInput(i).endYear));
    5517           0 :                 ErrorsFound = true;
    5518             :             }
    5519             : 
    5520             :             // A2 , \field Day of Week for Start Day
    5521        1154 :             bool inputWeekday = false;
    5522        1154 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) { // Have input
    5523        1009 :                 int dayType = getEnumerationValue(ScheduleManager::dayTypeNamesUC, state.dataIPShortCut->cAlphaArgs(2));
    5524        1009 :                 if (dayType < 1) {
    5525           0 :                     ShowWarningError(state,
    5526           0 :                                      state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->RunPeriodInput(i).title +
    5527           0 :                                          state.dataIPShortCut->cAlphaFieldNames(2) + " invalid (Day of Week) [" +
    5528           0 :                                          state.dataIPShortCut->cAlphaArgs(2) + "] for Start is not valid, Sunday will be used.");
    5529           0 :                     state.dataWeatherManager->RunPeriodInput(i).startWeekDay = ScheduleManager::DayType::Sunday;
    5530             :                 } else {
    5531        1009 :                     state.dataWeatherManager->RunPeriodInput(i).startWeekDay = static_cast<ScheduleManager::DayType>(dayType);
    5532        1009 :                     inputWeekday = true;
    5533             :                 }
    5534             :             } else { // No input, set the default as Sunday. This may get overriden below
    5535         145 :                 state.dataWeatherManager->RunPeriodInput(i).startWeekDay = ScheduleManager::DayType::Sunday;
    5536             :             }
    5537             : 
    5538             :             // Validate the dates now that the weekday field has been looked at
    5539        1154 :             if (state.dataWeatherManager->RunPeriodInput(i).startMonth == 2 && state.dataWeatherManager->RunPeriodInput(i).startDay == 29) {
    5540             :                 // Requested start date is a leap year
    5541           0 :                 if (state.dataWeatherManager->RunPeriodInput(i).startYear == 0) { // No input starting year
    5542           0 :                     if (inputWeekday) {
    5543           0 :                         state.dataWeatherManager->RunPeriodInput(i).startYear =
    5544           0 :                             findLeapYearForWeekday(state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5545           0 :                                                    state.dataWeatherManager->RunPeriodInput(i).startDay,
    5546           0 :                                                    state.dataWeatherManager->RunPeriodInput(i).startWeekDay);
    5547             :                     } else {
    5548             :                         // 2012 is the default year, 1/1 is a Sunday
    5549           0 :                         state.dataWeatherManager->RunPeriodInput(i).startYear = 2012;
    5550           0 :                         state.dataWeatherManager->RunPeriodInput(i).startWeekDay =
    5551           0 :                             calculateDayOfWeek(state,
    5552           0 :                                                state.dataWeatherManager->RunPeriodInput(i).startYear,
    5553           0 :                                                state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5554           0 :                                                state.dataWeatherManager->RunPeriodInput(i).startDay);
    5555             :                     }
    5556             :                 } else {                                                                      // Have an input start year
    5557           0 :                     if (!isLeapYear(state.dataWeatherManager->RunPeriodInput(i).startYear)) { // Start year is not a leap year
    5558           0 :                         ShowSevereError(state,
    5559           0 :                                         format("{}: object={}, start year ({}) is not a leap year but the requested start date is 2/29.",
    5560           0 :                                                state.dataIPShortCut->cCurrentModuleObject,
    5561           0 :                                                state.dataWeatherManager->RunPeriodInput(i).title,
    5562           0 :                                                state.dataWeatherManager->RunPeriodInput(i).startYear));
    5563           0 :                         ErrorsFound = true;
    5564             :                     } else { // Start year is a leap year
    5565           0 :                         ScheduleManager::DayType weekday = calculateDayOfWeek(state,
    5566           0 :                                                                               state.dataWeatherManager->RunPeriodInput(i).startYear,
    5567           0 :                                                                               state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5568           0 :                                                                               state.dataWeatherManager->RunPeriodInput(i).startDay);
    5569           0 :                         if (inputWeekday) { // Check for correctness of input
    5570           0 :                             if (weekday != state.dataWeatherManager->RunPeriodInput(i).startWeekDay) {
    5571           0 :                                 ShowWarningError(state,
    5572           0 :                                                  format("{}: object={}, start weekday ({}) does not match the start year ({}), corrected to {}.",
    5573           0 :                                                         state.dataIPShortCut->cCurrentModuleObject,
    5574           0 :                                                         state.dataWeatherManager->RunPeriodInput(i).title,
    5575           0 :                                                         state.dataIPShortCut->cAlphaArgs(2),
    5576           0 :                                                         state.dataWeatherManager->RunPeriodInput(i).startYear,
    5577           0 :                                                         ScheduleManager::dayTypeNamesUC[static_cast<int>(weekday)]));
    5578           0 :                                 state.dataWeatherManager->RunPeriodInput(i).startWeekDay = weekday;
    5579             :                             }
    5580             :                         } else { // Set the weekday if it was not input
    5581           0 :                             state.dataWeatherManager->RunPeriodInput(i).startWeekDay = weekday;
    5582             :                         }
    5583             :                     }
    5584             :                 }
    5585             :             } else {
    5586             :                 // Non leap-day start date
    5587        1154 :                 if (!validMonthDay(state.dataWeatherManager->RunPeriodInput(i).startMonth, state.dataWeatherManager->RunPeriodInput(i).startDay)) {
    5588           0 :                     ShowSevereError(state,
    5589           0 :                                     format("{}: object={}, Invalid input start month/day ({}/{})",
    5590           0 :                                            state.dataIPShortCut->cCurrentModuleObject,
    5591           0 :                                            state.dataWeatherManager->RunPeriodInput(i).title,
    5592           0 :                                            state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5593           0 :                                            state.dataWeatherManager->RunPeriodInput(i).startDay));
    5594           0 :                     ErrorsFound = true;
    5595             :                 } else {                                                              // Month/day is valid
    5596        1154 :                     if (state.dataWeatherManager->RunPeriodInput(i).startYear == 0) { // No input starting year
    5597        1148 :                         if (inputWeekday) {
    5598        1005 :                             state.dataWeatherManager->RunPeriodInput(i).startYear =
    5599        2010 :                                 findYearForWeekday(state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5600        1005 :                                                    state.dataWeatherManager->RunPeriodInput(i).startDay,
    5601        1005 :                                                    state.dataWeatherManager->RunPeriodInput(i).startWeekDay);
    5602             :                         } else {
    5603             :                             // 2017 is the default year, 1/1 is a Sunday
    5604         143 :                             state.dataWeatherManager->RunPeriodInput(i).startYear = 2017;
    5605         143 :                             state.dataWeatherManager->RunPeriodInput(i).startWeekDay =
    5606         429 :                                 calculateDayOfWeek(state,
    5607         143 :                                                    state.dataWeatherManager->RunPeriodInput(i).startYear,
    5608         143 :                                                    state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5609         143 :                                                    state.dataWeatherManager->RunPeriodInput(i).startDay);
    5610             :                         }
    5611             :                     } else { // Have an input starting year
    5612          18 :                         ScheduleManager::DayType weekday = calculateDayOfWeek(state,
    5613           6 :                                                                               state.dataWeatherManager->RunPeriodInput(i).startYear,
    5614           6 :                                                                               state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5615          12 :                                                                               state.dataWeatherManager->RunPeriodInput(i).startDay);
    5616           6 :                         if (inputWeekday) { // Check for correctness of input
    5617           4 :                             if (weekday != state.dataWeatherManager->RunPeriodInput(i).startWeekDay) {
    5618           0 :                                 ShowWarningError(state,
    5619           0 :                                                  format("{}: object={}, start weekday ({}) does not match the start year ({}), corrected to {}.",
    5620           0 :                                                         state.dataIPShortCut->cCurrentModuleObject,
    5621           0 :                                                         state.dataWeatherManager->RunPeriodInput(i).title,
    5622           0 :                                                         state.dataIPShortCut->cAlphaArgs(2),
    5623           0 :                                                         state.dataWeatherManager->RunPeriodInput(i).startYear,
    5624           0 :                                                         ScheduleManager::dayTypeNamesUC[static_cast<int>(weekday)]));
    5625           0 :                                 state.dataWeatherManager->RunPeriodInput(i).startWeekDay = weekday;
    5626             :                             }
    5627             :                         } else { // Set the weekday if it was not input
    5628           2 :                             state.dataWeatherManager->RunPeriodInput(i).startWeekDay = weekday;
    5629             :                         }
    5630             :                     }
    5631             :                 }
    5632             :             }
    5633             : 
    5634             :             // Compute the Julian date of the start date
    5635        2308 :             state.dataWeatherManager->RunPeriodInput(i).startJulianDate = computeJulianDate(state.dataWeatherManager->RunPeriodInput(i).startYear,
    5636        1154 :                                                                                             state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5637        1154 :                                                                                             state.dataWeatherManager->RunPeriodInput(i).startDay);
    5638             : 
    5639             :             // Validate the end date
    5640        1154 :             if (state.dataWeatherManager->RunPeriodInput(i).endMonth == 2 && state.dataWeatherManager->RunPeriodInput(i).endDay == 29) {
    5641             :                 // Requested end date is a leap year
    5642           0 :                 if (state.dataWeatherManager->RunPeriodInput(i).endYear == 0) { // No input end year
    5643           0 :                     if (isLeapYear(state.dataWeatherManager->RunPeriodInput(i).startYear) &&
    5644           0 :                         state.dataWeatherManager->RunPeriodInput(i).startMonth < 3) {
    5645             :                         // The run period is from some date on or before 2/29 through 2/29
    5646           0 :                         state.dataWeatherManager->RunPeriodInput(i).endYear = state.dataWeatherManager->RunPeriodInput(i).startYear;
    5647             :                     } else {
    5648             :                         // There might be a better approach here, but for now just loop forward for the next leap year
    5649           0 :                         for (int yr = state.dataWeatherManager->RunPeriodInput(i).startYear + 1;
    5650           0 :                              yr < state.dataWeatherManager->RunPeriodInput(i).startYear + 10;
    5651             :                              yr++) {
    5652           0 :                             if (isLeapYear(yr)) {
    5653           0 :                                 state.dataWeatherManager->RunPeriodInput(i).endYear = yr;
    5654           0 :                                 break;
    5655             :                             }
    5656             :                         }
    5657             :                     }
    5658             :                 } else {                                                                    // Have an input end year
    5659           0 :                     if (!isLeapYear(state.dataWeatherManager->RunPeriodInput(i).endYear)) { // End year is not a leap year
    5660           0 :                         ShowSevereError(state,
    5661           0 :                                         format("{}: object={}, end year ({}) is not a leap year but the requested end date is 2/29.",
    5662           0 :                                                state.dataIPShortCut->cCurrentModuleObject,
    5663           0 :                                                state.dataWeatherManager->RunPeriodInput(i).title,
    5664           0 :                                                state.dataWeatherManager->RunPeriodInput(i).startYear));
    5665           0 :                         ErrorsFound = true;
    5666             :                     } else {
    5667           0 :                         state.dataWeatherManager->RunPeriodInput(i).endJulianDate =
    5668           0 :                             computeJulianDate(state.dataWeatherManager->RunPeriodInput(i).endYear,
    5669           0 :                                               state.dataWeatherManager->RunPeriodInput(i).endMonth,
    5670           0 :                                               state.dataWeatherManager->RunPeriodInput(i).endDay);
    5671           0 :                         if (state.dataWeatherManager->RunPeriodInput(i).startJulianDate > state.dataWeatherManager->RunPeriodInput(i).endJulianDate) {
    5672           0 :                             ShowSevereError(state,
    5673           0 :                                             format("{}: object={}, start Julian date ({}) is after the end Julian date ({}).",
    5674           0 :                                                    state.dataIPShortCut->cCurrentModuleObject,
    5675           0 :                                                    state.dataWeatherManager->RunPeriodInput(i).title,
    5676           0 :                                                    state.dataWeatherManager->RunPeriodInput(i).startJulianDate,
    5677           0 :                                                    state.dataWeatherManager->RunPeriodInput(i).endJulianDate));
    5678           0 :                             ErrorsFound = true;
    5679             :                         }
    5680             :                     }
    5681             :                 }
    5682             :             } else {
    5683             :                 // Non leap-day end date
    5684        1154 :                 if (!validMonthDay(state.dataWeatherManager->RunPeriodInput(i).endMonth, state.dataWeatherManager->RunPeriodInput(i).endDay)) {
    5685           0 :                     ShowSevereError(state,
    5686           0 :                                     format("{}: object={}, Invalid input end month/day ({}/{})",
    5687           0 :                                            state.dataIPShortCut->cCurrentModuleObject,
    5688           0 :                                            state.dataWeatherManager->RunPeriodInput(i).title,
    5689           0 :                                            state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5690           0 :                                            state.dataWeatherManager->RunPeriodInput(i).startDay));
    5691           0 :                     ErrorsFound = true;
    5692             :                 } else {                                                            // Month/day is valid
    5693        1154 :                     if (state.dataWeatherManager->RunPeriodInput(i).endYear == 0) { // No input end year
    5694             :                         // Assume same year as start year
    5695        1148 :                         state.dataWeatherManager->RunPeriodInput(i).endYear = state.dataWeatherManager->RunPeriodInput(i).startYear;
    5696        1148 :                         state.dataWeatherManager->RunPeriodInput(i).endJulianDate =
    5697        2296 :                             computeJulianDate(state.dataWeatherManager->RunPeriodInput(i).endYear,
    5698        1148 :                                               state.dataWeatherManager->RunPeriodInput(i).endMonth,
    5699        1148 :                                               state.dataWeatherManager->RunPeriodInput(i).endDay);
    5700        1148 :                         if (state.dataWeatherManager->RunPeriodInput(i).startJulianDate > state.dataWeatherManager->RunPeriodInput(i).endJulianDate) {
    5701           5 :                             state.dataWeatherManager->RunPeriodInput(i).endJulianDate = 0; // Force recalculation later
    5702           5 :                             state.dataWeatherManager->RunPeriodInput(i).endYear += 1;
    5703             :                         }
    5704             :                     } else { // Have an input end year
    5705           6 :                         state.dataWeatherManager->RunPeriodInput(i).endJulianDate =
    5706          12 :                             computeJulianDate(state.dataWeatherManager->RunPeriodInput(i).endYear,
    5707           6 :                                               state.dataWeatherManager->RunPeriodInput(i).endMonth,
    5708           6 :                                               state.dataWeatherManager->RunPeriodInput(i).endDay);
    5709           6 :                         if (state.dataWeatherManager->RunPeriodInput(i).startJulianDate > state.dataWeatherManager->RunPeriodInput(i).endJulianDate) {
    5710           0 :                             ShowSevereError(state,
    5711           0 :                                             format("{}: object={}, start Julian date ({}) is after the end Julian date ({}).",
    5712           0 :                                                    state.dataIPShortCut->cCurrentModuleObject,
    5713           0 :                                                    state.dataWeatherManager->RunPeriodInput(i).title,
    5714           0 :                                                    state.dataWeatherManager->RunPeriodInput(i).startJulianDate,
    5715           0 :                                                    state.dataWeatherManager->RunPeriodInput(i).endJulianDate));
    5716           0 :                             ErrorsFound = true;
    5717             :                         }
    5718             :                     }
    5719             :                 }
    5720             :             }
    5721             : 
    5722        1154 :             if (state.dataWeatherManager->RunPeriodInput(i).endJulianDate == 0) {
    5723          10 :                 state.dataWeatherManager->RunPeriodInput(i).endJulianDate = computeJulianDate(state.dataWeatherManager->RunPeriodInput(i).endYear,
    5724           5 :                                                                                               state.dataWeatherManager->RunPeriodInput(i).endMonth,
    5725           5 :                                                                                               state.dataWeatherManager->RunPeriodInput(i).endDay);
    5726             :             }
    5727             : 
    5728        1154 :             state.dataWeatherManager->RunPeriodInput(i).numSimYears =
    5729        1154 :                 state.dataWeatherManager->RunPeriodInput(i).endYear - state.dataWeatherManager->RunPeriodInput(i).startYear + 1;
    5730             : 
    5731             :             // A3,  \field Use Weather File Holidays and Special Days
    5732        1154 :             if (state.dataIPShortCut->lAlphaFieldBlanks(3) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "YES")) {
    5733         909 :                 state.dataWeatherManager->RunPeriodInput(i).useHolidays = true;
    5734         245 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "NO")) {
    5735         245 :                 state.dataWeatherManager->RunPeriodInput(i).useHolidays = false;
    5736             :             } else {
    5737           0 :                 ShowSevereError(state,
    5738           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->RunPeriodInput(i).title +
    5739           0 :                                     state.dataIPShortCut->cAlphaFieldNames(3) + " invalid [" + state.dataIPShortCut->cAlphaArgs(3) + ']');
    5740           0 :                 ErrorsFound = true;
    5741             :             }
    5742             : 
    5743             :             // A4,  \field Use Weather File Daylight Saving Period
    5744        1154 :             if (state.dataIPShortCut->lAlphaFieldBlanks(4) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(4), "YES")) {
    5745         905 :                 state.dataWeatherManager->RunPeriodInput(i).useDST = true;
    5746         249 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(4), "NO")) {
    5747         249 :                 state.dataWeatherManager->RunPeriodInput(i).useDST = false;
    5748             :             } else {
    5749           0 :                 ShowSevereError(state,
    5750           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->RunPeriodInput(i).title +
    5751           0 :                                     state.dataIPShortCut->cAlphaFieldNames(4) + " invalid [" + state.dataIPShortCut->cAlphaArgs(4) + ']');
    5752           0 :                 ErrorsFound = true;
    5753             :             }
    5754             : 
    5755             :             // A5,  \field Apply Weekend Holiday Rule
    5756        1154 :             if (state.dataIPShortCut->lAlphaFieldBlanks(5) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "YES")) {
    5757          48 :                 state.dataWeatherManager->RunPeriodInput(i).applyWeekendRule = true;
    5758        1106 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "NO")) {
    5759        1106 :                 state.dataWeatherManager->RunPeriodInput(i).applyWeekendRule = false;
    5760             :             } else {
    5761           0 :                 ShowSevereError(state,
    5762           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->RunPeriodInput(i).title +
    5763           0 :                                     state.dataIPShortCut->cAlphaFieldNames(5) + " invalid [" + state.dataIPShortCut->cAlphaArgs(5) + ']');
    5764           0 :                 ErrorsFound = true;
    5765             :             }
    5766             : 
    5767             :             // A6,  \field Use Weather File Rain Indicators
    5768        1154 :             if (state.dataIPShortCut->lAlphaFieldBlanks(6) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(6), "YES")) {
    5769        1087 :                 state.dataWeatherManager->RunPeriodInput(i).useRain = true;
    5770          67 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(6), "NO")) {
    5771          67 :                 state.dataWeatherManager->RunPeriodInput(i).useRain = false;
    5772             :             } else {
    5773           0 :                 ShowSevereError(state,
    5774           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->RunPeriodInput(i).title +
    5775           0 :                                     state.dataIPShortCut->cAlphaFieldNames(6) + " invalid [" + state.dataIPShortCut->cAlphaArgs(6) + ']');
    5776           0 :                 ErrorsFound = true;
    5777             :             }
    5778             : 
    5779             :             // A7,  \field Use Weather File Snow Indicators
    5780        1154 :             if (state.dataIPShortCut->lAlphaFieldBlanks(7) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(7), "YES")) {
    5781         978 :                 state.dataWeatherManager->RunPeriodInput(i).useSnow = true;
    5782         176 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(7), "NO")) {
    5783         176 :                 state.dataWeatherManager->RunPeriodInput(i).useSnow = false;
    5784             :             } else {
    5785           0 :                 ShowSevereError(state,
    5786           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->RunPeriodInput(i).title +
    5787           0 :                                     state.dataIPShortCut->cAlphaFieldNames(7) + " invalid [" + state.dataIPShortCut->cAlphaArgs(7) + ']');
    5788           0 :                 ErrorsFound = true;
    5789             :             }
    5790             : 
    5791             :             // A8,  \field Treat Weather as Actual
    5792        1154 :             if (state.dataIPShortCut->lAlphaFieldBlanks(8) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(8), "NO")) {
    5793        1154 :                 state.dataWeatherManager->RunPeriodInput(i).actualWeather = false;
    5794           0 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(8), "YES")) {
    5795           0 :                 state.dataWeatherManager->RunPeriodInput(i).actualWeather = true;
    5796             :             } else {
    5797           0 :                 ShowSevereError(state,
    5798           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": object=" + state.dataWeatherManager->RunPeriodInput(i).title +
    5799           0 :                                     state.dataIPShortCut->cAlphaFieldNames(8) + " invalid [" + state.dataIPShortCut->cAlphaArgs(8) + ']');
    5800           0 :                 ErrorsFound = true;
    5801             :             }
    5802             : 
    5803             :             // A9,  \field First Hour Interpolation Starting Values
    5804        1154 :             if (state.dataIPShortCut->lAlphaFieldBlanks(9) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(8), "Hour24")) {
    5805        1154 :                 state.dataWeatherManager->RunPeriodInput(i).firstHrInterpUsingHr1 = false;
    5806           0 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(9), "Hour1")) {
    5807           0 :                 state.dataWeatherManager->RunPeriodInput(i).firstHrInterpUsingHr1 = true;
    5808             :             } else {
    5809             :                 // fail-safe default
    5810           0 :                 state.dataWeatherManager->RunPeriodInput(i).firstHrInterpUsingHr1 = false;
    5811             :             }
    5812             : 
    5813        1154 :             state.dataWeatherManager->RunPeriodInput(i).dayOfWeek = static_cast<int>(state.dataWeatherManager->RunPeriodInput(i).startWeekDay);
    5814        1154 :             state.dataWeatherManager->RunPeriodInput(i).isLeapYear = isLeapYear(state.dataWeatherManager->RunPeriodInput(i).startYear);
    5815             : 
    5816             :             // calculate the annual start and end days from the user inputted month and day
    5817        1154 :             state.dataWeatherManager->RunPeriodInput(i).monWeekDay = 0;
    5818        1154 :             if (state.dataWeatherManager->RunPeriodInput(i).dayOfWeek != 0 && !ErrorsFound) {
    5819        4616 :                 SetupWeekDaysByMonth(state,
    5820        1154 :                                      state.dataWeatherManager->RunPeriodInput(i).startMonth,
    5821        1154 :                                      state.dataWeatherManager->RunPeriodInput(i).startDay,
    5822        1154 :                                      state.dataWeatherManager->RunPeriodInput(i).dayOfWeek,
    5823        1154 :                                      state.dataWeatherManager->RunPeriodInput(i).monWeekDay);
    5824             :             }
    5825             :         }
    5826             : 
    5827         747 :         if (nRunPeriods == 0 && state.dataSysVars->FullAnnualRun) {
    5828           0 :             ShowWarningError(state, "No Run Periods input but Full Annual Simulation selected.  Adding Run Period to 1/1 through 12/31.");
    5829           0 :             state.dataWeatherManager->Environment.redimension(++state.dataWeatherManager->NumOfEnvrn);
    5830           0 :             state.dataWeatherManager->Environment(state.dataWeatherManager->NumOfEnvrn).KindOfEnvrn =
    5831             :                 DataGlobalConstants::KindOfSim::RunPeriodWeather;
    5832           0 :             nRunPeriods = 1;
    5833           0 :             state.dataGlobal->WeathSimReq = true;
    5834           0 :             state.dataWeatherManager->RunPeriodInput.allocate(nRunPeriods);
    5835           0 :             state.dataWeatherManager->RunPeriodInput(1).startJulianDate = General::OrdinalDay(state.dataWeatherManager->RunPeriodInput(1).startMonth,
    5836           0 :                                                                                               state.dataWeatherManager->RunPeriodInput(1).startDay,
    5837           0 :                                                                                               state.dataWeatherManager->LeapYearAdd);
    5838           0 :             state.dataWeatherManager->RunPeriodInput(1).endJulianDate = General::OrdinalDay(state.dataWeatherManager->RunPeriodInput(1).endMonth,
    5839           0 :                                                                                             state.dataWeatherManager->RunPeriodInput(1).endDay,
    5840           0 :                                                                                             state.dataWeatherManager->LeapYearAdd);
    5841           0 :             state.dataWeatherManager->RunPeriodInput(1).monWeekDay = 0;
    5842           0 :             if (state.dataWeatherManager->RunPeriodInput(1).dayOfWeek != 0 && !ErrorsFound) {
    5843           0 :                 SetupWeekDaysByMonth(state,
    5844           0 :                                      state.dataWeatherManager->RunPeriodInput(1).startMonth,
    5845           0 :                                      state.dataWeatherManager->RunPeriodInput(1).startDay,
    5846           0 :                                      state.dataWeatherManager->RunPeriodInput(1).dayOfWeek,
    5847           0 :                                      state.dataWeatherManager->RunPeriodInput(1).monWeekDay);
    5848             :             }
    5849         747 :         } else if (nRunPeriods > 1 && state.dataSysVars->FullAnnualRun) {
    5850           0 :             nRunPeriods = 1;
    5851             :         }
    5852         747 :     }
    5853             : 
    5854           3 :     void GetRunPeriodDesignData(EnergyPlusData &state, bool &ErrorsFound)
    5855             :     {
    5856             : 
    5857             :         // SUBROUTINE INFORMATION:
    5858             :         //       AUTHOR         Linda Lawrie
    5859             :         //       DATE WRITTEN   March 2008
    5860             : 
    5861             :         // PURPOSE OF THIS SUBROUTINE:
    5862             :         // This subroutine gets the run period design info from User input and the
    5863             :         //  simulation dates
    5864             : 
    5865             :         // Call Input Get routine to retrieve annual run data
    5866           3 :         int RPD1 = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "SizingPeriod:WeatherFileDays");
    5867           3 :         int RPD2 = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "SizingPeriod:WeatherFileConditionType");
    5868           3 :         state.dataWeatherManager->TotRunDesPers = RPD1 + RPD2;
    5869             : 
    5870           3 :         state.dataWeatherManager->RunPeriodDesignInput.allocate(RPD1 + RPD2);
    5871           3 :         state.dataWeatherManager->RunPeriodDesignInputUniqueNames.reserve(static_cast<unsigned>(RPD1 + RPD2));
    5872             : 
    5873           3 :         int Count = 0;
    5874           3 :         state.dataIPShortCut->cCurrentModuleObject = "SizingPeriod:WeatherFileDays";
    5875           6 :         for (int i = 1; i <= RPD1; ++i) {
    5876             :             int NumAlphas;   // Number of alphas being input
    5877             :             int NumNumerics; // Number of Numerics being input
    5878             :             int IOStat;      // IO Status when calling get input subroutine
    5879          24 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5880           3 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
    5881             :                                                                      i,
    5882           3 :                                                                      state.dataIPShortCut->cAlphaArgs,
    5883             :                                                                      NumAlphas,
    5884           3 :                                                                      state.dataIPShortCut->rNumericArgs,
    5885             :                                                                      NumNumerics,
    5886             :                                                                      IOStat,
    5887           3 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    5888           3 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    5889           3 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    5890           3 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    5891           9 :             GlobalNames::VerifyUniqueInterObjectName(state,
    5892           3 :                                                      state.dataWeatherManager->RunPeriodDesignInputUniqueNames,
    5893           3 :                                                      state.dataIPShortCut->cAlphaArgs(1),
    5894           3 :                                                      state.dataIPShortCut->cCurrentModuleObject,
    5895           3 :                                                      state.dataIPShortCut->cAlphaFieldNames(1),
    5896             :                                                      ErrorsFound);
    5897             : 
    5898           3 :             ++Count;
    5899           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).title = state.dataIPShortCut->cAlphaArgs(1);
    5900           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).periodType = "User Selected WeatherFile RunPeriod (Design)";
    5901             : 
    5902             :             // set the start and end day of month from user input
    5903           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).startMonth = int(state.dataIPShortCut->rNumericArgs(1));
    5904           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).startDay = int(state.dataIPShortCut->rNumericArgs(2));
    5905           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).endMonth = int(state.dataIPShortCut->rNumericArgs(3));
    5906           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).endDay = int(state.dataIPShortCut->rNumericArgs(4));
    5907             : 
    5908           3 :             switch (state.dataWeatherManager->RunPeriodDesignInput(Count).startMonth) {
    5909           3 :             case 1:
    5910             :             case 3:
    5911             :             case 5:
    5912             :             case 7:
    5913             :             case 8:
    5914             :             case 10:
    5915             :             case 12:
    5916           3 :                 if (state.dataWeatherManager->RunPeriodDesignInput(Count).startDay > 31) {
    5917           0 :                     ShowSevereError(state,
    5918           0 :                                     state.dataIPShortCut->cCurrentModuleObject +
    5919           0 :                                         ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    5920           0 :                                         format("{} invalid (Day of Month) [{}]",
    5921           0 :                                                state.dataIPShortCut->cNumericFieldNames(2),
    5922           0 :                                                state.dataWeatherManager->RunPeriodDesignInput(Count).startDay));
    5923           0 :                     ErrorsFound = true;
    5924             :                 }
    5925           3 :                 break;
    5926           0 :             case 4:
    5927             :             case 6:
    5928             :             case 9:
    5929             :             case 11:
    5930           0 :                 if (state.dataWeatherManager->RunPeriodDesignInput(Count).startDay > 30) {
    5931           0 :                     ShowSevereError(state,
    5932           0 :                                     state.dataIPShortCut->cCurrentModuleObject +
    5933           0 :                                         ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    5934           0 :                                         format("{} invalid (Day of Month) [{}]",
    5935           0 :                                                state.dataIPShortCut->cNumericFieldNames(2),
    5936           0 :                                                state.dataWeatherManager->RunPeriodDesignInput(Count).startDay));
    5937           0 :                     ErrorsFound = true;
    5938             :                 }
    5939           0 :                 break;
    5940           0 :             case 2:
    5941           0 :                 if (state.dataWeatherManager->RunPeriodDesignInput(Count).startDay > 28 + state.dataWeatherManager->LeapYearAdd) {
    5942           0 :                     ShowSevereError(state,
    5943           0 :                                     state.dataIPShortCut->cCurrentModuleObject +
    5944           0 :                                         ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    5945           0 :                                         format("{} invalid (Day of Month) [{}]",
    5946           0 :                                                state.dataIPShortCut->cNumericFieldNames(2),
    5947           0 :                                                state.dataWeatherManager->RunPeriodDesignInput(Count).startDay));
    5948           0 :                     ErrorsFound = true;
    5949             :                 }
    5950           0 :                 break;
    5951           0 :             default:
    5952           0 :                 ShowSevereError(state,
    5953           0 :                                 state.dataIPShortCut->cCurrentModuleObject +
    5954           0 :                                     ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    5955           0 :                                     format("{} invalid (Month) [{}]",
    5956           0 :                                            state.dataIPShortCut->cNumericFieldNames(1),
    5957           0 :                                            state.dataWeatherManager->RunPeriodDesignInput(Count).startMonth));
    5958           0 :                 ErrorsFound = true;
    5959           0 :                 break;
    5960             :             }
    5961             : 
    5962           3 :             if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
    5963           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek =
    5964             :                     static_cast<int>(ScheduleManager::DayType::Monday); // Defaults to Monday
    5965             :             } else {
    5966           3 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek =
    5967           6 :                     getEnumerationValue(ScheduleManager::dayTypeNamesUC, state.dataIPShortCut->cAlphaArgs(2));
    5968           6 :                 if (state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek < 1 ||
    5969           3 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek == 8) {
    5970           0 :                     ShowWarningError(state,
    5971           0 :                                      state.dataIPShortCut->cCurrentModuleObject +
    5972           0 :                                          ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    5973           0 :                                          state.dataIPShortCut->cAlphaFieldNames(1) + " invalid (Day of Week) [" +
    5974           0 :                                          state.dataIPShortCut->cAlphaArgs(1) + " for Start is not Valid, Monday will be Used.");
    5975           0 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek =
    5976             :                         static_cast<int>(ScheduleManager::DayType::Monday); // Defaults to Monday
    5977             :                 }
    5978             :             }
    5979             : 
    5980           3 :             if (state.dataIPShortCut->lAlphaFieldBlanks(3) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "YES")) {
    5981           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useDST = true;
    5982           3 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "NO")) {
    5983           3 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useDST = false;
    5984             :             } else {
    5985           0 :                 ShowSevereError(state,
    5986           0 :                                 state.dataIPShortCut->cCurrentModuleObject +
    5987           0 :                                     ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    5988           0 :                                     state.dataIPShortCut->cAlphaFieldNames(3) + " invalid [" + state.dataIPShortCut->cAlphaArgs(3) + ']');
    5989           0 :                 ErrorsFound = true;
    5990             :             }
    5991             : 
    5992           3 :             if (state.dataIPShortCut->lAlphaFieldBlanks(4) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(4), "YES")) {
    5993           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useRain = true;
    5994           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useSnow = true;
    5995           3 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(4), "NO")) {
    5996           3 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useRain = false;
    5997           3 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useSnow = false;
    5998             :             } else {
    5999           0 :                 ShowSevereError(state,
    6000           0 :                                 state.dataIPShortCut->cCurrentModuleObject +
    6001           0 :                                     ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    6002           0 :                                     state.dataIPShortCut->cAlphaFieldNames(4) + " invalid [" + state.dataIPShortCut->cAlphaArgs(4) + ']');
    6003           0 :                 ErrorsFound = true;
    6004             :             }
    6005             : 
    6006             :             // calculate the annual start and end days from the user inputted month and day
    6007           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).startJulianDate =
    6008           6 :                 General::OrdinalDay(state.dataWeatherManager->RunPeriodDesignInput(Count).startMonth,
    6009           3 :                                     state.dataWeatherManager->RunPeriodDesignInput(Count).startDay,
    6010           3 :                                     state.dataWeatherManager->LeapYearAdd);
    6011           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).endJulianDate =
    6012           6 :                 General::OrdinalDay(state.dataWeatherManager->RunPeriodDesignInput(Count).endMonth,
    6013           3 :                                     state.dataWeatherManager->RunPeriodDesignInput(Count).endDay,
    6014           3 :                                     state.dataWeatherManager->LeapYearAdd);
    6015           6 :             if (state.dataWeatherManager->RunPeriodDesignInput(Count).startJulianDate <=
    6016           3 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).endJulianDate) {
    6017           3 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).totalDays =
    6018           6 :                     (state.dataWeatherManager->RunPeriodDesignInput(Count).endJulianDate -
    6019           9 :                      state.dataWeatherManager->RunPeriodDesignInput(Count).startJulianDate + 1) *
    6020           3 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).numSimYears;
    6021             :             } else {
    6022           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).totalDays =
    6023           0 :                     (General::OrdinalDay(12, 31, state.dataWeatherManager->LeapYearAdd) -
    6024           0 :                      state.dataWeatherManager->RunPeriodDesignInput(Count).startJulianDate + 1 +
    6025           0 :                      state.dataWeatherManager->RunPeriodDesignInput(Count).endJulianDate) *
    6026           0 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).numSimYears;
    6027             :             }
    6028           3 :             state.dataWeatherManager->RunPeriodDesignInput(Count).monWeekDay = 0;
    6029           3 :             if (state.dataWeatherManager->RunPeriodDesignInput(1).dayOfWeek != 0 && !ErrorsFound) {
    6030          12 :                 SetupWeekDaysByMonth(state,
    6031           3 :                                      state.dataWeatherManager->RunPeriodDesignInput(1).startMonth,
    6032           3 :                                      state.dataWeatherManager->RunPeriodDesignInput(1).startDay,
    6033           3 :                                      state.dataWeatherManager->RunPeriodDesignInput(1).dayOfWeek,
    6034           3 :                                      state.dataWeatherManager->RunPeriodDesignInput(1).monWeekDay);
    6035             :             }
    6036             :         }
    6037             : 
    6038           3 :         state.dataIPShortCut->cCurrentModuleObject = "SizingPeriod:WeatherFileConditionType";
    6039           5 :         for (int i = 1; i <= RPD2; ++i) {
    6040             :             int NumAlphas;   // Number of alphas being input
    6041             :             int NumNumerics; // Number of Numerics being input
    6042             :             int IOStat;      // IO Status when calling get input subroutine
    6043          16 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    6044           2 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
    6045             :                                                                      i,
    6046           2 :                                                                      state.dataIPShortCut->cAlphaArgs,
    6047             :                                                                      NumAlphas,
    6048           2 :                                                                      state.dataIPShortCut->rNumericArgs,
    6049             :                                                                      NumNumerics,
    6050             :                                                                      IOStat,
    6051           2 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    6052           2 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    6053           2 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    6054           2 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    6055           6 :             GlobalNames::VerifyUniqueInterObjectName(state,
    6056           2 :                                                      state.dataWeatherManager->RunPeriodDesignInputUniqueNames,
    6057           2 :                                                      state.dataIPShortCut->cAlphaArgs(1),
    6058           2 :                                                      state.dataIPShortCut->cCurrentModuleObject,
    6059           2 :                                                      state.dataIPShortCut->cAlphaFieldNames(1),
    6060             :                                                      ErrorsFound);
    6061             : 
    6062           2 :             ++Count;
    6063           2 :             state.dataWeatherManager->RunPeriodDesignInput(Count).title = state.dataIPShortCut->cAlphaArgs(1);
    6064           4 :             state.dataWeatherManager->RunPeriodDesignInput(Count).periodType =
    6065           6 :                 "User Selected WeatherFile Typical/Extreme Period (Design)=" + state.dataIPShortCut->cAlphaArgs(2);
    6066             : 
    6067             :             // Period Selection
    6068           2 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
    6069           4 :                 int WhichPeriod = UtilityRoutines::FindItem(
    6070           6 :                     state.dataIPShortCut->cAlphaArgs(2), state.dataWeatherManager->TypicalExtremePeriods, &TypicalExtremeData::MatchValue);
    6071           2 :                 if (WhichPeriod != 0) {
    6072           2 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).startDay =
    6073           2 :                         state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartDay;
    6074           2 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).startMonth =
    6075           2 :                         state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartMonth;
    6076           2 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).startJulianDate =
    6077           2 :                         state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartJDay;
    6078           2 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).endDay =
    6079           2 :                         state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndDay;
    6080           2 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).endMonth =
    6081           2 :                         state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndMonth;
    6082           2 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).endJulianDate =
    6083           2 :                         state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndJDay;
    6084           2 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).totalDays =
    6085           2 :                         state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).TotalDays;
    6086             :                 } else {
    6087           0 :                     WhichPeriod = UtilityRoutines::FindItem(
    6088           0 :                         state.dataIPShortCut->cAlphaArgs(2), state.dataWeatherManager->TypicalExtremePeriods, &TypicalExtremeData::MatchValue1);
    6089           0 :                     if (WhichPeriod != 0) {
    6090           0 :                         state.dataWeatherManager->RunPeriodDesignInput(Count).startDay =
    6091           0 :                             state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartDay;
    6092           0 :                         state.dataWeatherManager->RunPeriodDesignInput(Count).startMonth =
    6093           0 :                             state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartMonth;
    6094           0 :                         state.dataWeatherManager->RunPeriodDesignInput(Count).startJulianDate =
    6095           0 :                             state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartJDay;
    6096           0 :                         state.dataWeatherManager->RunPeriodDesignInput(Count).endDay =
    6097           0 :                             state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndDay;
    6098           0 :                         state.dataWeatherManager->RunPeriodDesignInput(Count).endMonth =
    6099           0 :                             state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndMonth;
    6100           0 :                         state.dataWeatherManager->RunPeriodDesignInput(Count).endJulianDate =
    6101           0 :                             state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndJDay;
    6102           0 :                         state.dataWeatherManager->RunPeriodDesignInput(Count).totalDays =
    6103           0 :                             state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).TotalDays;
    6104           0 :                         ShowWarningError(state,
    6105           0 :                                          state.dataIPShortCut->cCurrentModuleObject +
    6106           0 :                                              ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    6107           0 :                                              state.dataIPShortCut->cAlphaFieldNames(2) + '=' + state.dataIPShortCut->cAlphaArgs(2) + " matched to " +
    6108           0 :                                              state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).MatchValue);
    6109             :                     } else {
    6110           0 :                         WhichPeriod = UtilityRoutines::FindItem(
    6111           0 :                             state.dataIPShortCut->cAlphaArgs(2), state.dataWeatherManager->TypicalExtremePeriods, &TypicalExtremeData::MatchValue2);
    6112           0 :                         if (WhichPeriod != 0) {
    6113           0 :                             state.dataWeatherManager->RunPeriodDesignInput(Count).startDay =
    6114           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartDay;
    6115           0 :                             state.dataWeatherManager->RunPeriodDesignInput(Count).startMonth =
    6116           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartMonth;
    6117           0 :                             state.dataWeatherManager->RunPeriodDesignInput(Count).startJulianDate =
    6118           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).StartJDay;
    6119           0 :                             state.dataWeatherManager->RunPeriodDesignInput(Count).endDay =
    6120           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndDay;
    6121           0 :                             state.dataWeatherManager->RunPeriodDesignInput(Count).endMonth =
    6122           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndMonth;
    6123           0 :                             state.dataWeatherManager->RunPeriodDesignInput(Count).endJulianDate =
    6124           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).EndJDay;
    6125           0 :                             state.dataWeatherManager->RunPeriodDesignInput(Count).totalDays =
    6126           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).TotalDays;
    6127           0 :                             ShowWarningError(state,
    6128           0 :                                              state.dataIPShortCut->cCurrentModuleObject +
    6129           0 :                                                  ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    6130           0 :                                                  state.dataIPShortCut->cAlphaFieldNames(2) + '=' + state.dataIPShortCut->cAlphaArgs(2) +
    6131           0 :                                                  " matched to " + state.dataWeatherManager->TypicalExtremePeriods(WhichPeriod).MatchValue);
    6132             :                         } else {
    6133           0 :                             ShowSevereError(state,
    6134           0 :                                             state.dataIPShortCut->cCurrentModuleObject +
    6135           0 :                                                 ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    6136           0 :                                                 state.dataIPShortCut->cAlphaFieldNames(2) +
    6137           0 :                                                 " invalid (not on Weather File)=" + state.dataIPShortCut->cAlphaArgs(2));
    6138           0 :                             ErrorsFound = true;
    6139             :                         }
    6140             :                     }
    6141             :                 }
    6142             :             } else {
    6143           0 :                 ShowSevereError(state,
    6144           0 :                                 state.dataIPShortCut->cCurrentModuleObject +
    6145           0 :                                     ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    6146           0 :                                     state.dataIPShortCut->cAlphaFieldNames(2) + " invalid (blank).");
    6147           0 :                 ErrorsFound = true;
    6148             :             }
    6149             : 
    6150           2 :             if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
    6151           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek =
    6152             :                     static_cast<int>(ScheduleManager::DayType::Monday); // Defaults to Monday
    6153             :             } else {
    6154           2 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek =
    6155           4 :                     getEnumerationValue(ScheduleManager::dayTypeNamesUC, state.dataIPShortCut->cAlphaArgs(3));
    6156           4 :                 if (state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek < static_cast<int>(ScheduleManager::DayType::Sunday) ||
    6157           2 :                     state.dataWeatherManager->RunPeriodDesignInput(Count).dayOfWeek == static_cast<int>(ScheduleManager::DayType::Holiday)) {
    6158             :                     // Sunday-Saturday, SummerDesignDay, WinterDesignDay, CustomDay1, and CustomDay2 are all valid. Holiday is not valid.
    6159             :                     // The input processor should trap invalid key choices, so this should never trip.
    6160           0 :                     assert(false);
    6161             :                 }
    6162             :             }
    6163             : 
    6164           2 :             if (state.dataIPShortCut->lAlphaFieldBlanks(4) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(4), "YES")) {
    6165           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useDST = true;
    6166           2 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(4), "NO")) {
    6167           2 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useDST = false;
    6168             :             } else {
    6169           0 :                 ShowSevereError(state,
    6170           0 :                                 state.dataIPShortCut->cCurrentModuleObject +
    6171           0 :                                     ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    6172           0 :                                     state.dataIPShortCut->cAlphaFieldNames(4) + " invalid [" + state.dataIPShortCut->cAlphaArgs(4) + ']');
    6173           0 :                 ErrorsFound = true;
    6174             :             }
    6175             : 
    6176           2 :             if (state.dataIPShortCut->lAlphaFieldBlanks(5) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "YES")) {
    6177           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useRain = true;
    6178           0 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useSnow = true;
    6179           2 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "NO")) {
    6180           2 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useRain = false;
    6181           2 :                 state.dataWeatherManager->RunPeriodDesignInput(Count).useSnow = false;
    6182             :             } else {
    6183           0 :                 ShowSevereError(state,
    6184           0 :                                 state.dataIPShortCut->cCurrentModuleObject +
    6185           0 :                                     ": object=" + state.dataWeatherManager->RunPeriodDesignInput(Count).title + ' ' +
    6186           0 :                                     state.dataIPShortCut->cAlphaFieldNames(5) + " invalid [" + state.dataIPShortCut->cAlphaArgs(5) + ']');
    6187           0 :                 ErrorsFound = true;
    6188             :             }
    6189           2 :             state.dataWeatherManager->RunPeriodDesignInput(1).monWeekDay = 0;
    6190           2 :             if (state.dataWeatherManager->RunPeriodDesignInput(1).dayOfWeek != 0 && !ErrorsFound) {
    6191           8 :                 SetupWeekDaysByMonth(state,
    6192           2 :                                      state.dataWeatherManager->RunPeriodDesignInput(1).startMonth,
    6193           2 :                                      state.dataWeatherManager->RunPeriodDesignInput(1).startDay,
    6194           2 :                                      state.dataWeatherManager->RunPeriodDesignInput(1).dayOfWeek,
    6195           2 :                                      state.dataWeatherManager->RunPeriodDesignInput(1).monWeekDay);
    6196             :             }
    6197             :         }
    6198           3 :     }
    6199             : 
    6200         747 :     void GetSpecialDayPeriodData(EnergyPlusData &state, bool &ErrorsFound) // will be set to true if severe errors are found in inputs
    6201             :     {
    6202             : 
    6203             :         // SUBROUTINE INFORMATION:
    6204             :         //       AUTHOR         Linda Lawrie
    6205             :         //       DATE WRITTEN   June 2000
    6206             :         //       MODIFIED       na
    6207             :         //       RE-ENGINEERED  na
    6208             : 
    6209             :         // PURPOSE OF THIS SUBROUTINE:
    6210             :         // This subroutine reads any special day period data from the IDF and
    6211             :         // processes it into the data structure that will drive the values
    6212             :         // in the SpecialDayTypes array.
    6213             : 
    6214             :         // METHODOLOGY EMPLOYED:
    6215             :         // Processes the following IDD definition:
    6216             :         // SpecialDayPeriod,
    6217             :         //      \memo This object sets up holidays/special days to be used during weather file
    6218             :         //      \memo run periods.  (These are not used with DesignDay objects.)
    6219             :         //      \memo Depending on the value in the run period, days on the weather file may also
    6220             :         //      \memo be used.  However, the weather file specification will take precedence over
    6221             :         //      \memo any specification shown here.  (No error message on duplicate days or overlapping
    6222             :         //      \memo days).
    6223             :         //  A1, \field Holiday Name
    6224             :         //  A2, \field StartDate
    6225             :         //      \memo  Dates can be several formats:
    6226             :         //      \memo  <number>/<number>  (month/day)
    6227             :         //      \memo  <number> Month
    6228             :         //      \memo  Month <number>
    6229             :         //      \memo Months are January, February, March, April, May, June, July, August, September, October, November, December
    6230             :         //      \memo Months can be the first 3 letters of the month
    6231             :         //        \note will eventually allow: 3 Monday April (meaning 3rd Monday in April)
    6232             :         //  N1, \field duration (number of days)
    6233             :         //  A3; \field SpecialDayType
    6234             :         //        \note SpecialDayType selects the schedules appropriate for each day so labeled
    6235             :         //        \type choice
    6236             :         //        \key Holiday
    6237             :         //        \key SummerDesignDay
    6238             :         //        \key WinterDesignDay
    6239             :         //        \key CustomDay1
    6240             :         //        \key CustomDay2
    6241             : 
    6242         747 :         state.dataIPShortCut->cCurrentModuleObject = "RunPeriodControl:SpecialDays";
    6243         747 :         int NumSpecDays = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    6244             :         int Count;
    6245         747 :         if (allocated(state.dataWeatherManager->SpecialDays)) { // EPW already allocated the array
    6246         737 :             Count = state.dataWeatherManager->NumSpecialDays - NumSpecDays + 1;
    6247             :         } else {
    6248          10 :             state.dataWeatherManager->SpecialDays.allocate(NumSpecDays);
    6249          10 :             state.dataWeatherManager->NumSpecialDays = NumSpecDays;
    6250          10 :             Count = 1;
    6251             :         }
    6252             : 
    6253        1996 :         for (int i = 1; i <= NumSpecDays; ++i) {
    6254             : 
    6255        2498 :             Array1D_string AlphArray(3);
    6256             :             int NumAlphas;
    6257        2498 :             Array1D<Real64> Duration(1);
    6258             :             int NumNumbers;
    6259             :             int IOStat;
    6260        2498 :             state.dataInputProcessing->inputProcessor->getObjectItem(
    6261        1249 :                 state, state.dataIPShortCut->cCurrentModuleObject, i, AlphArray, NumAlphas, Duration, NumNumbers, IOStat);
    6262        1249 :             UtilityRoutines::IsNameEmpty(state, AlphArray(1), state.dataIPShortCut->cCurrentModuleObject, ErrorsFound);
    6263        1249 :             state.dataWeatherManager->SpecialDays(Count).Name = AlphArray(1);
    6264             : 
    6265             :             int PMonth;
    6266             :             int PDay;
    6267             :             int PWeekDay;
    6268             :             DateType dateType;
    6269        1249 :             General::ProcessDateString(state, AlphArray(2), PMonth, PDay, PWeekDay, dateType, ErrorsFound);
    6270        1249 :             if (dateType == DateType::MonthDay) {
    6271         506 :                 state.dataWeatherManager->SpecialDays(Count).DateType = dateType;
    6272         506 :                 state.dataWeatherManager->SpecialDays(Count).Month = PMonth;
    6273         506 :                 state.dataWeatherManager->SpecialDays(Count).Day = PDay;
    6274         506 :                 state.dataWeatherManager->SpecialDays(Count).WeekDay = 0;
    6275         506 :                 state.dataWeatherManager->SpecialDays(Count).CompDate = PMonth * 32 + PDay;
    6276         506 :                 state.dataWeatherManager->SpecialDays(Count).WthrFile = false;
    6277         743 :             } else if (dateType != DateType::Invalid) {
    6278         743 :                 state.dataWeatherManager->SpecialDays(Count).DateType = dateType;
    6279         743 :                 state.dataWeatherManager->SpecialDays(Count).Month = PMonth;
    6280         743 :                 state.dataWeatherManager->SpecialDays(Count).Day = PDay;
    6281         743 :                 state.dataWeatherManager->SpecialDays(Count).WeekDay = PWeekDay;
    6282         743 :                 state.dataWeatherManager->SpecialDays(Count).CompDate = 0;
    6283         743 :                 state.dataWeatherManager->SpecialDays(Count).WthrFile = false;
    6284           0 :             } else if (dateType == DateType::Invalid) {
    6285           0 :                 ShowSevereError(state,
    6286           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": " + AlphArray(1) + " Invalid " +
    6287           0 :                                     state.dataIPShortCut->cAlphaFieldNames(2) + '=' + AlphArray(2));
    6288           0 :                 ErrorsFound = true;
    6289             :             }
    6290             : 
    6291        1249 :             if (Duration(1) > 0) {
    6292        1249 :                 state.dataWeatherManager->SpecialDays(Count).Duration = int(Duration(1));
    6293             :             } else {
    6294           0 :                 ShowSevereError(state,
    6295           0 :                                 format("{}: {} Invalid {}={:.0T}",
    6296           0 :                                        state.dataIPShortCut->cCurrentModuleObject,
    6297             :                                        AlphArray(1),
    6298           0 :                                        state.dataIPShortCut->cNumericFieldNames(1),
    6299           0 :                                        Duration(1)));
    6300           0 :                 ErrorsFound = true;
    6301             :             }
    6302             : 
    6303        1249 :             int DayType = getEnumerationValue(ScheduleManager::dayTypeNamesUC, AlphArray(3));
    6304        1249 :             if (DayType == 0) {
    6305           0 :                 ShowSevereError(state,
    6306           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": " + AlphArray(1) + " Invalid " +
    6307           0 :                                     state.dataIPShortCut->cAlphaFieldNames(3) + '=' + AlphArray(3));
    6308           0 :                 ErrorsFound = true;
    6309             :             } else {
    6310        1249 :                 state.dataWeatherManager->SpecialDays(Count).DayType = DayType;
    6311             :             }
    6312        1249 :             ++Count;
    6313             :         }
    6314         747 :     }
    6315             : 
    6316           7 :     void CalcSpecialDayTypes(EnergyPlusData &state)
    6317             :     {
    6318             : 
    6319             :         // SUBROUTINE INFORMATION:
    6320             :         //       AUTHOR         Linda Lawrie
    6321             :         //       DATE WRITTEN   June 2000
    6322             :         //       MODIFIED       na
    6323             :         //       RE-ENGINEERED  na
    6324             : 
    6325             :         // PURPOSE OF THIS SUBROUTINE:
    6326             :         // This subroutine creates the array of Special Day types used during
    6327             :         // the simulation.
    6328             : 
    6329             :         // METHODOLOGY EMPLOYED:
    6330             :         // Sets up the SpecialDayTypes array that then is used during simulation.
    6331             : 
    6332           7 :         state.dataWeatherManager->SpecialDayTypes = 0; // Initialize/Reset Special Day Types array
    6333             : 
    6334          37 :         for (int i = 1; i <= state.dataWeatherManager->NumSpecialDays; ++i) {
    6335             : 
    6336          30 :             if (state.dataWeatherManager->SpecialDays(i).WthrFile) continue;
    6337             : 
    6338          30 :             int Warn = 0;
    6339             : 
    6340          60 :             int JDay = General::OrdinalDay(state.dataWeatherManager->SpecialDays(i).Month,
    6341          30 :                                            state.dataWeatherManager->SpecialDays(i).Day,
    6342          30 :                                            state.dataWeatherManager->LeapYearAdd) -
    6343          30 :                        1;
    6344             : 
    6345          60 :             for (int j = 1; j <= state.dataWeatherManager->SpecialDays(i).Duration; ++j) {
    6346          30 :                 ++JDay;
    6347          30 :                 if (JDay > 366) {
    6348           0 :                     ShowWarningError(state,
    6349           0 :                                      "SpecialDay=" + state.dataWeatherManager->SpecialDays(i).Name +
    6350             :                                          " causes index of more than 366, ignoring those beyond 366");
    6351             :                 } else {
    6352          30 :                     if (state.dataWeatherManager->SpecialDayTypes(JDay) != 0 && Warn == 0) {
    6353           0 :                         ShowWarningError(state,
    6354           0 :                                          "SpecialDay=" + state.dataWeatherManager->SpecialDays(i).Name +
    6355             :                                              " attempted overwrite of previous set special day");
    6356           0 :                         Warn = 1;
    6357          30 :                     } else if (state.dataWeatherManager->SpecialDayTypes(JDay) == 0) {
    6358          30 :                         state.dataWeatherManager->SpecialDayTypes(JDay) = state.dataWeatherManager->SpecialDays(i).DayType;
    6359             :                     }
    6360             :                 }
    6361             :             }
    6362             :         }
    6363           7 :     }
    6364             : 
    6365         747 :     void GetDSTData(EnergyPlusData &state, bool &ErrorsFound) // will be set to true if severe errors are found in inputs
    6366             :     {
    6367             : 
    6368             :         // SUBROUTINE INFORMATION:
    6369             :         //       AUTHOR         Linda Lawrie
    6370             :         //       DATE WRITTEN   August 2000
    6371             :         //       MODIFIED       na
    6372             :         //       RE-ENGINEERED  na
    6373             : 
    6374             :         // PURPOSE OF THIS SUBROUTINE:
    6375             :         // This subroutine gets a possible "Daylight Saving Period" from the IDF.  Using this
    6376             :         // will overwrite any prior DST data.
    6377             : 
    6378             :         // METHODOLOGY EMPLOYED:
    6379             :         // Processes the following IDD definition:
    6380             :         // DaylightSavingPeriod,
    6381             :         //      \memo This object sets up the Daylight Saving period for any RunPeriod.
    6382             :         //      \memo Ignores any DaylightSavingperiod values on the weather file and uses this definition.
    6383             :         //      \memo (These are not used with DesignDay objects.)
    6384             :         //  A1, \field StartDate
    6385             :         //  A2, \field EndDate
    6386             :         //      \memo  Dates can be several formats:
    6387             :         //      \memo  <number>/<number>  (month/day)
    6388             :         //      \memo  <number> <Month>
    6389             :         //      \memo  <Month> <number>
    6390             :         //      \memo <Nth> <Weekday> in <Month)
    6391             :         //      \memo Last <WeekDay> in <Month>
    6392             :         //      \memo <Month> can be January, February, March, April, May, June, July, August, September,
    6393             :         // October, November, December
    6394             :         //      \memo Months can be the first 3 letters of the month
    6395             :         //      \memo <Weekday> can be Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
    6396             :         //      \memo <Nth> can be 1 or 1st, 2 or 2nd, etc. up to 5(?)
    6397             : 
    6398         747 :         state.dataIPShortCut->cCurrentModuleObject = "RunPeriodControl:DaylightSavingTime";
    6399         747 :         int NumFound = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    6400             : 
    6401         747 :         if (NumFound == 1) {
    6402             :             int NumAlphas;
    6403             :             int IOStat;
    6404             :             int NumNumbers;
    6405        1392 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    6406         174 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
    6407             :                                                                      1,
    6408         174 :                                                                      state.dataIPShortCut->cAlphaArgs,
    6409             :                                                                      NumAlphas,
    6410         174 :                                                                      state.dataIPShortCut->rNumericArgs,
    6411             :                                                                      NumNumbers,
    6412             :                                                                      IOStat,
    6413         174 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    6414         174 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    6415         174 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    6416         174 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    6417         174 :             if (NumAlphas != 2) {
    6418           0 :                 ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Insufficient fields, must have Start AND End Dates");
    6419           0 :                 ErrorsFound = true;
    6420             :             } else { // Correct number of arguments
    6421        1044 :                 General::ProcessDateString(state,
    6422         174 :                                            state.dataIPShortCut->cAlphaArgs(1),
    6423         174 :                                            state.dataWeatherManager->IDFDST.StMon,
    6424         174 :                                            state.dataWeatherManager->IDFDST.StDay,
    6425         174 :                                            state.dataWeatherManager->IDFDST.StWeekDay,
    6426         174 :                                            state.dataWeatherManager->IDFDST.StDateType,
    6427             :                                            ErrorsFound);
    6428         174 :                 if (state.dataWeatherManager->IDFDST.StDateType == DateType::Invalid) {
    6429           0 :                     ShowSevereError(state,
    6430           0 :                                     state.dataIPShortCut->cCurrentModuleObject + ": Invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + '=' +
    6431           0 :                                         state.dataIPShortCut->cAlphaArgs(1));
    6432           0 :                     ErrorsFound = true;
    6433             :                 }
    6434        1044 :                 General::ProcessDateString(state,
    6435         174 :                                            state.dataIPShortCut->cAlphaArgs(2),
    6436         174 :                                            state.dataWeatherManager->IDFDST.EnMon,
    6437         174 :                                            state.dataWeatherManager->IDFDST.EnDay,
    6438         174 :                                            state.dataWeatherManager->IDFDST.EnWeekDay,
    6439         174 :                                            state.dataWeatherManager->IDFDST.EnDateType,
    6440             :                                            ErrorsFound);
    6441         174 :                 if (state.dataWeatherManager->IDFDST.EnDateType == DateType::Invalid) {
    6442           0 :                     ShowSevereError(state,
    6443           0 :                                     state.dataIPShortCut->cCurrentModuleObject + ": Invalid " + state.dataIPShortCut->cAlphaFieldNames(2) + '=' +
    6444           0 :                                         state.dataIPShortCut->cAlphaArgs(2));
    6445           0 :                     ErrorsFound = true;
    6446             :                 }
    6447         174 :                 state.dataWeatherManager->IDFDaylightSaving = true;
    6448             :             }
    6449         573 :         } else if (NumFound > 1) {
    6450           0 :             ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Too many objects in Input File, only one allowed.");
    6451           0 :             ErrorsFound = true;
    6452             :         }
    6453         747 :     }
    6454             : 
    6455         771 :     void GetDesignDayData(EnergyPlusData &state,
    6456             :                           int &TotDesDays, // Total number of Design days to Setup
    6457             :                           bool &ErrorsFound)
    6458             :     {
    6459             : 
    6460             :         // SUBROUTINE INFORMATION:
    6461             :         //       AUTHOR         Richard Liesen
    6462             :         //       DATE WRITTEN   September 1997
    6463             :         //       MODIFIED
    6464             :         //       RE-ENGINEERED  na
    6465             : 
    6466             :         // PURPOSE OF THIS SUBROUTINE:
    6467             :         // This subroutine retrieves the design day info from user input file
    6468             :         //  which is later to be used in the Setup Design Day Routine.
    6469             : 
    6470             :         // REFERENCES:
    6471             :         // SizingPeriod:DesignDay,
    6472             :         //   A1, \field Name
    6473             :         //   N1,  \field Month
    6474             :         //   N2,  \field Day of Month
    6475             :         //   A2,  \field Day Type
    6476             :         //   N3,  \field Maximum Dry-Bulb Temperature
    6477             :         //   N4,  \field Daily Dry-Bulb Temperature Range
    6478             :         //   A3,  \field Dry-Bulb Temperature Range Modifier Type
    6479             :         //   A4,  \field Dry-Bulb Temperature Range Modifier Day Schedule Name
    6480             :         //   A5,  \field Humidity Condition Type
    6481             :         //   N5,  \field Wetbulb or DewPoint at Maximum Dry-Bulb
    6482             :         //   A6,  \field Humidity Condition Day Schedule Name
    6483             :         //   N6,  \field Humidity Ratio at Maximum Dry-Bulb
    6484             :         //   N7,  \field Enthalpy at Maximum Dry-Bulb  !will require units transition.
    6485             :         //   N8,  \field Daily Wet-Bulb Temperature Range
    6486             :         //   N9,  \field Barometric Pressure
    6487             :         //   N10, \field Wind Speed
    6488             :         //   N11, \field Wind Direction
    6489             :         //   A7,  \field Rain Indicator
    6490             :         //   A8,  \field Snow Indicator
    6491             :         //   A9,  \field Daylight Saving Time Indicator
    6492             :         //   A10, \field Solar Model Indicator
    6493             :         //   A11, \field Beam Solar Day Schedule Name
    6494             :         //   A12, \field Diffuse Solar Day Schedule Name
    6495             :         //   N12, \field ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub)
    6496             :         //   N13, \field ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud)
    6497             :         //   N14; \field Sky Clearness
    6498             : 
    6499             :         static constexpr std::array<std::string_view, static_cast<int>(DDHumIndType::Num)> DDHumIndTypeStringRep = {
    6500             :             "Wetbulb [C]",
    6501             :             "Dewpoint [C]",
    6502             :             "Enthalpy [J/kg]",
    6503             :             "Humidity Ratio []",
    6504             :             "Schedule []",
    6505             :             "WetBulbProfileDefaultMultipliers []",
    6506             :             "WetBulbProfileDifferenceSchedule []",
    6507             :             "WetBulbProfileMultiplierSchedule []"};
    6508             : 
    6509             :         // Below are the 2009 fractions, HOF, Chap 14, Table 6
    6510             :         static constexpr std::array<Real64, 24> DefaultTempRangeMult = {0.88, 0.92, 0.95, 0.98, 1.0,  0.98, 0.91, 0.74, 0.55, 0.38, 0.23, 0.13,
    6511             :                                                                         0.05, 0.00, 0.00, 0.06, 0.14, 0.24, 0.39, 0.50, 0.59, 0.68, 0.75, 0.82};
    6512             : 
    6513             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6514        1542 :         std::string units;
    6515             :         OutputProcessor::Unit unitType;
    6516             : 
    6517         771 :         state.dataWeatherManager->DesDayInput.allocate(TotDesDays); // Allocate the array to the # of DD's
    6518         771 :         state.dataWeatherManager->DDDBRngModifier.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, TotDesDays);
    6519         771 :         state.dataWeatherManager->DDDBRngModifier = 0.0;
    6520         771 :         state.dataWeatherManager->DDHumIndModifier.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, TotDesDays);
    6521         771 :         state.dataWeatherManager->DDHumIndModifier = 0.0;
    6522         771 :         state.dataWeatherManager->DDBeamSolarValues.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, TotDesDays);
    6523         771 :         state.dataWeatherManager->DDBeamSolarValues = 0.0;
    6524         771 :         state.dataWeatherManager->DDDiffuseSolarValues.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, TotDesDays);
    6525         771 :         state.dataWeatherManager->DDDiffuseSolarValues = 0.0;
    6526         771 :         state.dataWeatherManager->DDSkyTempScheduleValues.allocate(state.dataGlobal->NumOfTimeStepInHour, 24, TotDesDays);
    6527         771 :         state.dataWeatherManager->DDSkyTempScheduleValues = 0.0;
    6528             : 
    6529         771 :         state.dataWeatherManager->SPSiteDryBulbRangeModScheduleValue.dimension(TotDesDays, 0.0);
    6530         771 :         state.dataWeatherManager->SPSiteHumidityConditionScheduleValue.dimension(TotDesDays, 0.0);
    6531         771 :         state.dataWeatherManager->SPSiteBeamSolarScheduleValue.dimension(TotDesDays, 0.0);
    6532         771 :         state.dataWeatherManager->SPSiteDiffuseSolarScheduleValue.dimension(TotDesDays, 0.0);
    6533         771 :         state.dataWeatherManager->SPSiteSkyTemperatureScheduleValue.dimension(TotDesDays, 0.0);
    6534             : 
    6535         771 :         if (state.dataSysVars->ReverseDD && TotDesDays <= 1) {
    6536           0 :             ShowSevereError(state, "GetDesignDayData: Reverse Design Day requested but # Design Days <=1");
    6537             :         }
    6538             : 
    6539         771 :         state.dataIPShortCut->cCurrentModuleObject = "SizingPeriod:DesignDay";
    6540        2385 :         for (int i = 1; i <= TotDesDays; ++i) {
    6541             : 
    6542             :             int EnvrnNum;
    6543        1614 :             if (state.dataSysVars->ReverseDD) {
    6544           0 :                 if (i == 1 && TotDesDays > 1) {
    6545           0 :                     EnvrnNum = 2;
    6546           0 :                 } else if (i == 2) {
    6547           0 :                     EnvrnNum = 1;
    6548             :                 } else {
    6549           0 :                     EnvrnNum = i;
    6550             :                 }
    6551             :             } else {
    6552        1614 :                 EnvrnNum = i;
    6553             :             }
    6554             : 
    6555             :             // Call Input Get routine to retrieve design day data
    6556        1614 :             bool MaxDryBulbEntered = false;
    6557        1614 :             bool PressureEntered = false;
    6558             :             int NumAlpha;    // Number of material alpha names being passed
    6559             :             int NumNumerics; // Number of material properties being passed
    6560             :             int IOStat;      // IO Status when calling get input subroutine
    6561       12912 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    6562        1614 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
    6563             :                                                                      i,
    6564        1614 :                                                                      state.dataIPShortCut->cAlphaArgs,
    6565             :                                                                      NumAlpha,
    6566        1614 :                                                                      state.dataIPShortCut->rNumericArgs,
    6567             :                                                                      NumNumerics,
    6568             :                                                                      IOStat,
    6569        1614 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    6570        1614 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    6571        1614 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    6572        1614 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    6573        1614 :             UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), state.dataIPShortCut->cCurrentModuleObject, ErrorsFound);
    6574        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).Title = state.dataIPShortCut->cAlphaArgs(1); // Environment name
    6575        1614 :             state.dataWeatherManager->Environment(EnvrnNum).Title = state.dataWeatherManager->DesDayInput(EnvrnNum).Title;
    6576             : 
    6577             :             //   N3,  \field Maximum Dry-Bulb Temperature
    6578             :             //   N4,  \field Daily Dry-Bulb Temperature Range
    6579             :             //   N9,  \field Barometric Pressure
    6580             :             //   N10, \field Wind Speed
    6581             :             //   N11, \field Wind Direction
    6582        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb = state.dataIPShortCut->rNumericArgs(3); // Maximum Dry-Bulb Temperature (C)
    6583        1614 :             if (!state.dataIPShortCut->lNumericFieldBlanks(3)) MaxDryBulbEntered = true;
    6584        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).DailyDBRange =
    6585        1614 :                 state.dataIPShortCut->rNumericArgs(4); // Daily dry-bulb temperature range (deltaC)
    6586        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).PressBarom =
    6587        1614 :                 state.dataIPShortCut->rNumericArgs(9); // Atmospheric/Barometric Pressure (Pascals)
    6588        1614 :             if (!state.dataIPShortCut->lNumericFieldBlanks(9)) PressureEntered = true;
    6589        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).PressureEntered = PressureEntered;
    6590        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).WindSpeed = state.dataIPShortCut->rNumericArgs(10);           // Wind Speed (m/s)
    6591        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).WindDir = mod(state.dataIPShortCut->rNumericArgs(11), 360.0); // Wind Direction
    6592             :             // (degrees clockwise from North, N=0, E=90, S=180, W=270)
    6593             :             //   N1,  \field Month
    6594             :             //   N2,  \field Day of Month
    6595             :             //   N12, \field ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub)
    6596             :             //   N13, \field ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud)
    6597             :             //   N8,  \field Daily Wet-Bulb Temperature Range
    6598        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).Month = int(state.dataIPShortCut->rNumericArgs(1));      // Month of Year ( 1 - 12 )
    6599        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth = int(state.dataIPShortCut->rNumericArgs(2)); // Day of Month ( 1 - 31 )
    6600        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).TauB = state.dataIPShortCut->rNumericArgs(12);           // beam tau >= 0
    6601        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).TauD = state.dataIPShortCut->rNumericArgs(13);           // diffuse tau >= 0
    6602        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).DailyWBRange =
    6603        1614 :                 state.dataIPShortCut->rNumericArgs(8); // Daily wet-bulb temperature range (deltaC)
    6604             : 
    6605             :             //   N14; \field Sky Clearness
    6606        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).SkyClear = state.dataIPShortCut->rNumericArgs(14); // Sky Clearness (0 to 1)
    6607             : 
    6608             :             //   N15, \field Maximum Warmup Days Between Sizing Periods
    6609        1614 :             if (state.dataIPShortCut->lNumericFieldBlanks(15)) {
    6610             :                 // Default to -1 if not input
    6611        1614 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).maxWarmupDays = -1;
    6612             :             } else {
    6613           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).maxWarmupDays = int(state.dataIPShortCut->rNumericArgs(15));
    6614             :             }
    6615             :             //   A13, \field Begin Environment Reset Mode
    6616        1614 :             if (state.dataIPShortCut->lAlphaFieldBlanks(13)) {
    6617        1614 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).suppressBegEnvReset = false;
    6618             :             } else {
    6619           0 :                 if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(13), "FullResetAtBeginEnvironment")) {
    6620           0 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).suppressBegEnvReset = false;
    6621           0 :                 } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(13), "SuppressThermalResetAtBeginEnvironment")) {
    6622           0 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).suppressBegEnvReset = true;
    6623             :                 }
    6624             :             }
    6625             :             // for PerformancePrecisionTradeoffs
    6626        1614 :             if (state.dataEnvrn->forceBeginEnvResetSuppress) {
    6627           2 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).suppressBegEnvReset = true;
    6628             :             }
    6629             :             //   A7,  \field Rain Indicator
    6630        1614 :             if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(7), "Yes")) {
    6631           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).RainInd = 1;
    6632        1614 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(7), "No") || state.dataIPShortCut->lAlphaFieldBlanks(7)) {
    6633        1614 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).RainInd = 0;
    6634             :             } else {
    6635           0 :                 ShowWarningError(state,
    6636           0 :                                  state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6637           0 :                                      "\", invalid field: " + state.dataIPShortCut->cAlphaFieldNames(7) + "=\"" + state.dataIPShortCut->cAlphaArgs(7) +
    6638             :                                      "\".");
    6639           0 :                 ShowContinueError(state, "\"No\" will be used.");
    6640           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).RainInd = 0;
    6641             :             }
    6642             : 
    6643             :             //   A8,  \field Snow Indicator
    6644        1614 :             if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(8), "Yes")) {
    6645           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SnowInd = 1;
    6646        1614 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(8), "No") || state.dataIPShortCut->lAlphaFieldBlanks(8)) {
    6647        1614 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SnowInd = 0;
    6648             :             } else {
    6649           0 :                 ShowWarningError(state,
    6650           0 :                                  state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6651           0 :                                      "\", invalid field: " + state.dataIPShortCut->cAlphaFieldNames(8) + "=\"" + state.dataIPShortCut->cAlphaArgs(8) +
    6652             :                                      "\".");
    6653           0 :                 ShowContinueError(state, "\"No\" will be used.");
    6654           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SnowInd = 0;
    6655             :             }
    6656             : 
    6657             :             //   A3,  \field Dry-Bulb Temperature Range Modifier Type
    6658             :             // check DB profile input
    6659        3357 :             if (state.dataIPShortCut->lAlphaFieldBlanks(3) ||
    6660        1743 :                 UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "DefaultMultipliers")) {
    6661        1608 :                 state.dataIPShortCut->cAlphaArgs(3) = "DefaultMultipliers";
    6662        1608 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType = DDDBRangeType::Default;
    6663          18 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "Multiplier") ||
    6664          12 :                        UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "MultiplierSchedule")) {
    6665           3 :                 state.dataIPShortCut->cAlphaArgs(3) = "MultiplierSchedule";
    6666           3 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType = DDDBRangeType::Multiplier;
    6667           3 :                 units = "[]";
    6668           3 :                 unitType = OutputProcessor::Unit::None;
    6669           9 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "Difference") ||
    6670           9 :                        UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "Delta") ||
    6671          10 :                        UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "DifferenceSchedule") ||
    6672           4 :                        UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "DeltaSchedule")) {
    6673           2 :                 state.dataIPShortCut->cAlphaArgs(3) = "DifferenceSchedule";
    6674           2 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType = DDDBRangeType::Difference;
    6675           2 :                 units = "[deltaC]";
    6676           2 :                 unitType = OutputProcessor::Unit::deltaC;
    6677           1 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3), "TemperatureProfileSchedule")) {
    6678           1 :                 state.dataIPShortCut->cAlphaArgs(3) = "TemperatureProfileSchedule";
    6679           1 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType = DDDBRangeType::Profile;
    6680           1 :                 units = "[C]";
    6681           1 :                 unitType = OutputProcessor::Unit::C;
    6682             :             } else {
    6683           0 :                 ShowSevereError(state,
    6684           0 :                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6685             :                                     "\", invalid data.");
    6686           0 :                 ShowContinueError(
    6687           0 :                     state, "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
    6688           0 :                 ErrorsFound = true;
    6689           0 :                 state.dataIPShortCut->cAlphaArgs(3) = "invalid field";
    6690           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType = DDDBRangeType::Default;
    6691             :             }
    6692             : 
    6693        1614 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType != DDDBRangeType::Profile && !MaxDryBulbEntered &&
    6694           0 :                 state.dataIPShortCut->cAlphaArgs(3) != "invalid field") {
    6695           0 :                 ShowSevereError(state,
    6696           0 :                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6697             :                                     "\", invalid data.");
    6698           0 :                 ShowContinueError(state, "..invalid blank field: " + state.dataIPShortCut->cNumericFieldNames(3));
    6699           0 :                 ShowContinueError(state,
    6700           0 :                                   "..this field is required when " + state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" +
    6701           0 :                                       state.dataIPShortCut->cAlphaArgs(3) + "\".");
    6702           0 :                 ErrorsFound = true;
    6703             :             }
    6704             : 
    6705             :             // Assume either "multiplier" option will make full use of range...
    6706        3226 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType != DDDBRangeType::Difference &&
    6707        1612 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType != DDDBRangeType::Profile) {
    6708             :                 Real64 testval =
    6709        1611 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb - state.dataWeatherManager->DesDayInput(EnvrnNum).DailyDBRange;
    6710        1611 :                 bool errFlag = false;
    6711        8055 :                 state.dataInputProcessing->inputProcessor->rangeCheck(state,
    6712             :                                                                       errFlag,
    6713        1611 :                                                                       state.dataIPShortCut->cAlphaFieldNames(3),
    6714        1611 :                                                                       state.dataIPShortCut->cCurrentModuleObject,
    6715             :                                                                       "Severe",
    6716             :                                                                       ">= -90",
    6717             :                                                                       (testval >= -90.0),
    6718             :                                                                       "<= 70",
    6719             :                                                                       (testval <= 70.0),
    6720             :                                                                       {},
    6721        3222 :                                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).Title);
    6722        1611 :                 if (errFlag) {
    6723           0 :                     ErrorsFound = true;
    6724             :                 }
    6725             :             }
    6726             : 
    6727             :             //   A4,  \field Dry-Bulb Temperature Range Modifier Day Schedule Name
    6728        1614 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).DBTempRangeType != DDDBRangeType::Default) {
    6729           6 :                 if (!state.dataIPShortCut->lAlphaFieldBlanks(4)) {
    6730           6 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).TempRangeSchPtr =
    6731           6 :                         ScheduleManager::GetDayScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(4));
    6732           6 :                     if (state.dataWeatherManager->DesDayInput(EnvrnNum).TempRangeSchPtr == 0) {
    6733           0 :                         ShowSevereError(state,
    6734           0 :                                         state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6735             :                                             "\", invalid data.");
    6736           0 :                         ShowContinueError(state,
    6737           0 :                                           "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" +
    6738           0 :                                               state.dataIPShortCut->cAlphaArgs(4) + "\".");
    6739           0 :                         ErrorsFound = true;
    6740             :                     } else {
    6741           6 :                         ScheduleManager::GetSingleDayScheduleValues(state,
    6742           6 :                                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).TempRangeSchPtr,
    6743          12 :                                                                     state.dataWeatherManager->DDDBRngModifier(_, _, EnvrnNum));
    6744          18 :                         int schPtr = General::FindNumberInList(state.dataWeatherManager->DesDayInput(EnvrnNum).TempRangeSchPtr,
    6745           6 :                                                                state.dataWeatherManager->SPSiteScheduleNamePtr,
    6746          12 :                                                                state.dataWeatherManager->NumSPSiteScheduleNamePtrs);
    6747           6 :                         if ((schPtr == 0) || (state.dataWeatherManager->SPSiteScheduleUnits(schPtr) != units)) {
    6748           4 :                             ++state.dataWeatherManager->NumSPSiteScheduleNamePtrs;
    6749           4 :                             state.dataWeatherManager->SPSiteScheduleNamePtr(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) =
    6750           4 :                                 state.dataWeatherManager->DesDayInput(EnvrnNum).TempRangeSchPtr;
    6751           4 :                             state.dataWeatherManager->SPSiteScheduleUnits(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) = units;
    6752          12 :                             SetupOutputVariable(state,
    6753             :                                                 "Sizing Period Site Drybulb Temperature Range Modifier Schedule Value",
    6754             :                                                 unitType,
    6755           4 :                                                 state.dataWeatherManager->SPSiteDryBulbRangeModScheduleValue(EnvrnNum),
    6756             :                                                 OutputProcessor::SOVTimeStepType::Zone,
    6757             :                                                 OutputProcessor::SOVStoreType::Average,
    6758           8 :                                                 state.dataIPShortCut->cAlphaArgs(4));
    6759             :                         }
    6760           6 :                         if (state.dataIPShortCut->cAlphaArgs(3) == "MultiplierSchedule") {
    6761           3 :                             if (!ScheduleManager::CheckDayScheduleValueMinMax(
    6762           3 :                                     state, state.dataWeatherManager->DesDayInput(EnvrnNum).TempRangeSchPtr, 0.0, false, 1.0, false)) {
    6763           0 :                                 ShowSevereError(state,
    6764           0 :                                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    6765           0 :                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).Title + "\", invalid data.");
    6766           0 :                                 ShowContinueError(state,
    6767           0 :                                                   "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" +
    6768           0 :                                                       state.dataIPShortCut->cAlphaArgs(4) + "\".");
    6769           0 :                                 ShowContinueError(state, "..Specified [Schedule] Dry-bulb Range Multiplier Values are not within [0.0, 1.0]");
    6770           0 :                                 ErrorsFound = true;
    6771             :                             }
    6772           3 :                         } else if (state.dataIPShortCut->cAlphaArgs(3) == "DifferenceSchedule") { // delta, must be > 0.0
    6773           2 :                             if (!ScheduleManager::CheckDayScheduleValueMinMax(
    6774           2 :                                     state, state.dataWeatherManager->DesDayInput(EnvrnNum).TempRangeSchPtr, 0.0, false)) {
    6775           0 :                                 ShowSevereError(state,
    6776           0 :                                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    6777           0 :                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).Title + "\", invalid data.");
    6778           0 :                                 ShowContinueError(state,
    6779           0 :                                                   "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" +
    6780           0 :                                                       state.dataIPShortCut->cAlphaArgs(4) + "\".");
    6781           0 :                                 ShowSevereError(state, "Some [Schedule] Dry-bulb Range Difference Values are < 0.0 [would make max larger].");
    6782           0 :                                 ErrorsFound = true;
    6783             :                             }
    6784             :                         }
    6785           6 :                         if (state.dataIPShortCut->cAlphaArgs(3) == "TemperatureProfileSchedule") {
    6786           1 :                             Real64 testval = maxval(state.dataWeatherManager->DDDBRngModifier(_, _, EnvrnNum));
    6787           1 :                             if (MaxDryBulbEntered) {
    6788           0 :                                 ShowWarningError(state,
    6789           0 :                                                  state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    6790           0 :                                                      state.dataWeatherManager->DesDayInput(EnvrnNum).Title + "\", data override.");
    6791           0 :                                 ShowContinueError(state,
    6792           0 :                                                   format("..{}=[{:.2R}] will be overwritten.",
    6793           0 :                                                          state.dataIPShortCut->cNumericFieldNames(3),
    6794           0 :                                                          state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb));
    6795           0 :                                 ShowContinueError(
    6796           0 :                                     state, ".." + state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
    6797           0 :                                 ShowContinueError(state, format("..with max value=[{:.2R}].", testval));
    6798             :                             }
    6799           1 :                             state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb = testval;
    6800             :                         }
    6801           6 :                         Real64 testval = maxval(state.dataWeatherManager->DDDBRngModifier(_, _, EnvrnNum));
    6802           6 :                         testval = state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb - testval;
    6803           6 :                         bool errFlag = false;
    6804          30 :                         state.dataInputProcessing->inputProcessor->rangeCheck(state,
    6805             :                                                                               errFlag,
    6806           6 :                                                                               state.dataIPShortCut->cAlphaFieldNames(4),
    6807           6 :                                                                               state.dataIPShortCut->cCurrentModuleObject,
    6808             :                                                                               "Severe",
    6809             :                                                                               ">= -90",
    6810             :                                                                               (testval >= -90.0),
    6811             :                                                                               "<= 70",
    6812             :                                                                               (testval <= 70.0),
    6813             :                                                                               {},
    6814          12 :                                                                               state.dataWeatherManager->DesDayInput(EnvrnNum).Title);
    6815           6 :                         if (errFlag) {
    6816           0 :                             ErrorsFound = true;
    6817             :                         }
    6818             :                     }
    6819             :                 } else {
    6820           0 :                     ShowSevereError(state,
    6821           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6822             :                                         "\", invalid data.");
    6823           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(4) + " is blank.");
    6824           0 :                     ShowContinueError(state, "..required when " + state.dataIPShortCut->cAlphaFieldNames(3) + " indicates \"SCHEDULE\".");
    6825           0 :                     ErrorsFound = true;
    6826             :                 }
    6827             :             } else {
    6828             :                 // Default dry-bulb temperature Range
    6829        1608 :                 Real64 LastHrValue = DefaultTempRangeMult[23];
    6830       40200 :                 for (int hour = 1; hour <= 24; ++hour) {
    6831      258192 :                     for (int ts = 1; ts <= state.dataGlobal->NumOfTimeStepInHour; ++ts) {
    6832      219600 :                         Real64 WNow = state.dataWeatherManager->Interpolation(ts);
    6833      219600 :                         Real64 WPrev = 1.0 - WNow;
    6834      219600 :                         state.dataWeatherManager->DDDBRngModifier(ts, hour, EnvrnNum) = LastHrValue * WPrev + DefaultTempRangeMult[hour - 1] * WNow;
    6835             :                     }
    6836       38592 :                     LastHrValue = DefaultTempRangeMult[hour - 1];
    6837             :                 }
    6838             :             }
    6839             : 
    6840             :             //   A5,  \field Humidity Condition Type
    6841        1614 :             if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "WetBulb")) {
    6842        1588 :                 state.dataIPShortCut->cAlphaArgs(5) = "WetBulb";
    6843             :                 //   N5,  \field Wetbulb or DewPoint at Maximum Dry-Bulb
    6844        1588 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
    6845        1588 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue =
    6846        1588 :                         state.dataIPShortCut->rNumericArgs(5); // Humidity Indicating Conditions at Max Dry-Bulb
    6847             :                 } else {
    6848           0 :                     ShowSevereError(state,
    6849           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6850             :                                         "\", invalid data.");
    6851           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cNumericFieldNames(5) + " is blank.");
    6852           0 :                     ShowContinueError(state,
    6853           0 :                                       "..field is required when " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" +
    6854           0 :                                           state.dataIPShortCut->cAlphaArgs(5) + "\".");
    6855           0 :                     ErrorsFound = true;
    6856             :                 }
    6857        1588 :                 bool errFlag = false;
    6858        1588 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::WetBulb;
    6859       11116 :                 state.dataInputProcessing->inputProcessor->rangeCheck(state,
    6860             :                                                                       errFlag,
    6861        3176 :                                                                       state.dataIPShortCut->cAlphaFieldNames(5) + " - Wet-Bulb",
    6862        1588 :                                                                       state.dataIPShortCut->cCurrentModuleObject,
    6863             :                                                                       "Severe",
    6864             :                                                                       ">= -90",
    6865        1588 :                                                                       (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue >= -90.0),
    6866             :                                                                       "<= 70",
    6867        1588 :                                                                       (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue <= 70.0),
    6868             :                                                                       {},
    6869        3176 :                                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).Title);
    6870        1588 :                 if (errFlag) {
    6871             :                     //        CALL ShowContinueError(state, TRIM(state.dataIPShortCut->cCurrentModuleObject)//': Occured in
    6872             :                     //        '//TRIM(DesDayInput(EnvrnNum)%Title))
    6873           0 :                     ErrorsFound = true;
    6874             :                 }
    6875          26 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "DewPoint")) {
    6876           5 :                 state.dataIPShortCut->cAlphaArgs(5) = "DewPoint";
    6877           5 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
    6878           5 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue =
    6879           5 :                         state.dataIPShortCut->rNumericArgs(5); // Humidity Indicating Conditions at Max Dry-Bulb
    6880             :                 } else {
    6881           0 :                     ShowSevereError(state,
    6882           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6883             :                                         "\", invalid data.");
    6884           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cNumericFieldNames(5) + " is blank.");
    6885           0 :                     ShowContinueError(state,
    6886           0 :                                       "..field is required when " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" +
    6887           0 :                                           state.dataIPShortCut->cAlphaArgs(5) + "\".");
    6888           0 :                     ErrorsFound = true;
    6889             :                 }
    6890           5 :                 bool errFlag = false;
    6891           5 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::DewPoint;
    6892          35 :                 state.dataInputProcessing->inputProcessor->rangeCheck(state,
    6893             :                                                                       errFlag,
    6894          10 :                                                                       state.dataIPShortCut->cAlphaFieldNames(5) + " - Dew-Point",
    6895           5 :                                                                       state.dataIPShortCut->cCurrentModuleObject,
    6896             :                                                                       "Severe",
    6897             :                                                                       ">= -90",
    6898           5 :                                                                       (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue >= -90.0),
    6899             :                                                                       "<= 70",
    6900           5 :                                                                       (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue <= 70.0),
    6901             :                                                                       {},
    6902          10 :                                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).Title);
    6903           5 :                 if (errFlag) {
    6904           0 :                     ErrorsFound = true;
    6905             :                 }
    6906          21 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "HumidityRatio")) {
    6907           0 :                 state.dataIPShortCut->cAlphaArgs(5) = "HumidityRatio";
    6908             :                 //   N6,  \field Humidity Ratio at Maximum Dry-Bulb
    6909           0 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(6)) {
    6910           0 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue =
    6911           0 :                         state.dataIPShortCut->rNumericArgs(6); // Humidity Indicating Conditions at Max Dry-Bulb
    6912             :                 } else {
    6913           0 :                     ShowSevereError(state,
    6914           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6915             :                                         "\", invalid data.");
    6916           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cNumericFieldNames(6) + " is blank.");
    6917           0 :                     ShowContinueError(state,
    6918           0 :                                       "..field is required when " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" +
    6919           0 :                                           state.dataIPShortCut->cAlphaArgs(5) + "\".");
    6920           0 :                     ErrorsFound = true;
    6921             :                 }
    6922           0 :                 bool errFlag = false;
    6923           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::HumRatio;
    6924           0 :                 state.dataInputProcessing->inputProcessor->rangeCheck(state,
    6925             :                                                                       errFlag,
    6926           0 :                                                                       state.dataIPShortCut->cAlphaFieldNames(5) + " - Humidity-Ratio",
    6927           0 :                                                                       state.dataIPShortCut->cCurrentModuleObject,
    6928             :                                                                       "Severe",
    6929             :                                                                       ">= 0",
    6930           0 :                                                                       (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue >= 0.0),
    6931             :                                                                       "<= .03",
    6932           0 :                                                                       (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue <= 0.03),
    6933             :                                                                       {},
    6934           0 :                                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).Title);
    6935           0 :                 if (errFlag) {
    6936           0 :                     ErrorsFound = true;
    6937             :                 }
    6938          21 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "Enthalpy")) {
    6939           3 :                 state.dataIPShortCut->cAlphaArgs(5) = "Enthalpy";
    6940             :                 //   N7,  \field Enthalpy at Maximum Dry-Bulb {J/kg}.
    6941           3 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(7)) {
    6942           3 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue =
    6943           3 :                         state.dataIPShortCut->rNumericArgs(7); // Humidity Indicating Conditions at Max Dry-Bulb
    6944             :                 } else {
    6945           0 :                     ShowSevereError(state,
    6946           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6947             :                                         "\", invalid data.");
    6948           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cNumericFieldNames(7) + " is blank.");
    6949           0 :                     ShowContinueError(state,
    6950           0 :                                       "..field is required when " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" +
    6951           0 :                                           state.dataIPShortCut->cAlphaArgs(5) + "\".");
    6952           0 :                     ErrorsFound = true;
    6953             :                 }
    6954           3 :                 bool errFlag = false;
    6955           3 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::Enthalpy;
    6956          18 :                 state.dataInputProcessing->inputProcessor->rangeCheck(state,
    6957             :                                                                       errFlag,
    6958           6 :                                                                       state.dataIPShortCut->cAlphaFieldNames(5) + " - Enthalpy",
    6959             :                                                                       "SizingPeriod:DesignDay",
    6960             :                                                                       "Severe",
    6961             :                                                                       ">= 0.0",
    6962           3 :                                                                       (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue >= 0.0),
    6963             :                                                                       "<= 130000",
    6964           3 :                                                                       (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue <= 130000.0),
    6965             :                                                                       {},
    6966           6 :                                                                       state.dataWeatherManager->DesDayInput(EnvrnNum).Title);
    6967           3 :                 if (errFlag) {
    6968           0 :                     ErrorsFound = true;
    6969             :                 }
    6970          18 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "RelativeHumiditySchedule")) {
    6971           3 :                 state.dataIPShortCut->cAlphaArgs(5) = "RelativeHumiditySchedule";
    6972           3 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::RelHumSch;
    6973           3 :                 units = "[%]";
    6974           3 :                 unitType = OutputProcessor::Unit::Perc;
    6975          15 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "WetBulbProfileMultiplierSchedule")) {
    6976           2 :                 state.dataIPShortCut->cAlphaArgs(5) = "WetBulbProfileMultiplierSchedule";
    6977           2 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::WBProfMul;
    6978           2 :                 units = "[]";
    6979           2 :                 unitType = OutputProcessor::Unit::None;
    6980           2 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
    6981           2 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue =
    6982           2 :                         state.dataIPShortCut->rNumericArgs(5); // Humidity Indicating Conditions at Max Dry-Bulb
    6983             :                 } else {
    6984           0 :                     ShowSevereError(state,
    6985           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    6986             :                                         "\", invalid data.");
    6987           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cNumericFieldNames(5) + " is blank.");
    6988           0 :                     ShowContinueError(state,
    6989           0 :                                       "..field is required when " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" +
    6990           0 :                                           state.dataIPShortCut->cAlphaArgs(5) + "\".");
    6991           0 :                     ErrorsFound = true;
    6992             :                 }
    6993          13 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "WetBulbProfileDifferenceSchedule")) {
    6994           1 :                 state.dataIPShortCut->cAlphaArgs(5) = "WetBulbProfileDifferenceSchedule";
    6995           1 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::WBProfDif;
    6996           1 :                 units = "[]";
    6997           1 :                 unitType = OutputProcessor::Unit::None;
    6998           1 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
    6999           1 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue =
    7000           1 :                         state.dataIPShortCut->rNumericArgs(5); // Humidity Indicating Conditions at Max Dry-Bulb
    7001             :                 } else {
    7002           0 :                     ShowSevereError(state,
    7003           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7004             :                                         "\", invalid data.");
    7005           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cNumericFieldNames(5) + " is blank.");
    7006           0 :                     ShowContinueError(state,
    7007           0 :                                       "..field is required when " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" +
    7008           0 :                                           state.dataIPShortCut->cAlphaArgs(5) + "\".");
    7009           0 :                     ErrorsFound = true;
    7010             :                 }
    7011          12 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "WetBulbProfileDefaultMultipliers")) {
    7012          12 :                 state.dataIPShortCut->cAlphaArgs(5) = "WetBulbProfileDefaultMultipliers";
    7013          12 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::WBProfDef;
    7014          12 :                 if (!state.dataIPShortCut->lNumericFieldBlanks(5)) {
    7015          12 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue =
    7016          12 :                         state.dataIPShortCut->rNumericArgs(5); // Humidity Indicating Conditions at Max Dry-Bulb
    7017             :                 } else {
    7018           0 :                     ShowSevereError(state,
    7019           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7020             :                                         "\", invalid data.");
    7021           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cNumericFieldNames(5) + " is blank.");
    7022           0 :                     ShowContinueError(state,
    7023           0 :                                       "..field is required when " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" +
    7024           0 :                                           state.dataIPShortCut->cAlphaArgs(5) + "\".");
    7025           0 :                     ErrorsFound = true;
    7026             :                 }
    7027             :             } else {
    7028           0 :                 ShowWarningError(state,
    7029           0 :                                  state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7030             :                                      "\", invalid data.");
    7031           0 :                 ShowContinueError(
    7032           0 :                     state, "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" + state.dataIPShortCut->cAlphaArgs(5) + "\".");
    7033           0 :                 ShowContinueError(state, "WetBulb will be used. Maximum Dry Bulb will be used as WetBulb at Maximum Dry Bulb.");
    7034           0 :                 state.dataIPShortCut->cAlphaArgs(5) = "WetBulb";
    7035           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType = DDHumIndType::WetBulb;
    7036           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue = state.dataIPShortCut->rNumericArgs(3);
    7037             :             }
    7038             : 
    7039             :             // resolve humidity schedule if needed
    7040             :             //   A6,  \field Humidity Condition Day Schedule Name
    7041        4839 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::RelHumSch ||
    7042        3223 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfMul ||
    7043        1609 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDif) {
    7044           6 :                 if (state.dataIPShortCut->lAlphaFieldBlanks(6)) {
    7045           0 :                     ShowSevereError(state,
    7046           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7047             :                                         "\", invalid data.");
    7048           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(6) + " is blank.");
    7049           0 :                     ShowContinueError(state,
    7050           0 :                                       "..field is required when " + state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" +
    7051           0 :                                           state.dataIPShortCut->cAlphaArgs(3) + "\".");
    7052           0 :                     ErrorsFound = true;
    7053             :                 } else {
    7054           6 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndSchPtr =
    7055           6 :                         ScheduleManager::GetDayScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(6));
    7056           6 :                     if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndSchPtr == 0) {
    7057           0 :                         ShowWarningError(state,
    7058           0 :                                          state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7059             :                                              "\", invalid data.");
    7060           0 :                         ShowContinueError(state,
    7061           0 :                                           "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(6) + "=\"" +
    7062           0 :                                               state.dataIPShortCut->cAlphaArgs(6) + "\".");
    7063           0 :                         ShowContinueError(state, "Default Humidity will be used (constant for day using Humidity Indicator Temp).");
    7064             :                         // reset HumIndType ?
    7065             :                     } else {
    7066             : 
    7067           6 :                         ScheduleManager::GetSingleDayScheduleValues(state,
    7068           6 :                                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndSchPtr,
    7069          12 :                                                                     state.dataWeatherManager->DDHumIndModifier(_, _, EnvrnNum));
    7070             : 
    7071          18 :                         int schPtr = General::FindNumberInList(state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndSchPtr,
    7072           6 :                                                                state.dataWeatherManager->SPSiteScheduleNamePtr,
    7073          12 :                                                                state.dataWeatherManager->NumSPSiteScheduleNamePtrs);
    7074           6 :                         if ((schPtr == 0) || (state.dataWeatherManager->SPSiteScheduleUnits(schPtr) != units)) {
    7075           5 :                             ++state.dataWeatherManager->NumSPSiteScheduleNamePtrs;
    7076           5 :                             state.dataWeatherManager->SPSiteScheduleNamePtr(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) =
    7077           5 :                                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndSchPtr;
    7078           5 :                             state.dataWeatherManager->SPSiteScheduleUnits(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) = units;
    7079          15 :                             SetupOutputVariable(state,
    7080             :                                                 "Sizing Period Site Humidity Condition Schedule Value",
    7081             :                                                 unitType,
    7082           5 :                                                 state.dataWeatherManager->SPSiteHumidityConditionScheduleValue(EnvrnNum),
    7083             :                                                 OutputProcessor::SOVTimeStepType::Zone,
    7084             :                                                 OutputProcessor::SOVStoreType::Average,
    7085          10 :                                                 state.dataIPShortCut->cAlphaArgs(6));
    7086             :                         }
    7087             : 
    7088           6 :                         switch (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType) {
    7089           3 :                         case DDHumIndType::RelHumSch:
    7090           3 :                             if (!ScheduleManager::CheckDayScheduleValueMinMax(
    7091           3 :                                     state, state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndSchPtr, 0.0, false, 100.0, false)) {
    7092           0 :                                 ShowSevereError(state,
    7093           0 :                                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7094           0 :                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).Title + "\", invalid data.");
    7095           0 :                                 ShowContinueError(state,
    7096           0 :                                                   "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(6) + "=\"" +
    7097           0 :                                                       state.dataIPShortCut->cAlphaArgs(6) + "\".");
    7098           0 :                                 ShowContinueError(state, "Specified [Scheduled] Relative Humidity Values are not within [0.0, 100.0]");
    7099           0 :                                 ErrorsFound = true;
    7100             :                             }
    7101           3 :                             break;
    7102           2 :                         case DDHumIndType::WBProfMul:
    7103             :                             // multiplier: use schedule value, check 0 <= v <= 1
    7104           2 :                             if (!ScheduleManager::CheckDayScheduleValueMinMax(
    7105           2 :                                     state, state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndSchPtr, 0.0, false, 1.0, false)) {
    7106           0 :                                 ShowSevereError(state,
    7107           0 :                                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7108           0 :                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).Title + "\", invalid data.");
    7109           0 :                                 ShowContinueError(state,
    7110           0 :                                                   "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(6) + "=\"" +
    7111           0 :                                                       state.dataIPShortCut->cAlphaArgs(6) + "\".");
    7112           0 :                                 ShowContinueError(state, "..Specified [Schedule] Wet-bulb Profile Range Multiplier Values are not within [0.0, 1.0]");
    7113           0 :                                 ErrorsFound = true;
    7114             :                             }
    7115           2 :                             break;
    7116           1 :                         case DDHumIndType::WBProfDif:
    7117           1 :                             if (!ScheduleManager::CheckDayScheduleValueMinMax(
    7118           1 :                                     state, state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndSchPtr, 0.0, false)) {
    7119           0 :                                 ShowSevereError(state,
    7120           0 :                                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7121           0 :                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).Title + "\", invalid data.");
    7122           0 :                                 ShowContinueError(state,
    7123           0 :                                                   "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(6) + "=\"" +
    7124           0 :                                                       state.dataIPShortCut->cAlphaArgs(6) + "\".");
    7125           0 :                                 ShowSevereError(state, "Some [Schedule] Wet-bulb Profile Difference Values are < 0.0 [would make max larger].");
    7126           0 :                                 ErrorsFound = true;
    7127             :                             }
    7128             :                         default:
    7129           1 :                             break;
    7130             :                         }
    7131             :                     }
    7132             :                 }
    7133             : 
    7134        1608 :             } else if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDef) {
    7135             :                 // re WetBulbProfileDefaultMultipliers
    7136          12 :                 Real64 LastHrValue = DefaultTempRangeMult[23];
    7137         300 :                 for (int hour = 1; hour <= 24; ++hour) {
    7138        1440 :                     for (int ts = 1; ts <= state.dataGlobal->NumOfTimeStepInHour; ++ts) {
    7139        1152 :                         Real64 WNow = state.dataWeatherManager->Interpolation(ts);
    7140        1152 :                         Real64 WPrev = 1.0 - WNow;
    7141        1152 :                         state.dataWeatherManager->DDHumIndModifier(ts, hour, EnvrnNum) = LastHrValue * WPrev + DefaultTempRangeMult[hour - 1] * WNow;
    7142             :                     }
    7143         288 :                     LastHrValue = DefaultTempRangeMult[hour - 1];
    7144             :                 }
    7145             :             }
    7146             : 
    7147             :             // verify that design WB or DP <= design DB
    7148        4837 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::DewPoint ||
    7149        1630 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WetBulb ||
    7150          40 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfMul ||
    7151        1640 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDef ||
    7152           7 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::WBProfDif) {
    7153        1608 :                 if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue > state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb) {
    7154           0 :                     ShowWarningError(state,
    7155           0 :                                      state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7156             :                                          "\", range check data.");
    7157           0 :                     ShowContinueError(state,
    7158           0 :                                       format("..Humidity Indicator Temperature at Max Temperature={:.1R} > Max DryBulb={:.1R}",
    7159           0 :                                              state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue,
    7160           0 :                                              state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb));
    7161           0 :                     ShowContinueError(state, ".." + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" + state.dataIPShortCut->cAlphaArgs(5) + "\".");
    7162           0 :                     ShowContinueError(state, "..Conditions for day will be set to Relative Humidity = 100%");
    7163           0 :                     if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType == DDHumIndType::DewPoint) {
    7164           0 :                         state.dataWeatherManager->DesDayInput(EnvrnNum).DewPointNeedsSet = true;
    7165             :                     } else {
    7166             :                         // wet-bulb
    7167           0 :                         state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue = state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb;
    7168             :                     }
    7169             :                 }
    7170             :             }
    7171             : 
    7172             :             //   A10, \field Solar Model Indicator
    7173        3318 :             if (state.dataIPShortCut->lAlphaFieldBlanks(10) || UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(10), "ASHRAEClearSky") ||
    7174        1704 :                 UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(10), "CLEARSKY")) {
    7175        1524 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel = DesignDaySolarModel::ASHRAE_ClearSky;
    7176          90 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(10), "ZhangHuang")) {
    7177           2 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel = DesignDaySolarModel::Zhang_Huang;
    7178          88 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(10), "ASHRAETau")) {
    7179          85 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel = DesignDaySolarModel::ASHRAE_Tau;
    7180           3 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(10), "ASHRAETau2017")) {
    7181           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel = DesignDaySolarModel::ASHRAE_Tau2017;
    7182           3 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(10), "Schedule")) {
    7183           3 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel = DesignDaySolarModel::SolarModel_Schedule;
    7184             :             } else {
    7185           0 :                 ShowWarningError(state,
    7186           0 :                                  state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7187             :                                      "\", invalid data.");
    7188           0 :                 ShowContinueError(
    7189           0 :                     state, "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(10) + "=\"" + state.dataIPShortCut->cAlphaArgs(10) + "\".");
    7190           0 :                 ShowContinueError(state, "Model used will be ASHRAE ClearSky");
    7191           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel = DesignDaySolarModel::ASHRAE_ClearSky;
    7192             :             }
    7193             : 
    7194        1614 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel == DesignDaySolarModel::SolarModel_Schedule) {
    7195             :                 //   A11, \field Beam Solar Day Schedule Name
    7196           3 :                 if (!state.dataIPShortCut->lAlphaFieldBlanks(11)) {
    7197           3 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).BeamSolarSchPtr =
    7198           3 :                         ScheduleManager::GetDayScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(11));
    7199           3 :                     if (state.dataWeatherManager->DesDayInput(EnvrnNum).BeamSolarSchPtr == 0) {
    7200           0 :                         ShowSevereError(state,
    7201           0 :                                         state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7202             :                                             "\", invalid data.");
    7203           0 :                         ShowContinueError(state,
    7204           0 :                                           "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(11) + "=\"" +
    7205           0 :                                               state.dataIPShortCut->cAlphaArgs(11) + "\".");
    7206           0 :                         ShowContinueError(state, "..Required when " + state.dataIPShortCut->cAlphaFieldNames(10) + " indicates \"Schedule\".");
    7207           0 :                         ErrorsFound = true;
    7208             :                     } else {
    7209           3 :                         ScheduleManager::GetSingleDayScheduleValues(state,
    7210           3 :                                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).BeamSolarSchPtr,
    7211           6 :                                                                     state.dataWeatherManager->DDBeamSolarValues(_, _, EnvrnNum));
    7212           9 :                         int schPtr = General::FindNumberInList(state.dataWeatherManager->DesDayInput(EnvrnNum).BeamSolarSchPtr,
    7213           3 :                                                                state.dataWeatherManager->SPSiteScheduleNamePtr,
    7214           6 :                                                                state.dataWeatherManager->NumSPSiteScheduleNamePtrs);
    7215           3 :                         units = "[W/m2]";
    7216           3 :                         unitType = OutputProcessor::Unit::W_m2;
    7217           3 :                         if ((schPtr == 0) || (state.dataWeatherManager->SPSiteScheduleUnits(schPtr) != units)) {
    7218           3 :                             ++state.dataWeatherManager->NumSPSiteScheduleNamePtrs;
    7219           3 :                             state.dataWeatherManager->SPSiteScheduleNamePtr(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) =
    7220           3 :                                 state.dataWeatherManager->DesDayInput(EnvrnNum).BeamSolarSchPtr;
    7221           3 :                             state.dataWeatherManager->SPSiteScheduleUnits(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) = units;
    7222           9 :                             SetupOutputVariable(state,
    7223             :                                                 "Sizing Period Site Beam Solar Schedule Value",
    7224             :                                                 unitType,
    7225           3 :                                                 state.dataWeatherManager->SPSiteBeamSolarScheduleValue(EnvrnNum),
    7226             :                                                 OutputProcessor::SOVTimeStepType::Zone,
    7227             :                                                 OutputProcessor::SOVStoreType::Average,
    7228           6 :                                                 state.dataIPShortCut->cAlphaArgs(11));
    7229             :                         }
    7230           3 :                         if (!ScheduleManager::CheckDayScheduleValueMinMax(
    7231           3 :                                 state, state.dataWeatherManager->DesDayInput(EnvrnNum).BeamSolarSchPtr, 0.0, false)) {
    7232           0 :                             ShowSevereError(state,
    7233           0 :                                             state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7234           0 :                                                 state.dataWeatherManager->DesDayInput(EnvrnNum).Title + "\", invalid data.");
    7235           0 :                             ShowContinueError(state,
    7236           0 :                                               "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(11) + "=\"" +
    7237           0 :                                                   state.dataIPShortCut->cAlphaArgs(11) + "\".");
    7238           0 :                             ShowContinueError(state, "..Specified [Schedule] Values are not >= 0.0");
    7239           0 :                             ErrorsFound = true;
    7240             :                         }
    7241             :                     }
    7242             :                 } else { // should have entered beam schedule
    7243           0 :                     ShowSevereError(state,
    7244           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7245             :                                         "\", invalid data.");
    7246           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(11) + " is blank.");
    7247           0 :                     ErrorsFound = true;
    7248             :                 }
    7249             :                 //   A12, \field Diffuse Solar Day Schedule Name
    7250           3 :                 if (!state.dataIPShortCut->lAlphaFieldBlanks(12)) {
    7251           3 :                     state.dataWeatherManager->DesDayInput(EnvrnNum).DiffuseSolarSchPtr =
    7252           3 :                         ScheduleManager::GetDayScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(12));
    7253           3 :                     if (state.dataWeatherManager->DesDayInput(EnvrnNum).DiffuseSolarSchPtr == 0) {
    7254           0 :                         ShowSevereError(state,
    7255           0 :                                         state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7256             :                                             "\", invalid data.");
    7257           0 :                         ShowContinueError(state,
    7258           0 :                                           "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(12) + "=\"" +
    7259           0 :                                               state.dataIPShortCut->cAlphaArgs(12) + "\".");
    7260           0 :                         ShowContinueError(state, "..Required when " + state.dataIPShortCut->cAlphaFieldNames(10) + " indicates \"Schedule\".");
    7261           0 :                         ErrorsFound = true;
    7262             :                     } else {
    7263           3 :                         ScheduleManager::GetSingleDayScheduleValues(state,
    7264           3 :                                                                     state.dataWeatherManager->DesDayInput(EnvrnNum).DiffuseSolarSchPtr,
    7265           6 :                                                                     state.dataWeatherManager->DDDiffuseSolarValues(_, _, EnvrnNum));
    7266           9 :                         int schPtr = General::FindNumberInList(state.dataWeatherManager->DesDayInput(EnvrnNum).DiffuseSolarSchPtr,
    7267           3 :                                                                state.dataWeatherManager->SPSiteScheduleNamePtr,
    7268           6 :                                                                state.dataWeatherManager->NumSPSiteScheduleNamePtrs);
    7269           3 :                         units = "[W/m2]";
    7270           3 :                         unitType = OutputProcessor::Unit::W_m2;
    7271           3 :                         if ((schPtr == 0) || (state.dataWeatherManager->SPSiteScheduleUnits(schPtr) != units)) {
    7272           3 :                             ++state.dataWeatherManager->NumSPSiteScheduleNamePtrs;
    7273           3 :                             state.dataWeatherManager->SPSiteScheduleNamePtr(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) =
    7274           3 :                                 state.dataWeatherManager->DesDayInput(EnvrnNum).DiffuseSolarSchPtr;
    7275           3 :                             state.dataWeatherManager->SPSiteScheduleUnits(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) = units;
    7276           9 :                             SetupOutputVariable(state,
    7277             :                                                 "Sizing Period Site Diffuse Solar Schedule Value",
    7278             :                                                 unitType,
    7279           3 :                                                 state.dataWeatherManager->SPSiteDiffuseSolarScheduleValue(EnvrnNum),
    7280             :                                                 OutputProcessor::SOVTimeStepType::Zone,
    7281             :                                                 OutputProcessor::SOVStoreType::Average,
    7282           6 :                                                 state.dataIPShortCut->cAlphaArgs(12));
    7283             :                         }
    7284           3 :                         if (!ScheduleManager::CheckDayScheduleValueMinMax(
    7285           3 :                                 state, state.dataWeatherManager->DesDayInput(EnvrnNum).DiffuseSolarSchPtr, 0.0, false)) {
    7286           0 :                             ShowSevereError(state,
    7287           0 :                                             state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7288           0 :                                                 state.dataWeatherManager->DesDayInput(EnvrnNum).Title + "\", invalid data.");
    7289           0 :                             ShowContinueError(state,
    7290           0 :                                               "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(12) + "=\"" +
    7291           0 :                                                   state.dataIPShortCut->cAlphaArgs(12) + "\".");
    7292           0 :                             ShowContinueError(state, "..Specified [Schedule] Values are not >= 0.0");
    7293           0 :                             ErrorsFound = true;
    7294             :                         }
    7295             :                     }
    7296             :                 } else { // should have entered diffuse schedule
    7297           0 :                     ShowSevereError(state,
    7298           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7299             :                                         "\", invalid data.");
    7300           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(12) + " is blank.");
    7301           0 :                     ErrorsFound = true;
    7302             :                 }
    7303             :             }
    7304             : 
    7305        1614 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).SolarModel == DesignDaySolarModel::ASHRAE_ClearSky) {
    7306        1524 :                 if (state.dataIPShortCut->lNumericFieldBlanks(14)) {
    7307           0 :                     ShowWarningError(state,
    7308           0 :                                      state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7309             :                                          "\", invalid data.");
    7310           0 :                     ShowContinueError(state, "..invalid field: " + state.dataIPShortCut->cNumericFieldNames(14) + " is blank.");
    7311           0 :                     ShowContinueError(state, "..Zero clear sky (no solar) will be used.");
    7312             :                 }
    7313             :             }
    7314             : 
    7315             :             // Validate Design Day Month
    7316             : 
    7317        1614 :             switch (state.dataWeatherManager->DesDayInput(EnvrnNum).Month) {
    7318        1592 :             case 1:
    7319             :             case 3:
    7320             :             case 5:
    7321             :             case 7:
    7322             :             case 8:
    7323             :             case 10:
    7324             :             case 12:
    7325        1592 :                 if (state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth > 31) {
    7326           0 :                     ShowSevereError(state,
    7327           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7328             :                                         "\", invalid data.");
    7329           0 :                     ShowContinueError(state,
    7330           0 :                                       format(".. invalid field: {}=[{}], Month=[{}].",
    7331           0 :                                              state.dataIPShortCut->cNumericFieldNames(2),
    7332           0 :                                              state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth,
    7333           0 :                                              state.dataWeatherManager->DesDayInput(EnvrnNum).Month));
    7334           0 :                     ErrorsFound = true;
    7335             :                 }
    7336        1592 :                 break;
    7337          20 :             case 4:
    7338             :             case 6:
    7339             :             case 9:
    7340             :             case 11:
    7341          20 :                 if (state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth > 30) {
    7342           0 :                     ShowSevereError(state,
    7343           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7344             :                                         "\", invalid data.");
    7345           0 :                     ShowContinueError(state,
    7346           0 :                                       format(".. invalid {}=[{}], Month=[{}].",
    7347           0 :                                              state.dataIPShortCut->cNumericFieldNames(2),
    7348           0 :                                              state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth,
    7349           0 :                                              state.dataWeatherManager->DesDayInput(EnvrnNum).Month));
    7350           0 :                     ErrorsFound = true;
    7351             :                 }
    7352          20 :                 break;
    7353           2 :             case 2:
    7354           2 :                 if (state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth > 28) {
    7355           0 :                     ShowSevereError(state,
    7356           0 :                                     state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7357             :                                         "\", invalid data.");
    7358           0 :                     ShowContinueError(state,
    7359           0 :                                       format(".. invalid {}=[{}], Month=[{}].",
    7360           0 :                                              state.dataIPShortCut->cNumericFieldNames(2),
    7361           0 :                                              state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth,
    7362           0 :                                              state.dataWeatherManager->DesDayInput(EnvrnNum).Month));
    7363           0 :                     ErrorsFound = true;
    7364             :                 }
    7365           2 :                 break;
    7366           0 :             default:
    7367           0 :                 ShowSevereError(state,
    7368           0 :                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7369             :                                     "\", invalid data.");
    7370           0 :                 ShowContinueError(state,
    7371           0 :                                   format(".. invalid {} invalid (Month) [{}].",
    7372           0 :                                          state.dataIPShortCut->cNumericFieldNames(1),
    7373           0 :                                          state.dataWeatherManager->DesDayInput(EnvrnNum).Month));
    7374           0 :                 ErrorsFound = true;
    7375           0 :                 break;
    7376             :             }
    7377             : 
    7378             :             //   A9,  \field Daylight Saving Time Indicator
    7379        1614 :             if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(9), "Yes")) {
    7380           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DSTIndicator = 1;
    7381        1614 :             } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(9), "No") || state.dataIPShortCut->lAlphaFieldBlanks(9)) {
    7382        1614 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DSTIndicator = 0;
    7383             :             } else {
    7384           0 :                 ShowWarningError(state,
    7385           0 :                                  state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7386             :                                      "\", invalid data.");
    7387           0 :                 ShowContinueError(state,
    7388           0 :                                   "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(9) + "=\"" + state.dataIPShortCut->cAlphaArgs(9) +
    7389             :                                       R"(". "No" will be used.)");
    7390           0 :                 state.dataWeatherManager->DesDayInput(EnvrnNum).DSTIndicator = 0;
    7391             :             }
    7392             : 
    7393             :             //   A2,  \field Day Type
    7394        1614 :             state.dataWeatherManager->DesDayInput(EnvrnNum).DayType =
    7395        3228 :                 getEnumerationValue(ScheduleManager::dayTypeNamesUC, state.dataIPShortCut->cAlphaArgs(2));
    7396        1614 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).DayType <= 0) {
    7397           0 :                 ShowSevereError(state,
    7398           0 :                                 state.dataIPShortCut->cCurrentModuleObject + "=\"" + state.dataWeatherManager->DesDayInput(EnvrnNum).Title +
    7399             :                                     "\", invalid data.");
    7400           0 :                 ShowContinueError(
    7401           0 :                     state, "..invalid field: " + state.dataIPShortCut->cAlphaFieldNames(2) + "=\"" + state.dataIPShortCut->cAlphaArgs(2) + "\".");
    7402           0 :                 ShowContinueError(state,
    7403             :                                   "Valid values are "
    7404             :                                   "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Holiday,SummerDesignDay,WinterDesignDay,CustomDay1,"
    7405             :                                   "CustomDay2.");
    7406           0 :                 ErrorsFound = true;
    7407             :             }
    7408             : 
    7409        1614 :             state.dataWeatherManager->Environment(EnvrnNum).Title = state.dataWeatherManager->DesDayInput(EnvrnNum).Title;
    7410        1614 :             state.dataWeatherManager->Environment(EnvrnNum).KindOfEnvrn = DataGlobalConstants::KindOfSim::DesignDay;
    7411        1614 :             state.dataWeatherManager->Environment(EnvrnNum).DesignDayNum = EnvrnNum;
    7412        1614 :             state.dataWeatherManager->Environment(EnvrnNum).RunPeriodDesignNum = 0;
    7413        1614 :             state.dataWeatherManager->Environment(EnvrnNum).TotalDays = 1;
    7414        1614 :             state.dataWeatherManager->Environment(EnvrnNum).StartMonth = state.dataWeatherManager->DesDayInput(EnvrnNum).Month;
    7415        1614 :             state.dataWeatherManager->Environment(EnvrnNum).StartDay = state.dataWeatherManager->DesDayInput(EnvrnNum).DayOfMonth;
    7416        1614 :             state.dataWeatherManager->Environment(EnvrnNum).EndMonth = state.dataWeatherManager->Environment(EnvrnNum).StartMonth;
    7417        1614 :             state.dataWeatherManager->Environment(EnvrnNum).EndDay = state.dataWeatherManager->Environment(EnvrnNum).StartDay;
    7418        1614 :             state.dataWeatherManager->Environment(EnvrnNum).DayOfWeek = 0;
    7419        1614 :             state.dataWeatherManager->Environment(EnvrnNum).UseDST = false;
    7420        1614 :             state.dataWeatherManager->Environment(EnvrnNum).UseHolidays = false;
    7421        1614 :             state.dataWeatherManager->Environment(EnvrnNum).StartJDay = state.dataWeatherManager->DesignDay(EnvrnNum).DayOfYear;
    7422        1614 :             state.dataWeatherManager->Environment(EnvrnNum).EndJDay = state.dataWeatherManager->Environment(EnvrnNum).StartJDay;
    7423             : 
    7424             :             // create predefined report on design day
    7425        3228 :             std::string envTitle = state.dataWeatherManager->DesDayInput(EnvrnNum).Title;
    7426        4842 :             OutputReportPredefined::PreDefTableEntry(
    7427        3228 :                 state, state.dataOutRptPredefined->pdchDDmaxDB, envTitle, state.dataWeatherManager->DesDayInput(EnvrnNum).MaxDryBulb);
    7428        4842 :             OutputReportPredefined::PreDefTableEntry(
    7429        3228 :                 state, state.dataOutRptPredefined->pdchDDrange, envTitle, state.dataWeatherManager->DesDayInput(EnvrnNum).DailyDBRange);
    7430        1614 :             if (state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType != DDHumIndType::RelHumSch) {
    7431        4833 :                 OutputReportPredefined::PreDefTableEntry(
    7432        3222 :                     state, state.dataOutRptPredefined->pdchDDhumid, envTitle, state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndValue);
    7433             :             } else {
    7434           3 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDDhumid, envTitle, "N/A");
    7435             :             }
    7436        3228 :             OutputReportPredefined::PreDefTableEntry(
    7437             :                 state,
    7438        1614 :                 state.dataOutRptPredefined->pdchDDhumTyp,
    7439             :                 envTitle,
    7440        1614 :                 DDHumIndTypeStringRep[static_cast<int>(state.dataWeatherManager->DesDayInput(EnvrnNum).HumIndType)]);
    7441        4842 :             OutputReportPredefined::PreDefTableEntry(
    7442        3228 :                 state, state.dataOutRptPredefined->pdchDDwindSp, envTitle, state.dataWeatherManager->DesDayInput(EnvrnNum).WindSpeed);
    7443        4842 :             OutputReportPredefined::PreDefTableEntry(
    7444        3228 :                 state, state.dataOutRptPredefined->pdchDDwindDr, envTitle, state.dataWeatherManager->DesDayInput(EnvrnNum).WindDir);
    7445             :         }
    7446         771 :     }
    7447             : 
    7448         771 :     void GetLocationInfo(EnergyPlusData &state, bool &ErrorsFound)
    7449             :     {
    7450             : 
    7451             :         // SUBROUTINE INFORMATION:
    7452             :         //       AUTHOR         Richard Liesen
    7453             :         //       DATE WRITTEN   October 1997
    7454             :         //       MODIFIED
    7455             :         //       RE-ENGINEERED  na
    7456             : 
    7457             :         // PURPOSE OF THIS SUBROUTINE:
    7458             :         // This subroutine gets the location info from the IDF file; latitude,
    7459             :         //  longitude and time zone number.
    7460             : 
    7461         771 :         state.dataIPShortCut->cCurrentModuleObject = "Site:Location";
    7462         771 :         int const NumLocations = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    7463             : 
    7464         771 :         if (NumLocations > 1) {
    7465           0 :             ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Too many objects entered. Only one allowed.");
    7466           0 :             ErrorsFound = true;
    7467             :         }
    7468             : 
    7469         771 :         if (NumLocations == 1) {
    7470             :             int LocNumAlpha;             // Number of alpha names being passed
    7471             :             int LocNumProp;              // Number of properties being passed
    7472             :             int IOStat;                  // IO Status when calling get input subroutine
    7473        1528 :             Array1D_string LocNames(1);  // Temp Array to transfer location info
    7474        1528 :             Array1D<Real64> LocProps(4); // Temporary array to transfer location info
    7475             :             // Call Input Get routine to retrieve Location information
    7476        1528 :             state.dataInputProcessing->inputProcessor->getObjectItem(
    7477         764 :                 state, state.dataIPShortCut->cCurrentModuleObject, 1, LocNames, LocNumAlpha, LocProps, LocNumProp, IOStat);
    7478             : 
    7479             :             // set latitude, longitude, and time zone number variables
    7480         764 :             state.dataWeatherManager->LocationTitle = LocNames(1);
    7481         764 :             state.dataEnvrn->Latitude = LocProps(1);
    7482         764 :             state.dataEnvrn->Longitude = LocProps(2);
    7483         764 :             state.dataEnvrn->TimeZoneNumber = LocProps(3);
    7484         764 :             state.dataEnvrn->Elevation = LocProps(4);
    7485         764 :             state.dataWeatherManager->LocationGathered = true;
    7486             :         }
    7487         771 :     }
    7488             : 
    7489         771 :     void GetWeatherProperties(EnergyPlusData &state, bool &ErrorsFound)
    7490             :     {
    7491             : 
    7492             :         // SUBROUTINE INFORMATION:
    7493             :         //       AUTHOR         Linda Lawrie
    7494             :         //       DATE WRITTEN   July 2009
    7495             :         //       MODIFIED       na
    7496             :         //       RE-ENGINEERED  na
    7497             : 
    7498             :         // PURPOSE OF THIS SUBROUTINE:
    7499             :         // Weather properties are an advanced concept for simulation.  Primarily, these properties are
    7500             :         // used in the test suite runs that have specific requirements for certain properties (such as
    7501             :         // sky temperature).
    7502             : 
    7503             :         // REFERENCES:
    7504             :         // WeatherProperty:SkyTemperature,
    7505             :         //        \memo This object is used to override internal sky temperature calculations.
    7506             :         //   A1,  \field Name
    7507             :         //        \reference DesignDays
    7508             :         //        \note leave blank for RunPeriods (until we name them)
    7509             :         //        \note This field references the applicable design day or runperiod(s) if left blank.
    7510             :         //   A2,  \field Calculation Type
    7511             :         //        \type choice
    7512             :         //        \key ScheduleValue
    7513             :         //        \key DifferenceScheduleDryBulbValue
    7514             :         //        \key DifferenceScheduleDewPointValue
    7515             :         //        \key AlgorithmA
    7516             :         //   A3;  \field Schedule Name
    7517             :         //        \type object-list
    7518             :         //        \object-list DayScheduleNames
    7519             :         //        \object-list ScheduleNames
    7520             : 
    7521             :         static constexpr std::string_view RoutineName("GetWeatherProperties:");
    7522             : 
    7523             :         int Found;
    7524             :         int envFound;
    7525             : 
    7526         771 :         state.dataIPShortCut->cCurrentModuleObject = "WeatherProperty:SkyTemperature";
    7527         771 :         state.dataWeatherManager->NumWPSkyTemperatures =
    7528         771 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    7529             : 
    7530         771 :         state.dataWeatherManager->WPSkyTemperature.allocate(state.dataWeatherManager->NumWPSkyTemperatures); // by default, not used.
    7531             : 
    7532         773 :         for (int i = 1; i <= state.dataWeatherManager->NumWPSkyTemperatures; ++i) {
    7533             :             int IOStat;
    7534             :             int NumAlpha;
    7535             :             int NumNumerics;
    7536          16 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    7537           2 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
    7538             :                                                                      i,
    7539           2 :                                                                      state.dataIPShortCut->cAlphaArgs,
    7540             :                                                                      NumAlpha,
    7541           2 :                                                                      state.dataIPShortCut->rNumericArgs,
    7542             :                                                                      NumNumerics,
    7543             :                                                                      IOStat,
    7544           2 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    7545           2 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    7546           2 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    7547           2 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    7548             : 
    7549           2 :             if (state.dataIPShortCut->cAlphaArgs(1).empty()) {
    7550           1 :                 Found = 0;
    7551          14 :                 for (int j = 1; j <= state.dataWeatherManager->NumOfEnvrn; ++j) {
    7552          13 :                     if (state.dataWeatherManager->Environment(j).KindOfEnvrn != DataGlobalConstants::KindOfSim::RunPeriodWeather) continue;
    7553           1 :                     if (state.dataWeatherManager->Environment(j).WP_Type1 != 0) {
    7554           0 :                         ShowSevereError(state,
    7555           0 :                                         std::string{RoutineName} + state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7556           0 :                                             state.dataIPShortCut->cAlphaArgs(1) + "\", indicated Environment Name already assigned.");
    7557           0 :                         if (!state.dataWeatherManager->Environment(j).Title.empty()) {
    7558           0 :                             ShowContinueError(state,
    7559           0 :                                               "...Environment=\"" + state.dataWeatherManager->Environment(j).Title + "\", already using " +
    7560           0 :                                                   state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7561           0 :                                                   state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(j).WP_Type1).Name +
    7562             :                                                   "\".");
    7563             :                         } else {
    7564           0 :                             ShowContinueError(state,
    7565           0 :                                               "... Runperiod Environment, already using " + state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7566           0 :                                                   state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(j).WP_Type1).Name +
    7567             :                                                   "\".");
    7568             :                         }
    7569           0 :                         ErrorsFound = true;
    7570             :                     } else {
    7571           1 :                         state.dataWeatherManager->Environment(j).WP_Type1 = i;
    7572           1 :                         Found = j;
    7573             :                     }
    7574             :                 }
    7575           1 :                 if (Found == 0) {
    7576           0 :                     ShowWarningError(state, "GetWeatherProperties: WeatherProperty:SkyTemperature=blank, no run periods found.");
    7577           0 :                     ShowContinueError(state, "...SkyTemperature will not be applied.");
    7578           0 :                     continue;
    7579             :                 }
    7580             :             } else { // really a name
    7581           2 :                 Found = UtilityRoutines::FindItemInList(
    7582           2 :                     state.dataIPShortCut->cAlphaArgs(1), state.dataWeatherManager->Environment, &EnvironmentData::Title);
    7583           1 :                 envFound = Found;
    7584           1 :                 if (Found == 0) {
    7585           0 :                     ShowSevereError(state,
    7586           0 :                                     std::string{RoutineName} + state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7587           0 :                                         state.dataIPShortCut->cAlphaArgs(1) + "\", invalid Environment Name referenced.");
    7588           0 :                     ShowContinueError(state, "...remainder of object not processed.");
    7589           0 :                     ErrorsFound = true;
    7590           0 :                     continue;
    7591             :                 } else {
    7592           1 :                     if (state.dataWeatherManager->Environment(Found).WP_Type1 != 0) {
    7593           0 :                         ShowSevereError(state,
    7594           0 :                                         std::string{RoutineName} + state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7595           0 :                                             state.dataIPShortCut->cAlphaArgs(1) + "\", indicated Environment Name already assigned.");
    7596           0 :                         ShowContinueError(state,
    7597           0 :                                           "...Environment=\"" + state.dataWeatherManager->Environment(Found).Title + "\", already using " +
    7598           0 :                                               state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7599           0 :                                               state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(Found).WP_Type1).Name +
    7600             :                                               "\".");
    7601           0 :                         ErrorsFound = true;
    7602             :                     } else {
    7603           1 :                         state.dataWeatherManager->Environment(Found).WP_Type1 = i;
    7604             :                     }
    7605             :                 }
    7606             :             }
    7607             : 
    7608           2 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(1)) {
    7609           1 :                 UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), state.dataIPShortCut->cCurrentModuleObject, ErrorsFound);
    7610           1 :                 state.dataWeatherManager->WPSkyTemperature(i).Name = state.dataIPShortCut->cAlphaArgs(1); // Name
    7611             :             } else {
    7612           1 :                 state.dataWeatherManager->WPSkyTemperature(i).Name = "All RunPeriods";
    7613             :             }
    7614             :             // Validate Calculation Type.
    7615           4 :             std::string units;
    7616             :             OutputProcessor::Unit unitType;
    7617           2 :             state.dataWeatherManager->WPSkyTemperature(i).CalculationType =
    7618           4 :                 static_cast<SkyTempCalcType>(getEnumerationValue(WeatherManager::SkyTempModelInputNamesUC, state.dataIPShortCut->cAlphaArgs(2)));
    7619             : 
    7620           2 :             switch (state.dataWeatherManager->WPSkyTemperature(i).CalculationType) {
    7621           2 :             case SkyTempCalcType::ScheduleValue: {
    7622           2 :                 state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = true;
    7623           2 :                 units = "[C]";
    7624           2 :                 unitType = OutputProcessor::Unit::C;
    7625           2 :             } break;
    7626           0 :             case SkyTempCalcType::DryBulbDelta: {
    7627           0 :                 state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = true;
    7628           0 :                 units = "[deltaC]";
    7629           0 :                 unitType = OutputProcessor::Unit::deltaC;
    7630           0 :             } break;
    7631           0 :             case SkyTempCalcType::DewPointDelta: {
    7632           0 :                 state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = true;
    7633           0 :                 units = "[deltaC]";
    7634           0 :                 unitType = OutputProcessor::Unit::deltaC;
    7635           0 :             } break;
    7636           0 :             case SkyTempCalcType::BruntModel: {
    7637           0 :                 state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = false;
    7638           0 :             } break;
    7639           0 :             case SkyTempCalcType::IdsoModel: {
    7640           0 :                 state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = false;
    7641           0 :             } break;
    7642           0 :             case SkyTempCalcType::BerdahlMartinModel: {
    7643           0 :                 state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = false;
    7644           0 :             } break;
    7645           0 :             case SkyTempCalcType::ClarkAllenModel: {
    7646           0 :                 state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = false;
    7647           0 :             } break;
    7648           0 :             default: {
    7649             :                 // Bad inputs are trapped by input processor
    7650           0 :                 assert(false);
    7651             :             }
    7652             :             }
    7653             : 
    7654           2 :             if (state.dataWeatherManager->WPSkyTemperature(i).IsSchedule) {
    7655           2 :                 state.dataWeatherManager->WPSkyTemperature(i).ScheduleName = state.dataIPShortCut->cAlphaArgs(3);
    7656           3 :                 if (state.dataWeatherManager->Environment(Found).KindOfEnvrn == DataGlobalConstants::KindOfSim::RunPeriodWeather ||
    7657           1 :                     state.dataWeatherManager->Environment(Found).KindOfEnvrn == DataGlobalConstants::KindOfSim::RunPeriodDesign) {
    7658           1 :                     state.dataWeatherManager->WPSkyTemperature(i).ScheduleName = state.dataIPShortCut->cAlphaArgs(3);
    7659             :                     // See if it's a schedule.
    7660           1 :                     Found = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3));
    7661           1 :                     if (Found == 0) {
    7662           0 :                         ShowSevereError(state,
    7663           0 :                                         std::string{RoutineName} + state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7664           0 :                                             state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " + state.dataIPShortCut->cAlphaFieldNames(3) + '.');
    7665           0 :                         ShowContinueError(state, "...Entered name=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
    7666           0 :                         ShowContinueError(state,
    7667             :                                           "...Should be a full year schedule (\"Schedule:Year\", \"Schedule:Compact\", \"Schedule:File\", or "
    7668             :                                           "\"Schedule:Constant\" objects.");
    7669           0 :                         ErrorsFound = true;
    7670             :                     } else {
    7671           1 :                         state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = true;
    7672           1 :                         state.dataWeatherManager->WPSkyTemperature(i).SchedulePtr = Found;
    7673             :                     }
    7674             :                 } else { // See if it's a valid schedule.
    7675           1 :                     Found = ScheduleManager::GetDayScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3));
    7676           1 :                     if (Found == 0) {
    7677           0 :                         ShowSevereError(state,
    7678           0 :                                         std::string{RoutineName} + state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7679           0 :                                             state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " + state.dataIPShortCut->cAlphaFieldNames(3) + '.');
    7680           0 :                         ShowContinueError(state, "...Entered name=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
    7681           0 :                         ShowContinueError(
    7682             :                             state,
    7683             :                             R"(...Should be a single day schedule ("Schedule:Day:Hourly", "Schedule:Day:Interval", or "Schedule:Day:List" objects.)");
    7684           0 :                         ErrorsFound = true;
    7685             :                     } else {
    7686           1 :                         if (envFound != 0) {
    7687           3 :                             int schPtr = General::FindNumberInList(
    7688           3 :                                 Found, state.dataWeatherManager->SPSiteScheduleNamePtr, state.dataWeatherManager->NumSPSiteScheduleNamePtrs);
    7689           1 :                             if ((schPtr == 0) || (state.dataWeatherManager->SPSiteScheduleUnits(schPtr) != units)) {
    7690           1 :                                 ++state.dataWeatherManager->NumSPSiteScheduleNamePtrs;
    7691           1 :                                 state.dataWeatherManager->SPSiteScheduleNamePtr(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) = Found;
    7692           1 :                                 state.dataWeatherManager->SPSiteScheduleUnits(state.dataWeatherManager->NumSPSiteScheduleNamePtrs) = units;
    7693           3 :                                 SetupOutputVariable(state,
    7694             :                                                     "Sizing Period Site Sky Temperature Schedule Value",
    7695             :                                                     unitType,
    7696           1 :                                                     state.dataWeatherManager->SPSiteSkyTemperatureScheduleValue(envFound),
    7697             :                                                     OutputProcessor::SOVTimeStepType::Zone,
    7698             :                                                     OutputProcessor::SOVStoreType::Average,
    7699           2 :                                                     state.dataIPShortCut->cAlphaArgs(3));
    7700             :                             }
    7701           1 :                             state.dataWeatherManager->WPSkyTemperature(i).IsSchedule = true;
    7702           1 :                             state.dataWeatherManager->WPSkyTemperature(i).SchedulePtr = Found;
    7703             :                         }
    7704             :                     }
    7705             :                 }
    7706             :             }
    7707             : 
    7708           2 :             if (!state.dataWeatherManager->WPSkyTemperature(i).IsSchedule && !state.dataIPShortCut->lAlphaFieldBlanks(4)) {
    7709           0 :                 if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(4), "Yes")) {
    7710           0 :                     state.dataWeatherManager->WPSkyTemperature(i).UseWeatherFileHorizontalIR = true;
    7711           0 :                 } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(4), "No")) {
    7712           0 :                     state.dataWeatherManager->WPSkyTemperature(i).UseWeatherFileHorizontalIR = false;
    7713             :                 } else {
    7714           0 :                     ShowSevereError(state,
    7715           0 :                                     std::string{RoutineName} + state.dataIPShortCut->cCurrentModuleObject + "=\"" +
    7716           0 :                                         state.dataIPShortCut->cAlphaArgs(1) + "\", invalid " + state.dataIPShortCut->cAlphaFieldNames(4) + '.');
    7717           0 :                     ShowContinueError(state, "...entered value=\"" + state.dataIPShortCut->cAlphaArgs(4) + "\", should be Yes or No.");
    7718           0 :                     ErrorsFound = true;
    7719             :                 }
    7720             :             } else {
    7721           2 :                 state.dataWeatherManager->WPSkyTemperature(i).UseWeatherFileHorizontalIR = true;
    7722             :             }
    7723             :         }
    7724        3544 :         for (int envrn = 1; envrn <= state.dataWeatherManager->NumOfEnvrn; ++envrn) {
    7725        2775 :             if (state.dataWeatherManager->Environment(envrn).WP_Type1 != 0 &&
    7726           2 :                 state.dataWeatherManager->NumWPSkyTemperatures >= state.dataWeatherManager->Environment(envrn).WP_Type1) {
    7727           2 :                 state.dataWeatherManager->Environment(envrn).SkyTempModel =
    7728           2 :                     state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(envrn).WP_Type1).CalculationType;
    7729           2 :                 state.dataWeatherManager->Environment(envrn).UseWeatherFileHorizontalIR =
    7730           2 :                     state.dataWeatherManager->WPSkyTemperature(state.dataWeatherManager->Environment(envrn).WP_Type1).UseWeatherFileHorizontalIR;
    7731             :             }
    7732             :         }
    7733         771 :     }
    7734             : 
    7735         771 :     void GetGroundTemps(EnergyPlusData &state)
    7736             :     {
    7737             : 
    7738             :         // SUBROUTINE INFORMATION:
    7739             :         //       AUTHOR         Richard Liesen
    7740             :         //       DATE WRITTEN   October 1997
    7741             :         //       MODIFIED       na
    7742             :         //       RE-ENGINEERED  na
    7743             : 
    7744             :         // PURPOSE OF THIS SUBROUTINE:
    7745             :         // This file reads the Ground Temps from the input file and puts them
    7746             :         //  in a new variable.
    7747             : 
    7748             :         // Initialize Site:GroundTemperature:BuildingSurface object
    7749        2313 :         state.dataWeatherManager->siteBuildingSurfaceGroundTempsPtr = GroundTemperatureManager::GetGroundTempModelAndInit(
    7750        1542 :             state, GroundTemperatureManager::groundTempModelNamesUC[static_cast<int>(GroundTempObjType::SiteBuildingSurfaceGroundTemp)], "");
    7751             : 
    7752             :         // Initialize Site:GroundTemperature:FCFactorMethod object
    7753        2313 :         state.dataWeatherManager->siteFCFactorMethodGroundTempsPtr = GroundTemperatureManager::GetGroundTempModelAndInit(
    7754        1542 :             state, GroundTemperatureManager::groundTempModelNamesUC[static_cast<int>(GroundTempObjType::SiteFCFactorMethodGroundTemp)], "");
    7755             : 
    7756             :         // Initialize Site:GroundTemperature:Shallow object
    7757        2313 :         state.dataWeatherManager->siteShallowGroundTempsPtr = GroundTemperatureManager::GetGroundTempModelAndInit(
    7758        1542 :             state, GroundTemperatureManager::groundTempModelNamesUC[static_cast<int>(GroundTempObjType::SiteShallowGroundTemp)], "");
    7759             : 
    7760             :         // Initialize Site:GroundTemperature:Deep object
    7761        2313 :         state.dataWeatherManager->siteDeepGroundTempsPtr = GroundTemperatureManager::GetGroundTempModelAndInit(
    7762        1542 :             state, GroundTemperatureManager::groundTempModelNamesUC[static_cast<int>(GroundTempObjType::SiteDeepGroundTemp)], "");
    7763         771 :     }
    7764             : 
    7765         771 :     void GetGroundReflectances(EnergyPlusData &state, bool &ErrorsFound)
    7766             :     {
    7767             : 
    7768             :         // SUBROUTINE INFORMATION:
    7769             :         //       AUTHOR         Linda Lawrie
    7770             :         //       DATE WRITTEN   March 2002
    7771             :         //       MODIFIED       na
    7772             :         //       RE-ENGINEERED  na
    7773             : 
    7774             :         // PURPOSE OF THIS SUBROUTINE:
    7775             :         // This file reads the Ground Reflectances from the input file (optional) and
    7776             :         // places them in the monthly array.
    7777             : 
    7778         771 :         state.dataIPShortCut->cCurrentModuleObject = "Site:GroundReflectance";
    7779         771 :         int nObjs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    7780         771 :         if (nObjs != 0) {
    7781           6 :             Array1D_string GndAlphas(1);  // Construction Alpha names defined
    7782           6 :             Array1D<Real64> GndProps(12); // Temporary array to transfer ground reflectances
    7783           3 :             if (nObjs == 1) {
    7784             :                 int GndNumAlpha; // Number of construction alpha names being passed
    7785             :                 int GndNumProp;  // dummy variable for properties being passed
    7786             :                 int IOStat;      // IO Status when calling get input subroutine
    7787             :                 // Get the object names for each construction from the input processor
    7788           6 :                 state.dataInputProcessing->inputProcessor->getObjectItem(
    7789           3 :                     state, state.dataIPShortCut->cCurrentModuleObject, 1, GndAlphas, GndNumAlpha, GndProps, GndNumProp, IOStat);
    7790             : 
    7791           3 :                 if (GndNumProp < 12) {
    7792           0 :                     ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Less than 12 values entered.");
    7793           0 :                     ErrorsFound = true;
    7794             :                 }
    7795             : 
    7796             :                 // Assign the ground reflectances to the variable
    7797           3 :                 state.dataWeatherManager->GroundReflectances({1, 12}) = GndProps({1, 12});
    7798             : 
    7799             :             } else {
    7800           0 :                 ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Too many objects entered. Only one allowed.");
    7801           0 :                 ErrorsFound = true;
    7802             :             }
    7803             :         }
    7804             : 
    7805             :         // Write Final Ground Reflectance Information to the initialization output file
    7806         771 :         print(state.files.eio,
    7807             :               "{}\n",
    7808             :               "! "
    7809             :               "<Site:GroundReflectance>,Jan{dimensionless},Feb{dimensionless},Mar{dimensionless},Apr{dimensionless},"
    7810             :               "May{dimensionless},Jun{dimensionless},Jul{dimensionless},Aug{dimensionless},Sep{dimensionless},Oct{"
    7811         771 :               "dimensionless},Nov{dimensionless},Dec{dimensionless}");
    7812             : 
    7813         771 :         print(state.files.eio, " Site:GroundReflectance");
    7814       10023 :         for (int i = 1; i <= 12; ++i) {
    7815        9252 :             print(state.files.eio, ", {:5.2F}", state.dataWeatherManager->GroundReflectances(i));
    7816             :         }
    7817         771 :         print(state.files.eio, "\n");
    7818         771 :     }
    7819             : 
    7820         771 :     void GetSnowGroundRefModifiers(EnergyPlusData &state, bool &ErrorsFound)
    7821             :     {
    7822             : 
    7823             :         // SUBROUTINE INFORMATION:
    7824             :         //       AUTHOR         Linda Lawrie
    7825             :         //       DATE WRITTEN   March 2002
    7826             :         //       MODIFIED       na
    7827             :         //       RE-ENGINEERED  na
    7828             : 
    7829             :         // PURPOSE OF THIS SUBROUTINE:
    7830             :         // This file reads the Snow Ground Reflectance Modifiers from the input file (optional) and
    7831             :         // places them in the variables.
    7832             : 
    7833         771 :         state.dataIPShortCut->cCurrentModuleObject = "Site:GroundReflectance:SnowModifier";
    7834         771 :         int nObjs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    7835         771 :         if (nObjs != 0) {
    7836           4 :             Array1D_string GndAlphas(1); // Construction Alpha names defined
    7837           4 :             Array1D<Real64> GndProps(2); // Temporary array to transfer ground reflectances
    7838           2 :             if (nObjs == 1) {
    7839             :                 int GndNumAlpha; // Number of construction alpha names being passed
    7840             :                 int GndNumProp;  // dummy variable for properties being passed
    7841             :                 int IOStat;      // IO Status when calling get input subroutine
    7842             :                 // Get the object names for each construction from the input processor
    7843           4 :                 state.dataInputProcessing->inputProcessor->getObjectItem(
    7844           2 :                     state, state.dataIPShortCut->cCurrentModuleObject, 1, GndAlphas, GndNumAlpha, GndProps, GndNumProp, IOStat);
    7845             : 
    7846             :                 // Assign the ground reflectances to the variable
    7847           2 :                 state.dataWeatherManager->SnowGndRefModifier = GndProps(1);
    7848           2 :                 state.dataWeatherManager->SnowGndRefModifierForDayltg = GndProps(2);
    7849             : 
    7850             :             } else {
    7851           0 :                 ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Too many objects entered. Only one allowed.");
    7852           0 :                 ErrorsFound = true;
    7853             :             }
    7854             :         }
    7855             : 
    7856             :         // Write Final Ground Reflectance Modifier Information to the initialization output file
    7857         771 :         print(state.files.eio, "{}\n", "! <Site:GroundReflectance:SnowModifier>, Normal, Daylighting {dimensionless}");
    7858             :         static constexpr std::string_view Format_720(" Site:GroundReflectance:SnowModifier, {:7.3F}, {:7.3F}\n");
    7859         771 :         print(state.files.eio, Format_720, state.dataWeatherManager->SnowGndRefModifier, state.dataWeatherManager->SnowGndRefModifierForDayltg);
    7860             : 
    7861         771 :         print(state.files.eio,
    7862             :               "{}\n",
    7863             :               "! "
    7864             :               "<Site:GroundReflectance:Snow>,Jan{dimensionless},Feb{dimensionless},Mar{dimensionless},Apr{"
    7865             :               "dimensionless},May{dimensionless},Jun{dimensionless},Jul{dimensionless},Aug{dimensionless},Sep{"
    7866         771 :               "dimensionless},Oct{dimensionless},Nov{dimensionless},Dec{dimensionless}");
    7867         771 :         print(state.files.eio, "{}", " Site:GroundReflectance:Snow");
    7868       10023 :         for (int i = 1; i <= 12; ++i) {
    7869        9252 :             print(state.files.eio,
    7870             :                   ", {:5.2F}",
    7871       18504 :                   max(min(state.dataWeatherManager->GroundReflectances(i) * state.dataWeatherManager->SnowGndRefModifier, 1.0), 0.0));
    7872             :         }
    7873         771 :         print(state.files.eio, "\n");
    7874         771 :         print(state.files.eio,
    7875             :               "{}\n",
    7876             :               "! "
    7877             :               "<Site:GroundReflectance:Snow:Daylighting>,Jan{dimensionless},Feb{dimensionless},Mar{dimensionless},Apr{"
    7878             :               "dimensionless},May{dimensionless},Jun{dimensionless},Jul{dimensionless},Aug{dimensionless},Sep{"
    7879         771 :               "dimensionless},Oct{dimensionless},Nov{dimensionless},Dec{dimensionless}");
    7880         771 :         print(state.files.eio, " Site:GroundReflectance:Snow:Daylighting");
    7881       10023 :         for (nObjs = 1; nObjs <= 12; ++nObjs) {
    7882        9252 :             print(state.files.eio,
    7883             :                   ", {:5.2F}",
    7884       18504 :                   max(min(state.dataWeatherManager->GroundReflectances(nObjs) * state.dataWeatherManager->SnowGndRefModifierForDayltg, 1.0), 0.0));
    7885             :         }
    7886         771 :         print(state.files.eio, "\n");
    7887         771 :     }
    7888             : 
    7889         771 :     void GetWaterMainsTemperatures(EnergyPlusData &state, bool &ErrorsFound)
    7890             :     {
    7891             : 
    7892             :         // SUBROUTINE INFORMATION:
    7893             :         //       AUTHOR         Peter Graham Ellis
    7894             :         //       DATE WRITTEN   January 2005
    7895             :         //       MODIFIED       na
    7896             :         //       RE-ENGINEERED  na
    7897             : 
    7898             :         // PURPOSE OF THIS SUBROUTINE:
    7899             :         // Reads the input data for the WATER MAINS TEMPERATURES object.
    7900             : 
    7901         771 :         state.dataIPShortCut->cCurrentModuleObject = "Site:WaterMainsTemperature";
    7902         771 :         int NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    7903             : 
    7904         771 :         if (NumObjects == 1) {
    7905             :             int NumAlphas;               // Number of elements in the alpha array
    7906             :             int NumNums;                 // Number of elements in the numeric array
    7907             :             int IOStat;                  // IO Status when calling get input subroutine
    7908         246 :             Array1D_string AlphArray(2); // Character string data
    7909         246 :             Array1D<Real64> NumArray(2); // Numeric data
    7910         738 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    7911         123 :                                                                      state.dataIPShortCut->cCurrentModuleObject,
    7912             :                                                                      1,
    7913             :                                                                      AlphArray,
    7914             :                                                                      NumAlphas,
    7915             :                                                                      NumArray,
    7916             :                                                                      NumNums,
    7917             :                                                                      IOStat,
    7918         123 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
    7919         123 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    7920         123 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    7921         123 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    7922             : 
    7923         123 :             state.dataWeatherManager->WaterMainsTempsMethod =
    7924         246 :                 static_cast<WeatherManager::WaterMainsTempCalcMethod>(getEnumerationValue(waterMainsCalcMethodNamesUC, AlphArray(1)));
    7925         123 :             if (state.dataWeatherManager->WaterMainsTempsMethod == WaterMainsTempCalcMethod::Schedule) {
    7926           3 :                 state.dataWeatherManager->WaterMainsTempsScheduleName = AlphArray(2);
    7927           3 :                 state.dataWeatherManager->WaterMainsTempsSchedule = ScheduleManager::GetScheduleIndex(state, AlphArray(2));
    7928           3 :                 if (state.dataWeatherManager->WaterMainsTempsSchedule == 0) {
    7929           0 :                     ShowSevereError(state,
    7930           0 :                                     state.dataIPShortCut->cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(2) + '=' +
    7931           0 :                                         AlphArray(2));
    7932           0 :                     ErrorsFound = true;
    7933             :                 }
    7934             : 
    7935         120 :             } else if (state.dataWeatherManager->WaterMainsTempsMethod == WaterMainsTempCalcMethod::Correlation) {
    7936         120 :                 if (NumNums == 0) {
    7937           0 :                     ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Missing Annual Average and Maximum Difference fields.");
    7938           0 :                     ErrorsFound = true;
    7939         120 :                 } else if (NumNums == 1) {
    7940           0 :                     ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Missing Maximum Difference field.");
    7941           0 :                     ErrorsFound = true;
    7942             :                 } else {
    7943         120 :                     state.dataWeatherManager->WaterMainsTempsAnnualAvgAirTemp = NumArray(1);
    7944         120 :                     state.dataWeatherManager->WaterMainsTempsMaxDiffAirTemp = NumArray(2);
    7945             :                 }
    7946           0 :             } else if (state.dataWeatherManager->WaterMainsTempsMethod == WaterMainsTempCalcMethod::CorrelationFromWeatherFile) {
    7947             :                 // No action
    7948             :             } else {
    7949           0 :                 ShowSevereError(state,
    7950           0 :                                 state.dataIPShortCut->cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(1) + '=' +
    7951           0 :                                     AlphArray(1));
    7952           0 :                 ErrorsFound = true;
    7953             :             }
    7954             : 
    7955         648 :         } else if (NumObjects > 1) {
    7956           0 :             ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Too many objects entered. Only one allowed.");
    7957           0 :             ErrorsFound = true;
    7958             :         }
    7959         771 :     }
    7960             : 
    7961     2661169 :     void CalcWaterMainsTemp(EnergyPlusData &state)
    7962             :     {
    7963             : 
    7964             :         // SUBROUTINE INFORMATION:
    7965             :         //       AUTHOR         Peter Graham Ellis
    7966             :         //       DATE WRITTEN   January 2005
    7967             :         //       MODIFIED       June 2018, B. Nigusse
    7968             :         //       RE-ENGINEERED  na
    7969             : 
    7970             :         // PURPOSE OF THIS SUBROUTINE:
    7971             :         // Calculates the daily water mains temperature based on input data from the WATER MAINS TEMPERATURES object.
    7972             : 
    7973             :         // METHODOLOGY EMPLOYED:
    7974             :         // Water mains temperature is either taken from a schedule or calculated by a correlation.  The correlation
    7975             :         // is fit to Fahrenheit units, so the air temperature values are first convert to F, then mains temperature
    7976             :         // is calculated and converted back to C.
    7977             : 
    7978     2661169 :         switch (state.dataWeatherManager->WaterMainsTempsMethod) {
    7979        6942 :         case WaterMainsTempCalcMethod::Schedule:
    7980        6942 :             state.dataEnvrn->WaterMainsTemp = ScheduleManager::GetCurrentScheduleValue(state, state.dataWeatherManager->WaterMainsTempsSchedule);
    7981        6942 :             break;
    7982      487558 :         case WaterMainsTempCalcMethod::Correlation:
    7983      975116 :             state.dataEnvrn->WaterMainsTemp = WaterMainsTempFromCorrelation(
    7984      975116 :                 state, state.dataWeatherManager->WaterMainsTempsAnnualAvgAirTemp, state.dataWeatherManager->WaterMainsTempsMaxDiffAirTemp);
    7985      487558 :             break;
    7986           0 :         case WaterMainsTempCalcMethod::CorrelationFromWeatherFile:
    7987           0 :             if (state.dataWeatherManager->OADryBulbAverage.OADryBulbWeatherDataProcessed) {
    7988           0 :                 state.dataEnvrn->WaterMainsTemp =
    7989           0 :                     WaterMainsTempFromCorrelation(state,
    7990           0 :                                                   state.dataWeatherManager->OADryBulbAverage.AnnualAvgOADryBulbTemp,
    7991           0 :                                                   state.dataWeatherManager->OADryBulbAverage.MonthlyAvgOADryBulbTempMaxDiff);
    7992             :             } else {
    7993           0 :                 state.dataEnvrn->WaterMainsTemp = 10.0; // 50 F
    7994             :             }
    7995           0 :             break;
    7996     2166669 :         default:
    7997     2166669 :             state.dataEnvrn->WaterMainsTemp = 10.0; // 50 F
    7998     2166669 :             break;
    7999             :         }
    8000     2661169 :     }
    8001             : 
    8002      487558 :     Real64 WaterMainsTempFromCorrelation(EnergyPlusData &state, Real64 const AnnualOAAvgDryBulbTemp, Real64 const MonthlyOAAvgDryBulbTempMaxDiff)
    8003             :     {
    8004             : 
    8005             :         // SUBROUTINE INFORMATION:
    8006             :         //       AUTHOR         Peter Graham Ellis
    8007             :         //       DATE WRITTEN   January 2005
    8008             :         //       MODIFIED       na B Nigusse June 2018 (Refactored)
    8009             :         //       RE-ENGINEERED  na
    8010             : 
    8011             :         // PURPOSE OF THIS SUBROUTINE:
    8012             :         // Calculates the daily water mains temperature based on input data from the WATER MAINS TEMPERATURES object.
    8013             : 
    8014             :         // METHODOLOGY EMPLOYED:
    8015             :         // Water mains temperature calculated by a correlation.  The correlation is fit to Fahrenheit units, so the
    8016             :         // air temperature values are first convert to F, then mains temperature is calculated and converted back to C.
    8017             :         // used for Calculated Method: 'Correlation' and 'CorrelationFromWeatherFile'.
    8018             : 
    8019             :         // REFERENCES:
    8020             :         // Correlation developed by Jay Burch and Craig Christensen at NREL, described in:
    8021             :         // Hendron, R., Anderson, R., Christensen, C., Eastment, M., and Reeves, P.  2004.  "Development of an Energy
    8022             :         // Savings Benchmark for All Residential End-Uses", Proceedings of SimBuild 2004, IBPSA-USA National Conference,
    8023             :         // Boulder, CO, August 4 - 6, 2004.
    8024             : 
    8025             :         // Annual Average Outdoor Air Temperature (F)
    8026      487558 :         Real64 const Tavg = AnnualOAAvgDryBulbTemp * (9.0 / 5.0) + 32.0;
    8027             :         // Maximum difference in monthly average outdoor air temperatures (deltaF)
    8028      487558 :         Real64 const Tdiff = MonthlyOAAvgDryBulbTempMaxDiff * (9.0 / 5.0);
    8029             : 
    8030      487558 :         Real64 const Ratio = 0.4 + 0.01 * (Tavg - 44.0);
    8031      487558 :         Real64 const Lag = 35.0 - 1.0 * (Tavg - 44.0);
    8032      487558 :         Real64 constexpr Offset = 6.0;
    8033      487558 :         int const latitude_sign = (state.dataEnvrn->Latitude >= 0) ? 1 : -1;
    8034             : 
    8035             :         // calculated water main temp (F)
    8036      487558 :         Real64 CurrentWaterMainsTemp = Tavg + Offset +
    8037      975116 :                                        Ratio * (Tdiff / 2.0) * latitude_sign *
    8038      975116 :                                            std::sin((0.986 * (state.dataEnvrn->DayOfYear - 15.0 - Lag) - 90) * DataGlobalConstants::DegToRadians);
    8039             : 
    8040      487558 :         if (CurrentWaterMainsTemp < 32.0) CurrentWaterMainsTemp = 32.0;
    8041             : 
    8042             :         // Convert F to C
    8043      487558 :         return (CurrentWaterMainsTemp - 32.0) * (5.0 / 9.0);
    8044             :     }
    8045         771 :     void GetWeatherStation(EnergyPlusData &state, bool &ErrorsFound)
    8046             :     {
    8047             : 
    8048             :         // SUBROUTINE INFORMATION:
    8049             :         //       AUTHOR         Peter Graham Ellis
    8050             :         //       DATE WRITTEN   January 2006
    8051             :         //       MODIFIED       na
    8052             :         //       RE-ENGINEERED  na
    8053             : 
    8054             :         // PURPOSE OF THIS SUBROUTINE:
    8055             :         // Reads the input data for the WEATHER STATION object.
    8056             : 
    8057         771 :         state.dataIPShortCut->cCurrentModuleObject = "Site:WeatherStation";
    8058         771 :         int const NumObjects = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, state.dataIPShortCut->cCurrentModuleObject);
    8059             : 
    8060             :         // Default conditions for a weather station in an open field at a height of 10 m. (These should match the IDD defaults.)
    8061         771 :         Real64 WeatherFileWindSensorHeight = 10.0; // Height of the wind sensor at the weather station, i.e., weather file
    8062         771 :         Real64 WeatherFileWindExp = 0.14;          // Exponent for the wind velocity profile at the weather station
    8063         771 :         Real64 WeatherFileWindBLHeight = 270.0;    // Boundary layer height for the wind velocity profile at the weather station (m)
    8064         771 :         Real64 WeatherFileTempSensorHeight = 1.5;  // Height of the air temperature sensor at the weather station (m)
    8065             : 
    8066         771 :         if (NumObjects == 1) {
    8067             :             int NumAlphas;               // Number of elements in the alpha array
    8068             :             int NumNums;                 // Number of elements in the numeric array
    8069             :             int IOStat;                  // IO Status when calling get input subroutine
    8070           2 :             Array1D_string AlphArray(1); // Character string data
    8071           2 :             Array1D<Real64> NumArray(4); // Numeric data
    8072           2 :             state.dataInputProcessing->inputProcessor->getObjectItem(
    8073           1 :                 state, state.dataIPShortCut->cCurrentModuleObject, 1, AlphArray, NumAlphas, NumArray, NumNums, IOStat);
    8074             : 
    8075           1 :             if (NumNums > 0) WeatherFileWindSensorHeight = NumArray(1);
    8076           1 :             if (NumNums > 1) WeatherFileWindExp = NumArray(2);
    8077           1 :             if (NumNums > 2) WeatherFileWindBLHeight = NumArray(3);
    8078           1 :             if (NumNums > 3) WeatherFileTempSensorHeight = NumArray(4);
    8079             : 
    8080         770 :         } else if (NumObjects > 1) {
    8081           0 :             ShowSevereError(state, state.dataIPShortCut->cCurrentModuleObject + ": Too many objects entered. Only one allowed.");
    8082           0 :             ErrorsFound = true;
    8083             :         }
    8084             : 
    8085         771 :         state.dataEnvrn->WeatherFileWindModCoeff = std::pow(WeatherFileWindBLHeight / WeatherFileWindSensorHeight, WeatherFileWindExp);
    8086        1542 :         state.dataEnvrn->WeatherFileTempModCoeff = DataEnvironment::AtmosphericTempGradient * DataEnvironment::EarthRadius *
    8087         771 :                                                    WeatherFileTempSensorHeight / (DataEnvironment::EarthRadius + WeatherFileTempSensorHeight);
    8088             : 
    8089             :         // Write to the initialization output file
    8090         771 :         print(state.files.eio,
    8091             :               "{}\n",
    8092             :               "! <Environment:Weather Station>,Wind Sensor Height Above Ground {m},Wind Speed Profile Exponent "
    8093             :               "{},Wind Speed Profile Boundary Layer Thickness {m},Air Temperature Sensor Height Above Ground {m},Wind "
    8094         771 :               "Speed Modifier Coefficient-Internal,Temperature Modifier Coefficient-Internal");
    8095             : 
    8096             :         // Formats
    8097             :         static constexpr std::string_view Format_720("Environment:Weather Station,{:.3R},{:.3R},{:.3R},{:.3R},{:.3R},{:.3R}\n");
    8098        1542 :         print(state.files.eio,
    8099             :               Format_720,
    8100             :               WeatherFileWindSensorHeight,
    8101             :               WeatherFileWindExp,
    8102             :               WeatherFileWindBLHeight,
    8103             :               WeatherFileTempSensorHeight,
    8104         771 :               state.dataEnvrn->WeatherFileWindModCoeff,
    8105         771 :               state.dataEnvrn->WeatherFileTempModCoeff);
    8106         771 :     }
    8107             : 
    8108     2661169 :     void DayltgCurrentExtHorizIllum(EnergyPlusData &state)
    8109             :     {
    8110             : 
    8111             :         // SUBROUTINE INFORMATION:
    8112             :         //       AUTHOR         Fred Winkelmann
    8113             :         //       DATE WRITTEN   July 1997
    8114             :         //       MODIFIED       Nov98 (FW); Nov 2000 (FW)
    8115             :         //       RE-ENGINEERED  na
    8116             : 
    8117             :         // PURPOSE OF THIS SUBROUTINE:
    8118             :         // CALCULATES EXTERIOR DAYLIGHT ILLUMINANCE AND LUMINOUS EFFICACY
    8119             : 
    8120             :         // METHODOLOGY EMPLOYED:
    8121             :         // CALLED by SetCurrentWeather.
    8122             :         // CALCULATES THE CURRENT-TIME-STEP
    8123             :         // ILLUMINANCE ON AN UNOBSTRUCTED HORIZONTAL SURFACE FROM THE
    8124             :         // THE SKY AND FROM DIRECT SUN.
    8125             : 
    8126             :         // REFERENCES:
    8127             :         // Based on DOE-2.1E subroutine DEXTIL.
    8128             : 
    8129             :         // SOLCOS(3), below, is the cosine of the solar zenith angle.
    8130     2661169 :         if (state.dataEnvrn->SunIsUp) {
    8131             :             // Exterior horizontal beam irradiance (W/m2)
    8132     1334742 :             Real64 SDIRH = state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3);
    8133             :             // Exterior horizontal sky diffuse irradiance (W/m2)
    8134     1334742 :             Real64 SDIFH = state.dataEnvrn->DifSolarRad;
    8135             :             // Fraction of sky covered by clouds
    8136     1334742 :             state.dataEnvrn->CloudFraction = pow_2(SDIFH / (SDIRH + SDIFH + 0.0001));
    8137             :             // Luminous efficacy of sky diffuse solar and beam solar (lumens/W);
    8138             :             // Horizontal illuminance from sky and horizontal beam illuminance (lux)
    8139             :             // obtained from solar quantities on weather file and luminous efficacy.
    8140             : 
    8141     1334742 :             DayltgLuminousEfficacy(state, state.dataEnvrn->PDIFLW, state.dataEnvrn->PDIRLW);
    8142     1334742 :             state.dataEnvrn->HISKF = SDIFH * state.dataEnvrn->PDIFLW;
    8143     1334742 :             state.dataEnvrn->HISUNF = SDIRH * state.dataEnvrn->PDIRLW;
    8144     1334742 :             state.dataEnvrn->HISUNFnorm = state.dataEnvrn->BeamSolarRad * state.dataEnvrn->PDIRLW;
    8145             :         } else {
    8146     1326427 :             state.dataEnvrn->CloudFraction = 0.0;
    8147     1326427 :             state.dataEnvrn->PDIFLW = 0.0;
    8148     1326427 :             state.dataEnvrn->PDIRLW = 0.0;
    8149     1326427 :             state.dataEnvrn->HISKF = 0.0;
    8150     1326427 :             state.dataEnvrn->HISUNF = 0.0;
    8151     1326427 :             state.dataEnvrn->HISUNFnorm = 0.0;
    8152     1326427 :             state.dataEnvrn->SkyClearness = 0.0;
    8153     1326427 :             state.dataEnvrn->SkyBrightness = 0.0;
    8154             :         }
    8155     2661169 :     }
    8156             : 
    8157     1334742 :     void DayltgLuminousEfficacy(EnergyPlusData &state,
    8158             :                                 Real64 &DiffLumEff, // Luminous efficacy of sky diffuse solar radiation (lum/W)
    8159             :                                 Real64 &DirLumEff   // Luminous efficacy of beam solar radiation (lum/W)
    8160             :     )
    8161             :     {
    8162             :         // SUBROUTINE INFORMATION:
    8163             :         //       AUTHOR         Fred Winkelmann
    8164             :         //       DATE WRITTEN   July 1997
    8165             :         //       MODIFIED       August 2009, BG fixed upper bound for sky clearness bin 7
    8166             :         //       RE-ENGINEERED  na
    8167             : 
    8168             :         // PURPOSE OF THIS SUBROUTINE:
    8169             :         // Uses diffuse horizontal solar irradiance, direct normal solar
    8170             :         // irradiance, atmospheric moisture and sun position
    8171             :         // to determine the luminous efficacy in lumens/watt
    8172             :         // of sky diffuse solar radiation and direct normal solar radiation.
    8173             :         // Based on an empirical method described in
    8174             :         // R. Perez, P. Ineichen, R. Seals, J. Michalsky and R. Stewart,
    8175             :         // "Modeling daylight availability and irradiance components from direct
    8176             :         // global irradiance components from direct and global irradiance,"
    8177             :         // Solar Energy 44 (1990) 271-289.
    8178             : 
    8179             :         static Array1D<Real64> const ADiffLumEff(
    8180     1334742 :             8, {97.24, 107.22, 104.97, 102.39, 100.71, 106.42, 141.88, 152.23}); // Diffuse luminous efficacy coefficients
    8181     1334742 :         static Array1D<Real64> const BDiffLumEff(8, {-0.46, 1.15, 2.96, 5.59, 5.94, 3.83, 1.90, 0.35});
    8182     1334742 :         static Array1D<Real64> const CDiffLumEff(8, {12.00, 0.59, -5.53, -13.95, -22.75, -36.15, -53.24, -45.27});
    8183     1334742 :         static Array1D<Real64> const DDiffLumEff(8, {-8.91, -3.95, -8.77, -13.90, -23.74, -28.83, -14.03, -7.98});
    8184             :         static Array1D<Real64> const ADirLumEff(
    8185     1334742 :             8, {57.20, 98.99, 109.83, 110.34, 106.36, 107.19, 105.75, 101.18}); // Direct luminous efficacy coefficients
    8186     1334742 :         static Array1D<Real64> const BDirLumEff(8, {-4.55, -3.46, -4.90, -5.84, -3.97, -1.25, 0.77, 1.58});
    8187     1334742 :         static Array1D<Real64> const CDirLumEff(8, {-2.98, -1.21, -1.71, -1.99, -1.75, -1.51, -1.26, -1.10});
    8188     1334742 :         static Array1D<Real64> const DDirLumEff(8, {117.12, 12.38, -8.81, -4.56, -6.16, -26.73, -34.44, -8.29});
    8189             :         static Array1D<Real64> const ExtraDirNormIll(12,
    8190             :                                                      {131153.0,
    8191             :                                                       130613.0,
    8192             :                                                       128992.0,
    8193             :                                                       126816.0,
    8194             :                                                       124731.0,
    8195             :                                                       123240.0,
    8196             :                                                       122652.0,
    8197             :                                                       123120.0,
    8198             :                                                       124576.0,
    8199             :                                                       126658.0,
    8200             :                                                       128814.0,
    8201     1334742 :                                                       130471.0}); // Monthly exterrestrial direct normal illuminance (lum/m2)
    8202             : 
    8203     1334742 :         Real64 const SunZenith = std::acos(state.dataEnvrn->SOLCOS(3));     // Solar zenith angle (radians)
    8204     1334742 :         Real64 const SunAltitude = DataGlobalConstants::PiOvr2 - SunZenith; // Solar altitude angle (radians)
    8205     1334742 :         Real64 const SinSunAltitude = std::sin(SunAltitude);
    8206             :         // Clearness of sky. SkyClearness close to 1.0 corresponds to an overcast sky.
    8207             :         // SkyClearness > 6 is a clear sky.
    8208             :         // DifSolarRad is the diffuse horizontal irradiance.
    8209             :         // BeamSolarRad is the direct normal irradiance.
    8210     1334742 :         Real64 const Zeta = 1.041 * pow_3(SunZenith);
    8211     1334742 :         state.dataEnvrn->SkyClearness =
    8212     1334742 :             ((state.dataEnvrn->DifSolarRad + state.dataEnvrn->BeamSolarRad) / (state.dataEnvrn->DifSolarRad + 0.0001) + Zeta) / (1.0 + Zeta);
    8213             :         // Relative optical air mass
    8214     1334742 :         Real64 const AirMass = (1.0 - 0.1 * state.dataEnvrn->Elevation / 1000.0) /
    8215     1334742 :                                (SinSunAltitude + 0.15 / std::pow(SunAltitude / DataGlobalConstants::DegToRadians + 3.885, 1.253));
    8216             :         // In the following, 93.73 is the extraterrestrial luminous efficacy
    8217     1334742 :         state.dataEnvrn->SkyBrightness = (state.dataEnvrn->DifSolarRad * 93.73) * AirMass / ExtraDirNormIll(state.dataEnvrn->Month);
    8218             :         int ISkyClearness; // Sky clearness bin
    8219     1334742 :         if (state.dataEnvrn->SkyClearness <= 1.065) {
    8220      499343 :             ISkyClearness = 1;
    8221      835399 :         } else if (state.dataEnvrn->SkyClearness <= 1.23) {
    8222        4562 :             ISkyClearness = 2;
    8223      830837 :         } else if (state.dataEnvrn->SkyClearness <= 1.50) {
    8224        6713 :             ISkyClearness = 3;
    8225      824124 :         } else if (state.dataEnvrn->SkyClearness <= 1.95) {
    8226       10753 :             ISkyClearness = 4;
    8227      813371 :         } else if (state.dataEnvrn->SkyClearness <= 2.80) {
    8228       84120 :             ISkyClearness = 5;
    8229      729251 :         } else if (state.dataEnvrn->SkyClearness <= 4.50) {
    8230      256932 :             ISkyClearness = 6;
    8231      472319 :         } else if (state.dataEnvrn->SkyClearness <= 6.20) {
    8232      168676 :             ISkyClearness = 7;
    8233             :         } else {
    8234      303643 :             ISkyClearness = 8;
    8235             :         }
    8236             :         // Atmospheric moisture (cm of precipitable water)
    8237     1334742 :         Real64 const AtmosMoisture = std::exp(0.07 * state.dataEnvrn->OutDewPointTemp - 0.075);
    8238             :         // Sky diffuse luminous efficacy
    8239     1334742 :         if (state.dataEnvrn->SkyBrightness <= 0.0) {
    8240      482314 :             DiffLumEff = 0.0;
    8241             :         } else {
    8242     2557284 :             DiffLumEff = ADiffLumEff(ISkyClearness) + BDiffLumEff(ISkyClearness) * AtmosMoisture +
    8243     1704856 :                          CDiffLumEff(ISkyClearness) * state.dataEnvrn->SOLCOS(3) +
    8244      852428 :                          DDiffLumEff(ISkyClearness) * std::log(state.dataEnvrn->SkyBrightness);
    8245             :         }
    8246             :         // Direct normal luminous efficacy
    8247     1334742 :         if (state.dataEnvrn->SkyBrightness <= 0.0) {
    8248      482314 :             DirLumEff = 0.0;
    8249             :         } else {
    8250      852428 :             DirLumEff =
    8251      852428 :                 max(0.0,
    8252     1704856 :                     ADirLumEff(ISkyClearness) + BDirLumEff(ISkyClearness) * AtmosMoisture +
    8253     1704856 :                         CDirLumEff(ISkyClearness) * std::exp(5.73 * SunZenith - 5.0) + DDirLumEff(ISkyClearness) * state.dataEnvrn->SkyBrightness);
    8254             :         }
    8255     1334742 :     }
    8256             : 
    8257        2115 :     Real64 GetSTM(Real64 const Longitude) // Longitude from user input
    8258             :     {
    8259             :         // FUNCTION INFORMATION:
    8260             :         //       AUTHOR         Linda K. Lawrie
    8261             :         //       DATE WRITTEN   August 2003
    8262             :         //       MODIFIED       na
    8263             :         //       RE-ENGINEERED  na
    8264             : 
    8265             :         // PURPOSE OF THIS FUNCTION:
    8266             :         // This function determines the "standard time meridian" from the input
    8267             :         // longitude. Calculates the proper Meridian from Longitude.  This
    8268             :         // value is needed for weather calculations so that the sun comes
    8269             :         // up and goes down at the right times.
    8270             : 
    8271             :         Real64 GetSTM;
    8272             : 
    8273        4230 :         Array1D<Real64> longl({-12, 12}); // Lower Longitude value for a Time Zone
    8274        4230 :         Array1D<Real64> longh({-12, 12}); // Upper Longitude value for a Time Zone
    8275             : 
    8276        2115 :         GetSTM = 0.0;
    8277             : 
    8278        2115 :         longl(0) = -7.5;
    8279        2115 :         longh(0) = 7.5;
    8280       27495 :         for (int i = 1; i <= 12; ++i) {
    8281       25380 :             longl(i) = longl(i - 1) + 15.0;
    8282       25380 :             longh(i) = longh(i - 1) + 15.0;
    8283             :         }
    8284       27495 :         for (int i = 1; i <= 12; ++i) {
    8285       25380 :             longl(-i) = longl(-i + 1) - 15.0;
    8286       25380 :             longh(-i) = longh(-i + 1) - 15.0;
    8287             :         }
    8288        2115 :         Real64 temp = mod(Longitude, 360.0);
    8289        2115 :         if (temp > 180.0) temp -= 180.0;
    8290             :         Real64 tz; // resultant tz meridian
    8291       13388 :         for (int i = -12; i <= 12; ++i) {
    8292       13388 :             if (temp > longl(i) && temp <= longh(i)) {
    8293        2115 :                 tz = i;
    8294        2115 :                 tz = mod(i, 24.0);
    8295        2115 :                 GetSTM = tz;
    8296        2115 :                 break;
    8297             :             }
    8298             :         }
    8299             : 
    8300        4230 :         return GetSTM;
    8301             :     }
    8302             : 
    8303        6088 :     void ProcessEPWHeader(EnergyPlusData &state, EpwHeaderType const headerType, std::string &Line, bool &ErrorsFound)
    8304             :     {
    8305             : 
    8306             :         // SUBROUTINE INFORMATION:
    8307             :         //       AUTHOR         Linda Lawrie
    8308             :         //       DATE WRITTEN   December 1999
    8309             :         //       MODIFIED       na
    8310             :         //       RE-ENGINEERED  na
    8311             : 
    8312             :         // PURPOSE OF THIS SUBROUTINE:
    8313             :         // This subroutine processes each header line in the EPW weather file.
    8314             : 
    8315             :         // METHODOLOGY EMPLOYED:
    8316             :         // File is positioned to the correct line, then backspaced.  This routine
    8317             :         // reads in the line and processes as appropriate.
    8318             : 
    8319             :         WeatherManager::DateType dateType;
    8320             :         int NumHdArgs;
    8321             : 
    8322             :         // Strip off Header value from Line
    8323        6088 :         std::string::size_type Pos = index(Line, ',');
    8324        6088 :         if ((Pos == std::string::npos) && !((headerType == EpwHeaderType::Comments1) || (headerType == EpwHeaderType::Comments2))) {
    8325           0 :             ShowSevereError(state, "Invalid Header line in in.epw -- no commas");
    8326           0 :             ShowContinueError(state, "Line=" + Line);
    8327           0 :             ShowFatalError(state, "Previous conditions cause termination.");
    8328             :         }
    8329        6088 :         if (Pos != std::string::npos) Line.erase(0, Pos + 1);
    8330             : 
    8331        6088 :         switch (headerType) {
    8332         761 :         case WeatherManager::EpwHeaderType::Location: {
    8333             : 
    8334             :             // LOCATION, A1 [City], A2 [State/Province/Region], A3 [Country],
    8335             :             // A4 [Source], N1 [WMO], N2 [Latitude],
    8336             :             // N3 [Longitude], N4 [Time Zone], N5 [Elevation {m}]
    8337             : 
    8338         761 :             NumHdArgs = 9;
    8339        7610 :             for (int i = 1; i <= NumHdArgs; ++i) {
    8340        6849 :                 strip(Line);
    8341        6849 :                 Pos = index(Line, ',');
    8342        6849 :                 if (Pos == std::string::npos) {
    8343         757 :                     if (len(Line) == 0) {
    8344           0 :                         while (Pos == std::string::npos) {
    8345           0 :                             Line = state.files.inputWeatherFile.readLine().data;
    8346           0 :                             strip(Line);
    8347           0 :                             uppercase(Line);
    8348           0 :                             Pos = index(Line, ',');
    8349             :                         }
    8350             :                     } else {
    8351         757 :                         Pos = len(Line);
    8352             :                     }
    8353             :                 }
    8354             : 
    8355        6849 :                 switch (i) {
    8356         761 :                 case 1:
    8357         761 :                     state.dataWeatherManager->EPWHeaderTitle = stripped(Line.substr(0, Pos));
    8358         761 :                     break;
    8359        2283 :                 case 2:
    8360             :                 case 3:
    8361             :                 case 4:
    8362        2283 :                     state.dataWeatherManager->EPWHeaderTitle = strip(state.dataWeatherManager->EPWHeaderTitle) + ' ' + stripped(Line.substr(0, Pos));
    8363        2283 :                     break;
    8364         761 :                 case 5:
    8365         761 :                     state.dataWeatherManager->EPWHeaderTitle += " WMO#=" + stripped(Line.substr(0, Pos));
    8366         761 :                     break;
    8367        3044 :                 case 6:
    8368             :                 case 7:
    8369             :                 case 8:
    8370             :                 case 9: {
    8371             :                     bool errFlag;
    8372        3044 :                     Real64 const Number = UtilityRoutines::ProcessNumber(Line.substr(0, Pos), errFlag);
    8373        3044 :                     if (!errFlag) {
    8374        3044 :                         switch (i) {
    8375         761 :                         case 6:
    8376         761 :                             state.dataWeatherManager->WeatherFileLatitude = Number;
    8377         761 :                             break;
    8378         761 :                         case 7:
    8379         761 :                             state.dataWeatherManager->WeatherFileLongitude = Number;
    8380         761 :                             break;
    8381         761 :                         case 8:
    8382         761 :                             state.dataWeatherManager->WeatherFileTimeZone = Number;
    8383         761 :                             break;
    8384         761 :                         case 9:
    8385         761 :                             state.dataWeatherManager->WeatherFileElevation = Number;
    8386         761 :                             break;
    8387           0 :                         default:
    8388           0 :                             break;
    8389             :                         }
    8390        3044 :                     }
    8391        3044 :                 } break;
    8392           0 :                 default:
    8393           0 :                     ShowSevereError(state, format("GetEPWHeader:LOCATION, invalid numeric={}", Line.substr(0, Pos)));
    8394           0 :                     ErrorsFound = true;
    8395           0 :                     break;
    8396             :                 }
    8397        6849 :                 Line.erase(0, Pos + 1);
    8398             :             }
    8399         761 :             state.dataEnvrn->WeatherFileLocationTitle = stripped(state.dataWeatherManager->EPWHeaderTitle);
    8400         761 :         } break;
    8401         761 :         case WeatherManager::EpwHeaderType::TypicalExtremePeriods: {
    8402         761 :             strip(Line);
    8403         761 :             Pos = index(Line, ',');
    8404         761 :             if (Pos == std::string::npos) {
    8405           0 :                 if (len(Line) == 0) {
    8406           0 :                     while (Pos == std::string::npos && len(Line) == 0) {
    8407           0 :                         Line = state.files.inputWeatherFile.readLine().data;
    8408           0 :                         strip(Line);
    8409           0 :                         Pos = index(Line, ',');
    8410             :                     }
    8411             :                 } else {
    8412           0 :                     Pos = len(Line);
    8413             :                 }
    8414             :             }
    8415             :             bool IOStatus;
    8416         761 :             state.dataWeatherManager->NumEPWTypExtSets = UtilityRoutines::ProcessNumber(Line.substr(0, Pos), IOStatus);
    8417         761 :             Line.erase(0, Pos + 1);
    8418         761 :             state.dataWeatherManager->TypicalExtremePeriods.allocate(state.dataWeatherManager->NumEPWTypExtSets);
    8419         761 :             int TropExtremeCount = 0;
    8420        5198 :             for (int i = 1; i <= state.dataWeatherManager->NumEPWTypExtSets; ++i) {
    8421        4437 :                 strip(Line);
    8422        4437 :                 Pos = index(Line, ',');
    8423        4437 :                 if (Pos != std::string::npos) {
    8424        4437 :                     state.dataWeatherManager->TypicalExtremePeriods(i).Title = Line.substr(0, Pos);
    8425        4437 :                     Line.erase(0, Pos + 1);
    8426             :                 } else {
    8427           0 :                     ShowWarningError(state, format("ProcessEPWHeader: Invalid Typical/Extreme Periods Header(WeatherFile)={}", Line.substr(0, Pos)));
    8428           0 :                     ShowContinueError(state, format("...on processing Typical/Extreme period #{}", i));
    8429           0 :                     state.dataWeatherManager->NumEPWTypExtSets = i - 1;
    8430           0 :                     break;
    8431             :                 }
    8432        4437 :                 Pos = index(Line, ',');
    8433        4437 :                 if (Pos != std::string::npos) {
    8434        4437 :                     state.dataWeatherManager->TypicalExtremePeriods(i).TEType = Line.substr(0, Pos);
    8435        4437 :                     Line.erase(0, Pos + 1);
    8436        4437 :                     if (UtilityRoutines::SameString(state.dataWeatherManager->TypicalExtremePeriods(i).TEType, "EXTREME")) {
    8437        1522 :                         if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO DRY SEASON - WEEK NEAR ANNUAL MAX")) {
    8438           0 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoDrySeasonMax";
    8439        1522 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO DRY SEASON - WEEK NEAR ANNUAL MIN")) {
    8440           0 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoDrySeasonMin";
    8441        1522 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO WET SEASON - WEEK NEAR ANNUAL MAX")) {
    8442           0 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoWetSeasonMax";
    8443        1522 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO WET SEASON - WEEK NEAR ANNUAL MIN")) {
    8444           0 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoWetSeasonMin";
    8445             :                             // to account for problems earlier in weather files:
    8446        1522 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO DRY")) {
    8447           0 :                             if (TropExtremeCount == 0) {
    8448           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).Title = "No Dry Season - Week Near Annual Max";
    8449           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoDrySeasonMax";
    8450           0 :                                 ++TropExtremeCount;
    8451           0 :                             } else if (TropExtremeCount == 1) {
    8452           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).Title = "No Dry Season - Week Near Annual Min";
    8453           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoDrySeasonMin";
    8454           0 :                                 ++TropExtremeCount;
    8455             :                             }
    8456             :                         } else { // make new short titles
    8457        1522 :                             if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "SUMMER")) {
    8458         696 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "Summer";
    8459         826 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "WINTER")) {
    8460         696 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "Winter";
    8461         130 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "TROPICAL HOT")) {
    8462          65 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "TropicalHot";
    8463          65 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "TROPICAL COLD")) {
    8464          65 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "TropicalCold";
    8465           0 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "AUTUMN")) {
    8466           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "Autumn";
    8467           0 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO DRY")) {
    8468           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoDrySeason";
    8469           0 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO WET")) {
    8470           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoWetSeason";
    8471           0 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "WET ")) {
    8472           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "WetSeason";
    8473           0 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "DRY ")) {
    8474           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "DrySeason";
    8475           0 :                             } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "SPRING")) {
    8476           0 :                                 state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "Spring";
    8477             :                             }
    8478             :                         }
    8479             :                     } else { // not extreme
    8480        2915 :                         if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "SUMMER")) {
    8481         696 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "Summer";
    8482        2219 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "WINTER")) {
    8483         696 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "Winter";
    8484        1523 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "TROPICAL HOT")) {
    8485           0 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "TropicalHot";
    8486        1523 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "TROPICAL COLD")) {
    8487           0 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "TropicalCold";
    8488        1523 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "AUTUMN")) {
    8489         696 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "Autumn";
    8490         827 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO DRY")) {
    8491           0 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoDrySeason";
    8492         827 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "NO WET")) {
    8493           1 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "NoWetSeason";
    8494         826 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "WET ")) {
    8495          65 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "WetSeason";
    8496         761 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "DRY ")) {
    8497          65 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "DrySeason";
    8498         696 :                         } else if (has_prefixi(state.dataWeatherManager->TypicalExtremePeriods(i).Title, "SPRING")) {
    8499         696 :                             state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle = "Spring";
    8500             :                         }
    8501             :                     }
    8502             :                 } else {
    8503           0 :                     ShowWarningError(state,
    8504           0 :                                      "ProcessEPWHeader: Invalid Typical/Extreme Periods Header(WeatherFile)=" +
    8505           0 :                                          state.dataWeatherManager->TypicalExtremePeriods(i).Title + " " + Line.substr(0, Pos));
    8506           0 :                     ShowContinueError(state, format("...on processing Typical/Extreme period #{}", i));
    8507           0 :                     state.dataWeatherManager->NumEPWTypExtSets = i - 1;
    8508           0 :                     break;
    8509             :                 }
    8510             :                 int PMonth;
    8511             :                 int PDay;
    8512             :                 int PWeekDay;
    8513        4437 :                 Pos = index(Line, ',');
    8514        4437 :                 if (Pos != std::string::npos) {
    8515        8874 :                     std::string dateStringUC = Line.substr(0, Pos);
    8516        4437 :                     dateStringUC = uppercase(dateStringUC);
    8517        4437 :                     General::ProcessDateString(state, dateStringUC, PMonth, PDay, PWeekDay, dateType, ErrorsFound);
    8518        4437 :                     if (dateType != DateType::Invalid) {
    8519        4437 :                         if (PMonth != 0 && PDay != 0) {
    8520        4437 :                             state.dataWeatherManager->TypicalExtremePeriods(i).StartMonth = PMonth;
    8521        4437 :                             state.dataWeatherManager->TypicalExtremePeriods(i).StartDay = PDay;
    8522             :                         }
    8523             :                     } else {
    8524           0 :                         ShowSevereError(state,
    8525           0 :                                         "ProcessEPWHeader: Invalid Typical/Extreme Periods Start Date Field(WeatherFile)=" + Line.substr(0, Pos));
    8526           0 :                         ShowContinueError(state, format("...on processing Typical/Extreme period #{}", i));
    8527           0 :                         ErrorsFound = true;
    8528             :                     }
    8529        4437 :                     Line.erase(0, Pos + 1);
    8530             :                 }
    8531        4437 :                 Pos = index(Line, ',');
    8532        4437 :                 if (Pos != std::string::npos) {
    8533        7352 :                     std::string dateStringUC = Line.substr(0, Pos);
    8534        3676 :                     dateStringUC = uppercase(dateStringUC);
    8535        3676 :                     General::ProcessDateString(state, dateStringUC, PMonth, PDay, PWeekDay, dateType, ErrorsFound);
    8536        3676 :                     if (dateType != DateType::Invalid) {
    8537        3676 :                         if (PMonth != 0 && PDay != 0) {
    8538        3676 :                             state.dataWeatherManager->TypicalExtremePeriods(i).EndMonth = PMonth;
    8539        3676 :                             state.dataWeatherManager->TypicalExtremePeriods(i).EndDay = PDay;
    8540             :                         }
    8541             :                     } else {
    8542           0 :                         ShowSevereError(state,
    8543           0 :                                         "ProcessEPWHeader: Invalid Typical/Extreme Periods End Date Field(WeatherFile)=" + Line.substr(0, Pos));
    8544           0 :                         ShowContinueError(state, format("...on processing Typical/Extreme period #{}", i));
    8545           0 :                         ErrorsFound = true;
    8546             :                     }
    8547        3676 :                     Line.erase(0, Pos + 1);
    8548             :                 } else { // Pos=0, probably last one
    8549        1522 :                     std::string const dateStringUC = uppercase(Line);
    8550         761 :                     General::ProcessDateString(state, dateStringUC, PMonth, PDay, PWeekDay, dateType, ErrorsFound);
    8551         761 :                     if (dateType != DateType::Invalid) {
    8552         761 :                         if (PMonth != 0 && PDay != 0) {
    8553         761 :                             state.dataWeatherManager->TypicalExtremePeriods(i).EndMonth = PMonth;
    8554         761 :                             state.dataWeatherManager->TypicalExtremePeriods(i).EndDay = PDay;
    8555             :                         }
    8556             :                     } else {
    8557           0 :                         ShowSevereError(state,
    8558           0 :                                         "ProcessEPWHeader: Invalid Typical/Extreme Periods End Date Field(WeatherFile)=" + Line.substr(0, Pos));
    8559           0 :                         ErrorsFound = true;
    8560             :                     }
    8561             :                 }
    8562             :             }
    8563             :             // Process periods to set up other values.
    8564        5198 :             for (int i = 1; i <= state.dataWeatherManager->NumEPWTypExtSets; ++i) {
    8565             :                 // JulianDay (Month,Day,LeapYearValue)
    8566        8874 :                 auto const ExtremePeriodTitle(UtilityRoutines::MakeUPPERCase(state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle));
    8567        4437 :                 if (ExtremePeriodTitle == "SUMMER") {
    8568        1392 :                     if (UtilityRoutines::SameString(state.dataWeatherManager->TypicalExtremePeriods(i).TEType, "EXTREME")) {
    8569         696 :                         state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "SummerExtreme";
    8570         696 :                         state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue1 = "TropicalHot";
    8571         696 :                         state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue2 = "NoDrySeasonMax";
    8572             :                     } else {
    8573         696 :                         state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "SummerTypical";
    8574             :                     }
    8575             : 
    8576        3045 :                 } else if (ExtremePeriodTitle == "WINTER") {
    8577        1392 :                     if (UtilityRoutines::SameString(state.dataWeatherManager->TypicalExtremePeriods(i).TEType, "EXTREME")) {
    8578         696 :                         state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "WinterExtreme";
    8579         696 :                         state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue1 = "TropicalCold";
    8580         696 :                         state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue2 = "NoDrySeasonMin";
    8581             :                     } else {
    8582         696 :                         state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "WinterTypical";
    8583             :                     }
    8584             : 
    8585        1653 :                 } else if (ExtremePeriodTitle == "AUTUMN") {
    8586         696 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "AutumnTypical";
    8587             : 
    8588         957 :                 } else if (ExtremePeriodTitle == "SPRING") {
    8589         696 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "SpringTypical";
    8590             : 
    8591         261 :                 } else if (ExtremePeriodTitle == "WETSEASON") {
    8592          65 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "WetSeason";
    8593             : 
    8594         196 :                 } else if (ExtremePeriodTitle == "DRYSEASON") {
    8595          65 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "DrySeason";
    8596             : 
    8597         131 :                 } else if (ExtremePeriodTitle == "NOWETSEASON") {
    8598           1 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "NoWetSeason";
    8599             : 
    8600         130 :                 } else if (ExtremePeriodTitle == "NODRYSEASON") {
    8601           0 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "NoDrySeason";
    8602             : 
    8603         130 :                 } else if ((ExtremePeriodTitle == "NODRYSEASONMAX") || (ExtremePeriodTitle == "NOWETSEASONMAX")) {
    8604           0 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle;
    8605           0 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue1 = "TropicalHot";
    8606           0 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue2 = "SummerExtreme";
    8607             : 
    8608         130 :                 } else if ((ExtremePeriodTitle == "NODRYSEASONMIN") || (ExtremePeriodTitle == "NOWETSEASONMIN")) {
    8609           0 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = state.dataWeatherManager->TypicalExtremePeriods(i).ShortTitle;
    8610           0 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue1 = "TropicalCold";
    8611           0 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue2 = "WinterExtreme";
    8612             : 
    8613         130 :                 } else if (ExtremePeriodTitle == "TROPICALHOT") {
    8614          65 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "TropicalHot";
    8615          65 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue1 = "SummerExtreme";
    8616          65 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue2 = "NoDrySeasonMax";
    8617             : 
    8618          65 :                 } else if (ExtremePeriodTitle == "TROPICALCOLD") {
    8619          65 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "TropicalCold";
    8620          65 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue1 = "WinterExtreme";
    8621          65 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue2 = "NoDrySeasonMin";
    8622             : 
    8623             :                 } else {
    8624           0 :                     state.dataWeatherManager->TypicalExtremePeriods(i).MatchValue = "Invalid - no match";
    8625             :                 }
    8626        8874 :                 state.dataWeatherManager->TypicalExtremePeriods(i).StartJDay = General::OrdinalDay(
    8627        8874 :                     state.dataWeatherManager->TypicalExtremePeriods(i).StartMonth, state.dataWeatherManager->TypicalExtremePeriods(i).StartDay, 0);
    8628        8874 :                 state.dataWeatherManager->TypicalExtremePeriods(i).EndJDay = General::OrdinalDay(
    8629        8874 :                     state.dataWeatherManager->TypicalExtremePeriods(i).EndMonth, state.dataWeatherManager->TypicalExtremePeriods(i).EndDay, 0);
    8630        4437 :                 if (state.dataWeatherManager->TypicalExtremePeriods(i).StartJDay <= state.dataWeatherManager->TypicalExtremePeriods(i).EndJDay) {
    8631        4431 :                     state.dataWeatherManager->TypicalExtremePeriods(i).TotalDays =
    8632        4431 :                         state.dataWeatherManager->TypicalExtremePeriods(i).EndJDay - state.dataWeatherManager->TypicalExtremePeriods(i).StartJDay + 1;
    8633             :                 } else {
    8634           6 :                     state.dataWeatherManager->TypicalExtremePeriods(i).TotalDays =
    8635          12 :                         General::OrdinalDay(12, 31, state.dataWeatherManager->LeapYearAdd) -
    8636          12 :                         state.dataWeatherManager->TypicalExtremePeriods(i).StartJDay + 1 + state.dataWeatherManager->TypicalExtremePeriods(i).EndJDay;
    8637             :                 }
    8638         761 :             }
    8639         761 :         } break;
    8640         761 :         case WeatherManager::EpwHeaderType::GroundTemperatures: {
    8641             :             // Added for ground surfaces defined with F or c factor method. TH 7/2009
    8642             :             // Assume the 0.5 m set of ground temperatures
    8643             :             // or first set on a weather file, if any.
    8644         761 :             Pos = index(Line, ',');
    8645         761 :             if (Pos != std::string::npos) {
    8646             :                 bool errFlag;
    8647         761 :                 int NumGrndTemps = UtilityRoutines::ProcessNumber(Line.substr(0, Pos), errFlag);
    8648         761 :                 if (!errFlag && NumGrndTemps >= 1) {
    8649         761 :                     Line.erase(0, Pos + 1);
    8650             :                     // skip depth, soil conductivity, soil density, soil specific heat
    8651        3805 :                     for (int i = 1; i <= 4; ++i) {
    8652        3044 :                         Pos = index(Line, ',');
    8653        3044 :                         if (Pos == std::string::npos) {
    8654           0 :                             Line.clear();
    8655           0 :                             break;
    8656             :                         }
    8657        3044 :                         Line.erase(0, Pos + 1);
    8658             :                     }
    8659         761 :                     state.dataWeatherManager->GroundTempsFCFromEPWHeader = 0.0;
    8660         761 :                     int actcount = 0;
    8661        9893 :                     for (int i = 1; i <= 12; ++i) { // take the first set of ground temperatures.
    8662        9132 :                         Pos = index(Line, ',');
    8663        9132 :                         if (Pos != std::string::npos) {
    8664        9132 :                             state.dataWeatherManager->GroundTempsFCFromEPWHeader(i) = UtilityRoutines::ProcessNumber(Line.substr(0, Pos), errFlag);
    8665        9132 :                             ++actcount;
    8666             :                         } else {
    8667           0 :                             if (len(Line) > 0) {
    8668           0 :                                 state.dataWeatherManager->GroundTempsFCFromEPWHeader(i) =
    8669           0 :                                     UtilityRoutines::ProcessNumber(Line.substr(0, Pos), errFlag);
    8670           0 :                                 ++actcount;
    8671             :                             }
    8672           0 :                             break;
    8673             :                         }
    8674        9132 :                         Line.erase(0, Pos + 1);
    8675             :                     }
    8676         761 :                     if (actcount == 12) state.dataWeatherManager->wthFCGroundTemps = true;
    8677             :                 }
    8678             :             }
    8679         761 :         } break;
    8680         761 :         case WeatherManager::EpwHeaderType::HolidaysDST: {
    8681             :             // A1, \field LeapYear Observed
    8682             :             // \type choice
    8683             :             // \key Yes
    8684             :             // \key No
    8685             :             // \note Yes if Leap Year will be observed for this file
    8686             :             // \note No if Leap Year days (29 Feb) should be ignored in this file
    8687             :             // A2, \field Daylight Saving Start Day
    8688             :             // A3, \field Daylight Saving End Day
    8689             :             // N1, \field Number of Holidays
    8690             :             // A4, \field Holiday 1 Name
    8691             :             // A5, \field Holiday 1 Day
    8692             :             // etc.
    8693             :             // Start with Minimum number of NumHdArgs
    8694         761 :             uppercase(Line);
    8695         761 :             NumHdArgs = 4;
    8696         761 :             int CurCount = 0;
    8697        3827 :             for (int i = 1; i <= NumHdArgs; ++i) {
    8698        3066 :                 strip(Line);
    8699        3066 :                 Pos = index(Line, ',');
    8700        3066 :                 if (Pos == std::string::npos) {
    8701         757 :                     if (len(Line) == 0) {
    8702           0 :                         while (Pos == std::string::npos) {
    8703           0 :                             Line = state.files.inputWeatherFile.readLine().data;
    8704           0 :                             strip(Line);
    8705           0 :                             uppercase(Line);
    8706           0 :                             Pos = index(Line, ',');
    8707             :                         }
    8708             :                     } else {
    8709         757 :                         Pos = len(Line);
    8710             :                     }
    8711             :                 }
    8712             : 
    8713             :                 int PMonth;
    8714             :                 int PDay;
    8715             :                 int PWeekDay;
    8716             :                 bool IOStatus;
    8717        3066 :                 if (i == 1) {
    8718         761 :                     state.dataWeatherManager->WFAllowsLeapYears = (Line[0] == 'Y');
    8719        2305 :                 } else if (i == 2) {
    8720             :                     // In this section, we call ProcessDateString, and if that fails, we can recover from it
    8721             :                     // by setting DST to false, so we don't affect ErrorsFound
    8722             : 
    8723             :                     // call ProcessDateString with local bool (unused)
    8724             :                     bool errflag1;
    8725         761 :                     General::ProcessDateString(state, Line.substr(0, Pos), PMonth, PDay, PWeekDay, dateType, errflag1);
    8726         761 :                     if (dateType != DateType::Invalid) {
    8727             :                         // ErrorsFound is still false after ProcessDateString
    8728         761 :                         if (PMonth == 0 && PDay == 0) {
    8729         760 :                             state.dataWeatherManager->EPWDaylightSaving = false;
    8730             :                         } else {
    8731           1 :                             state.dataWeatherManager->EPWDaylightSaving = true;
    8732           1 :                             state.dataWeatherManager->EPWDST.StDateType = dateType;
    8733           1 :                             state.dataWeatherManager->EPWDST.StMon = PMonth;
    8734           1 :                             state.dataWeatherManager->EPWDST.StDay = PDay;
    8735           1 :                             state.dataWeatherManager->EPWDST.StWeekDay = PWeekDay;
    8736             :                         }
    8737             :                     } else {
    8738             :                         // ErrorsFound is untouched
    8739           0 :                         ShowContinueError(
    8740           0 :                             state, format("ProcessEPWHeader: Invalid Daylight Saving Period Start Date Field(WeatherFile)={}", Line.substr(0, Pos)));
    8741           0 :                         ShowContinueError(state, format("...invalid header={}", epwHeaders[static_cast<int>(headerType)]));
    8742           0 :                         ShowContinueError(state, "...Setting Weather File DST to false.");
    8743           0 :                         state.dataWeatherManager->EPWDaylightSaving = false;
    8744             :                     }
    8745             : 
    8746        1544 :                 } else if (i == 3) {
    8747         761 :                     General::ProcessDateString(state, Line.substr(0, Pos), PMonth, PDay, PWeekDay, dateType, ErrorsFound);
    8748         761 :                     if (state.dataWeatherManager->EPWDaylightSaving) {
    8749           1 :                         if (dateType != DateType::Invalid) {
    8750           1 :                             state.dataWeatherManager->EPWDST.EnDateType = dateType;
    8751           1 :                             state.dataWeatherManager->EPWDST.EnMon = PMonth;
    8752           1 :                             state.dataWeatherManager->EPWDST.EnDay = PDay;
    8753           1 :                             state.dataWeatherManager->EPWDST.EnWeekDay = PWeekDay;
    8754             :                         } else {
    8755           0 :                             ShowWarningError(
    8756             :                                 state,
    8757           0 :                                 format("ProcessEPWHeader: Invalid Daylight Saving Period End Date Field(WeatherFile)={}", Line.substr(0, Pos)));
    8758           0 :                             ShowContinueError(state, "...Setting Weather File DST to false.");
    8759           0 :                             state.dataWeatherManager->EPWDaylightSaving = false;
    8760             :                         }
    8761           1 :                         state.dataWeatherManager->DST = state.dataWeatherManager->EPWDST;
    8762             :                     }
    8763             : 
    8764         783 :                 } else if (i == 4) {
    8765         761 :                     int NumEPWHolidays = UtilityRoutines::ProcessNumber(Line.substr(0, Pos), IOStatus);
    8766         761 :                     state.dataWeatherManager->NumSpecialDays =
    8767        1522 :                         NumEPWHolidays + state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "RunPeriodControl:SpecialDays");
    8768         761 :                     state.dataWeatherManager->SpecialDays.allocate(state.dataWeatherManager->NumSpecialDays);
    8769         761 :                     NumHdArgs = 4 + NumEPWHolidays * 2;
    8770             : 
    8771          22 :                 } else if ((i >= 5)) {
    8772          22 :                     if (mod(i, 2) != 0) {
    8773          11 :                         ++CurCount;
    8774          11 :                         if (CurCount > state.dataWeatherManager->NumSpecialDays) {
    8775           0 :                             ShowSevereError(state, "Too many SpecialDays");
    8776           0 :                             ErrorsFound = true;
    8777             :                         } else {
    8778          11 :                             state.dataWeatherManager->SpecialDays(CurCount).Name = Line.substr(0, Pos);
    8779             :                         }
    8780             :                         // Process name
    8781             :                     } else {
    8782          11 :                         if (CurCount <= state.dataWeatherManager->NumSpecialDays) {
    8783             :                             // Process date
    8784          11 :                             General::ProcessDateString(state, Line.substr(0, Pos), PMonth, PDay, PWeekDay, dateType, ErrorsFound);
    8785          11 :                             if (dateType == DateType::MonthDay) {
    8786           6 :                                 state.dataWeatherManager->SpecialDays(CurCount).DateType = dateType;
    8787           6 :                                 state.dataWeatherManager->SpecialDays(CurCount).Month = PMonth;
    8788           6 :                                 state.dataWeatherManager->SpecialDays(CurCount).Day = PDay;
    8789           6 :                                 state.dataWeatherManager->SpecialDays(CurCount).WeekDay = 0;
    8790           6 :                                 state.dataWeatherManager->SpecialDays(CurCount).CompDate = PMonth * 32 + PDay;
    8791           6 :                                 state.dataWeatherManager->SpecialDays(CurCount).Duration = 1;
    8792           6 :                                 state.dataWeatherManager->SpecialDays(CurCount).DayType = 1;
    8793           6 :                                 state.dataWeatherManager->SpecialDays(CurCount).WthrFile = true;
    8794           5 :                             } else if (dateType != DateType::Invalid) {
    8795           5 :                                 state.dataWeatherManager->SpecialDays(CurCount).DateType = dateType;
    8796           5 :                                 state.dataWeatherManager->SpecialDays(CurCount).Month = PMonth;
    8797           5 :                                 state.dataWeatherManager->SpecialDays(CurCount).Day = PDay;
    8798           5 :                                 state.dataWeatherManager->SpecialDays(CurCount).WeekDay = PWeekDay;
    8799           5 :                                 state.dataWeatherManager->SpecialDays(CurCount).CompDate = 0;
    8800           5 :                                 state.dataWeatherManager->SpecialDays(CurCount).Duration = 1;
    8801           5 :                                 state.dataWeatherManager->SpecialDays(CurCount).DayType = 1;
    8802           5 :                                 state.dataWeatherManager->SpecialDays(CurCount).WthrFile = true;
    8803           0 :                             } else if (dateType == DateType::Invalid) {
    8804           0 :                                 ShowSevereError(state, format("Invalid SpecialDay Date Field(WeatherFile)={}", Line.substr(0, Pos)));
    8805           0 :                                 ErrorsFound = true;
    8806             :                             }
    8807             :                         }
    8808             :                     }
    8809             :                 }
    8810        3066 :                 Line.erase(0, Pos + 1);
    8811             :             }
    8812        5198 :             for (int i = 1; i <= state.dataWeatherManager->NumEPWTypExtSets; ++i) {
    8813             :                 // General::OrdinalDay (Month,Day,LeapYearValue)
    8814        4437 :                 state.dataWeatherManager->TypicalExtremePeriods(i).StartJDay =
    8815        8874 :                     General::OrdinalDay(state.dataWeatherManager->TypicalExtremePeriods(i).StartMonth,
    8816        4437 :                                         state.dataWeatherManager->TypicalExtremePeriods(i).StartDay,
    8817        4437 :                                         state.dataWeatherManager->LeapYearAdd);
    8818        4437 :                 state.dataWeatherManager->TypicalExtremePeriods(i).EndJDay =
    8819        8874 :                     General::OrdinalDay(state.dataWeatherManager->TypicalExtremePeriods(i).EndMonth,
    8820        4437 :                                         state.dataWeatherManager->TypicalExtremePeriods(i).EndDay,
    8821        4437 :                                         state.dataWeatherManager->LeapYearAdd);
    8822        4437 :                 if (state.dataWeatherManager->TypicalExtremePeriods(i).StartJDay <= state.dataWeatherManager->TypicalExtremePeriods(i).EndJDay) {
    8823        4431 :                     state.dataWeatherManager->TypicalExtremePeriods(i).TotalDays =
    8824        4431 :                         state.dataWeatherManager->TypicalExtremePeriods(i).EndJDay - state.dataWeatherManager->TypicalExtremePeriods(i).StartJDay + 1;
    8825             :                 } else {
    8826           6 :                     state.dataWeatherManager->TypicalExtremePeriods(i).TotalDays =
    8827          12 :                         General::OrdinalDay(12, 31, state.dataWeatherManager->LeapYearAdd) -
    8828          12 :                         state.dataWeatherManager->TypicalExtremePeriods(i).StartJDay + 1 + state.dataWeatherManager->TypicalExtremePeriods(i).EndJDay;
    8829             :                 }
    8830         761 :             }
    8831         761 :         } break;
    8832        2283 :         case WeatherManager::EpwHeaderType::Comments1:
    8833             :         case WeatherManager::EpwHeaderType::Comments2:
    8834             :         case WeatherManager::EpwHeaderType::DesignConditions: {
    8835             :             // no action
    8836        2283 :         } break;
    8837         761 :         case WeatherManager::EpwHeaderType::DataPeriods: {
    8838             :             //     N1, \field Number of Data Periods
    8839             :             //     N2, \field Number of Records per hour
    8840             :             //     A1, \field Data Period 1 Name/Description
    8841             :             //     A2, \field Data Period 1 Start Day of Week
    8842             :             //       \type choice
    8843             :             //       \key  Sunday
    8844             :             //       \key  Monday
    8845             :             //       \key  Tuesday
    8846             :             //       \key  Wednesday
    8847             :             //       \key  Thursday
    8848             :             //       \key  Friday
    8849             :             //       \key  Saturday
    8850             :             //     A3, \field Data Period 1 Start Day
    8851             :             //     A4, \field Data Period 1 End Day
    8852         761 :             uppercase(Line);
    8853         761 :             NumHdArgs = 2;
    8854         761 :             int CurCount = 0;
    8855        5327 :             for (int i = 1; i <= NumHdArgs; ++i) {
    8856        4566 :                 strip(Line);
    8857        4566 :                 Pos = index(Line, ',');
    8858        4566 :                 if (Pos == std::string::npos) {
    8859         761 :                     if (len(Line) == 0) {
    8860           0 :                         while (Pos == std::string::npos) {
    8861           0 :                             Line = state.files.inputWeatherFile.readLine().data;
    8862           0 :                             strip(Line);
    8863           0 :                             uppercase(Line);
    8864           0 :                             Pos = index(Line, ',');
    8865             :                         }
    8866             :                     } else {
    8867         761 :                         Pos = len(Line);
    8868             :                     }
    8869             :                 }
    8870             : 
    8871             :                 bool IOStatus;
    8872        4566 :                 if (i == 1) {
    8873         761 :                     state.dataWeatherManager->NumDataPeriods = UtilityRoutines::ProcessNumber(Line.substr(0, Pos), IOStatus);
    8874         761 :                     state.dataWeatherManager->DataPeriods.allocate(state.dataWeatherManager->NumDataPeriods);
    8875         761 :                     NumHdArgs += 4 * state.dataWeatherManager->NumDataPeriods;
    8876         761 :                     if (state.dataWeatherManager->NumDataPeriods > 0) {
    8877        1522 :                         for (auto &e : state.dataWeatherManager->DataPeriods)
    8878         761 :                             e.NumDays = 0;
    8879             :                     }
    8880             : 
    8881        3805 :                 } else if (i == 2) {
    8882         761 :                     state.dataWeatherManager->NumIntervalsPerHour = UtilityRoutines::ProcessNumber(Line.substr(0, Pos), IOStatus);
    8883        3044 :                 } else if (i >= 3) {
    8884        3044 :                     int const CurOne = mod(i - 3, 4);
    8885             :                     int PMonth;
    8886             :                     int PDay;
    8887             :                     int PWeekDay;
    8888             :                     int PYear;
    8889        3044 :                     if (CurOne == 0) {
    8890             :                         // Description of Data Period
    8891         761 :                         ++CurCount;
    8892         761 :                         if (CurCount > state.dataWeatherManager->NumDataPeriods) {
    8893           0 :                             ShowSevereError(state, "Too many data periods");
    8894           0 :                             ErrorsFound = true;
    8895             :                         } else {
    8896         761 :                             state.dataWeatherManager->DataPeriods(CurCount).Name = Line.substr(0, Pos);
    8897             :                         }
    8898             : 
    8899        2283 :                     } else if (CurOne == 1) {
    8900             :                         // Start Day of Week
    8901         761 :                         if (CurCount <= state.dataWeatherManager->NumDataPeriods) {
    8902         761 :                             state.dataWeatherManager->DataPeriods(CurCount).DayOfWeek = Line.substr(0, Pos);
    8903         761 :                             state.dataWeatherManager->DataPeriods(CurCount).WeekDay =
    8904        1522 :                                 getEnumerationValue(ScheduleManager::dayTypeNamesUC, state.dataWeatherManager->DataPeriods(CurCount).DayOfWeek);
    8905        1522 :                             if (state.dataWeatherManager->DataPeriods(CurCount).WeekDay < 1 ||
    8906         761 :                                 state.dataWeatherManager->DataPeriods(CurCount).WeekDay > 7) {
    8907           0 :                                 ShowSevereError(state,
    8908           0 :                                                 fmt::format("Weather File -- Invalid Start Day of Week for Data Period #{}, Invalid day={}",
    8909             :                                                             CurCount,
    8910           0 :                                                             state.dataWeatherManager->DataPeriods(CurCount).DayOfWeek));
    8911           0 :                                 ErrorsFound = true;
    8912             :                             }
    8913             :                         }
    8914             : 
    8915        1522 :                     } else if (CurOne == 2) {
    8916             :                         // DataPeriod Start Day
    8917         761 :                         if (CurCount <= state.dataWeatherManager->NumDataPeriods) {
    8918         761 :                             General::ProcessDateString(state, Line.substr(0, Pos), PMonth, PDay, PWeekDay, dateType, ErrorsFound, PYear);
    8919         761 :                             if (dateType == DateType::MonthDay) {
    8920         761 :                                 state.dataWeatherManager->DataPeriods(CurCount).StMon = PMonth;
    8921         761 :                                 state.dataWeatherManager->DataPeriods(CurCount).StDay = PDay;
    8922         761 :                                 state.dataWeatherManager->DataPeriods(CurCount).StYear = PYear;
    8923         761 :                                 if (PYear != 0) state.dataWeatherManager->DataPeriods(CurCount).HasYearData = true;
    8924             :                             } else {
    8925           0 :                                 ShowSevereError(state,
    8926           0 :                                                 format("Data Periods must be of the form <DayOfYear> or <Month Day> (WeatherFile), found={}",
    8927           0 :                                                        Line.substr(0, Pos)));
    8928           0 :                                 ErrorsFound = true;
    8929             :                             }
    8930             :                         }
    8931             : 
    8932         761 :                     } else if (CurOne == 3) {
    8933         761 :                         if (CurCount <= state.dataWeatherManager->NumDataPeriods) {
    8934         761 :                             General::ProcessDateString(state, Line.substr(0, Pos), PMonth, PDay, PWeekDay, dateType, ErrorsFound, PYear);
    8935         761 :                             if (dateType == DateType::MonthDay) {
    8936         761 :                                 state.dataWeatherManager->DataPeriods(CurCount).EnMon = PMonth;
    8937         761 :                                 state.dataWeatherManager->DataPeriods(CurCount).EnDay = PDay;
    8938         761 :                                 state.dataWeatherManager->DataPeriods(CurCount).EnYear = PYear;
    8939         761 :                                 if (PYear == 0 && state.dataWeatherManager->DataPeriods(CurCount).HasYearData) {
    8940           0 :                                     ShowWarningError(state, "Data Period (WeatherFile) - Start Date contains year. End Date does not.");
    8941           0 :                                     ShowContinueError(state, "...Assuming same year as Start Date for this data.");
    8942           0 :                                     state.dataWeatherManager->DataPeriods(CurCount).EnYear = state.dataWeatherManager->DataPeriods(CurCount).StYear;
    8943             :                                 }
    8944             :                             } else {
    8945           0 :                                 ShowSevereError(state,
    8946           0 :                                                 format("Data Periods must be of the form <DayOfYear> or <Month Day>, (WeatherFile) found={}",
    8947           0 :                                                        Line.substr(0, Pos)));
    8948           0 :                                 ErrorsFound = true;
    8949             :                             }
    8950             :                         }
    8951         761 :                         if (state.dataWeatherManager->DataPeriods(CurCount).StYear == 0 ||
    8952           0 :                             state.dataWeatherManager->DataPeriods(CurCount).EnYear == 0) {
    8953         761 :                             state.dataWeatherManager->DataPeriods(CurCount).DataStJDay =
    8954        1522 :                                 General::OrdinalDay(state.dataWeatherManager->DataPeriods(CurCount).StMon,
    8955         761 :                                                     state.dataWeatherManager->DataPeriods(CurCount).StDay,
    8956         761 :                                                     state.dataWeatherManager->LeapYearAdd);
    8957         761 :                             state.dataWeatherManager->DataPeriods(CurCount).DataEnJDay =
    8958        1522 :                                 General::OrdinalDay(state.dataWeatherManager->DataPeriods(CurCount).EnMon,
    8959         761 :                                                     state.dataWeatherManager->DataPeriods(CurCount).EnDay,
    8960         761 :                                                     state.dataWeatherManager->LeapYearAdd);
    8961        1522 :                             if (state.dataWeatherManager->DataPeriods(CurCount).DataStJDay <=
    8962         761 :                                 state.dataWeatherManager->DataPeriods(CurCount).DataEnJDay) {
    8963        2283 :                                 state.dataWeatherManager->DataPeriods(CurCount).NumDays = state.dataWeatherManager->DataPeriods(CurCount).DataEnJDay -
    8964        1522 :                                                                                           state.dataWeatherManager->DataPeriods(CurCount).DataStJDay +
    8965             :                                                                                           1;
    8966             :                             } else {
    8967           0 :                                 state.dataWeatherManager->DataPeriods(CurCount).NumDays =
    8968           0 :                                     (365 - state.dataWeatherManager->DataPeriods(CurCount).DataStJDay + 1) +
    8969           0 :                                     (state.dataWeatherManager->DataPeriods(CurCount).DataEnJDay - 1 + 1);
    8970             :                             }
    8971             :                         } else { // weather file has actual year(s)
    8972           0 :                             auto &dataPeriod{state.dataWeatherManager->DataPeriods(CurCount)};
    8973           0 :                             dataPeriod.DataStJDay = computeJulianDate(dataPeriod.StYear, dataPeriod.StMon, dataPeriod.StDay);
    8974           0 :                             dataPeriod.DataEnJDay = computeJulianDate(dataPeriod.EnYear, dataPeriod.EnMon, dataPeriod.EnDay);
    8975           0 :                             dataPeriod.NumDays = dataPeriod.DataEnJDay - dataPeriod.DataStJDay + 1;
    8976             :                         }
    8977             :                         // Have processed the last item for this, can set up Weekdays for months
    8978         761 :                         state.dataWeatherManager->DataPeriods(CurCount).MonWeekDay = 0;
    8979         761 :                         if (!ErrorsFound) {
    8980        3044 :                             SetupWeekDaysByMonth(state,
    8981         761 :                                                  state.dataWeatherManager->DataPeriods(CurCount).StMon,
    8982         761 :                                                  state.dataWeatherManager->DataPeriods(CurCount).StDay,
    8983         761 :                                                  state.dataWeatherManager->DataPeriods(CurCount).WeekDay,
    8984         761 :                                                  state.dataWeatherManager->DataPeriods(CurCount).MonWeekDay);
    8985             :                         }
    8986             :                     }
    8987             :                 }
    8988        4566 :                 Line.erase(0, Pos + 1);
    8989         761 :             }
    8990         761 :         } break;
    8991           0 :         default: {
    8992             :             // Invalid header type
    8993           0 :             assert(false);
    8994             :         } break;
    8995             :         }
    8996        6088 :     }
    8997             : 
    8998        4794 :     void SkipEPlusWFHeader(EnergyPlusData &state)
    8999             :     {
    9000             : 
    9001             :         // SUBROUTINE INFORMATION:
    9002             :         //       AUTHOR         Linda K. Lawrie
    9003             :         //       DATE WRITTEN   August 2000
    9004             :         //       MODIFIED       na
    9005             :         //       RE-ENGINEERED  na
    9006             : 
    9007             :         // PURPOSE OF THIS SUBROUTINE:
    9008             :         // This subroutine skips the initial header records on the EnergyPlus Weather File (in.epw).
    9009             : 
    9010             :         static constexpr std::string_view Header("DATA PERIODS");
    9011             : 
    9012             :         // Read in Header Information
    9013        9588 :         InputFile::ReadResult<std::string> Line{"", true, false};
    9014             : 
    9015             :         // Headers should come in order
    9016             :         while (true) {
    9017       71910 :             Line = state.files.inputWeatherFile.readLine();
    9018       38352 :             if (Line.eof) {
    9019           0 :                 ShowFatalError(state,
    9020           0 :                                "Unexpected End-of-File on EPW Weather file, while reading header information, looking for header=" +
    9021           0 :                                    std::string{Header},
    9022           0 :                                OptionalOutputFileRef{state.files.eso});
    9023             :             }
    9024       38352 :             uppercase(Line.data);
    9025       38352 :             if (has(Line.data, Header)) break;
    9026             :         }
    9027             : 
    9028             :         // Dummy process Data Periods line
    9029             :         //  'DATA PERIODS'
    9030             :         //     N1, \field Number of Data Periods
    9031             :         //     N2, \field Number of Records per hour
    9032             :         //     A1, \field Data Period 1 Name/Description
    9033             :         //     A2, \field Data Period 1 Start Day of Week
    9034             :         //       \type choice
    9035             :         //       \key  Sunday
    9036             :         //       \key  Monday
    9037             :         //       \key  Tuesday
    9038             :         //       \key  Wednesday
    9039             :         //       \key  Thursday
    9040             :         //       \key  Friday
    9041             :         //       \key  Saturday
    9042             :         //     A3, \field Data Period 1 Start Day
    9043             :         //     A4, \field Data Period 1 End Day
    9044             : 
    9045        4794 :         int NumHdArgs = 2;
    9046        4794 :         int CurCount = 0;
    9047       14382 :         for (int i = 1; i <= NumHdArgs; ++i) {
    9048        9588 :             strip(Line.data);
    9049        9588 :             std::string::size_type Pos = index(Line.data, ',');
    9050        9588 :             if (Pos == std::string::npos) {
    9051           0 :                 if (len(Line.data) == 0) {
    9052           0 :                     while (Pos == std::string::npos) {
    9053           0 :                         Line = state.files.inputWeatherFile.readLine();
    9054           0 :                         strip(Line.data);
    9055           0 :                         uppercase(Line.data);
    9056           0 :                         Pos = index(Line.data, ',');
    9057             :                     }
    9058             :                 } else {
    9059           0 :                     Pos = len(Line.data);
    9060             :                 }
    9061             :             }
    9062             : 
    9063        9588 :             if (i == 1) {
    9064             :                 bool IOStatus;
    9065        4794 :                 int const NumPeriods = UtilityRoutines::ProcessNumber(Line.data.substr(0, Pos), IOStatus);
    9066        4794 :                 NumHdArgs += 4 * NumPeriods;
    9067        4794 :             } else if ((i >= 3)) {
    9068           0 :                 if (mod(i - 3, 4) == 0) ++CurCount;
    9069             :             }
    9070        9588 :             Line.data.erase(0, Pos + 1);
    9071             :         }
    9072        4794 :     }
    9073             : 
    9074        1186 :     void ReportMissing_RangeData(EnergyPlusData &state)
    9075             :     {
    9076             : 
    9077             :         // SUBROUTINE INFORMATION:
    9078             :         //       AUTHOR         Linda Lawrie
    9079             :         //       DATE WRITTEN   January 2002
    9080             :         //       MODIFIED       na
    9081             :         //       RE-ENGINEERED  na
    9082             : 
    9083             :         // PURPOSE OF THIS SUBROUTINE:
    9084             :         // This subroutine reports the counts of missing/out of range data
    9085             :         // for weather file environments.
    9086             : 
    9087             :         static constexpr std::string_view MissString("Missing Data Found on Weather Data File");
    9088             :         static constexpr std::string_view msFmt("Missing {}, Number of items={:5}");
    9089             :         static constexpr std::string_view InvString("Invalid Data Found on Weather Data File");
    9090             :         static constexpr std::string_view ivFmt("Invalid {}, Number of items={:5}");
    9091             :         static constexpr std::string_view RangeString("Out of Range Data Found on Weather Data File");
    9092             :         static constexpr std::string_view rgFmt("Out of Range {} [{},{}], Number of items={:5}");
    9093             : 
    9094        1186 :         if (!state.dataEnvrn->DisplayWeatherMissingDataWarnings) return;
    9095             : 
    9096           0 :         bool MissedHeader = false;
    9097           0 :         auto missedHeaderCheck{[&](Real64 const value, std::string const &description) {
    9098           0 :             if (value > 0) {
    9099           0 :                 if (!MissedHeader) {
    9100           0 :                     ShowWarningError(state, std::string{MissString});
    9101           0 :                     MissedHeader = true;
    9102             :                 }
    9103           0 :                 ShowMessage(state, format(msFmt, "\"" + description + "\"", value));
    9104             :             }
    9105           0 :         }};
    9106             : 
    9107           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.DryBulb, "Dry Bulb Temperature");
    9108           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.StnPres, "Atmospheric Pressure");
    9109           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.RelHumid, "Relative Humidity");
    9110           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.DewPoint, "Dew Point Temperatures");
    9111           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.WindSpd, "Wind Speed");
    9112           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.WindDir, "Wind Direction");
    9113           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.DirectRad, "Direct Radiation");
    9114           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.DiffuseRad, "Diffuse Radiation");
    9115           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.TotSkyCvr, "Total Sky Cover");
    9116           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.OpaqSkyCvr, "Opaque Sky Cover");
    9117           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.SnowDepth, "Snow Depth");
    9118           0 :         if (state.dataWeatherManager->Missed.WeathCodes > 0) {
    9119           0 :             ShowWarningError(state, std::string{InvString});
    9120           0 :             ShowMessage(state, format(ivFmt, "\"Weather Codes\" (not equal 9 digits)", state.dataWeatherManager->Missed.WeathCodes));
    9121             :         }
    9122           0 :         missedHeaderCheck(state.dataWeatherManager->Missed.LiquidPrecip, "Liquid Precipitation Depth");
    9123             : 
    9124           0 :         bool OutOfRangeHeader = false;
    9125             :         auto outOfRangeHeaderCheck{
    9126           0 :             [&](Real64 const value, std::string_view description, std::string_view rangeLow, std::string_view rangeHigh, std::string_view extraMsg) {
    9127           0 :                 if (value > 0) {
    9128           0 :                     if (!OutOfRangeHeader) {
    9129           0 :                         ShowWarningError(state, std::string{RangeString});
    9130           0 :                         OutOfRangeHeader = true;
    9131             :                     }
    9132           0 :                     ShowMessage(state, EnergyPlus::format(rgFmt, description, rangeLow, rangeHigh, value));
    9133           0 :                     if (!extraMsg.empty()) ShowMessage(state, std::string{extraMsg});
    9134             :                 }
    9135           0 :             }};
    9136           0 :         outOfRangeHeaderCheck(state.dataWeatherManager->OutOfRange.DryBulb, "Dry Bulb Temperatures", ">=-90", "<=70", "");
    9137           0 :         outOfRangeHeaderCheck(
    9138           0 :             state.dataWeatherManager->OutOfRange.StnPres, "Atmospheric Pressure", ">31000", "<=120000", "Out of Range values set to last good value");
    9139           0 :         outOfRangeHeaderCheck(state.dataWeatherManager->OutOfRange.RelHumid, "Relative Humidity", ">=0", "<=110", "");
    9140           0 :         outOfRangeHeaderCheck(state.dataWeatherManager->OutOfRange.DewPoint, "Dew Point Temperatures", ">=-90", "<=70", "");
    9141           0 :         outOfRangeHeaderCheck(state.dataWeatherManager->OutOfRange.WindSpd, "Wind Speed", ">=0", "<=40", "");
    9142           0 :         outOfRangeHeaderCheck(state.dataWeatherManager->OutOfRange.WindDir, "Wind Direction", ">=0", "<=360", "");
    9143           0 :         outOfRangeHeaderCheck(state.dataWeatherManager->OutOfRange.DirectRad, "Direct Radiation", ">=0", "NoLimit", "");
    9144           0 :         outOfRangeHeaderCheck(state.dataWeatherManager->OutOfRange.DiffuseRad, "Diffuse Radiation", ">=0", "NoLimit", "");
    9145             :     }
    9146             : 
    9147         771 :     void SetupInterpolationValues(EnergyPlusData &state)
    9148             :     {
    9149             : 
    9150             :         // SUBROUTINE INFORMATION:
    9151             :         //       AUTHOR         Linda Lawrie
    9152             :         //       DATE WRITTEN   November 2002
    9153             :         //       MODIFIED       na
    9154             :         //       RE-ENGINEERED  na
    9155             : 
    9156             :         // PURPOSE OF THIS SUBROUTINE:
    9157             :         // This subroutine creates the "interpolation" values / weights that are used for
    9158             :         // interpolating weather data from hourly down to the time step level.
    9159             : 
    9160             :         // METHODOLOGY EMPLOYED:
    9161             :         // Create arrays (InterpolationValues, SolarInterpolationValues) dependent on
    9162             :         // Number of Time Steps in Hour.  This will be used in the "SetCurrentWeather" procedure.
    9163             : 
    9164         771 :         int halfpoint = 0;
    9165             : 
    9166         771 :         state.dataWeatherManager->Interpolation.allocate(state.dataGlobal->NumOfTimeStepInHour);
    9167         771 :         state.dataWeatherManager->SolarInterpolation.allocate(state.dataGlobal->NumOfTimeStepInHour);
    9168         771 :         state.dataWeatherManager->Interpolation = 0.0;
    9169         771 :         state.dataWeatherManager->SolarInterpolation = 0.0;
    9170             : 
    9171        5171 :         for (int tloop = 1; tloop <= state.dataGlobal->NumOfTimeStepInHour; ++tloop) {
    9172        4400 :             state.dataWeatherManager->Interpolation(tloop) =
    9173        4400 :                 (state.dataGlobal->NumOfTimeStepInHour == 1) ? 1.0 : min(1.0, (double(tloop) / double(state.dataGlobal->NumOfTimeStepInHour)));
    9174             :         }
    9175             : 
    9176         771 :         if (mod(state.dataGlobal->NumOfTimeStepInHour, 2) == 0) {
    9177             :             // even number of time steps.
    9178         759 :             halfpoint = state.dataGlobal->NumOfTimeStepInHour / 2;
    9179         759 :             state.dataWeatherManager->SolarInterpolation(halfpoint) = 1.0;
    9180         759 :             Real64 tweight = 1.0 / double(state.dataGlobal->NumOfTimeStepInHour);
    9181        2953 :             for (int tloop = halfpoint + 1, hpoint = 1; tloop <= state.dataGlobal->NumOfTimeStepInHour; ++tloop, ++hpoint) {
    9182        2194 :                 state.dataWeatherManager->SolarInterpolation(tloop) = 1.0 - hpoint * tweight;
    9183             :             }
    9184        2194 :             for (int tloop = halfpoint - 1, hpoint = 1; tloop >= 1; --tloop, ++hpoint) {
    9185        1435 :                 state.dataWeatherManager->SolarInterpolation(tloop) = 1.0 - hpoint * tweight;
    9186             :             }
    9187             :         } else { // odd number of time steps
    9188          12 :             if (state.dataGlobal->NumOfTimeStepInHour == 1) {
    9189          12 :                 state.dataWeatherManager->SolarInterpolation(1) = 0.5;
    9190           0 :             } else if (state.dataGlobal->NumOfTimeStepInHour == 3) {
    9191           0 :                 state.dataWeatherManager->SolarInterpolation(1) = 5.0 / 6.0;
    9192           0 :                 state.dataWeatherManager->SolarInterpolation(2) = 5.0 / 6.0;
    9193           0 :                 state.dataWeatherManager->SolarInterpolation(3) = 0.5;
    9194             :             } else {
    9195           0 :                 Real64 tweight = 1.0 / double(state.dataGlobal->NumOfTimeStepInHour);
    9196           0 :                 halfpoint = state.dataGlobal->NumOfTimeStepInHour / 2;
    9197           0 :                 Real64 tweight1 = 1.0 - tweight / 2.0;
    9198           0 :                 state.dataWeatherManager->SolarInterpolation(halfpoint) = tweight1;
    9199           0 :                 state.dataWeatherManager->SolarInterpolation(halfpoint + 1) = tweight1;
    9200           0 :                 for (int tloop = halfpoint + 2, hpoint = 1; tloop <= state.dataGlobal->NumOfTimeStepInHour; ++tloop, ++hpoint) {
    9201           0 :                     state.dataWeatherManager->SolarInterpolation(tloop) = tweight1 - hpoint * tweight;
    9202             :                 }
    9203           0 :                 for (int tloop = halfpoint - 1, hpoint = 1; tloop >= 1; --tloop, ++hpoint) {
    9204           0 :                     state.dataWeatherManager->SolarInterpolation(tloop) = tweight1 - hpoint * tweight;
    9205             :                 }
    9206             :             }
    9207             :         }
    9208         771 :     }
    9209             : 
    9210         772 :     void SetupEnvironmentTypes(EnergyPlusData &state)
    9211             :     {
    9212             : 
    9213             :         // SUBROUTINE INFORMATION:
    9214             :         //       AUTHOR         Linda Lawrie
    9215             :         //       DATE WRITTEN   October 2010
    9216             :         //       MODIFIED       na
    9217             :         //       RE-ENGINEERED  na
    9218             : 
    9219             :         // PURPOSE OF THIS SUBROUTINE:
    9220             :         // Make sure Environment derived type is set prior to getting
    9221             :         // Weather Properties
    9222             : 
    9223             :         // Transfer weather file information to the Environment derived type
    9224         772 :         state.dataWeatherManager->Envrn = state.dataEnvrn->TotDesDays + 1;
    9225             : 
    9226             :         // Sizing Periods from Weather File
    9227         777 :         for (int i = 1; i <= state.dataWeatherManager->TotRunDesPers; ++i) {
    9228           5 :             auto &env = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn);
    9229           5 :             auto &runPer = state.dataWeatherManager->RunPeriodDesignInput(i);
    9230             : 
    9231           5 :             env.StartMonth = runPer.startMonth;
    9232           5 :             env.StartDay = runPer.startDay;
    9233           5 :             env.StartJDay = General::OrdinalDay(runPer.startMonth, runPer.startDay, state.dataWeatherManager->LeapYearAdd);
    9234           5 :             env.TotalDays = runPer.totalDays;
    9235           5 :             env.EndMonth = runPer.endMonth;
    9236           5 :             env.EndDay = runPer.endDay;
    9237           5 :             env.EndJDay = General::OrdinalDay(runPer.endMonth, runPer.endDay, state.dataWeatherManager->LeapYearAdd);
    9238           5 :             env.NumSimYears = runPer.numSimYears;
    9239           5 :             if (env.StartJDay <= env.EndJDay) {
    9240           5 :                 env.TotalDays = (env.EndJDay - env.StartJDay + 1) * env.NumSimYears;
    9241             :             } else {
    9242           0 :                 env.TotalDays =
    9243           0 :                     (General::OrdinalDay(12, 31, state.dataWeatherManager->LeapYearAdd) - env.StartJDay + 1 + env.EndJDay) * env.NumSimYears;
    9244             :             }
    9245           5 :             state.dataEnvrn->TotRunDesPersDays += env.TotalDays;
    9246           5 :             env.UseDST = runPer.useDST;
    9247           5 :             env.UseHolidays = runPer.useHolidays;
    9248           5 :             env.Title = runPer.title;
    9249           5 :             env.cKindOfEnvrn = runPer.periodType;
    9250           5 :             env.KindOfEnvrn = DataGlobalConstants::KindOfSim::RunPeriodDesign;
    9251           5 :             env.DesignDayNum = 0;
    9252           5 :             env.RunPeriodDesignNum = i;
    9253           5 :             env.DayOfWeek = runPer.dayOfWeek;
    9254           5 :             env.MonWeekDay = runPer.monWeekDay;
    9255           5 :             env.SetWeekDays = false;
    9256           5 :             env.ApplyWeekendRule = runPer.applyWeekendRule;
    9257           5 :             env.UseRain = runPer.useRain;
    9258           5 :             env.UseSnow = runPer.useSnow;
    9259           5 :             env.firstHrInterpUseHr1 = runPer.firstHrInterpUsingHr1; // this will just the default
    9260           5 :             ++state.dataWeatherManager->Envrn;
    9261             :         }
    9262             : 
    9263             :         // RunPeriods from weather file
    9264        1928 :         for (int i = 1; i <= state.dataWeatherManager->TotRunPers; ++i) { // Run Periods.
    9265        1156 :             auto &env = state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn);
    9266        1156 :             auto &runPer = state.dataWeatherManager->RunPeriodInput(i);
    9267             : 
    9268        1156 :             env.StartMonth = runPer.startMonth;
    9269        1156 :             env.StartDay = runPer.startDay;
    9270        1156 :             env.StartYear = runPer.startYear;
    9271        1156 :             env.EndMonth = runPer.endMonth;
    9272        1156 :             env.EndDay = runPer.endDay;
    9273        1156 :             env.EndYear = runPer.endYear;
    9274        1156 :             env.NumSimYears = runPer.numSimYears;
    9275        1156 :             env.CurrentYear = runPer.startYear;
    9276        1156 :             env.IsLeapYear = runPer.isLeapYear;
    9277        1156 :             env.TreatYearsAsConsecutive = true;
    9278        1156 :             if (runPer.actualWeather) {
    9279             :                 // This will require leap years to be present, thus Julian days can be used for all the calculations
    9280           0 :                 env.StartJDay = env.StartDate = runPer.startJulianDate;
    9281           0 :                 env.EndJDay = env.EndDate = runPer.endJulianDate;
    9282           0 :                 env.TotalDays = env.EndDate - env.StartDate + 1;
    9283           0 :                 env.RawSimDays = env.EndDate - env.StartDate + 1;
    9284           0 :                 env.MatchYear = true;
    9285           0 :                 env.ActualWeather = true;
    9286             :             } else { // std RunPeriod
    9287        1156 :                 env.RollDayTypeOnRepeat = runPer.RollDayTypeOnRepeat;
    9288        1156 :                 if (env.StartYear == env.EndYear) {
    9289             :                     // Short-circuit all the calculations, we're in a single year
    9290        1150 :                     int LocalLeapYearAdd = 0;
    9291        1150 :                     if (isLeapYear(env.StartYear)) {
    9292             :                         // If a leap year is supported by the weather file, do it.
    9293           1 :                         if (state.dataWeatherManager->WFAllowsLeapYears) {
    9294           1 :                             env.IsLeapYear = true; // explicit set, this might be unwise
    9295           1 :                             LocalLeapYearAdd = 1;
    9296             :                         } else {
    9297           0 :                             env.IsLeapYear = false; // explicit set, this might be unwise
    9298             :                         }
    9299             :                     }
    9300        1150 :                     env.StartJDay = General::OrdinalDay(runPer.startMonth, runPer.startDay, LocalLeapYearAdd);
    9301        1150 :                     env.EndJDay = General::OrdinalDay(runPer.endMonth, runPer.endDay, LocalLeapYearAdd);
    9302        1150 :                     env.RawSimDays = (env.EndJDay - env.StartJDay + 1);
    9303        1150 :                     env.TotalDays = env.RawSimDays;
    9304             :                 } else {
    9305             :                     // Environment crosses year boundaries
    9306           6 :                     env.RollDayTypeOnRepeat = runPer.RollDayTypeOnRepeat;
    9307           6 :                     env.StartJDay = General::OrdinalDay(runPer.startMonth, runPer.startDay, runPer.isLeapYear ? 1 : 0);
    9308           6 :                     env.EndJDay = General::OrdinalDay(
    9309           6 :                         runPer.endMonth, runPer.endDay, isLeapYear(runPer.endYear) && state.dataWeatherManager->WFAllowsLeapYears ? 1 : 0);
    9310           6 :                     env.TotalDays = 366 - env.StartJDay + env.EndJDay + 365 * std::max(env.NumSimYears - 2, 0);
    9311           6 :                     if (state.dataWeatherManager->WFAllowsLeapYears) {
    9312             :                         // First year
    9313           0 :                         if (env.StartJDay < 59) {
    9314           0 :                             if (isLeapYear(env.StartYear)) {
    9315           0 :                                 ++env.TotalDays;
    9316             :                             }
    9317             :                         }
    9318             :                         // Middle years
    9319           0 :                         for (int yr = env.StartYear + 1; yr < env.EndYear; ++yr) {
    9320           0 :                             if (isLeapYear(yr)) {
    9321           0 :                                 ++env.TotalDays;
    9322             :                             }
    9323             :                         }
    9324             :                         // Last year not needed, the end ordinal date will take this into account
    9325             :                     }
    9326           6 :                     env.RawSimDays = env.TotalDays;
    9327             :                 }
    9328             :             }
    9329        1156 :             env.UseDST = runPer.useDST;
    9330        1156 :             env.UseHolidays = runPer.useHolidays;
    9331        1156 :             if (runPer.title.empty()) {
    9332           1 :                 env.Title = state.dataEnvrn->WeatherFileLocationTitle;
    9333             :             } else {
    9334        1155 :                 env.Title = runPer.title;
    9335             :             }
    9336        1156 :             if (env.KindOfEnvrn == DataGlobalConstants::KindOfSim::ReadAllWeatherData) {
    9337           1 :                 env.cKindOfEnvrn = "ReadAllWeatherDataRunPeriod";
    9338             :             } else {
    9339        1155 :                 env.cKindOfEnvrn = "WeatherFileRunPeriod";
    9340        1155 :                 env.KindOfEnvrn = DataGlobalConstants::KindOfSim::RunPeriodWeather;
    9341             :             }
    9342        1156 :             env.DayOfWeek = runPer.dayOfWeek;
    9343        1156 :             env.MonWeekDay = runPer.monWeekDay;
    9344        1156 :             env.SetWeekDays = false;
    9345        1156 :             env.ApplyWeekendRule = runPer.applyWeekendRule;
    9346        1156 :             env.UseRain = runPer.useRain;
    9347        1156 :             env.UseSnow = runPer.useSnow;
    9348        1156 :             env.firstHrInterpUseHr1 = runPer.firstHrInterpUsingHr1; // first hour interpolation choice
    9349        1156 :             ++state.dataWeatherManager->Envrn;
    9350             :         }
    9351         772 :     }
    9352             : 
    9353        2310 :     bool isLeapYear(int const Year)
    9354             :     {
    9355             :         // true if it's a leap year, false if not.
    9356             : 
    9357        2310 :         if (mod(Year, 4) == 0) { // Potential Leap Year
    9358           2 :             if (!(mod(Year, 100) == 0 && mod(Year, 400) != 0)) {
    9359           2 :                 return true;
    9360             :             }
    9361             :         }
    9362        2308 :         return false;
    9363             :     }
    9364             : 
    9365        9243 :     int computeJulianDate(int const gyyyy, // input/output gregorian year, should be specified as 4 digits
    9366             :                           int const gmm,   // input/output gregorian month
    9367             :                           int const gdd    // input/output gregorian day
    9368             :     )
    9369             :     {
    9370             :         // SUBROUTINE INFORMATION:
    9371             :         //       AUTHOR         Jason DeGraw
    9372             :         //       DATE WRITTEN   10/25/2017
    9373             :         //       MODIFIED       na
    9374             :         //       RE-ENGINEERED  na
    9375             : 
    9376             :         // PURPOSE OF THIS SUBROUTINE:
    9377             :         // Split the former JGDate function in two. Convert a gregorian
    9378             :         // date to actual julian date.  the advantage of storing a julian date
    9379             :         // in the jdate format rather than a 5 digit format is that any
    9380             :         // number of days can be add or subtracted to jdate and
    9381             :         // that result is a proper julian date.
    9382             : 
    9383             :         // REFERENCES:
    9384             :         // for discussion of this algorithm,
    9385             :         // see cacm, vol 11, no 10, oct 1968, page 657
    9386             : 
    9387        9243 :         int tyyyy = gyyyy;
    9388        9243 :         int tmm = gmm;
    9389        9243 :         int tdd = gdd;
    9390        9243 :         int l = (tmm - 14) / 12;
    9391        9243 :         return tdd - 32075 + 1461 * (tyyyy + 4800 + l) / 4 + 367 * (tmm - 2 - l * 12) / 12 - 3 * ((tyyyy + 4900 + l) / 100) / 4;
    9392             :     }
    9393             : 
    9394           0 :     int computeJulianDate(GregorianDate const gdate)
    9395             :     {
    9396           0 :         return computeJulianDate(gdate.year, gdate.month, gdate.day);
    9397             :     }
    9398             : 
    9399           0 :     GregorianDate computeGregorianDate(int const jdate)
    9400             :     {
    9401           0 :         int tdate = jdate;
    9402           0 :         int l = tdate + 68569;
    9403           0 :         int n = 4 * l / 146097;
    9404           0 :         l -= (146097 * n + 3) / 4;
    9405           0 :         int tyyyy = 4000 * (l + 1) / 1461001;
    9406           0 :         l = l - 1461 * tyyyy / 4 + 31;
    9407           0 :         int tmm = 80 * l / 2447;
    9408           0 :         int tdd = l - 2447 * tmm / 80;
    9409           0 :         l = tmm / 11;
    9410           0 :         tmm += 2 - 12 * l;
    9411           0 :         tyyyy += 100 * (n - 49) + l;
    9412           0 :         return {tyyyy, tmm, tdd};
    9413             :     }
    9414             : 
    9415         149 :     ScheduleManager::DayType calculateDayOfWeek(EnergyPlusData &state, int const year, int const month, int const day)
    9416             :     {
    9417             : 
    9418             :         // FUNCTION INFORMATION:
    9419             :         //       AUTHOR         Linda Lawrie
    9420             :         //       DATE WRITTEN   March 2012
    9421             :         //       MODIFIED       October 2017, Jason DeGraw
    9422             : 
    9423             :         // PURPOSE OF THIS FUNCTION:
    9424             :         // Calculate the correct day of week.
    9425             : 
    9426             :         // METHODOLOGY EMPLOYED:
    9427             :         // Zeller's algorithm.
    9428             : 
    9429             :         // REFERENCES:
    9430             :         // http://en.wikipedia.org/wiki/Zeller%27s_congruence
    9431             :         // and other references around the web.
    9432             : 
    9433         149 :         int Gyyyy(year); // Gregorian yyyy
    9434         149 :         int Gmm(month);  // Gregorian mm
    9435             : 
    9436             :         // Jan, Feb are 13, 14 months of previous year
    9437         149 :         if (Gmm < 3) {
    9438          88 :             Gmm += 12;
    9439          88 :             --Gyyyy;
    9440             :         }
    9441             : 
    9442         149 :         state.dataEnvrn->DayOfWeek = mod(day + (13 * (Gmm + 1) / 5) + Gyyyy + (Gyyyy / 4) + 6 * (Gyyyy / 100) + (Gyyyy / 400), 7);
    9443         149 :         if (state.dataEnvrn->DayOfWeek == 0) state.dataEnvrn->DayOfWeek = 7;
    9444             : 
    9445         149 :         return static_cast<ScheduleManager::DayType>(state.dataEnvrn->DayOfWeek);
    9446             :     }
    9447             : 
    9448        1005 :     int calculateDayOfYear(int const Month, int const Day, bool const leapYear)
    9449             :     {
    9450             : 
    9451             :         // FUNCTION INFORMATION:
    9452             :         //       AUTHOR         Jason DeGraw
    9453             :         //       DATE WRITTEN   October 10, 2017
    9454             :         //       MODIFIED       na
    9455             :         //       RE-ENGINEERED  na
    9456             : 
    9457             :         // PURPOSE OF THIS FUNCTION:
    9458             :         // Compute the day of the year for leap and non-leap years.
    9459             : 
    9460             :         static std::array<int, 12> const daysbefore{{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}};
    9461             :         static std::array<int, 12> const daysbeforeleap{{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}};
    9462             : 
    9463             :         // Could probably do some bounds checking here, but for now assume the month is in [1, 12]
    9464        1005 :         if (leapYear) {
    9465           0 :             return daysbeforeleap[Month - 1] + Day;
    9466             :         } else {
    9467        1005 :             return daysbefore[Month - 1] + Day;
    9468             :         }
    9469             :     }
    9470             : 
    9471        2308 :     bool validMonthDay(int const month, int const day, int const leapYearAdd)
    9472             :     {
    9473             : 
    9474             :         // FUNCTION INFORMATION:
    9475             :         //       AUTHOR         Jason DeGraw
    9476             :         //       DATE WRITTEN   October 31, 2017
    9477             :         //       MODIFIED       na
    9478             :         //       RE-ENGINEERED  na
    9479             : 
    9480             :         // PURPOSE OF THIS FUNCTION:
    9481             :         // Determine if a month/day+leapyear combination is valid.
    9482             : 
    9483        2308 :         switch (month) {
    9484        2153 :         case 1:
    9485             :         case 3:
    9486             :         case 5:
    9487             :         case 7:
    9488             :         case 8:
    9489             :         case 10:
    9490             :         case 12:
    9491        2153 :             if (day > 31) {
    9492           0 :                 return false;
    9493             :             }
    9494        2153 :             break;
    9495         116 :         case 4:
    9496             :         case 6:
    9497             :         case 9:
    9498             :         case 11:
    9499         116 :             if (day > 30) {
    9500           0 :                 return false;
    9501             :             }
    9502         116 :             break;
    9503          39 :         case 2:
    9504          39 :             if (day > 28 + leapYearAdd) {
    9505           0 :                 return false;
    9506             :             }
    9507          39 :             break;
    9508           0 :         default:
    9509           0 :             return false;
    9510             :         }
    9511        2308 :         return true;
    9512             :     }
    9513             : 
    9514           0 :     void AnnualMonthlyDryBulbWeatherData::CalcAnnualAndMonthlyDryBulbTemp(EnergyPlusData &state)
    9515             :     {
    9516             : 
    9517             :         // PURPOSE OF THIS SUBROUTINE:
    9518             :         // Calculates monthly daily average outdoor air drybulb temperature from
    9519             :         // either weather (*.EPW) file or reads monthly daily average outdoor air
    9520             :         // drybulb temperature from STAT (*.stat) for use to autosize main water
    9521             :         // temperature.
    9522             : 
    9523           0 :         Real64 MonthlyDailyDryBulbMin(200.0);               // monthly-daily minimum outside air dry-bulb temperature
    9524           0 :         Real64 MonthlyDailyDryBulbMax(-200.0);              // monthly-daily maximum outside air dry-bulb temperature
    9525           0 :         Real64 AnnualDailyAverageDryBulbTempSum(0.0);       // annual sum of daily average outside air dry-bulb temperature
    9526           0 :         Array1D<Real64> MonthlyAverageDryBulbTemp(12, 0.0); // monthly-daily average outside air temperature
    9527             : 
    9528           0 :         if (!this->OADryBulbWeatherDataProcessed) {
    9529           0 :             const auto statFileExists = FileSystem::fileExists(state.files.inStatFilePath.filePath);
    9530           0 :             const auto epwFileExists = FileSystem::fileExists(state.files.inputWeatherFilePath.filePath);
    9531           0 :             if (statFileExists) {
    9532           0 :                 auto statFile = state.files.inStatFilePath.try_open();
    9533           0 :                 if (!statFile.good()) {
    9534           0 :                     ShowSevereError(state,
    9535           0 :                                     "CalcAnnualAndMonthlyDryBulbTemp: Could not open file " + statFile.filePath.string() + " for input (read).");
    9536           0 :                     ShowContinueError(state, "Water Mains Temperature will be set to a fixed default value of 10.0 C.");
    9537           0 :                     return;
    9538             :                 }
    9539             : 
    9540           0 :                 std::string lineAvg;
    9541           0 :                 while (statFile.good()) {
    9542           0 :                     auto lineIn = statFile.readLine();
    9543           0 :                     if (has(lineIn.data, "Monthly Statistics for Dry Bulb temperatures")) {
    9544           0 :                         for (int i = 1; i <= 7; ++i) {
    9545           0 :                             lineIn = statFile.readLine();
    9546             :                         }
    9547           0 :                         lineIn = statFile.readLine();
    9548           0 :                         lineAvg = lineIn.data;
    9549           0 :                         break;
    9550             :                     }
    9551             :                 }
    9552           0 :                 if (lineAvg.empty()) {
    9553           0 :                     ShowSevereError(state,
    9554           0 :                                     "CalcAnnualAndMonthlyDryBulbTemp: Stat file '" + statFile.filePath.string() +
    9555             :                                         "' does not have Monthly Statistics for Dry Bulb temperatures.");
    9556           0 :                     ShowContinueError(state, "Water Mains Temperature will be set to a fixed default value of 10.0 C.");
    9557           0 :                     return;
    9558           0 :                 } else if (lineAvg.find("Daily Avg") == std::string::npos) {
    9559           0 :                     ShowSevereError(state,
    9560           0 :                                     "CalcAnnualAndMonthlyDryBulbTemp: Stat file '" + statFile.filePath.string() +
    9561             :                                         "' does not have the 'Daily Avg' line in the Monthly Statistics for Dry Bulb temperatures.");
    9562           0 :                     ShowContinueError(state, "Water Mains Temperature will be set to a fixed default value of 10.0 C.");
    9563           0 :                     return;
    9564             :                 } else {
    9565           0 :                     int AnnualNumberOfDays = 0;
    9566           0 :                     for (int i = 1; i <= 12; ++i) {
    9567           0 :                         MonthlyAverageDryBulbTemp(i) = OutputReportTabular::StrToReal(OutputReportTabular::GetColumnUsingTabs(lineAvg, i + 2));
    9568           0 :                         AnnualDailyAverageDryBulbTempSum += MonthlyAverageDryBulbTemp(i) * state.dataWeatherManager->EndDayOfMonth(i);
    9569           0 :                         MonthlyDailyDryBulbMin = min(MonthlyDailyDryBulbMin, MonthlyAverageDryBulbTemp(i));
    9570           0 :                         MonthlyDailyDryBulbMax = max(MonthlyDailyDryBulbMax, MonthlyAverageDryBulbTemp(i));
    9571           0 :                         AnnualNumberOfDays += state.dataWeatherManager->EndDayOfMonth(i);
    9572             :                     }
    9573           0 :                     this->AnnualAvgOADryBulbTemp = AnnualDailyAverageDryBulbTempSum / AnnualNumberOfDays;
    9574           0 :                     this->MonthlyAvgOADryBulbTempMaxDiff = MonthlyDailyDryBulbMax - MonthlyDailyDryBulbMin;
    9575           0 :                     this->MonthlyDailyAverageDryBulbTemp = MonthlyAverageDryBulbTemp;
    9576           0 :                     this->OADryBulbWeatherDataProcessed = true;
    9577             :                 }
    9578           0 :             } else if (epwFileExists) {
    9579           0 :                 auto epwFile = state.files.inputWeatherFilePath.try_open();
    9580           0 :                 bool epwHasLeapYear(false);
    9581           0 :                 if (!epwFile.good()) {
    9582           0 :                     ShowSevereError(state,
    9583           0 :                                     "CalcAnnualAndMonthlyDryBulbTemp: Could not open file " + epwFile.filePath.string() + " for input (read).");
    9584           0 :                     ShowContinueError(state, "Water Mains Temperature will be set to a fixed default value of 10.0 C.");
    9585           0 :                     return;
    9586             :                 }
    9587           0 :                 for (int i = 1; i <= 8; ++i) { // Headers
    9588           0 :                     auto epwLine = epwFile.readLine();
    9589             : 
    9590           0 :                     if (i == 5) {
    9591             :                         // HOLIDAYS/DAYLIGHT SAVINGS,Yes,0,0,0
    9592           0 :                         std::string::size_type pos = index(epwLine.data, ',');
    9593           0 :                         epwLine.data.erase(0, pos + 1);
    9594           0 :                         pos = index(epwLine.data, ',');
    9595           0 :                         std::string LeapYear = UtilityRoutines::MakeUPPERCase(epwLine.data.substr(0, pos));
    9596           0 :                         if (LeapYear[0] == 'Y') {
    9597           0 :                             epwHasLeapYear = true;
    9598             :                         }
    9599             :                     }
    9600             :                 }
    9601           0 :                 Array1D<int> EndDayOfMonthLocal;
    9602           0 :                 EndDayOfMonthLocal = state.dataWeatherManager->EndDayOfMonth;
    9603           0 :                 if (epwHasLeapYear) {
    9604             :                     // increase number of days for february by one day if weather data has leap year
    9605           0 :                     EndDayOfMonthLocal(2) = EndDayOfMonthLocal(2) + 1;
    9606             :                 }
    9607             :                 int DayNum;
    9608             :                 int DaysCountOfMonth;
    9609           0 :                 for (int i = 1; i <= 12; ++i) {
    9610           0 :                     Real64 MonthlyDailyDryBulbAvg = 0.0;
    9611           0 :                     DaysCountOfMonth = EndDayOfMonthLocal(i);
    9612           0 :                     for (DayNum = 1; DayNum <= DaysCountOfMonth; ++DayNum) {
    9613           0 :                         Real64 DailyAverageDryBulbTemp = 0.0;
    9614             :                         std::string::size_type pos;
    9615           0 :                         for (int j = 1; j <= 24; ++j) {
    9616           0 :                             auto epwLine = epwFile.readLine();
    9617           0 :                             for (int ind = 1; ind <= 6; ++ind) {
    9618           0 :                                 pos = index(epwLine.data, ',');
    9619           0 :                                 epwLine.data.erase(0, pos + 1);
    9620             :                             }
    9621           0 :                             pos = index(epwLine.data, ',');
    9622           0 :                             Real64 HourlyDryBulbTemp = OutputReportTabular::StrToReal(epwLine.data.substr(0, pos));
    9623           0 :                             DailyAverageDryBulbTemp += (HourlyDryBulbTemp / 24.0);
    9624             :                         }
    9625           0 :                         AnnualDailyAverageDryBulbTempSum += DailyAverageDryBulbTemp;
    9626           0 :                         MonthlyDailyDryBulbAvg += (DailyAverageDryBulbTemp / DaysCountOfMonth);
    9627             :                     }
    9628           0 :                     MonthlyAverageDryBulbTemp(i) = MonthlyDailyDryBulbAvg;
    9629           0 :                     MonthlyDailyDryBulbMin = min(MonthlyDailyDryBulbMin, MonthlyDailyDryBulbAvg);
    9630           0 :                     MonthlyDailyDryBulbMax = max(MonthlyDailyDryBulbMax, MonthlyDailyDryBulbAvg);
    9631             :                 }
    9632             :                 // calculate annual average outdoor air dry-bulb temperature and monthly daily average
    9633             :                 // outdoor air temperature maximum difference
    9634           0 :                 int AnnualNumberOfDays = 365;
    9635           0 :                 if (epwHasLeapYear) AnnualNumberOfDays++;
    9636           0 :                 this->AnnualAvgOADryBulbTemp = AnnualDailyAverageDryBulbTempSum / AnnualNumberOfDays;
    9637           0 :                 this->MonthlyAvgOADryBulbTempMaxDiff = MonthlyDailyDryBulbMax - MonthlyDailyDryBulbMin;
    9638           0 :                 this->MonthlyDailyAverageDryBulbTemp = MonthlyAverageDryBulbTemp;
    9639           0 :                 this->OADryBulbWeatherDataProcessed = true;
    9640             :             } else {
    9641           0 :                 ShowSevereError(state, "CalcAnnualAndMonthlyDryBulbTemp: weather file or stat file does not exist.");
    9642           0 :                 ShowContinueError(state, "Weather file: " + state.files.inputWeatherFilePath.filePath.string() + ".");
    9643           0 :                 ShowContinueError(state, "Stat file: " + state.files.inStatFilePath.filePath.string() + ".");
    9644           0 :                 ShowContinueError(state, "Water Mains Monthly Temperature cannot be calculated using CorrelationFromWeatherFile method.");
    9645           0 :                 ShowContinueError(state, "Instead a fixed default value of 10.0 C will be used.");
    9646             :             }
    9647             :         }
    9648             :     }
    9649             : 
    9650         771 :     void ReportWaterMainsTempParameters(EnergyPlusData &state)
    9651             :     {
    9652             :         // PURPOSE OF THIS SUBROUTINE:
    9653             :         // report site water mains temperature object user inputs and/or parameters calculated
    9654             :         // from weather or stat file
    9655             : 
    9656         771 :         if (!state.files.eio.good()) {
    9657           0 :             return;
    9658             :         }
    9659             : 
    9660        1542 :         std::stringstream ss;
    9661         771 :         auto *eiostream = &ss;
    9662             : 
    9663             :         // Write annual average OA temperature and maximum difference in monthly-daily average outdoor air temperature
    9664         771 :         *eiostream << "! <Site Water Mains Temperature Information>"
    9665             :                       ",Calculation Method{}"
    9666             :                       ",Water Mains Temperature Schedule Name{}"
    9667             :                       ",Annual Average Outdoor Air Temperature{C}"
    9668             :                       ",Maximum Difference In Monthly Average Outdoor Air Temperatures{deltaC}"
    9669         771 :                       ",Fixed Default Water Mains Temperature{C}\n";
    9670             : 
    9671         771 :         switch (state.dataWeatherManager->WaterMainsTempsMethod) {
    9672           3 :         case WaterMainsTempCalcMethod::Schedule:
    9673           3 :             *eiostream << "Site Water Mains Temperature Information,";
    9674           3 :             *eiostream << waterMainsCalcMethodNames[static_cast<int>(state.dataWeatherManager->WaterMainsTempsMethod)] << ","
    9675           6 :                        << state.dataWeatherManager->WaterMainsTempsScheduleName << ",";
    9676           6 :             *eiostream << format("{:.2R}", state.dataWeatherManager->WaterMainsTempsAnnualAvgAirTemp) << ","
    9677           6 :                        << format("{:.2R}", state.dataWeatherManager->WaterMainsTempsMaxDiffAirTemp) << ",";
    9678           3 :             *eiostream << "NA\n";
    9679           3 :             break;
    9680         120 :         case WaterMainsTempCalcMethod::Correlation:
    9681         120 :             *eiostream << "Site Water Mains Temperature Information,";
    9682         120 :             *eiostream << waterMainsCalcMethodNames[static_cast<int>(state.dataWeatherManager->WaterMainsTempsMethod)] << ","
    9683             :                        << "NA"
    9684         240 :                        << ",";
    9685         240 :             *eiostream << format("{:.2R}", state.dataWeatherManager->WaterMainsTempsAnnualAvgAirTemp) << ","
    9686         240 :                        << format("{:.2R}", state.dataWeatherManager->WaterMainsTempsMaxDiffAirTemp) << ",";
    9687         120 :             *eiostream << "NA\n";
    9688         120 :             break;
    9689           0 :         case WaterMainsTempCalcMethod::CorrelationFromWeatherFile:
    9690           0 :             if (state.dataWeatherManager->OADryBulbAverage.OADryBulbWeatherDataProcessed) {
    9691           0 :                 *eiostream << "Site Water Mains Temperature Information,";
    9692           0 :                 *eiostream << waterMainsCalcMethodNames[static_cast<int>(state.dataWeatherManager->WaterMainsTempsMethod)] << ","
    9693             :                            << "NA"
    9694           0 :                            << ",";
    9695           0 :                 *eiostream << format("{:.2R}", state.dataWeatherManager->OADryBulbAverage.AnnualAvgOADryBulbTemp) << ","
    9696           0 :                            << format("{:.2R}", state.dataWeatherManager->OADryBulbAverage.MonthlyAvgOADryBulbTempMaxDiff) << ","
    9697           0 :                            << "NA\n";
    9698             :             } else {
    9699           0 :                 *eiostream << "Site Water Mains Temperature Information,";
    9700             :                 *eiostream << "FixedDefault"
    9701             :                            << ","
    9702             :                            << "NA"
    9703             :                            << ","
    9704             :                            << "NA"
    9705             :                            << ","
    9706             :                            << "NA"
    9707           0 :                            << "," << format("{:.1R}", 10.0) << '\n';
    9708             :             }
    9709           0 :             break;
    9710         648 :         default:
    9711         648 :             *eiostream << "Site Water Mains Temperature Information,";
    9712             :             *eiostream << "FixedDefault"
    9713             :                        << ","
    9714             :                        << "NA"
    9715             :                        << ","
    9716             :                        << "NA"
    9717             :                        << ","
    9718             :                        << "NA"
    9719         648 :                        << "," << format("{:.1R}", 10.0) << '\n';
    9720         648 :             break;
    9721             :         }
    9722             : 
    9723         771 :         print(state.files.eio, "{}", ss.str());
    9724             :     }
    9725             : 
    9726      292584 :     void calcSky(EnergyPlusData &state,
    9727             :                  Real64 &HorizIRSky,
    9728             :                  Real64 &SkyTemp,
    9729             :                  Real64 OpaqueSkyCover,
    9730             :                  Real64 DryBulb,
    9731             :                  Real64 DewPoint,
    9732             :                  Real64 RelHum,
    9733             :                  Real64 IRHoriz)
    9734             :     {
    9735             :         Real64 ESky;
    9736             : 
    9737      292584 :         if (IRHoriz <= 0.0) IRHoriz = 9999.0;
    9738             : 
    9739      292584 :         if (!state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).UseWeatherFileHorizontalIR || IRHoriz >= 9999.0) {
    9740             :             // Missing or user defined to not use IRHoriz from weather, using sky cover and clear sky emissivity
    9741           0 :             ESky = CalcSkyEmissivity(state,
    9742           0 :                                      state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel,
    9743             :                                      OpaqueSkyCover,
    9744             :                                      DryBulb,
    9745             :                                      DewPoint,
    9746             :                                      RelHum);
    9747           0 :             HorizIRSky = ESky * state.dataWeatherManager->Sigma * pow_4(DryBulb + DataGlobalConstants::KelvinConv);
    9748           0 :             if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::BruntModel ||
    9749           0 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::IdsoModel ||
    9750           0 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::BerdahlMartinModel ||
    9751           0 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::ClarkAllenModel) {
    9752           0 :                 SkyTemp = (DryBulb + DataGlobalConstants::KelvinConv) * root_4(ESky) - DataGlobalConstants::KelvinConv;
    9753             :             } else {
    9754           0 :                 SkyTemp = 0.0; // dealt with later
    9755             :             }
    9756             :         } else {
    9757             :             // Valid IR from weather files
    9758      292584 :             HorizIRSky = IRHoriz;
    9759      877752 :             if (state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::BruntModel ||
    9760      585168 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::IdsoModel ||
    9761      877752 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::BerdahlMartinModel ||
    9762      292584 :                 state.dataWeatherManager->Environment(state.dataWeatherManager->Envrn).SkyTempModel == SkyTempCalcType::ClarkAllenModel) {
    9763      292584 :                 SkyTemp = root_4(IRHoriz / state.dataWeatherManager->Sigma) - DataGlobalConstants::KelvinConv;
    9764             :             } else {
    9765           0 :                 SkyTemp = 0.0; // dealt with later
    9766             :             }
    9767             :         }
    9768      292584 :     }
    9769             : 
    9770             : } // namespace WeatherManager
    9771             : 
    9772        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13