LCOV - code coverage report
Current view: top level - EnergyPlus - SystemAvailabilityManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 35.2 % 2655 935
Test Date: 2025-06-02 12:03:30 Functions: 67.9 % 28 19

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <algorithm>
      50              : #include <cmath>
      51              : 
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Array.functions.hh>
      54              : #include <ObjexxFCL/Array2D.hh>
      55              : 
      56              : // EnergyPlus Headers
      57              : #include <AirflowNetwork/Elements.hpp>
      58              : #include <AirflowNetwork/Solver.hpp>
      59              : #include <EnergyPlus/CurveManager.hh>
      60              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      61              : #include <EnergyPlus/DataAirLoop.hh>
      62              : #include <EnergyPlus/DataAirSystems.hh>
      63              : #include <EnergyPlus/DataContaminantBalance.hh>
      64              : #include <EnergyPlus/DataEnvironment.hh>
      65              : #include <EnergyPlus/DataGlobalConstants.hh>
      66              : #include <EnergyPlus/DataHeatBalFanSys.hh>
      67              : #include <EnergyPlus/DataHeatBalance.hh>
      68              : #include <EnergyPlus/DataIPShortCuts.hh>
      69              : #include <EnergyPlus/DataLoopNode.hh>
      70              : #include <EnergyPlus/DataZoneControls.hh>
      71              : #include <EnergyPlus/DataZoneEquipment.hh>
      72              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      73              : #include <EnergyPlus/NodeInputManager.hh>
      74              : #include <EnergyPlus/OutputProcessor.hh>
      75              : #include <EnergyPlus/Psychrometrics.hh>
      76              : #include <EnergyPlus/ScheduleManager.hh>
      77              : #include <EnergyPlus/SystemAvailabilityManager.hh>
      78              : #include <EnergyPlus/ThermalComfort.hh>
      79              : #include <EnergyPlus/UtilityRoutines.hh>
      80              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      81              : 
      82              : namespace EnergyPlus {
      83              : 
      84              : namespace Avail {
      85              : 
      86              :     // Module containing the System Availability Manager routines
      87              : 
      88              :     // MODULE INFORMATION:
      89              :     //       AUTHOR         Fred Buhl
      90              :     //       DATE WRITTEN   August 2001
      91              :     //       MODIFIED       February 2004, PGE: Added plant managers.
      92              :     //       MODIFIED       March 2007, LG: Added hybrid ventilation control.
      93              :     //                      August 2008, R. Raustad - FSEC: added 2 new scheduled sys avail managers
      94              :     //                      March 2011, Chandan Sharma - FSEC: Added zone sys avail managers
      95              :     //                      August 2013, Xiufeng Pang (XP) - added algorithms for optimal start
      96              :     //       RE-ENGINEERED  na
      97              : 
      98              :     // PURPOSE OF THIS MODULE
      99              :     // To encapsulate the data and algorithms required to
     100              :     // determine system (loop) availability and "cycle on" status.
     101              : 
     102              :     // METHODOLOGY EMPLOYED:
     103              :     // Previous time step node data and current zone thermostat setpoints are used
     104              :     // in a set of fixed, precoded algorithms to determine the current time step
     105              :     // on/off status of systems and loops.
     106              : 
     107              :     // USE STATEMENTS:
     108              :     // Use statements for data only modules
     109              :     static constexpr std::array<std::string_view, (int)ManagerType::Num> managerTypeNamesUC = {"AVAILABILITYMANAGER:SCHEDULED",
     110              :                                                                                                "AVAILABILITYMANAGER:SCHEDULEDON",
     111              :                                                                                                "AVAILABILITYMANAGER:SCHEDULEDOFF",
     112              :                                                                                                "AVAILABILITYMANAGER:NIGHTCYCLE",
     113              :                                                                                                "AVAILABILITYMANAGER:DIFFERENTIALTHERMOSTAT",
     114              :                                                                                                "AVAILABILITYMANAGER:HIGHTEMPERATURETURNOFF",
     115              :                                                                                                "AVAILABILITYMANAGER:HIGHTEMPERATURETURNON",
     116              :                                                                                                "AVAILABILITYMANAGER:LOWTEMPERATURETURNOFF",
     117              :                                                                                                "AVAILABILITYMANAGER:LOWTEMPERATURETURNON",
     118              :                                                                                                "AVAILABILITYMANAGER:NIGHTVENTILATION",
     119              :                                                                                                "AVAILABILITYMANAGER:HYBRIDVENTILATION",
     120              :                                                                                                "AVAILABILITYMANAGER:OPTIMUMSTART"};
     121              : 
     122              :     static constexpr std::array<std::string_view, (int)ManagerType::Num> managerTypeNames = {"AvailabilityManager:Scheduled",
     123              :                                                                                              "AvailabilityManager:ScheduledOn",
     124              :                                                                                              "AvailabilityManager:ScheduledOff",
     125              :                                                                                              "AvailabilityManager:NightCycle",
     126              :                                                                                              "AvailabilityManager:DifferentialThermostat",
     127              :                                                                                              "AvailabilityManager:HighTemperatureTurnOff",
     128              :                                                                                              "AvailabilityManager:HighTemperatureTurnOn",
     129              :                                                                                              "AvailabilityManager:LowTemperatureTurnOff",
     130              :                                                                                              "AvailabilityManager:LowTemperatureTurnOn",
     131              :                                                                                              "AvailabilityManager:NightVentilation",
     132              :                                                                                              "AvailabilityManager:HybridVentilation",
     133              :                                                                                              "AvailabilityManager:OptimumStart"};
     134              : 
     135       208460 :     void ManageSystemAvailability(EnergyPlusData &state)
     136              :     {
     137              : 
     138              :         // SUBROUTINE INFORMATION:
     139              :         //       AUTHOR         Fred Buhl
     140              :         //       DATE WRITTEN   August 2001
     141              :         //       MODIFIED       L. Gu, April, 2007. Added hybrid ventilation control
     142              :         //                      Chandan Sharma, March 2011/July 2012 - FSEC: Added zone sys avail managers
     143              :         //       RE-ENGINEERED  na
     144              : 
     145              :         // PURPOSE OF THIS SUBROUTINE:
     146              :         // Manage the simulation of the System Availability Managers
     147              : 
     148              :         using DataZoneEquipment::NumValidSysAvailZoneComponents;
     149              :         using namespace DataLoopNode;
     150              :         using namespace DataAirLoop;
     151              :         using namespace DataPlant;
     152              : 
     153              :         int PriAirSysNum;         // Primary Air System index
     154              :         int PriAirSysAvailMgrNum; // Index of Sys Avail Manager in a Primary Air System
     155              :         int PlantNum;             // Plant Loop index
     156              :         int PlantAvailMgrNum;     // Index of Plant Avail Manager in a Plant Loop
     157              :         Status availStatus;
     158              :         Status previousAvailStatus;
     159              :         int ZoneInSysNum;
     160              :         int CtrldZoneNum;
     161              :         int HybridVentNum;              // Hybrid ventilation control number
     162              :         int ZoneEquipType;              // Type of ZoneHVAC:* component
     163              :         int CompNum;                    // Index of ZoneHVAC:* component
     164              :         int ZoneCompAvailMgrNum;        // Index of availability manager associated with the ZoneHVAC:* component
     165       208460 :         int constexpr DummyArgument(1); // This variable is used when SimSysAvailManager is called for a ZoneHVAC:* component
     166              : 
     167       208460 :         if (state.dataAvail->GetAvailMgrInputFlag) {
     168           62 :             GetSysAvailManagerInputs(state);
     169           62 :             state.dataAvail->GetAvailMgrInputFlag = false;
     170           62 :             return;
     171              :         }
     172              : 
     173       208398 :         InitSysAvailManagers(state);
     174              : 
     175       242671 :         for (PriAirSysNum = 1; PriAirSysNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++PriAirSysNum) { // loop over the primary air systems
     176        34273 :             auto &availMgr = state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum);
     177        34273 :             previousAvailStatus = availMgr.availStatus; // Save the previous status for differential thermostat
     178        34273 :             availMgr.availStatus = Status::NoAction;    // initialize the availability to "take no action"
     179              : 
     180        68546 :             for (PriAirSysAvailMgrNum = 1; PriAirSysAvailMgrNum <= availMgr.NumAvailManagers; ++PriAirSysAvailMgrNum) {
     181              : 
     182        68546 :                 availStatus = SimSysAvailManager(state,
     183        34273 :                                                  availMgr.availManagers(PriAirSysAvailMgrNum).type,
     184        34273 :                                                  availMgr.availManagers(PriAirSysAvailMgrNum).Name,
     185        34273 :                                                  availMgr.availManagers(PriAirSysAvailMgrNum).Num,
     186              :                                                  PriAirSysNum,
     187              :                                                  previousAvailStatus);
     188              : 
     189        34273 :                 if (availStatus == Status::ForceOff) {
     190            0 :                     availMgr.availStatus = Status::ForceOff;
     191            0 :                     break; // Fans forced off takes precedence
     192        34273 :                 } else if (availStatus == Status::CycleOnZoneFansOnly) {
     193            0 :                     availMgr.availStatus = Status::CycleOnZoneFansOnly; // zone fans only takes next precedence
     194        34273 :                 } else if ((availStatus == Status::CycleOn) && (availMgr.availStatus == Status::NoAction)) {
     195        29481 :                     availMgr.availStatus = Status::CycleOn; // cycle on is lowest precedence
     196              :                 }
     197              : 
     198              :             } // end of availability manager loop
     199              : 
     200              :             // Add hybrid ventilation control
     201        34273 :             if (state.dataAvail->NumHybridVentSysAvailMgrs > 0) {
     202            0 :                 for (HybridVentNum = 1; HybridVentNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++HybridVentNum) {
     203            0 :                     if (state.dataAvail->HybridVentData(HybridVentNum).AirLoopNum == PriAirSysNum &&
     204            0 :                         state.dataAvail->HybridVentData(HybridVentNum).ctrlStatus == VentCtrlStatus::Open) {
     205            0 :                         availMgr.availStatus = Status::ForceOff; // Force the system off
     206              :                     }
     207              :                 }
     208              :             }
     209              : 
     210              :             // loop over the zones served by the system and set the zone equipment availability
     211        90150 :             for (ZoneInSysNum = 1; ZoneInSysNum <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesCooled; ++ZoneInSysNum) {
     212              : 
     213        55877 :                 CtrldZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).CoolCtrlZoneNums(ZoneInSysNum);
     214        55877 :                 state.dataZoneEquip->ZoneEquipAvail(CtrldZoneNum) = availMgr.availStatus;
     215              :             }
     216              : 
     217              :         } // end of primary air system loop
     218              : 
     219       226379 :         for (PlantNum = 1; PlantNum <= state.dataHVACGlobal->NumPlantLoops; ++PlantNum) {
     220        17981 :             auto &availMgr = state.dataAvail->PlantAvailMgr(PlantNum);
     221        17981 :             previousAvailStatus = availMgr.availStatus; // Save the previous status for differential thermostat
     222        17981 :             availMgr.availStatus = Status::NoAction;    // Initialize the availability to "take no action"
     223              : 
     224        17981 :             for (PlantAvailMgrNum = 1; PlantAvailMgrNum <= availMgr.NumAvailManagers; ++PlantAvailMgrNum) { // loop over the avail managers in plant
     225              : 
     226         3824 :                 availStatus = SimSysAvailManager(state,
     227         1912 :                                                  availMgr.availManagers(PlantAvailMgrNum).type,
     228         1912 :                                                  availMgr.availManagers(PlantAvailMgrNum).Name,
     229         1912 :                                                  availMgr.availManagers(PlantAvailMgrNum).Num,
     230              :                                                  PlantNum,
     231              :                                                  previousAvailStatus);
     232              : 
     233         1912 :                 if (availStatus != Status::NoAction) {
     234         1912 :                     availMgr.availStatus = availStatus;
     235         1912 :                     break; // First manager to do anything other than "NoAction" gets to set the availability
     236              :                 }
     237              : 
     238              :             } // end of availability manager loop
     239              : 
     240              :         } // end of plant loop
     241              : 
     242       208398 :         if (!allocated(state.dataAvail->ZoneComp)) {
     243            0 :             return;
     244              :         }
     245              : 
     246              :         // loop over the zone equipment types which allow system avail managers
     247      3125970 :         for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) {
     248      2917572 :             auto &zoneComp = state.dataAvail->ZoneComp(ZoneEquipType);
     249      2917572 :             if (zoneComp.TotalNumComp == 0) {
     250      2908367 :                 continue;
     251              :             }
     252         9205 :             if (!allocated(zoneComp.ZoneCompAvailMgrs)) {
     253            0 :                 continue;
     254              :             }
     255              : 
     256        29625 :             for (CompNum = 1; CompNum <= zoneComp.TotalNumComp; ++CompNum) {
     257              : 
     258        20420 :                 auto &zcam = zoneComp.ZoneCompAvailMgrs(CompNum);
     259        20420 :                 if (zcam.NumAvailManagers > 0) {
     260              : 
     261              :                     // Save the previous status for differential thermostat
     262            0 :                     previousAvailStatus = zcam.availStatus;
     263              :                     // initialize the availability to "take no action"
     264            0 :                     zcam.availStatus = Status::NoAction;
     265            0 :                     for (ZoneCompAvailMgrNum = 1; ZoneCompAvailMgrNum <= zcam.NumAvailManagers; ++ZoneCompAvailMgrNum) {
     266              :                         // loop over the avail managers in ZoneHVAC:* components
     267            0 :                         availStatus = SimSysAvailManager(state,
     268            0 :                                                          zcam.availManagers(ZoneCompAvailMgrNum).type,
     269            0 :                                                          zcam.availManagers(ZoneCompAvailMgrNum).Name,
     270            0 :                                                          zcam.availManagers(ZoneCompAvailMgrNum).Num,
     271              :                                                          DummyArgument,
     272              :                                                          previousAvailStatus,
     273              :                                                          ZoneEquipType,
     274              :                                                          CompNum);
     275            0 :                         if (availStatus == Status::ForceOff) {
     276            0 :                             zcam.availStatus = Status::ForceOff;
     277            0 :                             break; // Fans forced off takes precedence
     278            0 :                         } else if ((availStatus == Status::CycleOn) && (zcam.availStatus == Status::NoAction)) {
     279              :                             // cycle on is next precedence
     280            0 :                             zcam.availStatus = Status::CycleOn;
     281              :                         }
     282              :                     }
     283              :                 } else {
     284        20420 :                     zcam.availStatus = Status::NoAction;
     285              :                 }
     286              : 
     287        20420 :                 if (zcam.ZoneNum == 0) {
     288            1 :                     continue;
     289              :                 }
     290        20419 :                 if (state.dataAvail->NumHybridVentSysAvailMgrs == 0) {
     291        20419 :                     continue;
     292              :                 }
     293              : 
     294            0 :                 for (HybridVentNum = 1; HybridVentNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++HybridVentNum) {
     295            0 :                     if (!state.dataAvail->HybridVentData(HybridVentNum).HybridVentMgrConnectedToAirLoop) {
     296            0 :                         if (state.dataAvail->HybridVentData(HybridVentNum).ControlledZoneNum == zcam.ZoneNum) {
     297            0 :                             if (state.dataAvail->HybridVentData(HybridVentNum).ctrlStatus == VentCtrlStatus::Open) {
     298            0 :                                 zcam.availStatus = Status::ForceOff;
     299              :                             }
     300              :                         }
     301              :                     }
     302              :                 }
     303              :             }
     304              :         } // for (ZoneEquipType)
     305              :     } // ManageSystemAvailability()
     306              : 
     307          143 :     void GetSysAvailManagerInputs(EnergyPlusData &state)
     308              :     {
     309              : 
     310              :         // SUBROUTINE INFORMATION:
     311              :         //       AUTHOR         Fred Buhl
     312              :         //       DATE WRITTEN   August 2001
     313              :         //       MODIFIED       na
     314              :         //       RE-ENGINEERED  na
     315              : 
     316              :         // PURPOSE OF THIS SUBROUTINE:
     317              :         // Obtains input data for System Availability Managers and stores it in
     318              :         // appropriate data structures.
     319              : 
     320              :         // METHODOLOGY EMPLOYED:
     321              :         // Uses InputProcessor "Get" routines to obtain data.
     322              : 
     323              :         // Using/Aliasing
     324              :         using NodeInputManager::GetOnlySingleNode;
     325              :         using NodeInputManager::MarkNode;
     326              :         using namespace DataLoopNode;
     327              :         using DataZoneEquipment::cValidSysAvailManagerCompTypes;
     328              :         using DataZoneEquipment::NumValidSysAvailZoneComponents;
     329              : 
     330              :         // SUBROUTINE PARAMETER DEFINITIONS:
     331              :         static constexpr std::string_view RoutineName("GetSysAvailManagerInputs: "); // include trailing blank
     332              :         static constexpr std::string_view routineName = "GetSysAvailManagerInputs";
     333              : 
     334          143 :         constexpr std::array<std::string_view, (int)ControlAlgorithm::Num> ControlAlgorithmNamesUC = {
     335              :             "CONSTANTTEMPERATUREGRADIENT", "ADAPTIVETEMPERATUREGRADIENT", "ADAPTIVEASHRAE", "CONSTANTSTARTTIME"};
     336              : 
     337          143 :         constexpr std::array<std::string_view, (int)CyclingRunTimeControl::Num> CyclingRunTimeControlNamesUC{
     338              :             "FIXEDRUNTIME",
     339              :             "THERMOSTAT",
     340              :             "THERMOSTATWITHMINIMUMRUNTIME",
     341              :         };
     342              : 
     343          143 :         constexpr std::array<std::string_view, (int)NightCycleControlType::Num> NightCycleControlTypeNamesUC{
     344              :             "STAYOFF",
     345              :             "CYCLEONANY",
     346              :             "CYCLEONCONTROLZONE",
     347              :             "CYCLEONANYZONEFANSONLY",
     348              :             "CYCLEONANYCOOLINGORHEATINGZONE",
     349              :             "CYCLEONANYCOOLINGZONE",
     350              :             "CYCLEONANYHEATINGZONE",
     351              :             "CYCLEONANYHEATINGZONEFANSONLY",
     352              :         };
     353              : 
     354          143 :         constexpr std::array<std::string_view, (int)OptimumStartControlType::Num> OptimumStartControlTypeNamesUC{
     355              :             "STAYOFF",
     356              :             "CONTROLZONE",
     357              :             "MAXIMUMOFZONELIST",
     358              :         };
     359              : 
     360              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     361          143 :         Array1D_string cAlphaFieldNames;
     362          143 :         Array1D_string cNumericFieldNames;
     363          143 :         Array1D_bool lNumericFieldBlanks;
     364          143 :         Array1D_bool lAlphaFieldBlanks;
     365          143 :         Array1D_string cAlphaArgs;
     366          143 :         Array1D<Real64> rNumericArgs;
     367              :         int NumAlphas;           // Number of Alphas for each GetObjectItem call
     368              :         int NumNumbers;          // Number of Numbers for each GetObjectItem call
     369          143 :         int maxAlphas = 0;       // maximum number of alphas for this set of objects
     370          143 :         int maxNumbers = 0;      // maximum number of numbers for this set of objects
     371              :         int numArgs;             // maximum number of arguments for this set of objects
     372              :         int IOStatus;            // Used in GetObjectItem
     373          143 :         bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
     374              :         int CyclingTimeSteps;
     375              :         int ZoneEquipType;
     376              :         int TotalNumComp;
     377              : 
     378              :         // Get the number of occurrences of each type of manager and read in data
     379         1859 :         for (int currentModuleObjectCount = 0; currentModuleObjectCount < (int)ManagerType::Num; ++currentModuleObjectCount) {
     380         1716 :             std::string_view cCurrentModuleObject = managerTypeNames[currentModuleObjectCount];
     381         1716 :             state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, numArgs, NumAlphas, NumNumbers);
     382         1716 :             maxNumbers = max(maxNumbers, NumNumbers);
     383         1716 :             maxAlphas = max(maxAlphas, NumAlphas);
     384              :         }
     385              : 
     386          143 :         cAlphaFieldNames.allocate(maxAlphas);
     387          143 :         cAlphaArgs.allocate(maxAlphas);
     388          143 :         lAlphaFieldBlanks.dimension(maxAlphas, false);
     389          143 :         cNumericFieldNames.allocate(maxNumbers);
     390          143 :         rNumericArgs.dimension(maxNumbers, 0.0);
     391          143 :         lNumericFieldBlanks.dimension(maxNumbers, false);
     392              : 
     393          143 :         if (!allocated(state.dataAvail->ZoneComp)) {
     394          140 :             state.dataAvail->ZoneComp.allocate(NumValidSysAvailZoneComponents);
     395              :         }
     396              : 
     397         2145 :         for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) {
     398         2002 :             auto &zoneComp = state.dataAvail->ZoneComp(ZoneEquipType);
     399         2002 :             if (!allocated(zoneComp.ZoneCompAvailMgrs)) {
     400         2001 :                 TotalNumComp = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cValidSysAvailManagerCompTypes(ZoneEquipType));
     401         2001 :                 zoneComp.TotalNumComp = TotalNumComp;
     402         2001 :                 if (TotalNumComp > 0) {
     403           19 :                     zoneComp.ZoneCompAvailMgrs.allocate(TotalNumComp);
     404              :                 }
     405              :             }
     406              :         }
     407              : 
     408          143 :         std::string_view cCurrentModuleObject = managerTypeNames[(int)ManagerType::Scheduled];
     409          143 :         state.dataAvail->NumSchedSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     410              : 
     411          143 :         if (state.dataAvail->NumSchedSysAvailMgrs > 0) {
     412              : 
     413           38 :             state.dataAvail->SchedData.allocate(state.dataAvail->NumSchedSysAvailMgrs);
     414              : 
     415           87 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumSchedSysAvailMgrs; ++SysAvailNum) {
     416              : 
     417           49 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     418              :                                                                          cCurrentModuleObject,
     419              :                                                                          SysAvailNum,
     420              :                                                                          cAlphaArgs,
     421              :                                                                          NumAlphas,
     422              :                                                                          rNumericArgs,
     423              :                                                                          NumNumbers,
     424              :                                                                          IOStatus,
     425              :                                                                          lNumericFieldBlanks,
     426              :                                                                          lAlphaFieldBlanks,
     427              :                                                                          cAlphaFieldNames,
     428              :                                                                          cNumericFieldNames);
     429              : 
     430           49 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
     431           49 :                 auto &schedMgr = state.dataAvail->SchedData(SysAvailNum);
     432           49 :                 schedMgr.Name = cAlphaArgs(1);
     433           49 :                 schedMgr.type = ManagerType::Scheduled;
     434              : 
     435           49 :                 if (lAlphaFieldBlanks(2)) {
     436            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
     437           49 :                 } else if ((schedMgr.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
     438            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
     439            0 :                     ErrorsFound = true;
     440              :                 }
     441              : 
     442           49 :                 SetupOutputVariable(state,
     443              :                                     "Availability Manager Scheduled Control Status",
     444              :                                     Constant::Units::None,
     445           49 :                                     (int &)schedMgr.availStatus,
     446              :                                     OutputProcessor::TimeStepType::System,
     447              :                                     OutputProcessor::StoreType::Average,
     448           49 :                                     schedMgr.Name);
     449              : 
     450              :             } // SysAvailNum
     451              :         }
     452              : 
     453          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::ScheduledOn];
     454          143 :         state.dataAvail->NumSchedOnSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     455              : 
     456          143 :         if (state.dataAvail->NumSchedOnSysAvailMgrs > 0) {
     457              : 
     458            1 :             state.dataAvail->SchedOnData.allocate(state.dataAvail->NumSchedOnSysAvailMgrs);
     459              : 
     460            2 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumSchedOnSysAvailMgrs; ++SysAvailNum) {
     461              : 
     462            1 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     463              :                                                                          cCurrentModuleObject,
     464              :                                                                          SysAvailNum,
     465              :                                                                          cAlphaArgs,
     466              :                                                                          NumAlphas,
     467              :                                                                          rNumericArgs,
     468              :                                                                          NumNumbers,
     469              :                                                                          IOStatus,
     470              :                                                                          lNumericFieldBlanks,
     471              :                                                                          lAlphaFieldBlanks,
     472              :                                                                          cAlphaFieldNames,
     473              :                                                                          cNumericFieldNames);
     474              : 
     475            1 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
     476            1 :                 auto &schedOnMgr = state.dataAvail->SchedOnData(SysAvailNum);
     477            1 :                 schedOnMgr.Name = cAlphaArgs(1);
     478            1 :                 schedOnMgr.type = ManagerType::ScheduledOn;
     479              : 
     480            1 :                 if (lAlphaFieldBlanks(2)) {
     481            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
     482            0 :                     ErrorsFound = true;
     483            1 :                 } else if ((schedOnMgr.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
     484            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
     485            0 :                     ErrorsFound = true;
     486              :                 }
     487              : 
     488            1 :                 SetupOutputVariable(state,
     489              :                                     "Availability Manager Scheduled On Control Status",
     490              :                                     Constant::Units::None,
     491            1 :                                     (int &)schedOnMgr.availStatus,
     492              :                                     OutputProcessor::TimeStepType::System,
     493              :                                     OutputProcessor::StoreType::Average,
     494            1 :                                     schedOnMgr.Name);
     495              : 
     496              :             } // SysAvailNum
     497              :         }
     498              : 
     499          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::ScheduledOff];
     500          143 :         state.dataAvail->NumSchedOffSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     501              : 
     502          143 :         if (state.dataAvail->NumSchedOffSysAvailMgrs > 0) {
     503              : 
     504            1 :             state.dataAvail->SchedOffData.allocate(state.dataAvail->NumSchedOffSysAvailMgrs);
     505              : 
     506            2 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumSchedOffSysAvailMgrs; ++SysAvailNum) {
     507              : 
     508            1 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     509              :                                                                          cCurrentModuleObject,
     510              :                                                                          SysAvailNum,
     511              :                                                                          cAlphaArgs,
     512              :                                                                          NumAlphas,
     513              :                                                                          rNumericArgs,
     514              :                                                                          NumNumbers,
     515              :                                                                          IOStatus,
     516              :                                                                          lNumericFieldBlanks,
     517              :                                                                          lAlphaFieldBlanks,
     518              :                                                                          cAlphaFieldNames,
     519              :                                                                          cNumericFieldNames);
     520              : 
     521            1 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
     522            1 :                 auto &schedOffMgr = state.dataAvail->SchedOffData(SysAvailNum);
     523            1 :                 schedOffMgr.Name = cAlphaArgs(1);
     524            1 :                 schedOffMgr.type = ManagerType::ScheduledOff;
     525              : 
     526            1 :                 if (lAlphaFieldBlanks(2)) {
     527            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
     528            0 :                     ErrorsFound = true;
     529            1 :                 } else if ((schedOffMgr.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
     530            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
     531            0 :                     ErrorsFound = true;
     532              :                 }
     533              : 
     534            1 :                 SetupOutputVariable(state,
     535              :                                     "Availability Manager Scheduled Off Control Status",
     536              :                                     Constant::Units::None,
     537            1 :                                     (int &)schedOffMgr.availStatus,
     538              :                                     OutputProcessor::TimeStepType::System,
     539              :                                     OutputProcessor::StoreType::Average,
     540            1 :                                     schedOffMgr.Name);
     541              : 
     542              :             } // SysAvailNum
     543              :         }
     544              : 
     545          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::NightCycle];
     546          143 :         state.dataAvail->NumNCycSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     547          143 :         CyclingTimeSteps = 0;
     548              : 
     549          143 :         if (state.dataAvail->NumNCycSysAvailMgrs > 0) {
     550              : 
     551            9 :             state.dataAvail->NightCycleData.allocate(state.dataAvail->NumNCycSysAvailMgrs);
     552              : 
     553           28 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumNCycSysAvailMgrs; ++SysAvailNum) {
     554              : 
     555           19 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     556              :                                                                          cCurrentModuleObject,
     557              :                                                                          SysAvailNum,
     558              :                                                                          cAlphaArgs,
     559              :                                                                          NumAlphas,
     560              :                                                                          rNumericArgs,
     561              :                                                                          NumNumbers,
     562              :                                                                          IOStatus,
     563              :                                                                          lNumericFieldBlanks,
     564              :                                                                          lAlphaFieldBlanks,
     565              :                                                                          cAlphaFieldNames,
     566              :                                                                          cNumericFieldNames);
     567              : 
     568           19 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
     569           19 :                 auto &nightCycleMgr = state.dataAvail->NightCycleData(SysAvailNum);
     570           19 :                 nightCycleMgr.Name = cAlphaArgs(1);
     571           19 :                 nightCycleMgr.type = ManagerType::NightCycle;
     572           19 :                 nightCycleMgr.TempTolRange = rNumericArgs(1);
     573           19 :                 CyclingTimeSteps = nint((rNumericArgs(2) / Constant::rSecsInHour) * double(state.dataGlobal->TimeStepsInHour));
     574           19 :                 CyclingTimeSteps = max(1, CyclingTimeSteps);
     575           19 :                 nightCycleMgr.CyclingTimeSteps = CyclingTimeSteps;
     576              : 
     577           19 :                 if (lAlphaFieldBlanks(2)) {
     578            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
     579            0 :                     ErrorsFound = true;
     580           19 :                 } else if ((nightCycleMgr.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
     581            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
     582            0 :                     ErrorsFound = true;
     583              :                 }
     584              : 
     585           19 :                 if (lAlphaFieldBlanks(3)) {
     586            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(3));
     587            0 :                     ErrorsFound = true;
     588           19 :                 } else if ((nightCycleMgr.fanSched = Sched::GetSchedule(state, cAlphaArgs(3))) == nullptr) {
     589            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(3), cAlphaArgs(3));
     590            0 :                     ErrorsFound = true;
     591              :                 }
     592              : 
     593           19 :                 nightCycleMgr.nightCycleControlType = static_cast<NightCycleControlType>(getEnumValue(NightCycleControlTypeNamesUC, cAlphaArgs(4)));
     594              : 
     595              :                 // Cycling Run Time Control Type
     596           19 :                 nightCycleMgr.cyclingRunTimeControl = static_cast<CyclingRunTimeControl>(getEnumValue(CyclingRunTimeControlNamesUC, cAlphaArgs(5)));
     597              : 
     598              :                 // Control zone or zonelist
     599           19 :                 if (!lAlphaFieldBlanks(6)) {
     600            3 :                     nightCycleMgr.CtrlZoneListName = cAlphaArgs(6);
     601            3 :                     int ZoneNum = Util::FindItemInList(cAlphaArgs(6), state.dataHeatBal->Zone);
     602            3 :                     if (ZoneNum > 0) {
     603            3 :                         nightCycleMgr.NumOfCtrlZones = 1;
     604            3 :                         nightCycleMgr.CtrlZonePtrs.allocate(1);
     605            3 :                         nightCycleMgr.CtrlZonePtrs(1) = ZoneNum;
     606              :                     } else {
     607            0 :                         int zoneListNum = 0;
     608            0 :                         if (state.dataHeatBal->NumOfZoneLists > 0) {
     609            0 :                             zoneListNum = Util::FindItemInList(cAlphaArgs(6), state.dataHeatBal->ZoneList);
     610              :                         }
     611            0 :                         if (zoneListNum > 0) {
     612            0 :                             int NumZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
     613            0 :                             nightCycleMgr.NumOfCtrlZones = NumZones;
     614            0 :                             nightCycleMgr.CtrlZonePtrs.allocate(NumZones);
     615            0 :                             for (int zoneNumInList = 1; zoneNumInList <= NumZones; ++zoneNumInList) {
     616            0 :                                 nightCycleMgr.CtrlZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
     617              :                             }
     618              :                         } else {
     619            0 :                             ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(6), cAlphaArgs(6));
     620            0 :                             ErrorsFound = true;
     621              :                         }
     622              :                     }
     623           16 :                 } else if (nightCycleMgr.nightCycleControlType == NightCycleControlType::OnControlZone) {
     624            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(6), cAlphaFieldNames(4), cAlphaArgs(4));
     625            0 :                     ErrorsFound = true;
     626              :                 }
     627              : 
     628              :                 // Cooling zone or zonelist
     629           19 :                 if (!lAlphaFieldBlanks(7)) {
     630            0 :                     nightCycleMgr.CoolingZoneListName = cAlphaArgs(7);
     631            0 :                     int ZoneNum = Util::FindItemInList(cAlphaArgs(7), state.dataHeatBal->Zone);
     632            0 :                     if (ZoneNum > 0) {
     633            0 :                         nightCycleMgr.NumOfCoolingZones = 1;
     634            0 :                         nightCycleMgr.CoolingZonePtrs.allocate(1);
     635            0 :                         nightCycleMgr.CoolingZonePtrs(1) = ZoneNum;
     636              :                     } else {
     637            0 :                         int zoneListNum = 0;
     638            0 :                         if (state.dataHeatBal->NumOfZoneLists > 0) {
     639            0 :                             zoneListNum = Util::FindItemInList(cAlphaArgs(7), state.dataHeatBal->ZoneList);
     640              :                         }
     641            0 :                         if (zoneListNum > 0) {
     642            0 :                             int NumZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
     643            0 :                             nightCycleMgr.NumOfCoolingZones = NumZones;
     644            0 :                             nightCycleMgr.CoolingZonePtrs.allocate(NumZones);
     645            0 :                             for (int zoneNumInList = 1; zoneNumInList <= NumZones; ++zoneNumInList) {
     646            0 :                                 nightCycleMgr.CoolingZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
     647              :                             }
     648              :                         } else {
     649            0 :                             ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(7), cAlphaArgs(7));
     650            0 :                             ErrorsFound = true;
     651              :                         }
     652              :                     }
     653              :                 }
     654              : 
     655              :                 // Heating zone or zonelist
     656           19 :                 if (!lAlphaFieldBlanks(8)) {
     657            0 :                     nightCycleMgr.HeatingZoneListName = cAlphaArgs(8);
     658            0 :                     int ZoneNum = Util::FindItemInList(cAlphaArgs(8), state.dataHeatBal->Zone);
     659            0 :                     if (ZoneNum > 0) {
     660            0 :                         nightCycleMgr.NumOfHeatingZones = 1;
     661            0 :                         nightCycleMgr.HeatingZonePtrs.allocate(1);
     662            0 :                         nightCycleMgr.HeatingZonePtrs(1) = ZoneNum;
     663              :                     } else {
     664            0 :                         int zoneListNum = 0;
     665            0 :                         if (state.dataHeatBal->NumOfZoneLists > 0) {
     666            0 :                             zoneListNum = Util::FindItemInList(cAlphaArgs(8), state.dataHeatBal->ZoneList);
     667              :                         }
     668            0 :                         if (zoneListNum > 0) {
     669            0 :                             int NumZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
     670            0 :                             nightCycleMgr.NumOfHeatingZones = NumZones;
     671            0 :                             nightCycleMgr.HeatingZonePtrs.allocate(NumZones);
     672            0 :                             for (int zoneNumInList = 1; zoneNumInList <= NumZones; ++zoneNumInList) {
     673            0 :                                 nightCycleMgr.HeatingZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
     674              :                             }
     675              :                         } else {
     676            0 :                             ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(8), cAlphaArgs(8));
     677            0 :                             ErrorsFound = true;
     678              :                         }
     679              :                     }
     680              :                 }
     681              : 
     682              :                 // HeatZnFan zone or zonelist
     683           19 :                 if (!lAlphaFieldBlanks(9)) {
     684            0 :                     nightCycleMgr.HeatZnFanZoneListName = cAlphaArgs(9);
     685            0 :                     int ZoneNum = Util::FindItemInList(cAlphaArgs(9), state.dataHeatBal->Zone);
     686            0 :                     if (ZoneNum > 0) {
     687            0 :                         nightCycleMgr.NumOfHeatZnFanZones = 1;
     688            0 :                         nightCycleMgr.HeatZnFanZonePtrs.allocate(1);
     689            0 :                         nightCycleMgr.HeatZnFanZonePtrs(1) = ZoneNum;
     690              :                     } else {
     691            0 :                         int zoneListNum = 0;
     692            0 :                         if (state.dataHeatBal->NumOfZoneLists > 0) {
     693            0 :                             zoneListNum = Util::FindItemInList(cAlphaArgs(9), state.dataHeatBal->ZoneList);
     694              :                         }
     695            0 :                         if (zoneListNum > 0) {
     696            0 :                             int NumZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
     697            0 :                             nightCycleMgr.NumOfHeatZnFanZones = NumZones;
     698            0 :                             nightCycleMgr.HeatZnFanZonePtrs.allocate(NumZones);
     699            0 :                             for (int zoneNumInList = 1; zoneNumInList <= NumZones; ++zoneNumInList) {
     700            0 :                                 nightCycleMgr.HeatZnFanZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
     701              :                             }
     702              :                         } else {
     703            0 :                             ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(9), cAlphaArgs(9));
     704            0 :                             ErrorsFound = true;
     705              :                         }
     706              :                     }
     707              :                 }
     708              : 
     709           19 :                 SetupOutputVariable(state,
     710              :                                     "Availability Manager Night Cycle Control Status",
     711              :                                     Constant::Units::None,
     712           19 :                                     (int &)nightCycleMgr.availStatus,
     713              :                                     OutputProcessor::TimeStepType::System,
     714              :                                     OutputProcessor::StoreType::Average,
     715           19 :                                     nightCycleMgr.Name);
     716              : 
     717              :             } // SysAvailNum
     718              :         }
     719              : 
     720          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::OptimumStart];
     721          143 :         state.dataAvail->NumOptStartSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     722          143 :         CyclingTimeSteps = 0;
     723              : 
     724          143 :         if (state.dataAvail->NumOptStartSysAvailMgrs > 0) {
     725              :             // Array size of variable type OptStartSysAvailMgrData is updated
     726            1 :             state.dataAvail->OptimumStartData.allocate(state.dataAvail->NumOptStartSysAvailMgrs);
     727              : 
     728            4 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumOptStartSysAvailMgrs; ++SysAvailNum) {
     729              : 
     730            3 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     731              :                                                                          cCurrentModuleObject,
     732              :                                                                          SysAvailNum,
     733              :                                                                          cAlphaArgs,
     734              :                                                                          NumAlphas,
     735              :                                                                          rNumericArgs,
     736              :                                                                          NumNumbers,
     737              :                                                                          IOStatus,
     738              :                                                                          lNumericFieldBlanks,
     739              :                                                                          lAlphaFieldBlanks,
     740              :                                                                          cAlphaFieldNames,
     741              :                                                                          cNumericFieldNames);
     742              : 
     743            3 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
     744            3 :                 auto &optimumStartMgr = state.dataAvail->OptimumStartData(SysAvailNum);
     745            3 :                 optimumStartMgr.Name = cAlphaArgs(1);
     746            3 :                 optimumStartMgr.type = ManagerType::OptimumStart;
     747              : 
     748            3 :                 if (lAlphaFieldBlanks(2)) {
     749            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
     750            0 :                     ErrorsFound = true;
     751            3 :                 } else if ((optimumStartMgr.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
     752            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
     753            0 :                     ErrorsFound = true;
     754              :                 }
     755              : 
     756            3 :                 if (lAlphaFieldBlanks(3)) {
     757            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(3));
     758            0 :                     ErrorsFound = true;
     759            3 :                 } else if ((optimumStartMgr.fanSched = Sched::GetSchedule(state, cAlphaArgs(3))) == nullptr) {
     760            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(3), cAlphaArgs(3));
     761            0 :                     ErrorsFound = true;
     762              :                 }
     763              : 
     764            3 :                 optimumStartMgr.MaxOptStartTime = rNumericArgs(1);
     765            3 :                 optimumStartMgr.optimumStartControlType =
     766            3 :                     static_cast<OptimumStartControlType>(getEnumValue(OptimumStartControlTypeNamesUC, cAlphaArgs(4)));
     767              : 
     768            3 :                 if (optimumStartMgr.optimumStartControlType == OptimumStartControlType::Invalid) {
     769            0 :                     optimumStartMgr.optimumStartControlType = OptimumStartControlType::ControlZone;
     770            0 :                     ShowSevereInvalidKey(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
     771            0 :                     ErrorsFound = true;
     772              :                 }
     773              : 
     774            3 :                 if (optimumStartMgr.optimumStartControlType == OptimumStartControlType::ControlZone) {
     775            2 :                     optimumStartMgr.CtrlZoneName = cAlphaArgs(5);
     776            2 :                     optimumStartMgr.ZoneNum = Util::FindItemInList(cAlphaArgs(5), state.dataHeatBal->Zone);
     777            2 :                     if (optimumStartMgr.ZoneNum == 0) {
     778            0 :                         ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(5), cAlphaArgs(5));
     779            0 :                         ErrorsFound = true;
     780              :                     }
     781              :                 }
     782              : 
     783            3 :                 if (optimumStartMgr.optimumStartControlType == OptimumStartControlType::MaximumOfZoneList) {
     784            1 :                     optimumStartMgr.ZoneListName = cAlphaArgs(6);
     785            2 :                     for (int zoneListNum = 1; zoneListNum <= state.dataHeatBal->NumOfZoneLists; ++zoneListNum) {
     786            1 :                         if (state.dataHeatBal->ZoneList(zoneListNum).Name == cAlphaArgs(6)) {
     787            1 :                             optimumStartMgr.NumOfZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
     788            1 :                             optimumStartMgr.ZonePtrs.allocate(state.dataHeatBal->ZoneList(zoneListNum).NumOfZones);
     789            4 :                             for (int zoneNumInList = 1; zoneNumInList <= state.dataHeatBal->ZoneList(zoneListNum).NumOfZones; ++zoneNumInList) {
     790            3 :                                 optimumStartMgr.ZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
     791              :                             }
     792              :                         }
     793              :                     }
     794            1 :                     optimumStartMgr.NumOfZones = Util::FindItemInList(cAlphaArgs(6), state.dataHeatBal->ZoneList);
     795            1 :                     if (optimumStartMgr.NumOfZones == 0) {
     796            0 :                         ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(6), cAlphaArgs(6));
     797            0 :                         ErrorsFound = true;
     798              :                     }
     799              :                 }
     800              : 
     801            3 :                 optimumStartMgr.controlAlgorithm = static_cast<ControlAlgorithm>(getEnumValue(ControlAlgorithmNamesUC, cAlphaArgs(7)));
     802              : 
     803            3 :                 switch (optimumStartMgr.controlAlgorithm) {
     804            0 :                 case ControlAlgorithm::ConstantTemperatureGradient: {
     805            0 :                     optimumStartMgr.ConstTGradCool = rNumericArgs(2);
     806            0 :                     optimumStartMgr.ConstTGradHeat = rNumericArgs(3);
     807            0 :                 } break;
     808              : 
     809            3 :                 case ControlAlgorithm::AdaptiveTemperatureGradient: {
     810            3 :                     optimumStartMgr.InitTGradCool = rNumericArgs(4);
     811            3 :                     optimumStartMgr.InitTGradHeat = rNumericArgs(5);
     812            3 :                     optimumStartMgr.NumPreDays = rNumericArgs(7);
     813            3 :                 } break;
     814              : 
     815            0 :                 case ControlAlgorithm::ConstantStartTime: {
     816            0 :                     optimumStartMgr.ConstStartTime = rNumericArgs(6);
     817            0 :                 } break;
     818              : 
     819            0 :                 default:
     820            0 :                     break;
     821              :                 }
     822              : 
     823            3 :                 SetupOutputVariable(state,
     824              :                                     "Availability Manager Optimum Start Control Status",
     825              :                                     Constant::Units::None,
     826            3 :                                     (int &)optimumStartMgr.availStatus,
     827              :                                     OutputProcessor::TimeStepType::System,
     828              :                                     OutputProcessor::StoreType::Average,
     829            3 :                                     optimumStartMgr.Name);
     830              : 
     831              :                 // add
     832           18 :                 SetupOutputVariable(state,
     833              :                                     "Availability Manager Optimum Start Time Before Occupancy",
     834              :                                     Constant::Units::hr,
     835            3 :                                     optimumStartMgr.NumHoursBeforeOccupancy,
     836              :                                     OutputProcessor::TimeStepType::System,
     837              :                                     OutputProcessor::StoreType::Average,
     838            3 :                                     optimumStartMgr.Name,
     839              :                                     Constant::eResource::Invalid,
     840              :                                     OutputProcessor::Group::Invalid,
     841              :                                     OutputProcessor::EndUseCat::Invalid,
     842              :                                     "",   // End-use SubCat
     843              :                                     "",   // Zone
     844              :                                     1,    // ZoneMult
     845              :                                     1,    // ZoneListMult
     846              :                                     "",   // space type
     847              :                                     -999, // indexGroupKey
     848              :                                     "",   // custom units
     849              :                                     OutputProcessor::ReportFreq::Day);
     850              :             }
     851              :         }
     852              : 
     853          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::DiffThermo];
     854          143 :         state.dataAvail->NumDiffTSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     855              : 
     856          143 :         if (state.dataAvail->NumDiffTSysAvailMgrs > 0) {
     857              : 
     858            0 :             state.dataAvail->DiffThermoData.allocate(state.dataAvail->NumDiffTSysAvailMgrs);
     859              : 
     860            0 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumDiffTSysAvailMgrs; ++SysAvailNum) {
     861              : 
     862            0 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     863              :                                                                          cCurrentModuleObject,
     864              :                                                                          SysAvailNum,
     865              :                                                                          cAlphaArgs,
     866              :                                                                          NumAlphas,
     867              :                                                                          rNumericArgs,
     868              :                                                                          NumNumbers,
     869              :                                                                          IOStatus,
     870              :                                                                          lNumericFieldBlanks,
     871              :                                                                          lAlphaFieldBlanks,
     872              :                                                                          cAlphaFieldNames,
     873              :                                                                          cNumericFieldNames);
     874              : 
     875            0 :                 auto &diffThermoMgr = state.dataAvail->DiffThermoData(SysAvailNum);
     876            0 :                 diffThermoMgr.Name = cAlphaArgs(1);
     877            0 :                 diffThermoMgr.type = ManagerType::DiffThermo;
     878              : 
     879            0 :                 diffThermoMgr.HotNode = GetOnlySingleNode(state,
     880            0 :                                                           cAlphaArgs(2),
     881              :                                                           ErrorsFound,
     882              :                                                           DataLoopNode::ConnectionObjectType::AvailabilityManagerDifferentialThermostat,
     883            0 :                                                           cAlphaArgs(1),
     884              :                                                           DataLoopNode::NodeFluidType::Blank,
     885              :                                                           DataLoopNode::ConnectionType::Sensor,
     886              :                                                           NodeInputManager::CompFluidStream::Primary,
     887              :                                                           ObjectIsNotParent);
     888            0 :                 MarkNode(state,
     889              :                          diffThermoMgr.HotNode,
     890              :                          DataLoopNode::ConnectionObjectType::AvailabilityManagerDifferentialThermostat,
     891            0 :                          cAlphaArgs(1),
     892              :                          "Hot Node");
     893            0 :                 diffThermoMgr.ColdNode = GetOnlySingleNode(state,
     894            0 :                                                            cAlphaArgs(3),
     895              :                                                            ErrorsFound,
     896              :                                                            DataLoopNode::ConnectionObjectType::AvailabilityManagerDifferentialThermostat,
     897            0 :                                                            cAlphaArgs(1),
     898              :                                                            DataLoopNode::NodeFluidType::Blank,
     899              :                                                            DataLoopNode::ConnectionType::Sensor,
     900              :                                                            NodeInputManager::CompFluidStream::Primary,
     901              :                                                            ObjectIsNotParent);
     902            0 :                 MarkNode(state,
     903              :                          diffThermoMgr.ColdNode,
     904              :                          DataLoopNode::ConnectionObjectType::AvailabilityManagerDifferentialThermostat,
     905            0 :                          cAlphaArgs(1),
     906              :                          "Cold Node");
     907              : 
     908            0 :                 diffThermoMgr.TempDiffOn = rNumericArgs(1);
     909              : 
     910            0 :                 if (NumNumbers > 1) {
     911            0 :                     diffThermoMgr.TempDiffOff = rNumericArgs(2);
     912              :                 } else {
     913            0 :                     diffThermoMgr.TempDiffOff = diffThermoMgr.TempDiffOn;
     914              :                 }
     915              : 
     916            0 :                 if (diffThermoMgr.TempDiffOff > diffThermoMgr.TempDiffOn) {
     917            0 :                     ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
     918            0 :                     ShowContinueError(state, format("The {} is greater than the {}.", cNumericFieldNames(2), cNumericFieldNames(1)));
     919            0 :                     ErrorsFound = true;
     920              :                 }
     921              : 
     922            0 :                 SetupOutputVariable(state,
     923              :                                     "Availability Manager Differential Thermostat Control Status",
     924              :                                     Constant::Units::None,
     925            0 :                                     (int &)diffThermoMgr.availStatus,
     926              :                                     OutputProcessor::TimeStepType::System,
     927              :                                     OutputProcessor::StoreType::Average,
     928            0 :                                     diffThermoMgr.Name);
     929              : 
     930              :             } // SysAvailNum
     931              :         }
     932              : 
     933          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::HiTempTOff];
     934          143 :         state.dataAvail->NumHiTurnOffSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     935              : 
     936          143 :         if (state.dataAvail->NumHiTurnOffSysAvailMgrs > 0) {
     937            0 :             state.dataAvail->HiTurnOffData.allocate(state.dataAvail->NumHiTurnOffSysAvailMgrs);
     938              : 
     939            0 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHiTurnOffSysAvailMgrs; ++SysAvailNum) {
     940              : 
     941            0 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     942              :                                                                          cCurrentModuleObject,
     943              :                                                                          SysAvailNum,
     944              :                                                                          cAlphaArgs,
     945              :                                                                          NumAlphas,
     946              :                                                                          rNumericArgs,
     947              :                                                                          NumNumbers,
     948              :                                                                          IOStatus,
     949              :                                                                          lNumericFieldBlanks,
     950              :                                                                          lAlphaFieldBlanks,
     951              :                                                                          cAlphaFieldNames,
     952              :                                                                          cNumericFieldNames);
     953              : 
     954            0 :                 auto &hiTurnOffMgr = state.dataAvail->HiTurnOffData(SysAvailNum);
     955            0 :                 hiTurnOffMgr.Name = cAlphaArgs(1);
     956            0 :                 hiTurnOffMgr.type = ManagerType::HiTempTOff;
     957              : 
     958            0 :                 hiTurnOffMgr.Node = GetOnlySingleNode(state,
     959            0 :                                                       cAlphaArgs(2),
     960              :                                                       ErrorsFound,
     961              :                                                       DataLoopNode::ConnectionObjectType::AvailabilityManagerHighTemperatureTurnOff,
     962            0 :                                                       cAlphaArgs(1),
     963              :                                                       DataLoopNode::NodeFluidType::Blank,
     964              :                                                       DataLoopNode::ConnectionType::Sensor,
     965              :                                                       NodeInputManager::CompFluidStream::Primary,
     966              :                                                       ObjectIsNotParent);
     967            0 :                 MarkNode(state,
     968              :                          hiTurnOffMgr.Node,
     969              :                          DataLoopNode::ConnectionObjectType::AvailabilityManagerHighTemperatureTurnOff,
     970            0 :                          cAlphaArgs(1),
     971              :                          "Sensor Node");
     972              : 
     973            0 :                 hiTurnOffMgr.Temp = rNumericArgs(1);
     974              : 
     975            0 :                 SetupOutputVariable(state,
     976              :                                     "Availability Manager High Temperature Turn Off Control Status",
     977              :                                     Constant::Units::None,
     978            0 :                                     (int &)hiTurnOffMgr.availStatus,
     979              :                                     OutputProcessor::TimeStepType::System,
     980              :                                     OutputProcessor::StoreType::Average,
     981            0 :                                     hiTurnOffMgr.Name);
     982              : 
     983              :             } // SysAvailNum
     984              :         }
     985              : 
     986          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::HiTempTOn];
     987          143 :         state.dataAvail->NumHiTurnOnSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     988              : 
     989          143 :         if (state.dataAvail->NumHiTurnOnSysAvailMgrs > 0) {
     990              : 
     991            0 :             state.dataAvail->HiTurnOnData.allocate(state.dataAvail->NumHiTurnOnSysAvailMgrs);
     992              : 
     993            0 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHiTurnOnSysAvailMgrs; ++SysAvailNum) {
     994              : 
     995            0 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     996              :                                                                          cCurrentModuleObject,
     997              :                                                                          SysAvailNum,
     998              :                                                                          cAlphaArgs,
     999              :                                                                          NumAlphas,
    1000              :                                                                          rNumericArgs,
    1001              :                                                                          NumNumbers,
    1002              :                                                                          IOStatus,
    1003              :                                                                          lNumericFieldBlanks,
    1004              :                                                                          lAlphaFieldBlanks,
    1005              :                                                                          cAlphaFieldNames,
    1006              :                                                                          cNumericFieldNames);
    1007            0 :                 auto &hiTurnOnMgr = state.dataAvail->HiTurnOnData(SysAvailNum);
    1008            0 :                 hiTurnOnMgr.Name = cAlphaArgs(1);
    1009            0 :                 hiTurnOnMgr.type = ManagerType::HiTempTOn;
    1010              : 
    1011            0 :                 hiTurnOnMgr.Node = GetOnlySingleNode(state,
    1012            0 :                                                      cAlphaArgs(2),
    1013              :                                                      ErrorsFound,
    1014              :                                                      DataLoopNode::ConnectionObjectType::AvailabilityManagerHighTemperatureTurnOn,
    1015            0 :                                                      cAlphaArgs(1),
    1016              :                                                      DataLoopNode::NodeFluidType::Blank,
    1017              :                                                      DataLoopNode::ConnectionType::Sensor,
    1018              :                                                      NodeInputManager::CompFluidStream::Primary,
    1019              :                                                      ObjectIsNotParent);
    1020            0 :                 MarkNode(state,
    1021              :                          hiTurnOnMgr.Node,
    1022              :                          DataLoopNode::ConnectionObjectType::AvailabilityManagerHighTemperatureTurnOn,
    1023            0 :                          cAlphaArgs(1),
    1024              :                          "Sensor Node");
    1025              : 
    1026            0 :                 hiTurnOnMgr.Temp = rNumericArgs(1);
    1027              : 
    1028            0 :                 SetupOutputVariable(state,
    1029              :                                     "Availability Manager High Temperature Turn On Control Status",
    1030              :                                     Constant::Units::None,
    1031            0 :                                     (int &)hiTurnOnMgr.availStatus,
    1032              :                                     OutputProcessor::TimeStepType::System,
    1033              :                                     OutputProcessor::StoreType::Average,
    1034            0 :                                     hiTurnOnMgr.Name);
    1035              : 
    1036              :             } // SysAvailNum
    1037              :         }
    1038              : 
    1039          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::LoTempTOff];
    1040          143 :         state.dataAvail->NumLoTurnOffSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1041              : 
    1042          143 :         if (state.dataAvail->NumLoTurnOffSysAvailMgrs > 0) {
    1043              : 
    1044            1 :             state.dataAvail->LoTurnOffData.allocate(state.dataAvail->NumLoTurnOffSysAvailMgrs);
    1045              : 
    1046            2 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumLoTurnOffSysAvailMgrs; ++SysAvailNum) {
    1047              : 
    1048            1 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1049              :                                                                          cCurrentModuleObject,
    1050              :                                                                          SysAvailNum,
    1051              :                                                                          cAlphaArgs,
    1052              :                                                                          NumAlphas,
    1053              :                                                                          rNumericArgs,
    1054              :                                                                          NumNumbers,
    1055              :                                                                          IOStatus,
    1056              :                                                                          lNumericFieldBlanks,
    1057              :                                                                          lAlphaFieldBlanks,
    1058              :                                                                          cAlphaFieldNames,
    1059              :                                                                          cNumericFieldNames);
    1060            1 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
    1061            1 :                 auto &loTurnOffMgr = state.dataAvail->LoTurnOffData(SysAvailNum);
    1062            1 :                 loTurnOffMgr.Name = cAlphaArgs(1);
    1063            1 :                 loTurnOffMgr.type = ManagerType::LoTempTOff;
    1064              : 
    1065            2 :                 loTurnOffMgr.Node = GetOnlySingleNode(state,
    1066            1 :                                                       cAlphaArgs(2),
    1067              :                                                       ErrorsFound,
    1068              :                                                       DataLoopNode::ConnectionObjectType::AvailabilityManagerLowTemperatureTurnOff,
    1069            1 :                                                       cAlphaArgs(1),
    1070              :                                                       DataLoopNode::NodeFluidType::Blank,
    1071              :                                                       DataLoopNode::ConnectionType::Sensor,
    1072              :                                                       NodeInputManager::CompFluidStream::Primary,
    1073              :                                                       ObjectIsNotParent);
    1074            2 :                 MarkNode(state,
    1075              :                          loTurnOffMgr.Node,
    1076              :                          DataLoopNode::ConnectionObjectType::AvailabilityManagerLowTemperatureTurnOff,
    1077            1 :                          cAlphaArgs(1),
    1078              :                          "Sensor Node");
    1079              : 
    1080            1 :                 loTurnOffMgr.Temp = rNumericArgs(1);
    1081              : 
    1082            1 :                 if (lAlphaFieldBlanks(3)) {
    1083            0 :                 } else if ((loTurnOffMgr.availSched = Sched::GetSchedule(state, cAlphaArgs(3))) == nullptr) {
    1084            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(3), cAlphaArgs(3));
    1085            0 :                     ErrorsFound = true;
    1086              :                 }
    1087              : 
    1088            1 :                 SetupOutputVariable(state,
    1089              :                                     "Availability Manager Low Temperature Turn Off Control Status",
    1090              :                                     Constant::Units::None,
    1091            1 :                                     (int &)loTurnOffMgr.availStatus,
    1092              :                                     OutputProcessor::TimeStepType::System,
    1093              :                                     OutputProcessor::StoreType::Average,
    1094            1 :                                     loTurnOffMgr.Name);
    1095              : 
    1096              :             } // SysAvailNum
    1097              :         }
    1098              : 
    1099          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::LoTempTOn];
    1100          143 :         state.dataAvail->NumLoTurnOnSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1101              : 
    1102          143 :         if (state.dataAvail->NumLoTurnOnSysAvailMgrs > 0) {
    1103              : 
    1104            0 :             state.dataAvail->LoTurnOnData.allocate(state.dataAvail->NumLoTurnOnSysAvailMgrs);
    1105              : 
    1106            0 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumLoTurnOnSysAvailMgrs; ++SysAvailNum) {
    1107              : 
    1108            0 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1109              :                                                                          cCurrentModuleObject,
    1110              :                                                                          SysAvailNum,
    1111              :                                                                          cAlphaArgs,
    1112              :                                                                          NumAlphas,
    1113              :                                                                          rNumericArgs,
    1114              :                                                                          NumNumbers,
    1115              :                                                                          IOStatus,
    1116              :                                                                          lNumericFieldBlanks,
    1117              :                                                                          lAlphaFieldBlanks,
    1118              :                                                                          cAlphaFieldNames,
    1119              :                                                                          cNumericFieldNames);
    1120              : 
    1121            0 :                 auto &loTurnOnMgr = state.dataAvail->LoTurnOnData(SysAvailNum);
    1122            0 :                 loTurnOnMgr.Name = cAlphaArgs(1);
    1123            0 :                 loTurnOnMgr.type = ManagerType::LoTempTOn;
    1124              : 
    1125            0 :                 loTurnOnMgr.Node = GetOnlySingleNode(state,
    1126            0 :                                                      cAlphaArgs(2),
    1127              :                                                      ErrorsFound,
    1128              :                                                      DataLoopNode::ConnectionObjectType::AvailabilityManagerLowTemperatureTurnOn,
    1129            0 :                                                      cAlphaArgs(1),
    1130              :                                                      DataLoopNode::NodeFluidType::Blank,
    1131              :                                                      DataLoopNode::ConnectionType::Sensor,
    1132              :                                                      NodeInputManager::CompFluidStream::Primary,
    1133              :                                                      ObjectIsNotParent);
    1134            0 :                 MarkNode(state,
    1135              :                          loTurnOnMgr.Node,
    1136              :                          DataLoopNode::ConnectionObjectType::AvailabilityManagerLowTemperatureTurnOn,
    1137            0 :                          cAlphaArgs(1),
    1138              :                          "Sensor Node");
    1139              : 
    1140            0 :                 loTurnOnMgr.Temp = rNumericArgs(1);
    1141              : 
    1142            0 :                 SetupOutputVariable(state,
    1143              :                                     "Availability Manager Low Temperature Turn On Control Status",
    1144              :                                     Constant::Units::None,
    1145            0 :                                     (int &)loTurnOnMgr.availStatus,
    1146              :                                     OutputProcessor::TimeStepType::System,
    1147              :                                     OutputProcessor::StoreType::Average,
    1148            0 :                                     loTurnOnMgr.Name);
    1149              : 
    1150              :             } // SysAvailNum
    1151              :         }
    1152              : 
    1153          143 :         cCurrentModuleObject = managerTypeNames[(int)ManagerType::NightVent];
    1154          143 :         state.dataAvail->NumNVentSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    1155              : 
    1156          143 :         if (state.dataAvail->NumNVentSysAvailMgrs > 0) {
    1157              : 
    1158            0 :             state.dataAvail->NightVentData.allocate(state.dataAvail->NumNVentSysAvailMgrs);
    1159              : 
    1160            0 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumNVentSysAvailMgrs; ++SysAvailNum) {
    1161              : 
    1162            0 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1163              :                                                                          cCurrentModuleObject,
    1164              :                                                                          SysAvailNum,
    1165              :                                                                          cAlphaArgs,
    1166              :                                                                          NumAlphas,
    1167              :                                                                          rNumericArgs,
    1168              :                                                                          NumNumbers,
    1169              :                                                                          IOStatus,
    1170              :                                                                          lNumericFieldBlanks,
    1171              :                                                                          lAlphaFieldBlanks,
    1172              :                                                                          cAlphaFieldNames,
    1173              :                                                                          cNumericFieldNames);
    1174              : 
    1175            0 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, cAlphaArgs(1)};
    1176            0 :                 auto &nightVentMgr = state.dataAvail->NightVentData(SysAvailNum);
    1177            0 :                 nightVentMgr.Name = cAlphaArgs(1);
    1178            0 :                 nightVentMgr.type = ManagerType::NightVent;
    1179              : 
    1180            0 :                 if (lAlphaFieldBlanks(2)) {
    1181            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(2));
    1182            0 :                     ErrorsFound = true;
    1183            0 :                 } else if ((nightVentMgr.availSched = Sched::GetSchedule(state, cAlphaArgs(2))) == nullptr) {
    1184            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(2), cAlphaArgs(2));
    1185            0 :                     ErrorsFound = true;
    1186              :                 }
    1187              : 
    1188            0 :                 if (lAlphaFieldBlanks(3)) {
    1189            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(3));
    1190            0 :                     ErrorsFound = true;
    1191            0 :                 } else if ((nightVentMgr.fanSched = Sched::GetSchedule(state, cAlphaArgs(3))) == nullptr) {
    1192            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(3), cAlphaArgs(3));
    1193            0 :                     ErrorsFound = true;
    1194              :                 }
    1195              : 
    1196            0 :                 if (lAlphaFieldBlanks(4)) {
    1197            0 :                     ShowSevereEmptyField(state, eoh, cAlphaFieldNames(4));
    1198            0 :                     ErrorsFound = true;
    1199            0 :                 } else if ((nightVentMgr.ventTempSched = Sched::GetSchedule(state, cAlphaArgs(4))) == nullptr) {
    1200            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(4), cAlphaArgs(4));
    1201            0 :                     ErrorsFound = true;
    1202              :                 }
    1203              : 
    1204            0 :                 nightVentMgr.VentDelT = rNumericArgs(1);
    1205            0 :                 nightVentMgr.VentTempLowLim = rNumericArgs(2);
    1206            0 :                 nightVentMgr.VentFlowFrac = rNumericArgs(3);
    1207            0 :                 nightVentMgr.CtrlZoneName = cAlphaArgs(5);
    1208            0 :                 nightVentMgr.ZoneNum = Util::FindItemInList(cAlphaArgs(5), state.dataHeatBal->Zone);
    1209            0 :                 if (nightVentMgr.ZoneNum == 0) {
    1210            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFieldNames(5), cAlphaArgs(5));
    1211            0 :                     ErrorsFound = true;
    1212              :                 }
    1213              : 
    1214            0 :                 SetupOutputVariable(state,
    1215              :                                     "Availability Manager Night Ventilation Control Status",
    1216              :                                     Constant::Units::None,
    1217            0 :                                     (int &)nightVentMgr.availStatus,
    1218              :                                     OutputProcessor::TimeStepType::System,
    1219              :                                     OutputProcessor::StoreType::Average,
    1220            0 :                                     nightVentMgr.Name);
    1221              : 
    1222              :             } // SysAvailNum
    1223              :         }
    1224              : 
    1225          143 :         cAlphaFieldNames.deallocate();
    1226          143 :         cAlphaArgs.deallocate();
    1227          143 :         lAlphaFieldBlanks.deallocate();
    1228          143 :         cNumericFieldNames.deallocate();
    1229          143 :         rNumericArgs.deallocate();
    1230          143 :         lNumericFieldBlanks.deallocate();
    1231              : 
    1232          143 :         if (ErrorsFound) {
    1233            0 :             ShowFatalError(state, format("{}Errors found in input.  Preceding condition(s) cause termination.", RoutineName));
    1234              :         }
    1235          143 :     } // GetSysAvailManagerInputs()
    1236              : 
    1237           90 :     void GetSysAvailManagerListInputs(EnergyPlusData &state)
    1238              :     {
    1239              : 
    1240              :         // SUBROUTINE INFORMATION:
    1241              :         //       AUTHOR         Linda Lawrie
    1242              :         //       DATE WRITTEN   August 2007
    1243              :         //       MODIFIED       na
    1244              :         //       RE-ENGINEERED  na
    1245              : 
    1246              :         // PURPOSE OF THIS SUBROUTINE:
    1247              :         // This routine gets the System Availability Manager List object input and stores
    1248              :         // it for later retrieval of items from the Plant and Air Loops.
    1249              : 
    1250           90 :         if (state.dataAvail->GetAvailMgrInputFlag) {
    1251           78 :             GetSysAvailManagerInputs(state);
    1252           78 :             state.dataAvail->GetAvailMgrInputFlag = false;
    1253              :         }
    1254              : 
    1255           90 :         bool ErrorsFound = false;
    1256           90 :         std::string const cCurrentModuleObject = "AvailabilityManagerAssignmentList";
    1257           90 :         auto &ip = state.dataInputProcessing->inputProcessor;
    1258              : 
    1259           90 :         state.dataAvail->NumAvailManagerLists = ip->getNumObjectsFound(state, cCurrentModuleObject);
    1260              : 
    1261           90 :         if (state.dataAvail->NumAvailManagerLists > 0) {
    1262              : 
    1263           41 :             state.dataAvail->ListData.allocate(state.dataAvail->NumAvailManagerLists);
    1264           41 :             auto const instances = ip->epJSON.find(cCurrentModuleObject);
    1265           41 :             auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
    1266              : 
    1267           41 :             auto &instancesValue = instances.value();
    1268           41 :             int Item = 0;
    1269          106 :             for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
    1270           65 :                 ++Item;
    1271           65 :                 auto const &objectFields = instance.value();
    1272           65 :                 std::string const thisObjectName = Util::makeUPPER(instance.key());
    1273           65 :                 ip->markObjectAsUsed(cCurrentModuleObject, instance.key());
    1274           65 :                 auto &mgrList = state.dataAvail->ListData(Item);
    1275           65 :                 mgrList.Name = thisObjectName;
    1276              : 
    1277           65 :                 auto extensibles = objectFields.find("managers");
    1278           65 :                 auto const &extensionSchemaProps = objectSchemaProps["managers"]["items"]["properties"];
    1279           65 :                 if (extensibles != objectFields.end()) {
    1280           65 :                     auto &extensiblesArray = extensibles.value();
    1281           65 :                     int numExtensibles = extensiblesArray.size();
    1282           65 :                     mgrList.NumItems = numExtensibles;
    1283           65 :                     mgrList.availManagers.allocate(numExtensibles);
    1284          131 :                     for (int extItem = 1; extItem <= numExtensibles; ++extItem) {
    1285           66 :                         mgrList.availManagers(extItem).Name = "";
    1286           66 :                         mgrList.availManagers(extItem).type = ManagerType::Invalid;
    1287              :                     }
    1288              : 
    1289           65 :                     int listItem = 0;
    1290          131 :                     for (nlohmann::json const &extensibleInstance : extensiblesArray) {
    1291           66 :                         ++listItem;
    1292           66 :                         mgrList.availManagers(listItem).Name =
    1293          198 :                             ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "availability_manager_name");
    1294              :                         std::string availManagerObjType =
    1295          132 :                             ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "availability_manager_object_type");
    1296          132 :                         mgrList.availManagers(listItem).type =
    1297           66 :                             static_cast<ManagerType>(getEnumValue(managerTypeNamesUC, Util::makeUPPER(availManagerObjType)));
    1298           66 :                         if (mgrList.availManagers(listItem).type == ManagerType::HybridVent) {
    1299            0 :                             mgrList.availManagers(listItem).type = ManagerType::Invalid;
    1300              :                         }
    1301              :                         // these are validated individually in the GetPlant, GetSystem and GetZoneEq lists
    1302          131 :                     }
    1303              :                 }
    1304          106 :             }
    1305              : 
    1306           41 :             if (ErrorsFound) {
    1307            0 :                 ShowFatalError(state, "GetSysAvailManagerListInputs: Program terminates due to preceding conditions.");
    1308              :             }
    1309           41 :         }
    1310           90 :     } // GetSysAvailManagerListInputs()
    1311              : 
    1312           54 :     void GetPlantAvailabilityManager(EnergyPlusData &state,
    1313              :                                      std::string const &AvailabilityListName, // name that should be an Availability Manager List Name
    1314              :                                      int const Loop,                          // which loop this is
    1315              :                                      int const NumPlantLoops,                 // Total number of plant loops
    1316              :                                      bool &ErrorsFound                        // true if certain errors are detected here
    1317              :     )
    1318              :     {
    1319              : 
    1320              :         // SUBROUTINE INFORMATION:
    1321              :         //       AUTHOR         Linda Lawrie
    1322              :         //       DATE WRITTEN   August 2007
    1323              :         //       MODIFIED       na
    1324              :         //       RE-ENGINEERED  na
    1325              : 
    1326              :         // PURPOSE OF THIS SUBROUTINE:
    1327              :         // This subroutine gets the plant availability manager data for the indicated
    1328              :         // loop.  If the PlantAvailMgr structure has not been allocated, it will be allocated
    1329              :         // to "number of plant loops".
    1330           54 :         auto &availMgr = state.dataAvail->PlantAvailMgr(Loop);
    1331              : 
    1332           54 :         if (state.dataAvail->GetAvailListsInput) {
    1333           37 :             GetSysAvailManagerListInputs(state);
    1334           37 :             state.dataAvail->GetAvailListsInput = false;
    1335              :         }
    1336              : 
    1337           54 :         if (!allocated(state.dataAvail->PlantAvailMgr)) {
    1338            0 :             state.dataAvail->PlantAvailMgr.allocate(NumPlantLoops);
    1339              :         }
    1340              : 
    1341           54 :         int Found = 0;
    1342           54 :         if (state.dataAvail->NumAvailManagerLists > 0) {
    1343           16 :             Found = Util::FindItemInList(AvailabilityListName, state.dataAvail->ListData);
    1344              :         }
    1345              : 
    1346           54 :         if (Found != 0) {
    1347            2 :             availMgr.NumAvailManagers = state.dataAvail->ListData(Found).NumItems;
    1348            2 :             availMgr.availStatus = Status::NoAction;
    1349            2 :             availMgr.StartTime = 0;
    1350            2 :             availMgr.StopTime = 0;
    1351            2 :             availMgr.availManagers.allocate(availMgr.NumAvailManagers);
    1352            4 :             for (int Num = 1; Num <= availMgr.NumAvailManagers; ++Num) {
    1353            2 :                 auto &am = availMgr.availManagers(Num);
    1354            2 :                 am.Name = state.dataAvail->ListData(Found).availManagers(Num).Name;
    1355            2 :                 am.Num = 0;
    1356            2 :                 am.type = state.dataAvail->ListData(Found).availManagers(Num).type;
    1357            2 :                 assert(am.type != ManagerType::Invalid);
    1358              : 
    1359            2 :                 if (am.type == ManagerType::DiffThermo && Num != availMgr.NumAvailManagers) {
    1360            0 :                     ShowWarningError(
    1361            0 :                         state, format("GetPlantLoopData/GetPlantAvailabilityManager: AvailabilityManager:DifferentialThermostat=\"{}\".", am.Name));
    1362            0 :                     ShowContinueError(
    1363              :                         state, "...is not the last manager on the AvailabilityManagerAssignmentList.  Any remaining managers will not be used.");
    1364            0 :                     ShowContinueError(state, format("Occurs in AvailabilityManagerAssignmentList =\"{}\".", AvailabilityListName));
    1365              :                 }
    1366            2 :                 if (am.type == ManagerType::NightVent || am.type == ManagerType::NightCycle) {
    1367            0 :                     ShowSevereError(state,
    1368            0 :                                     format("GetPlantLoopData/GetPlantAvailabilityManager: Invalid System Availability Manager Type entered=\"{}\".",
    1369            0 :                                            managerTypeNames[(int)am.type]));
    1370            0 :                     ShowContinueError(state, "...this manager is not used in a Plant Loop.");
    1371            0 :                     ShowContinueError(state, format("Occurs in AvailabilityManagerAssignmentList=\"{}\".", AvailabilityListName));
    1372            0 :                     ErrorsFound = true;
    1373              :                 }
    1374              :             } // End of Num Loop
    1375              : 
    1376              :         } else {
    1377           52 :             if (AvailabilityListName != "") {
    1378            0 :                 ShowWarningError(state,
    1379            0 :                                  format("GetPlantLoopData/GetPlantAvailabilityManager: AvailabilityManagerAssignmentList={} not found in lists.  No "
    1380              :                                         "availability will be used.",
    1381              :                                         AvailabilityListName));
    1382              :             }
    1383           52 :             availMgr.NumAvailManagers = 0;
    1384           52 :             availMgr.availStatus = Status::NoAction;
    1385           52 :             availMgr.availManagers.allocate(availMgr.NumAvailManagers);
    1386              :         }
    1387           54 :     }
    1388              : 
    1389           62 :     void GetAirLoopAvailabilityManager(EnergyPlusData &state,
    1390              :                                        std::string const &AvailabilityListName, // name that should be an Availability Manager List Name
    1391              :                                        int const Loop,                          // which loop this is
    1392              :                                        int const NumAirLoops,                   // Total number of air loops
    1393              :                                        [[maybe_unused]] bool &ErrorsFound       // true if certain errors are detected here
    1394              :     )
    1395              :     {
    1396              : 
    1397              :         // SUBROUTINE INFORMATION:
    1398              :         //       AUTHOR         Linda Lawrie
    1399              :         //       DATE WRITTEN   August 2007
    1400              :         //       MODIFIED       na
    1401              :         //       RE-ENGINEERED  na
    1402              : 
    1403              :         // PURPOSE OF THIS SUBROUTINE:
    1404              :         // This subroutine gets the availability manager data for the indicated air
    1405              :         // loop or for the indicated type of zone equipment component.
    1406              :         // If the PriAirSysAvailMgr structure has not been allocated, it will be allocated
    1407              :         // to "number of air loops".
    1408           62 :         if (state.dataAvail->GetAvailListsInput) {
    1409           40 :             GetSysAvailManagerListInputs(state);
    1410           40 :             state.dataAvail->GetAvailListsInput = false;
    1411              :         }
    1412              : 
    1413           62 :         if (!allocated(state.dataAirLoop->PriAirSysAvailMgr)) {
    1414           50 :             state.dataAirLoop->PriAirSysAvailMgr.allocate(NumAirLoops);
    1415              :         }
    1416              : 
    1417           62 :         auto &availMgr = state.dataAirLoop->PriAirSysAvailMgr(Loop);
    1418              : 
    1419           62 :         int Found = 0;
    1420           62 :         if (state.dataAvail->NumAvailManagerLists > 0) {
    1421           48 :             Found = Util::FindItemInList(AvailabilityListName, state.dataAvail->ListData);
    1422              :         }
    1423              : 
    1424           62 :         if (Found != 0) {
    1425           48 :             availMgr.NumAvailManagers = state.dataAvail->ListData(Found).NumItems;
    1426           48 :             availMgr.availStatus = Status::NoAction;
    1427           48 :             availMgr.StartTime = 0;
    1428           48 :             availMgr.StopTime = 0;
    1429           48 :             availMgr.ReqSupplyFrac = 1.0;
    1430           48 :             availMgr.availManagers.allocate(availMgr.NumAvailManagers);
    1431           97 :             for (int Num = 1; Num <= availMgr.NumAvailManagers; ++Num) {
    1432           49 :                 auto &am = availMgr.availManagers(Num);
    1433           49 :                 am.Name = state.dataAvail->ListData(Found).availManagers(Num).Name;
    1434           49 :                 am.Num = 0;
    1435           49 :                 am.type = state.dataAvail->ListData(Found).availManagers(Num).type;
    1436           49 :                 assert(am.type != ManagerType::Invalid);
    1437              : 
    1438           49 :                 if (am.type == ManagerType::DiffThermo && Num != availMgr.NumAvailManagers) {
    1439            0 :                     ShowWarningError(
    1440            0 :                         state, format("GetAirPathData/GetAirLoopAvailabilityManager: AvailabilityManager:DifferentialThermostat=\"{}\".", am.Name));
    1441            0 :                     ShowContinueError(
    1442              :                         state, "...is not the last manager on the AvailabilityManagerAssignmentList.  Any remaining managers will not be used.");
    1443            0 :                     ShowContinueError(state, format("Occurs in AvailabilityManagerAssignmentList=\"{}\".", am.Name));
    1444              :                 }
    1445              :             } // End of Num Loop
    1446              : 
    1447              :         } else {
    1448           14 :             if (AvailabilityListName != "") {
    1449           18 :                 ShowWarningError(state,
    1450           18 :                                  format("GetAirPathData/GetAirLoopAvailabilityManager: AvailabilityManagerAssignmentList={} not found in lists.  No "
    1451              :                                         "availability will be used.",
    1452              :                                         AvailabilityListName));
    1453              :             }
    1454           14 :             availMgr.NumAvailManagers = 0;
    1455           14 :             availMgr.availStatus = Status::NoAction;
    1456           14 :             availMgr.availManagers.allocate(availMgr.NumAvailManagers);
    1457              :         }
    1458           62 :     }
    1459              : 
    1460        40983 :     void GetZoneEqAvailabilityManager(EnergyPlusData &state,
    1461              :                                       int const ZoneEquipType,           // Type of ZoneHVAC:* component
    1462              :                                       int const CompNum,                 // Index of a particular ZoneHVAC:* component
    1463              :                                       [[maybe_unused]] bool &ErrorsFound // true if certain errors are detected here
    1464              :     )
    1465              :     {
    1466              : 
    1467              :         // SUBROUTINE INFORMATION:
    1468              :         //       AUTHOR         Linda Lawrie
    1469              :         //       DATE WRITTEN   April 2011
    1470              :         //       MODIFIED       Chandan Sharma, March 2011/July 2012 - FSEC: Added zone sys avail managers
    1471              :         //       RE-ENGINEERED  na
    1472              : 
    1473              :         // PURPOSE OF THIS SUBROUTINE:
    1474              :         // This subroutine gets the availability manager data for the indicated type of zone
    1475              :         // equipment component.
    1476              :         // If not allocated, ZoneComp structure will be allocated to "Total num of zone equip types" and
    1477              :         // ZoneCompAvailMgrs structure will be allocated to "Total number of components of the indicated type".
    1478              : 
    1479              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1480        40983 :         std::string AvailabilityListName; // name that should be an Availability Manager List Name
    1481              :         int CompNumAvailManagers;         // Number of availability managers associated with a ZoneHVAC:* component
    1482              : 
    1483        40983 :         if (state.dataAvail->GetAvailListsInput) {
    1484           12 :             GetSysAvailManagerListInputs(state);
    1485           12 :             state.dataAvail->GetAvailListsInput = false;
    1486              :         }
    1487              : 
    1488        40983 :         auto &zoneComp = state.dataAvail->ZoneComp(ZoneEquipType);
    1489        40983 :         auto &availMgr = zoneComp.ZoneCompAvailMgrs(CompNum);
    1490        40983 :         if (availMgr.Input) { // when both air loop and zone eq avail managers are present, zone
    1491              :                               // avail mngrs list name has not been read in first time through here
    1492              :                               // (see end of if block)
    1493           52 :             AvailabilityListName = availMgr.AvailManagerListName;
    1494           52 :             int Found = 0;
    1495           52 :             if (state.dataAvail->NumAvailManagerLists > 0) {
    1496           28 :                 Found = Util::FindItemInList(AvailabilityListName, state.dataAvail->ListData);
    1497              :             }
    1498           52 :             if (Found != 0) {
    1499            1 :                 availMgr.NumAvailManagers = state.dataAvail->ListData(Found).NumItems;
    1500            1 :                 CompNumAvailManagers = availMgr.NumAvailManagers;
    1501            1 :                 availMgr.availStatus = Status::NoAction;
    1502            1 :                 availMgr.StartTime = 0;
    1503            1 :                 availMgr.StopTime = 0;
    1504            1 :                 if (!allocated(availMgr.availManagers)) {
    1505            1 :                     availMgr.availManagers.allocate(CompNumAvailManagers);
    1506              :                 }
    1507            2 :                 for (int Num = 1; Num <= availMgr.NumAvailManagers; ++Num) {
    1508            1 :                     auto &am = availMgr.availManagers(Num);
    1509            1 :                     am.Name = state.dataAvail->ListData(Found).availManagers(Num).Name;
    1510            1 :                     am.Num = 0;
    1511            1 :                     am.type = state.dataAvail->ListData(Found).availManagers(Num).type;
    1512            1 :                     assert(am.type != ManagerType::Invalid);
    1513              : 
    1514            1 :                     if (am.type == ManagerType::DiffThermo && Num != availMgr.NumAvailManagers) {
    1515            0 :                         ShowWarningError(state, format("GetZoneEqAvailabilityManager: AvailabilityManager:DifferentialThermostat=\"{}\".", am.Name));
    1516            0 :                         ShowContinueError(
    1517              :                             state, "...is not the last manager on the AvailabilityManagerAssignmentList.  Any remaining managers will not be used.");
    1518            0 :                         ShowContinueError(state, format("Occurs in AvailabilityManagerAssignmentList=\"{}\".", am.Name));
    1519              :                     }
    1520              :                 } // End of Num Loop
    1521              :             }
    1522           52 :             if (availMgr.Count > 0 || Found > 0) {
    1523           26 :                 availMgr.Input = false;
    1524              :             }
    1525           52 :             availMgr.Count += 1;
    1526              :         }
    1527        40983 :     }
    1528              : 
    1529       208398 :     void InitSysAvailManagers(EnergyPlusData &state)
    1530              :     {
    1531              : 
    1532              :         // SUBROUTINE INFORMATION:
    1533              :         //       AUTHOR         Fred Buhl
    1534              :         //       DATE WRITTEN   August 2001
    1535              :         //       MODIFIED       Brent Griffith, CR8376 initialize to Status::NoAction every timestep
    1536              : 
    1537              :         // PURPOSE OF THIS SUBROUTINE:
    1538              :         // This subroutine is for initializations of the System Availability Manager objects.
    1539              : 
    1540              :         // METHODOLOGY EMPLOYED:
    1541              :         // Uses the status flags to trigger initializations.
    1542              : 
    1543              :         using DataZoneEquipment::NumValidSysAvailZoneComponents;
    1544              : 
    1545              :         int ZoneListNum;
    1546              :         int ScanZoneListNum;
    1547              :         int ZoneNum;
    1548              :         // One time initializations
    1549              : 
    1550       208398 :         if (state.dataAvail->InitSysAvailManagers_MyOneTimeFlag) {
    1551              : 
    1552           95 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumOptStartSysAvailMgrs; ++SysAvailNum) {
    1553            3 :                 auto &optimumStartMgr = state.dataAvail->OptimumStartData(SysAvailNum);
    1554            3 :                 if (optimumStartMgr.optimumStartControlType == OptimumStartControlType::MaximumOfZoneList) {
    1555              :                     // a zone list
    1556            1 :                     ZoneListNum = Util::FindItemInList(optimumStartMgr.ZoneListName, state.dataHeatBal->ZoneList);
    1557            1 :                     if (ZoneListNum > 0) {
    1558            1 :                         optimumStartMgr.NumOfZones = state.dataHeatBal->ZoneList(ZoneListNum).NumOfZones;
    1559            1 :                         if (!allocated(optimumStartMgr.ZonePtrs)) {
    1560            0 :                             optimumStartMgr.ZonePtrs.allocate({1, state.dataHeatBal->ZoneList(ZoneListNum).NumOfZones});
    1561              :                         }
    1562            4 :                         for (ScanZoneListNum = 1; ScanZoneListNum <= state.dataHeatBal->ZoneList(ZoneListNum).NumOfZones; ++ScanZoneListNum) {
    1563            3 :                             ZoneNum = state.dataHeatBal->ZoneList(ZoneListNum).Zone(ScanZoneListNum);
    1564            3 :                             optimumStartMgr.ZonePtrs(ScanZoneListNum) = ZoneNum;
    1565              :                         }
    1566              :                     }
    1567              :                 }
    1568              :             }
    1569              : 
    1570           92 :             state.dataAvail->InitSysAvailManagers_MyOneTimeFlag = false;
    1571              : 
    1572              :         } // end 1 time initializations
    1573              : 
    1574              :         // initialize individual availability managers to no action (CR 8376 reporting issue)
    1575       208398 :         if (allocated(state.dataAvail->SchedData)) {
    1576        73818 :             for (auto &e : state.dataAvail->SchedData) {
    1577        39738 :                 e.availStatus = Status::NoAction;
    1578        34080 :             }
    1579              :         }
    1580       208398 :         if (allocated(state.dataAvail->SchedOnData)) {
    1581            0 :             for (auto &e : state.dataAvail->SchedOnData) {
    1582            0 :                 e.availStatus = Status::NoAction;
    1583            0 :             }
    1584              :         }
    1585       208398 :         if (allocated(state.dataAvail->SchedOffData)) {
    1586            0 :             for (auto &e : state.dataAvail->SchedOffData) {
    1587            0 :                 e.availStatus = Status::NoAction;
    1588            0 :             }
    1589              :         }
    1590       208398 :         if (allocated(state.dataAvail->NightCycleData)) {
    1591        14920 :             for (auto &e : state.dataAvail->NightCycleData) {
    1592         7460 :                 e.availStatus = Status::NoAction;
    1593         7460 :             }
    1594              :         }
    1595       208398 :         if (allocated(state.dataAvail->NightVentData)) {
    1596            0 :             for (auto &e : state.dataAvail->NightVentData) {
    1597            0 :                 e.availStatus = Status::NoAction;
    1598            0 :             }
    1599              :         }
    1600       208398 :         if (allocated(state.dataAvail->DiffThermoData)) {
    1601            0 :             for (auto &e : state.dataAvail->DiffThermoData) {
    1602            0 :                 e.availStatus = Status::NoAction;
    1603            0 :             }
    1604              :         }
    1605       208398 :         if (allocated(state.dataAvail->HiTurnOffData)) {
    1606            0 :             for (auto &e : state.dataAvail->HiTurnOffData) {
    1607            0 :                 e.availStatus = Status::NoAction;
    1608            0 :             }
    1609              :         }
    1610       208398 :         if (allocated(state.dataAvail->HiTurnOnData)) {
    1611            0 :             for (auto &e : state.dataAvail->HiTurnOnData) {
    1612            0 :                 e.availStatus = Status::NoAction;
    1613            0 :             }
    1614              :         }
    1615       208398 :         if (allocated(state.dataAvail->LoTurnOffData)) {
    1616          356 :             for (auto &e : state.dataAvail->LoTurnOffData) {
    1617          178 :                 e.availStatus = Status::NoAction;
    1618          178 :             }
    1619              :         }
    1620       208398 :         if (allocated(state.dataAvail->LoTurnOnData)) {
    1621            0 :             for (auto &e : state.dataAvail->LoTurnOnData) {
    1622            0 :                 e.availStatus = Status::NoAction;
    1623            0 :             }
    1624              :         }
    1625       208398 :         if (allocated(state.dataAvail->OptimumStartData)) {
    1626           24 :             for (auto &e : state.dataAvail->OptimumStartData) {
    1627           18 :                 e.availStatus = Status::NoAction;
    1628           18 :                 e.isSimulated = false;
    1629            6 :             }
    1630              :         }
    1631              :         //  HybridVentSysAvailMgrData%AvailStatus= Status::NoAction
    1632       208398 :         if (allocated(state.dataAvail->ZoneComp)) {
    1633      3125970 :             for (int ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) { // loop over the zone equipment types
    1634      2917572 :                 if (state.dataAvail->ZoneComp(ZoneEquipType).TotalNumComp > 0) {
    1635        29625 :                     for (auto &e : state.dataAvail->ZoneComp(ZoneEquipType).ZoneCompAvailMgrs) {
    1636        20420 :                         e.availStatus = Status::NoAction;
    1637              :                     }
    1638              :                 }
    1639              :             }
    1640              :         }
    1641       208398 :     }
    1642              : 
    1643        36187 :     Status SimSysAvailManager(EnergyPlusData &state,
    1644              :                               const ManagerType type,
    1645              :                               std::string const &SysAvailName,
    1646              :                               int &SysAvailNum,
    1647              :                               int const PriAirSysNum, // Primary Air System index. If being called for a ZoneHVAC:* component
    1648              :                               Status const previousStatus,
    1649              :                               ObjexxFCL::Optional_int_const ZoneEquipType, // Type of ZoneHVAC:* equipment component
    1650              :                               ObjexxFCL::Optional_int_const CompNum        // Index of ZoneHVAC:* equipment component
    1651              :     )
    1652              :     {
    1653              : 
    1654              :         // SUBROUTINE INFORMATION:
    1655              :         //       AUTHOR         Fred Buhl
    1656              :         //       DATE WRITTEN   August 2001
    1657              :         //       MODIFIED       na
    1658              :         //       RE-ENGINEERED  na
    1659              : 
    1660              :         // PURPOSE OF THIS SUBROUTINE
    1661              :         // Loop over all the System Availability Managers and invoke the correct
    1662              :         // System Availability Manager algorithm.
    1663              : 
    1664              :         Status availStatus;
    1665              : 
    1666        36187 :         switch (type) {
    1667        28532 :         case ManagerType::Scheduled: { // 'AvailabilityManager:Scheduled'
    1668        28532 :             if (SysAvailNum == 0) {
    1669           22 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->SchedData);
    1670              :             }
    1671        28532 :             if (SysAvailNum > 0) {
    1672        28532 :                 availStatus = CalcSchedSysAvailMgr(state, SysAvailNum);
    1673              :             } else {
    1674            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:Scheduled not found: {}", SysAvailName));
    1675              :             }
    1676              : 
    1677        28532 :         } break;
    1678            0 :         case ManagerType::ScheduledOn: { // 'AvailabilityManager:ScheduledOn'
    1679            0 :             if (SysAvailNum == 0) {
    1680            0 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->SchedOnData);
    1681              :             }
    1682            0 :             if (SysAvailNum > 0) {
    1683            0 :                 availStatus = CalcSchedOnSysAvailMgr(state, SysAvailNum);
    1684              :             } else {
    1685            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:ScheduledOn not found: {}", SysAvailName));
    1686              :             }
    1687              : 
    1688            0 :         } break;
    1689            0 :         case ManagerType::ScheduledOff: { // 'AvailabilityManager:ScheduledOff'
    1690            0 :             if (SysAvailNum == 0) {
    1691            0 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->SchedOffData);
    1692              :             }
    1693            0 :             if (SysAvailNum > 0) {
    1694            0 :                 availStatus = CalcSchedOffSysAvailMgr(state, SysAvailNum);
    1695              :             } else {
    1696            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:ScheduledOff not found: {}", SysAvailName));
    1697              :             }
    1698              : 
    1699            0 :         } break;
    1700         7459 :         case ManagerType::NightCycle: { // 'AvailabilityManager:NightCycle'
    1701         7459 :             if (SysAvailNum == 0) {
    1702            3 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->NightCycleData);
    1703              :             }
    1704         7459 :             if (SysAvailNum > 0) {
    1705         7459 :                 availStatus = CalcNCycSysAvailMgr(state, SysAvailNum, PriAirSysNum, ZoneEquipType, CompNum);
    1706              :             } else {
    1707            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:NightCycle not found: {}", SysAvailName));
    1708              :             }
    1709              : 
    1710         7459 :         } break;
    1711           18 :         case ManagerType::OptimumStart: { // 'AvailabilityManager:OptimumStart'
    1712           18 :             if (SysAvailNum == 0) {
    1713            0 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->OptimumStartData);
    1714              :             }
    1715           18 :             if (SysAvailNum > 0) {
    1716           18 :                 availStatus = CalcOptStartSysAvailMgr(state, SysAvailNum, PriAirSysNum, ZoneEquipType, CompNum);
    1717              :             } else {
    1718            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:OptimumStart not found: {}", SysAvailName));
    1719              :             }
    1720              : 
    1721           18 :         } break;
    1722            0 :         case ManagerType::NightVent: { // 'AvailabilityManager:NightVentilation'
    1723            0 :             if (SysAvailNum == 0) {
    1724            0 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->NightVentData);
    1725              :             }
    1726            0 :             if (SysAvailNum > 0) {
    1727            0 :                 availStatus = CalcNVentSysAvailMgr(state, SysAvailNum, PriAirSysNum, present(ZoneEquipType));
    1728              :             } else {
    1729            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:NightVentilation not found: {}", SysAvailName));
    1730              :             }
    1731              : 
    1732            0 :         } break;
    1733            0 :         case ManagerType::DiffThermo: { // 'AvailabilityManager:DifferentialThermostat'
    1734            0 :             if (SysAvailNum == 0) {
    1735            0 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->DiffThermoData);
    1736              :             }
    1737            0 :             if (SysAvailNum > 0) {
    1738            0 :                 availStatus = CalcDiffTSysAvailMgr(state, SysAvailNum, previousStatus);
    1739              :             } else {
    1740            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:DifferentialThermostat not found: {}", SysAvailName));
    1741              :             }
    1742            0 :         } break;
    1743            0 :         case ManagerType::HiTempTOff: { // 'AvailabilityManager:HighTemperatureTurnOff'
    1744            0 :             if (SysAvailNum == 0) {
    1745            0 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->HiTurnOffData);
    1746              :             }
    1747            0 :             if (SysAvailNum > 0) {
    1748            0 :                 availStatus = CalcHiTurnOffSysAvailMgr(state, SysAvailNum);
    1749              :             } else {
    1750            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:HighTemperatureTurnOff not found: {}", SysAvailName));
    1751              :             }
    1752            0 :         } break;
    1753            0 :         case ManagerType::HiTempTOn: { // 'AvailabilityManager:HighTemperatureTurnOn'
    1754            0 :             if (SysAvailNum == 0) {
    1755            0 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->HiTurnOnData);
    1756              :             }
    1757            0 :             if (SysAvailNum > 0) {
    1758            0 :                 availStatus = CalcHiTurnOnSysAvailMgr(state, SysAvailNum);
    1759              :             } else {
    1760            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:HighTemperatureTurnOn not found: {}", SysAvailName));
    1761              :             }
    1762            0 :         } break;
    1763          178 :         case ManagerType::LoTempTOff: { // 'AvailabilityManager:LowTemperatureTurnOff'
    1764          178 :             if (SysAvailNum == 0) {
    1765            1 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->LoTurnOffData);
    1766              :             }
    1767          178 :             if (SysAvailNum > 0) {
    1768          178 :                 availStatus = CalcLoTurnOffSysAvailMgr(state, SysAvailNum);
    1769              :             } else {
    1770            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:LowTemperatureTurnOff not found: {}", SysAvailName));
    1771              :             }
    1772              : 
    1773          178 :         } break;
    1774            0 :         case ManagerType::LoTempTOn: { // 'AvailabilityManager:LowTemperatureTurnOn'
    1775            0 :             if (SysAvailNum == 0) {
    1776            0 :                 SysAvailNum = Util::FindItemInList(SysAvailName, state.dataAvail->LoTurnOnData);
    1777              :             }
    1778            0 :             if (SysAvailNum > 0) {
    1779            0 :                 availStatus = CalcLoTurnOnSysAvailMgr(state, SysAvailNum);
    1780              :             } else {
    1781            0 :                 ShowFatalError(state, format("SimSysAvailManager: AvailabilityManager:LowTemperatureTurnOn not found: {}", SysAvailName));
    1782              :             }
    1783              : 
    1784            0 :         } break;
    1785              : 
    1786            0 :         default: {
    1787            0 :             ShowSevereError(state, format("AvailabilityManager Type not found: {}", type));
    1788            0 :             ShowContinueError(state, format("Occurs in Manager={}", SysAvailName));
    1789            0 :             ShowFatalError(state, "Preceding condition causes termination.");
    1790              :         }
    1791              :         }
    1792        36187 :         return availStatus;
    1793              :     }
    1794              : 
    1795        28532 :     Status CalcSchedSysAvailMgr(EnergyPlusData &state,
    1796              :                                 int const SysAvailNum // number of the current scheduled system availability manager
    1797              :     )
    1798              :     {
    1799              : 
    1800              :         // SUBROUTINE INFORMATION:
    1801              :         //       AUTHOR         Fred Buhl
    1802              :         //       DATE WRITTEN   August 2001
    1803              :         //       MODIFIED       na
    1804              :         //       RE-ENGINEERED  na
    1805              : 
    1806              :         // PURPOSE OF THIS SUBROUTINE:
    1807              :         // Set AvailStatus indicator for a primary air loop, plant loop or ZoneHVAC component.
    1808              : 
    1809              :         // METHODOLOGY EMPLOYED:
    1810              :         // Looks at the System Availability Manager schedule and sets the
    1811              :         // AvailStatus indicator accordingly. Mostly a useless algorithm
    1812              :         // since the fan schedules can do the same thing.
    1813        28532 :         auto &availMgr = state.dataAvail->SchedData(SysAvailNum);
    1814        28532 :         availMgr.availStatus = (availMgr.availSched->getCurrentVal() > 0.0) ? Status::CycleOn : Status::ForceOff;
    1815        28532 :         return availMgr.availStatus;
    1816              :     }
    1817              : 
    1818            0 :     Status CalcSchedOnSysAvailMgr(EnergyPlusData &state,
    1819              :                                   int const SysAvailNum // number of the current scheduled on system availability manager
    1820              :     )
    1821              :     {
    1822              : 
    1823              :         // SUBROUTINE INFORMATION:
    1824              :         //       AUTHOR         R. Raustad - FSEC
    1825              :         //       DATE WRITTEN   August 2008
    1826              :         //       MODIFIED       na
    1827              :         //       RE-ENGINEERED  na
    1828              : 
    1829              :         // PURPOSE OF THIS SUBROUTINE:
    1830              :         // Set AvailStatus indicator for a primary air loop, plant loop or ZoneHVAC component.
    1831              : 
    1832              :         // METHODOLOGY EMPLOYED:
    1833              :         // Looks at the System Availability Manager schedule and sets the
    1834              :         // AvailStatus indicator accordingly. If the schedule value is > 0
    1835              :         // the availability status is Status::CycleOn, ELSE the status is Status::NoAction.
    1836            0 :         auto &availMgr = state.dataAvail->SchedOnData(SysAvailNum);
    1837            0 :         availMgr.availStatus = (availMgr.availSched->getCurrentVal() > 0.0) ? Status::CycleOn : Status::NoAction;
    1838            0 :         return availMgr.availStatus;
    1839              :     }
    1840              : 
    1841            0 :     Status CalcSchedOffSysAvailMgr(EnergyPlusData &state,
    1842              :                                    int const SysAvailNum // number of the current scheduled off system availability manager
    1843              :     )
    1844              :     {
    1845              : 
    1846              :         // SUBROUTINE INFORMATION:
    1847              :         //       AUTHOR         R. Raustad - FSEC
    1848              :         //       DATE WRITTEN   August 2008
    1849              :         //       MODIFIED       na
    1850              :         //       RE-ENGINEERED  na
    1851              : 
    1852              :         // PURPOSE OF THIS SUBROUTINE:
    1853              :         // Set AvailStatus indicator for a primary air loop, plant loop or ZoneHVAC component.
    1854              : 
    1855              :         // METHODOLOGY EMPLOYED:
    1856              :         // Looks at the System Availability Manager schedule and sets the
    1857              :         // AvailStatus indicator accordingly.  If the schedule value is = 0
    1858              :         // the availability status is Status::ForceOff, ELSE the status is Status::NoAction.
    1859            0 :         auto &availMgr = state.dataAvail->SchedOffData(SysAvailNum);
    1860            0 :         availMgr.availStatus = (availMgr.availSched->getCurrentVal() == 0.0) ? Status::ForceOff : Status::NoAction;
    1861            0 :         return availMgr.availStatus;
    1862              :     }
    1863              : 
    1864         7478 :     Status CalcNCycSysAvailMgr(EnergyPlusData &state,
    1865              :                                int const SysAvailNum,                       // number of the current scheduled system availability manager
    1866              :                                int const PriAirSysNum,                      // number of the primary air system affected by this Avail. Manager
    1867              :                                ObjexxFCL::Optional_int_const ZoneEquipType, // Type of ZoneHVAC equipment component
    1868              :                                ObjexxFCL::Optional_int_const CompNum        // Index of ZoneHVAC equipment component
    1869              :     )
    1870              :     {
    1871              : 
    1872              :         // SUBROUTINE INFORMATION:
    1873              :         //       AUTHOR         Fred Buhl
    1874              :         //       DATE WRITTEN   August 2001
    1875              :         //       MODIFIED       March 2011, Chandan Sharma - FSEC: Allowed night cycle
    1876              :         //                             availability manager to work for ZoneHVAC component
    1877              :         //       RE-ENGINEERED  na
    1878              : 
    1879              :         // PURPOSE OF THIS SUBROUTINE:
    1880              :         // Set AvailStatus indicator for a primary air loop or ZoneHVAC component.
    1881              : 
    1882              :         // METHODOLOGY EMPLOYED:
    1883              :         // For air loop, depending on the type of control, looks at 1 named zone or all the zones
    1884              :         // attached to a primary air system, compares zone temperature to the setup
    1885              :         // or setback thermostat setpoint, and sets the AvailStaus indicator according
    1886              :         // to whether the system needs to be cycled on or not.
    1887              :         // For ZoneHVAC component, uses the exact same method as above but only looks at the
    1888              :         // zone where component is located.
    1889              :         int StartTime;
    1890              :         int StopTime;
    1891              :         int ZoneInSysNum;
    1892              :         Real64 TempTol;
    1893         7478 :         auto &ZoneCompNCControlType = state.dataAvail->ZoneCompNCControlType;
    1894              : 
    1895         7478 :         if (present(ZoneEquipType)) {
    1896           11 :             auto &zoneComp = state.dataAvail->ZoneComp(ZoneEquipType);
    1897           11 :             if (state.dataGlobal->WarmupFlag && state.dataGlobal->BeginDayFlag) {
    1898              :                 // reset start/stop times at beginning of each day during warmup to prevent non-convergence due to rotating start times
    1899            1 :                 zoneComp.ZoneCompAvailMgrs(CompNum).StartTime = state.dataGlobal->SimTimeSteps;
    1900            1 :                 zoneComp.ZoneCompAvailMgrs(CompNum).StopTime = state.dataGlobal->SimTimeSteps;
    1901              :             }
    1902              : 
    1903           11 :             StartTime = zoneComp.ZoneCompAvailMgrs(CompNum).StartTime;
    1904           11 :             StopTime = zoneComp.ZoneCompAvailMgrs(CompNum).StopTime;
    1905           11 :             if (state.dataAvail->CalcNCycSysAvailMgr_OneTimeFlag) {
    1906            3 :                 ZoneCompNCControlType.dimension(state.dataAvail->NumNCycSysAvailMgrs, true);
    1907            3 :                 state.dataAvail->CalcNCycSysAvailMgr_OneTimeFlag = false;
    1908              :             }
    1909              :         } else {
    1910         7467 :             auto &availMgr = state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum);
    1911         7467 :             if (state.dataGlobal->WarmupFlag && state.dataGlobal->BeginDayFlag) {
    1912              :                 // reset start/stop times at beginning of each day during warmup to prevent non-convergence due to rotating start times
    1913          102 :                 availMgr.StartTime = state.dataGlobal->SimTimeSteps;
    1914          102 :                 availMgr.StopTime = state.dataGlobal->SimTimeSteps;
    1915              :             }
    1916              : 
    1917         7467 :             StartTime = availMgr.StartTime;
    1918         7467 :             StopTime = availMgr.StopTime;
    1919              :         }
    1920              : 
    1921              :         // CR 7913 changed to allow during warmup
    1922         7478 :         auto &nightCycleMgr = state.dataAvail->NightCycleData(SysAvailNum);
    1923         7478 :         if ((nightCycleMgr.availSched->getCurrentVal() <= 0.0) || (nightCycleMgr.fanSched->getCurrentVal() > 0.0)) {
    1924         2562 :             return nightCycleMgr.availStatus = Status::NoAction; // CR 8358
    1925              :         }
    1926              : 
    1927         4916 :         TempTol = (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime) ? (0.5 * nightCycleMgr.TempTolRange) : 0.05;
    1928              : 
    1929              :         Status availStatus;
    1930              : 
    1931         4916 :         if (present(ZoneEquipType)) {
    1932           14 :             if (state.dataGlobal->SimTimeSteps >= StartTime && state.dataGlobal->SimTimeSteps < StopTime &&
    1933            4 :                 (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime ||
    1934            3 :                  nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::ThermostatWithMinimumRunTime)) { // if cycled on
    1935            3 :                 availStatus = Status::CycleOn;
    1936           13 :             } else if (state.dataGlobal->SimTimeSteps == StopTime &&
    1937            6 :                        nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime) { // if end of cycle run time, shut down if fan off
    1938            1 :                 availStatus = Status::NoAction;
    1939              :             } else {
    1940              : 
    1941            6 :                 switch (nightCycleMgr.nightCycleControlType) { // select type of night cycle control
    1942              : 
    1943            0 :                 case NightCycleControlType::Off: {
    1944            0 :                     availStatus = Status::NoAction;
    1945            0 :                 } break;
    1946            6 :                 case NightCycleControlType::OnControlZone: {
    1947              : 
    1948            6 :                     int ZoneNum = nightCycleMgr.CtrlZonePtrs(1);
    1949              : 
    1950            6 :                     auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
    1951              : 
    1952            6 :                     switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) { // select on thermostat control
    1953              : 
    1954            0 :                     case HVAC::SetptType::SingleHeat: {
    1955            0 :                         if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < zoneTstatSetpt.setpt - TempTol) {
    1956            0 :                             availStatus = Status::CycleOn;
    1957              :                         } else {
    1958            0 :                             availStatus = Status::NoAction;
    1959              :                         }
    1960              : 
    1961            0 :                     } break;
    1962            6 :                     case HVAC::SetptType::SingleCool: {
    1963            6 :                         if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > zoneTstatSetpt.setpt + TempTol) {
    1964            3 :                             availStatus = Status::CycleOn;
    1965              :                         } else {
    1966            3 :                             availStatus = Status::NoAction;
    1967              :                         }
    1968              : 
    1969            6 :                     } break;
    1970            0 :                     case HVAC::SetptType::SingleHeatCool: {
    1971            0 :                         if ((state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < zoneTstatSetpt.setpt - TempTol) ||
    1972            0 :                             (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > zoneTstatSetpt.setpt + TempTol)) {
    1973            0 :                             availStatus = Status::CycleOn;
    1974              :                         } else {
    1975            0 :                             availStatus = Status::NoAction;
    1976              :                         }
    1977              : 
    1978            0 :                     } break;
    1979            0 :                     case HVAC::SetptType::DualHeatCool: {
    1980            0 :                         if ((state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < zoneTstatSetpt.setptLo - TempTol) ||
    1981            0 :                             (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > zoneTstatSetpt.setptHi + TempTol)) {
    1982            0 :                             availStatus = Status::CycleOn;
    1983              :                         } else {
    1984            0 :                             availStatus = Status::NoAction;
    1985              :                         }
    1986              : 
    1987            0 :                     } break;
    1988            0 :                     default: {
    1989            0 :                         availStatus = Status::NoAction;
    1990              :                     }
    1991              :                     } // end select on thermostat control
    1992            6 :                 } break;
    1993            0 :                 case NightCycleControlType::OnAny:
    1994              :                 case NightCycleControlType::OnZoneFansOnly: {
    1995            0 :                     if (ZoneCompNCControlType(SysAvailNum)) {
    1996            0 :                         ShowWarningError(state,
    1997            0 :                                          format("AvailabilityManager:NightCycle = {}, is specified for a ZoneHVAC component.", nightCycleMgr.Name));
    1998            0 :                         ShowContinueError(state, "The only valid Control Types for ZoneHVAC components are Status::CycleOnControlZone and StayOff.");
    1999            0 :                         ShowContinueError(state, "Night Cycle operation will not be modeled for ZoneHVAC components that reference this manager.");
    2000            0 :                         ZoneCompNCControlType(SysAvailNum) = false;
    2001              :                     }
    2002            0 :                     availStatus = Status::NoAction;
    2003            0 :                 } break;
    2004            0 :                 default: {
    2005            0 :                     availStatus = Status::NoAction;
    2006            0 :                     break;
    2007              :                 }
    2008              :                 } // end select type of night cycle control
    2009              : 
    2010            6 :                 if (availStatus == Status::CycleOn) { // reset the start and stop times
    2011            3 :                     auto &zoneComp = state.dataAvail->ZoneComp(ZoneEquipType);
    2012            3 :                     if (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::Thermostat) { // Cycling Run Time is ignored
    2013            2 :                         zoneComp.ZoneCompAvailMgrs(CompNum).StartTime = state.dataGlobal->SimTimeSteps;
    2014            2 :                         zoneComp.ZoneCompAvailMgrs(CompNum).StopTime = state.dataGlobal->SimTimeSteps;
    2015              :                     } else {
    2016            1 :                         zoneComp.ZoneCompAvailMgrs(CompNum).StartTime = state.dataGlobal->SimTimeSteps;
    2017            1 :                         zoneComp.ZoneCompAvailMgrs(CompNum).StopTime = state.dataGlobal->SimTimeSteps + nightCycleMgr.CyclingTimeSteps;
    2018              :                     }
    2019              :                 }
    2020              :             }
    2021              :         } else {
    2022         7330 :             if (state.dataGlobal->SimTimeSteps >= StartTime && state.dataGlobal->SimTimeSteps < StopTime &&
    2023         2424 :                 (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime ||
    2024            1 :                  nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::ThermostatWithMinimumRunTime)) { // if cycled on
    2025         2423 :                 availStatus = nightCycleMgr.priorAvailStatus;
    2026         2423 :                 if (nightCycleMgr.nightCycleControlType == NightCycleControlType::OnZoneFansOnly) {
    2027            0 :                     availStatus = Status::CycleOnZoneFansOnly;
    2028              :                 }
    2029         4017 :             } else if (state.dataGlobal->SimTimeSteps == StopTime &&
    2030         1534 :                        nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime) { // if end of cycle run time, shut down if fan off
    2031         1529 :                 availStatus = Status::NoAction;
    2032              :             } else {
    2033              : 
    2034          954 :                 switch (nightCycleMgr.nightCycleControlType) { // select type of night cycle control
    2035              : 
    2036            0 :                 case NightCycleControlType::Off: {
    2037            0 :                     availStatus = Status::NoAction;
    2038            0 :                 } break;
    2039          948 :                 case NightCycleControlType::OnAny:
    2040              :                 case NightCycleControlType::OnZoneFansOnly: {
    2041              : 
    2042              :                     // If no zones cooled, Availstatus could be "unknown"
    2043          948 :                     availStatus = Status::NoAction;
    2044              : 
    2045         1640 :                     for (ZoneInSysNum = 1; ZoneInSysNum <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesCooled;
    2046              :                          ++ZoneInSysNum) { // loop over zones in system
    2047              : 
    2048          948 :                         int ZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).CoolCtrlZoneNums(ZoneInSysNum);
    2049          948 :                         auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
    2050              : 
    2051          948 :                         switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
    2052            0 :                         case HVAC::SetptType::SingleHeat: {
    2053            0 :                             if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < zoneTstatSetpt.setpt - TempTol) {
    2054            0 :                                 availStatus = Status::CycleOn;
    2055              :                             } else {
    2056            0 :                                 availStatus = Status::NoAction;
    2057              :                             }
    2058            0 :                         } break;
    2059            0 :                         case HVAC::SetptType::SingleCool: {
    2060            0 :                             if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > zoneTstatSetpt.setpt + TempTol) {
    2061            0 :                                 availStatus = Status::CycleOn;
    2062              :                             } else {
    2063            0 :                                 availStatus = Status::NoAction;
    2064              :                             }
    2065            0 :                         } break;
    2066            0 :                         case HVAC::SetptType::SingleHeatCool: {
    2067            0 :                             if ((state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < zoneTstatSetpt.setpt - TempTol) ||
    2068            0 :                                 (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > zoneTstatSetpt.setpt + TempTol)) {
    2069            0 :                                 availStatus = Status::CycleOn;
    2070              :                             } else {
    2071            0 :                                 availStatus = Status::NoAction;
    2072              :                             }
    2073            0 :                         } break;
    2074          948 :                         case HVAC::SetptType::DualHeatCool: {
    2075         1640 :                             if ((state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < zoneTstatSetpt.setptLo - TempTol) ||
    2076          692 :                                 (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > zoneTstatSetpt.setptHi + TempTol)) {
    2077          256 :                                 availStatus = Status::CycleOn;
    2078              :                             } else {
    2079          692 :                                 availStatus = Status::NoAction;
    2080              :                             }
    2081          948 :                         } break;
    2082            0 :                         default: {
    2083            0 :                             availStatus = Status::NoAction;
    2084              :                         }
    2085              :                         } // end select on thermostat control
    2086          948 :                         if (availStatus == Status::CycleOn) {
    2087          256 :                             break; // loop break
    2088              :                         }
    2089              :                     } // end loop over zones in system
    2090          948 :                 } break;
    2091              : 
    2092            6 :                 case NightCycleControlType::OnControlZone: {
    2093            6 :                     availStatus = Status::NoAction;
    2094            6 :                     if (CoolingZoneOutOfTolerance(state, nightCycleMgr.CtrlZonePtrs, nightCycleMgr.NumOfCtrlZones, TempTol)) {
    2095            3 :                         availStatus = Status::CycleOn;
    2096              :                     }
    2097            6 :                     if (HeatingZoneOutOfTolerance(state, nightCycleMgr.CtrlZonePtrs, nightCycleMgr.NumOfCtrlZones, TempTol)) {
    2098            0 :                         availStatus = Status::CycleOn;
    2099              :                     }
    2100            6 :                 } break;
    2101              : 
    2102            0 :                 case NightCycleControlType::OnAnyCoolingOrHeatingZone: {
    2103            0 :                     if (CoolingZoneOutOfTolerance(state, nightCycleMgr.CoolingZonePtrs, nightCycleMgr.NumOfCoolingZones, TempTol)) {
    2104            0 :                         availStatus = Status::CycleOn;
    2105            0 :                     } else if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatingZonePtrs, nightCycleMgr.NumOfHeatingZones, TempTol)) {
    2106            0 :                         availStatus = Status::CycleOn;
    2107            0 :                     } else if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatZnFanZonePtrs, nightCycleMgr.NumOfHeatZnFanZones, TempTol)) {
    2108            0 :                         availStatus = Status::CycleOnZoneFansOnly;
    2109              :                     } else {
    2110            0 :                         availStatus = Status::NoAction;
    2111              :                     }
    2112            0 :                 } break;
    2113              : 
    2114            0 :                 case NightCycleControlType::OnAnyCoolingZone: {
    2115            0 :                     if (CoolingZoneOutOfTolerance(state, nightCycleMgr.CoolingZonePtrs, nightCycleMgr.NumOfCoolingZones, TempTol)) {
    2116            0 :                         availStatus = Status::CycleOn;
    2117              :                     } else {
    2118            0 :                         availStatus = Status::NoAction;
    2119              :                     }
    2120            0 :                 } break;
    2121            0 :                 case NightCycleControlType::OnAnyHeatingZone: {
    2122            0 :                     if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatingZonePtrs, nightCycleMgr.NumOfHeatingZones, TempTol)) {
    2123            0 :                         availStatus = Status::CycleOn;
    2124            0 :                     } else if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatZnFanZonePtrs, nightCycleMgr.NumOfHeatZnFanZones, TempTol)) {
    2125            0 :                         availStatus = Status::CycleOnZoneFansOnly;
    2126              :                     } else {
    2127            0 :                         availStatus = Status::NoAction;
    2128              :                     }
    2129            0 :                 } break;
    2130              : 
    2131            0 :                 case NightCycleControlType::OnAnyHeatingZoneFansOnly: {
    2132            0 :                     if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatZnFanZonePtrs, nightCycleMgr.NumOfHeatZnFanZones, TempTol)) {
    2133            0 :                         availStatus = Status::CycleOnZoneFansOnly;
    2134              :                     } else {
    2135            0 :                         availStatus = Status::NoAction;
    2136              :                     }
    2137            0 :                 } break;
    2138              : 
    2139            0 :                 default:
    2140            0 :                     availStatus = Status::NoAction;
    2141              :                 } // end select type of night cycle control
    2142              : 
    2143          954 :                 if ((availStatus == Status::CycleOn) || (availStatus == Status::CycleOnZoneFansOnly)) { // reset the start and stop times
    2144          259 :                     if (nightCycleMgr.nightCycleControlType == NightCycleControlType::OnZoneFansOnly) {
    2145            0 :                         availStatus = Status::CycleOnZoneFansOnly;
    2146              :                     }
    2147              :                     // issue #6151
    2148          259 :                     auto &availMgr = state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum);
    2149          259 :                     if (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::Thermostat) { // Cycling Run Time is ignored
    2150            2 :                         availMgr.StartTime = state.dataGlobal->SimTimeSteps;
    2151            2 :                         availMgr.StopTime = state.dataGlobal->SimTimeSteps;
    2152              :                     } else {
    2153          257 :                         availMgr.StartTime = state.dataGlobal->SimTimeSteps;
    2154          257 :                         availMgr.StopTime = state.dataGlobal->SimTimeSteps + nightCycleMgr.CyclingTimeSteps;
    2155              :                     }
    2156              :                 }
    2157              :             }
    2158              :         }
    2159         4916 :         nightCycleMgr.availStatus = availStatus;
    2160         4916 :         nightCycleMgr.priorAvailStatus = availStatus;
    2161         4916 :         return availStatus;
    2162              :     }
    2163              : 
    2164            8 :     bool CoolingZoneOutOfTolerance(EnergyPlusData &state,
    2165              :                                    Array1D_int const ZonePtrList, // list of controlled zone pointers
    2166              :                                    int const NumZones,            // number of zones in list
    2167              :                                    Real64 const TempTolerance     // temperature tolerance
    2168              :     )
    2169              :     {
    2170              : 
    2171              :         // Check if any zone temperature is above the cooling setpoint plus tolerance
    2172           17 :         for (int Index = 1; Index <= NumZones; ++Index) { // loop over zones in list
    2173           13 :             int ZoneNum = ZonePtrList(Index);
    2174           13 :             auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
    2175              : 
    2176           13 :             switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
    2177           10 :             case HVAC::SetptType::SingleCool:
    2178              :             case HVAC::SetptType::SingleHeatCool:
    2179           10 :                 if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > zoneTstatSetpt.setpt + TempTolerance) {
    2180            4 :                     return true; // return on the first zone found
    2181              :                 }
    2182            6 :                 break;
    2183            1 :             case HVAC::SetptType::DualHeatCool:
    2184            1 :                 if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > zoneTstatSetpt.setptHi + TempTolerance) {
    2185            0 :                     return true; // return on the first zone found
    2186              :                 }
    2187            1 :                 break;
    2188            2 :             default:
    2189            2 :                 break;
    2190              :             }
    2191              :         }
    2192            4 :         return false;
    2193              :     }
    2194              : 
    2195            8 :     bool HeatingZoneOutOfTolerance(EnergyPlusData &state,
    2196              :                                    Array1D_int const ZonePtrList, // list of controlled zone pointers
    2197              :                                    int const NumZones,            // number of zones in list
    2198              :                                    Real64 const TempTolerance     // temperature tolerance
    2199              :     )
    2200              :     {
    2201              :         // Check if any zone temperature is below the heating setpoint less tolerance
    2202           18 :         for (int Index = 1; Index <= NumZones; ++Index) { // loop over zones in list
    2203           11 :             int ZoneNum = ZonePtrList(Index);
    2204              :             { // Why is this a new scope?
    2205           11 :                 auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
    2206              : 
    2207           11 :                 HVAC::SetptType const tstatType(state.dataHeatBalFanSys->TempControlType(ZoneNum));
    2208              : 
    2209           11 :                 if ((tstatType == HVAC::SetptType::SingleHeat) || (tstatType == HVAC::SetptType::SingleHeatCool)) {
    2210            3 :                     if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < zoneTstatSetpt.setpt - TempTolerance) {
    2211            1 :                         return true; // return on the first zone found
    2212              :                     }
    2213            8 :                 } else if (tstatType == HVAC::SetptType::DualHeatCool) {
    2214            1 :                     if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < zoneTstatSetpt.setptLo - TempTolerance) {
    2215            0 :                         return true; // return on the first zone found
    2216              :                     }
    2217              :                 }
    2218              :             }
    2219              :         }
    2220            7 :         return false;
    2221              :     }
    2222              : 
    2223           18 :     Status CalcOptStartSysAvailMgr(EnergyPlusData &state,
    2224              :                                    int const SysAvailNum,  // number of the current scheduled system availability manager
    2225              :                                    int const PriAirSysNum, // number of the primary air system affected by this Avail. Manager
    2226              :                                    [[maybe_unused]] ObjexxFCL::Optional_int_const ZoneEquipType, // Type of ZoneHVAC equipment component
    2227              :                                    [[maybe_unused]] ObjexxFCL::Optional_int_const CompNum        // Index of ZoneHVAC equipment component
    2228              :     )
    2229              :     {
    2230              : 
    2231              :         // SUBROUTINE INFORMATION:
    2232              :         //       AUTHOR            Xiufeng Pang (XP)
    2233              :         //       DATE WRITTEN      August 2013
    2234              :         //       MODIFIED
    2235              :         //       RE-ENGINEERED
    2236              : 
    2237              :         // PURPOSE OF THIS SUBROUTINE:
    2238              :         // Set AvailStatus indicator for a primary air loop, plant loop or ZoneHVAC component
    2239              : 
    2240              :         // METHODOLOGY EMPLOYED:
    2241              :         // Sets the AvailStatus indicator according to the
    2242              :         // optimum start algorithm
    2243              : 
    2244              :         // Using/Aliasing
    2245              :         using namespace DataAirLoop;
    2246              : 
    2247              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2248              : 
    2249           18 :         Array2D<Real64> DayValues;
    2250           18 :         Array2D<Real64> DayValuesTmr;
    2251              :         int JDay;
    2252              :         int TmrJDay;
    2253              :         int TmrDayOfWeek;
    2254              :         int ZoneNum;
    2255              :         Real64 FanStartTime;
    2256              :         Real64 FanStartTimeTmr;
    2257              :         Real64 PreStartTime;
    2258              :         Real64 PreStartTimeTmr;
    2259              :         Real64 DeltaTime;
    2260              :         Real64 TempDiff;
    2261              :         Real64 TempDiffHi;
    2262              :         Real64 TempDiffLo;
    2263           18 :         bool FirstTimeATGFlag(true);
    2264           18 :         bool OverNightStartFlag(false); // Flag to indicate the optimum start starts before mid night.
    2265           18 :         bool CycleOnFlag(false);
    2266           18 :         bool OSReportVarFlag(true);
    2267              :         int NumPreDays;
    2268              :         int NumOfZonesInList;
    2269              :         Real64 AdaTempGradHeat;
    2270              :         Real64 AdaTempGradCool;
    2271           18 :         Real64 ATGUpdateTime1(0.0);
    2272           18 :         Real64 ATGUpdateTime2(0.0);
    2273           18 :         Real64 ATGUpdateTemp1(0.0);
    2274           18 :         Real64 ATGUpdateTemp2(0.0);
    2275           18 :         bool ATGUpdateFlag1(false);
    2276           18 :         bool ATGUpdateFlag2(false);
    2277              :         int ATGCounter;
    2278              :         int ATGWCZoneNumHi;
    2279              :         int ATGWCZoneNumLo;
    2280              :         Real64 NumHoursBeforeOccupancy; // Variable to store the number of hours before occupancy in optimum start period
    2281              :         bool exitLoop;                  // exit loop on found data
    2282              : 
    2283              :         Status availStatus;
    2284              : 
    2285           18 :         auto &OptStartMgr = state.dataAvail->OptimumStartData(SysAvailNum);
    2286              : 
    2287              :         // some avail managers may be used in air loop and plant availability manager lists, if so they only need be simulated once
    2288           18 :         if (OptStartMgr.isSimulated) {
    2289            0 :             return OptStartMgr.availStatus;
    2290              :         }
    2291           18 :         OptStartMgr.isSimulated = true;
    2292              : 
    2293              :         // update air loop specific data
    2294           18 :         TempDiffLo = OptStartMgr.TempDiffLo;
    2295           18 :         TempDiffHi = OptStartMgr.TempDiffHi;
    2296           18 :         ATGWCZoneNumLo = OptStartMgr.ATGWCZoneNumLo;
    2297           18 :         ATGWCZoneNumHi = OptStartMgr.ATGWCZoneNumHi;
    2298           18 :         CycleOnFlag = OptStartMgr.CycleOnFlag;
    2299           18 :         ATGUpdateFlag1 = OptStartMgr.ATGUpdateFlag1;
    2300           18 :         ATGUpdateFlag2 = OptStartMgr.ATGUpdateFlag2;
    2301           18 :         NumHoursBeforeOccupancy = OptStartMgr.NumHoursBeforeOccupancy;
    2302           18 :         FirstTimeATGFlag = OptStartMgr.FirstTimeATGFlag;
    2303           18 :         OverNightStartFlag = OptStartMgr.OverNightStartFlag;
    2304           18 :         OSReportVarFlag = OptStartMgr.OSReportVarFlag;
    2305              : 
    2306           18 :         if (OptStartMgr.controlAlgorithm == ControlAlgorithm::AdaptiveTemperatureGradient) {
    2307           18 :             NumPreDays = OptStartMgr.NumPreDays;
    2308           18 :             if (!allocated(state.dataAvail->OptStart_AdaTempGradTrdHeat)) {
    2309            1 :                 state.dataAvail->OptStart_AdaTempGradTrdHeat.allocate(NumPreDays);
    2310            1 :                 state.dataAvail->OptStart_AdaTempGradTrdCool.allocate(NumPreDays);
    2311              :             }
    2312           18 :             if (!allocated(OptStartMgr.AdaTempGradTrdHeat)) {
    2313            3 :                 OptStartMgr.AdaTempGradTrdHeat.allocate(NumPreDays);
    2314            3 :                 OptStartMgr.AdaTempGradTrdHeat = 0.0;
    2315            3 :                 OptStartMgr.AdaTempGradTrdCool.allocate(NumPreDays);
    2316            3 :                 OptStartMgr.AdaTempGradTrdCool = 0.0;
    2317              :             }
    2318           18 :             state.dataAvail->OptStart_AdaTempGradTrdHeat = OptStartMgr.AdaTempGradTrdHeat;
    2319           18 :             state.dataAvail->OptStart_AdaTempGradTrdCool = OptStartMgr.AdaTempGradTrdCool;
    2320           18 :             AdaTempGradHeat = OptStartMgr.AdaTempGradHeat;
    2321           18 :             AdaTempGradCool = OptStartMgr.AdaTempGradCool;
    2322           18 :             ATGUpdateTime1 = OptStartMgr.ATGUpdateTime1;
    2323           18 :             ATGUpdateTime2 = OptStartMgr.ATGUpdateTime2;
    2324           18 :             ATGUpdateTemp1 = OptStartMgr.ATGUpdateTemp1;
    2325           18 :             ATGUpdateTemp2 = OptStartMgr.ATGUpdateTemp2;
    2326              :         }
    2327              : 
    2328              :         // add or use a new variable OptStartSysAvailMgrData(SysAvailNum)%FanSchIndex
    2329           18 :         if (state.dataGlobal->KickOffSimulation) {
    2330            0 :             availStatus = Status::NoAction;
    2331              :         } else {
    2332           18 :             JDay = state.dataEnvrn->DayOfYear;
    2333           18 :             TmrJDay = JDay + 1;
    2334           18 :             TmrDayOfWeek = state.dataEnvrn->DayOfWeekTomorrow;
    2335              : 
    2336           18 :             DayValues.allocate(state.dataGlobal->TimeStepsInHour, Constant::iHoursInDay);
    2337           18 :             DayValuesTmr.allocate(state.dataGlobal->TimeStepsInHour, Constant::iHoursInDay);
    2338           18 :             if (!allocated(state.dataAvail->OptStart)) {
    2339            1 :                 state.dataAvail->OptStart.allocate(state.dataGlobal->NumOfZones);
    2340              :             }
    2341              : 
    2342              :             // OptStartFlag needs to be reset each timestep to not stay set to true post-occupancy
    2343          126 :             for (auto &optStart : state.dataAvail->OptStart) {
    2344          108 :                 optStart.OptStartFlag = false;
    2345              :             }
    2346              : 
    2347              :             // reset OptStartData once per beginning of day
    2348           18 :             if (state.dataGlobal->BeginDayFlag) {
    2349            3 :                 NumHoursBeforeOccupancy = 0.0; // Initialize the hours of optimum start period. This variable is for reporting purpose.
    2350            3 :                 if (state.dataAvail->BeginOfDayResetFlag) {
    2351            7 :                     for (auto &optStart : state.dataAvail->OptStart) {
    2352            6 :                         optStart.OccStartTime = 22.99; // initialize the zone occupancy start time
    2353              :                     }
    2354            1 :                     state.dataAvail->BeginOfDayResetFlag = false;
    2355              :                 }
    2356              :             }
    2357           18 :             if (!state.dataGlobal->BeginDayFlag) {
    2358           15 :                 state.dataAvail->BeginOfDayResetFlag = true;
    2359              :             }
    2360              : 
    2361           18 :             std::vector<Real64> const &dayVals = OptStartMgr.fanSched->getDayVals(state);
    2362           18 :             std::vector<Real64> const &tmwDayVals = OptStartMgr.fanSched->getDayVals(state, TmrJDay, TmrDayOfWeek);
    2363              : 
    2364           18 :             FanStartTime = 0.0;
    2365           18 :             FanStartTimeTmr = 0.0;
    2366           18 :             exitLoop = false;
    2367          126 :             for (int hr = 0; hr < Constant::iHoursInDay; ++hr) {
    2368          726 :                 for (int ts = 0; ts <= state.dataGlobal->TimeStepsInHour; ++ts) {
    2369          618 :                     if (dayVals[hr * state.dataGlobal->TimeStepsInHour + ts] <= 0.0) {
    2370          600 :                         continue;
    2371              :                     }
    2372           18 :                     FanStartTime = hr + (1.0 / state.dataGlobal->TimeStepsInHour) * (ts + 1) - 0.01;
    2373           18 :                     exitLoop = true;
    2374           18 :                     break;
    2375              :                 }
    2376          126 :                 if (exitLoop) {
    2377           18 :                     break;
    2378              :                 }
    2379              :             }
    2380              : 
    2381           18 :             exitLoop = false;
    2382          138 :             for (int hr = 0; hr < Constant::iHoursInDay; ++hr) {
    2383          630 :                 for (int ts = 0; ts < state.dataGlobal->TimeStepsInHour; ++ts) {
    2384          510 :                     if (tmwDayVals[hr * state.dataGlobal->TimeStepsInHour + ts] <= 0.0) {
    2385          492 :                         continue;
    2386              :                     }
    2387           18 :                     FanStartTimeTmr = hr + (1.0 / state.dataGlobal->TimeStepsInHour) * (ts + 1) - 0.01;
    2388           18 :                     exitLoop = true;
    2389           18 :                     break;
    2390              :                 }
    2391          138 :                 if (exitLoop) {
    2392           18 :                     break;
    2393              :                 }
    2394              :             }
    2395              : 
    2396           18 :             if (FanStartTimeTmr == 0.0) {
    2397            0 :                 FanStartTimeTmr = 24.0;
    2398              :             }
    2399              : 
    2400              :             // Pass the start time to ZoneTempPredictorCorrector
    2401           54 :             for (int counter = 1; counter <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesCooled; ++counter) {
    2402           36 :                 int actZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).CoolCtrlZoneNums(counter);
    2403           36 :                 auto &optStart = state.dataAvail->OptStart(actZoneNum);
    2404           36 :                 optStart.OccStartTime = FanStartTime;
    2405           36 :                 optStart.ActualZoneNum = actZoneNum;
    2406              :             }
    2407           18 :             for (int counter = 1; counter <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesHeated; ++counter) {
    2408            0 :                 int actZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).HeatCtrlZoneNums(counter);
    2409            0 :                 auto &optStart = state.dataAvail->OptStart(actZoneNum);
    2410            0 :                 optStart.OccStartTime = FanStartTime;
    2411            0 :                 optStart.ActualZoneNum = actZoneNum;
    2412              :             }
    2413              : 
    2414           18 :             if (state.dataEnvrn->DSTIndicator > 0) {
    2415            0 :                 --FanStartTime;
    2416            0 :                 --FanStartTimeTmr;
    2417              :             }
    2418              : 
    2419           18 :             switch (OptStartMgr.controlAlgorithm) {
    2420            0 :             case ControlAlgorithm::ConstantStartTime: {
    2421            0 :                 if (OptStartMgr.optimumStartControlType == OptimumStartControlType::Off) {
    2422            0 :                     availStatus = Status::NoAction;
    2423              :                 } else {
    2424            0 :                     DeltaTime = OptStartMgr.ConstStartTime;
    2425            0 :                     if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    2426            0 :                         DeltaTime = OptStartMgr.MaxOptStartTime;
    2427              :                     }
    2428            0 :                     PreStartTime = FanStartTime - DeltaTime;
    2429            0 :                     if (PreStartTime < 0.0) {
    2430            0 :                         PreStartTime = -0.1;
    2431              :                     }
    2432            0 :                     PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    2433            0 :                     if (PreStartTimeTmr < 0.0) {
    2434            0 :                         PreStartTimeTmr += 24.0;
    2435            0 :                         OverNightStartFlag = true;
    2436              :                     } else {
    2437            0 :                         OverNightStartFlag = false;
    2438              :                     }
    2439            0 :                     if (!OverNightStartFlag) {
    2440            0 :                         if (FanStartTime == 0.0 || state.dataGlobal->PreviousHour > FanStartTime) {
    2441            0 :                             availStatus = Status::NoAction;
    2442            0 :                             OSReportVarFlag = true;
    2443            0 :                         } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    2444            0 :                             if (OSReportVarFlag) {
    2445            0 :                                 NumHoursBeforeOccupancy = DeltaTime;
    2446            0 :                                 OSReportVarFlag = false;
    2447              :                             }
    2448            0 :                             availStatus = Status::CycleOn;
    2449            0 :                             OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2450              :                         } else {
    2451            0 :                             availStatus = Status::NoAction;
    2452            0 :                             OSReportVarFlag = true;
    2453              :                         }
    2454              :                     } else {
    2455            0 :                         if (FanStartTime == 0.0 || (state.dataGlobal->HourOfDay > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    2456            0 :                             availStatus = Status::NoAction;
    2457            0 :                             OSReportVarFlag = true;
    2458            0 :                         } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    2459            0 :                             if (OSReportVarFlag) {
    2460            0 :                                 NumHoursBeforeOccupancy = DeltaTime;
    2461            0 :                                 OSReportVarFlag = false;
    2462              :                             }
    2463            0 :                             availStatus = Status::CycleOn;
    2464            0 :                             OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2465              :                         } else {
    2466            0 :                             availStatus = Status::NoAction;
    2467            0 :                             OSReportVarFlag = true;
    2468              :                         }
    2469              :                     }
    2470              :                 }
    2471            0 :             } break;
    2472              : 
    2473            0 :             case ControlAlgorithm::ConstantTemperatureGradient: {
    2474            0 :                 if (OptStartMgr.optimumStartControlType == OptimumStartControlType::ControlZone) {
    2475            0 :                     ZoneNum = OptStartMgr.ZoneNum;
    2476            0 :                     if (!allocated(state.dataHeatBalFanSys->TempTstatAir) || !allocated(state.dataHeatBalFanSys->zoneTstatSetpts)) {
    2477            0 :                         TempDiff = 0.0;
    2478              :                     } else {
    2479            0 :                         if (!CycleOnFlag) {
    2480            0 :                             if (allocated(state.dataZoneCtrls->OccRoomTSetPointHeat) && allocated(state.dataZoneCtrls->OccRoomTSetPointCool)) {
    2481            0 :                                 TempDiffHi = state.dataHeatBalFanSys->TempTstatAir(ZoneNum) - state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum);
    2482            0 :                                 TempDiffLo = state.dataHeatBalFanSys->TempTstatAir(ZoneNum) - state.dataZoneCtrls->OccRoomTSetPointHeat(ZoneNum);
    2483              :                             } else {
    2484            0 :                                 TempDiffHi = 0.0;
    2485            0 :                                 TempDiffLo = 0.0;
    2486              :                             }
    2487              :                         }
    2488              :                     }
    2489              : 
    2490            0 :                     if (TempDiffHi < 0.0) {
    2491            0 :                         TempDiff = TempDiffLo;
    2492            0 :                         if (TempDiff < 0.0) { // Heating Mode
    2493            0 :                             TempDiff = std::abs(TempDiff);
    2494            0 :                             DeltaTime = TempDiff / OptStartMgr.ConstTGradHeat;
    2495            0 :                             if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    2496            0 :                                 DeltaTime = OptStartMgr.MaxOptStartTime;
    2497              :                             }
    2498            0 :                             PreStartTime = FanStartTime - DeltaTime;
    2499            0 :                             if (PreStartTime < 0) {
    2500            0 :                                 PreStartTime = -0.1;
    2501              :                             }
    2502            0 :                             PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    2503            0 :                             if (PreStartTimeTmr < 0) {
    2504            0 :                                 PreStartTimeTmr += 24.0;
    2505            0 :                                 OverNightStartFlag = true;
    2506              :                             } else {
    2507            0 :                                 OverNightStartFlag = false;
    2508              :                             }
    2509            0 :                             if (!OverNightStartFlag) {
    2510            0 :                                 if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
    2511            0 :                                     CycleOnFlag = false;
    2512            0 :                                     OSReportVarFlag = true;
    2513            0 :                                 } else if (CycleOnFlag) {
    2514            0 :                                     availStatus = Status::CycleOn;
    2515            0 :                                     OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2516            0 :                                     if (state.dataGlobal->CurrentTime > FanStartTime) {
    2517            0 :                                         CycleOnFlag = false;
    2518              :                                     }
    2519            0 :                                 } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    2520            0 :                                     availStatus = Status::CycleOn;
    2521            0 :                                     CycleOnFlag = true;
    2522            0 :                                     if (OSReportVarFlag) {
    2523            0 :                                         NumHoursBeforeOccupancy = DeltaTime;
    2524            0 :                                         OSReportVarFlag = false;
    2525              :                                     }
    2526            0 :                                     OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2527              :                                 } else {
    2528            0 :                                     availStatus = Status::NoAction;
    2529            0 :                                     CycleOnFlag = false;
    2530            0 :                                     OSReportVarFlag = true;
    2531              :                                 }
    2532              :                             } else {
    2533            0 :                                 if (FanStartTime == 0.0 ||
    2534            0 :                                     (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    2535            0 :                                     availStatus = Status::NoAction;
    2536            0 :                                     CycleOnFlag = false;
    2537            0 :                                     OSReportVarFlag = true;
    2538            0 :                                 } else if (CycleOnFlag) {
    2539            0 :                                     availStatus = Status::CycleOn;
    2540            0 :                                     OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2541            0 :                                     if (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime < PreStartTimeTmr) {
    2542            0 :                                         CycleOnFlag = false;
    2543              :                                     }
    2544            0 :                                 } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    2545            0 :                                     if (OSReportVarFlag) {
    2546            0 :                                         NumHoursBeforeOccupancy = DeltaTime;
    2547            0 :                                         OSReportVarFlag = false;
    2548              :                                     }
    2549            0 :                                     availStatus = Status::CycleOn;
    2550            0 :                                     CycleOnFlag = true;
    2551            0 :                                     OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2552              :                                 } else {
    2553            0 :                                     availStatus = Status::NoAction;
    2554            0 :                                     CycleOnFlag = false;
    2555            0 :                                     OSReportVarFlag = true;
    2556              :                                 }
    2557              :                             }
    2558              :                         } else {
    2559            0 :                             availStatus = Status::NoAction;
    2560            0 :                             CycleOnFlag = false;
    2561              :                         }
    2562            0 :                     } else if (state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum) < 50.0) { // Cooling Mode
    2563            0 :                         TempDiff = TempDiffHi;
    2564            0 :                         DeltaTime = TempDiff / OptStartMgr.ConstTGradCool;
    2565            0 :                         if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    2566            0 :                             DeltaTime = OptStartMgr.MaxOptStartTime;
    2567              :                         }
    2568            0 :                         PreStartTime = FanStartTime - DeltaTime;
    2569            0 :                         if (PreStartTime < 0) {
    2570            0 :                             PreStartTime = -0.1;
    2571              :                         }
    2572            0 :                         PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    2573            0 :                         if (PreStartTimeTmr < 0) {
    2574            0 :                             PreStartTimeTmr += 24.0;
    2575            0 :                             OverNightStartFlag = true;
    2576              :                         } else {
    2577            0 :                             OverNightStartFlag = false;
    2578              :                         }
    2579            0 :                         if (!OverNightStartFlag) {
    2580            0 :                             if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
    2581            0 :                                 availStatus = Status::NoAction;
    2582            0 :                                 CycleOnFlag = false;
    2583            0 :                                 OSReportVarFlag = true;
    2584            0 :                             } else if (CycleOnFlag) {
    2585            0 :                                 availStatus = Status::CycleOn;
    2586            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2587            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    2588            0 :                                 if (OSReportVarFlag) {
    2589            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    2590            0 :                                     OSReportVarFlag = false;
    2591              :                                 }
    2592            0 :                                 availStatus = Status::CycleOn;
    2593            0 :                                 CycleOnFlag = true;
    2594            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2595              :                             } else {
    2596            0 :                                 availStatus = Status::NoAction;
    2597            0 :                                 CycleOnFlag = false;
    2598            0 :                                 OSReportVarFlag = true;
    2599              :                             }
    2600              :                         } else {
    2601            0 :                             if (FanStartTime == 0.0 ||
    2602            0 :                                 (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    2603            0 :                                 availStatus = Status::NoAction;
    2604            0 :                                 CycleOnFlag = false;
    2605            0 :                                 OSReportVarFlag = true;
    2606            0 :                             } else if (CycleOnFlag) {
    2607            0 :                                 availStatus = Status::CycleOn;
    2608            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2609            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    2610            0 :                                 if (OSReportVarFlag) {
    2611            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    2612            0 :                                     OSReportVarFlag = false;
    2613              :                                 }
    2614            0 :                                 availStatus = Status::CycleOn;
    2615            0 :                                 CycleOnFlag = true;
    2616            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2617              :                             } else {
    2618            0 :                                 availStatus = Status::NoAction;
    2619            0 :                                 CycleOnFlag = false;
    2620            0 :                                 OSReportVarFlag = true;
    2621              :                             }
    2622              :                         }
    2623              :                     } else {
    2624            0 :                         availStatus = Status::NoAction;
    2625            0 :                         CycleOnFlag = false;
    2626              :                     }
    2627            0 :                 } else if (OptStartMgr.optimumStartControlType == OptimumStartControlType::MaximumOfZoneList) {
    2628              : 
    2629            0 :                     NumOfZonesInList = OptStartMgr.NumOfZones;
    2630            0 :                     if (!allocated(state.dataHeatBalFanSys->TempTstatAir) || !allocated(state.dataHeatBalFanSys->zoneTstatSetpts)) {
    2631            0 :                         TempDiff = 0.0;
    2632              :                     } else {
    2633            0 :                         if (!CycleOnFlag) {
    2634            0 :                             if (allocated(state.dataZoneCtrls->OccRoomTSetPointHeat) && allocated(state.dataZoneCtrls->OccRoomTSetPointCool)) {
    2635            0 :                                 TempDiffHi = 0.0;
    2636            0 :                                 TempDiffLo = 0.0;
    2637            0 :                                 for (ZoneNum = 1; ZoneNum <= NumOfZonesInList; ++ZoneNum) {
    2638            0 :                                     TempDiff = state.dataHeatBalFanSys->TempTstatAir(OptStartMgr.ZonePtrs(ZoneNum)) -
    2639            0 :                                                state.dataZoneCtrls->OccRoomTSetPointCool(OptStartMgr.ZonePtrs(ZoneNum));
    2640            0 :                                     TempDiffHi = max(TempDiffHi, TempDiff);
    2641            0 :                                     TempDiff = state.dataHeatBalFanSys->TempTstatAir(OptStartMgr.ZonePtrs(ZoneNum)) -
    2642            0 :                                                state.dataZoneCtrls->OccRoomTSetPointHeat(OptStartMgr.ZonePtrs(ZoneNum));
    2643            0 :                                     TempDiffLo = min(TempDiffLo, TempDiff);
    2644              :                                 }
    2645              :                             } else {
    2646            0 :                                 TempDiffHi = 0.0;
    2647            0 :                                 TempDiffLo = 0.0;
    2648              :                             }
    2649              :                         }
    2650              :                     }
    2651            0 :                     if ((TempDiffHi < 0.0 && TempDiffLo < 0.0) || (std::abs(TempDiffLo) > std::abs(TempDiffHi) && TempDiffLo < 0)) { // Heating Mode
    2652            0 :                         TempDiff = TempDiffLo;
    2653            0 :                         TempDiff = std::abs(TempDiff);
    2654            0 :                         DeltaTime = TempDiff / OptStartMgr.ConstTGradHeat;
    2655            0 :                         if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    2656            0 :                             DeltaTime = OptStartMgr.MaxOptStartTime;
    2657              :                         }
    2658            0 :                         PreStartTime = FanStartTime - DeltaTime;
    2659            0 :                         if (PreStartTime < 0) {
    2660            0 :                             PreStartTime = -0.1;
    2661              :                         }
    2662            0 :                         PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    2663            0 :                         if (PreStartTimeTmr < 0) {
    2664            0 :                             PreStartTimeTmr += 24.0;
    2665            0 :                             OverNightStartFlag = true;
    2666              :                         } else {
    2667            0 :                             OverNightStartFlag = false;
    2668              :                         }
    2669            0 :                         if (!OverNightStartFlag) {
    2670            0 :                             if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
    2671            0 :                                 availStatus = Status::NoAction;
    2672            0 :                                 CycleOnFlag = false;
    2673            0 :                                 OSReportVarFlag = true;
    2674            0 :                             } else if (CycleOnFlag) {
    2675            0 :                                 availStatus = Status::CycleOn;
    2676            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2677            0 :                                 if (state.dataGlobal->CurrentTime > FanStartTime) {
    2678            0 :                                     CycleOnFlag = false;
    2679              :                                 }
    2680            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    2681            0 :                                 if (OSReportVarFlag) {
    2682            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    2683            0 :                                     OSReportVarFlag = false;
    2684              :                                 }
    2685            0 :                                 availStatus = Status::CycleOn;
    2686            0 :                                 CycleOnFlag = true;
    2687            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2688              :                             } else {
    2689            0 :                                 availStatus = Status::NoAction;
    2690            0 :                                 CycleOnFlag = false;
    2691            0 :                                 OSReportVarFlag = true;
    2692              :                             }
    2693              :                         } else {
    2694            0 :                             if (FanStartTime == 0.0 ||
    2695            0 :                                 (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    2696            0 :                                 availStatus = Status::NoAction;
    2697            0 :                                 CycleOnFlag = false;
    2698            0 :                                 OSReportVarFlag = true;
    2699            0 :                             } else if (CycleOnFlag) {
    2700            0 :                                 availStatus = Status::CycleOn;
    2701            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2702            0 :                                 if (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime < PreStartTimeTmr) {
    2703            0 :                                     CycleOnFlag = false;
    2704              :                                 }
    2705            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    2706            0 :                                 if (OSReportVarFlag) {
    2707            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    2708            0 :                                     OSReportVarFlag = false;
    2709              :                                 }
    2710            0 :                                 availStatus = Status::CycleOn;
    2711            0 :                                 CycleOnFlag = true;
    2712            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2713              :                             } else {
    2714            0 :                                 availStatus = Status::NoAction;
    2715            0 :                                 CycleOnFlag = false;
    2716            0 :                                 OSReportVarFlag = true;
    2717              :                             }
    2718              :                         }
    2719            0 :                     } else if (TempDiffHi <= 0.0 && TempDiffLo >= 0.0) { // not heating and not cooling
    2720            0 :                         availStatus = Status::NoAction;
    2721            0 :                         CycleOnFlag = false;
    2722            0 :                         TempDiffHi = 0.0;
    2723            0 :                         TempDiffLo = 0.0;
    2724            0 :                     } else if (TempDiffHi < 30.0) { // Cooling Mode
    2725            0 :                         TempDiff = TempDiffHi;
    2726            0 :                         DeltaTime = TempDiff / OptStartMgr.ConstTGradCool;
    2727            0 :                         if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    2728            0 :                             DeltaTime = OptStartMgr.MaxOptStartTime;
    2729              :                         }
    2730            0 :                         PreStartTime = FanStartTime - DeltaTime;
    2731            0 :                         if (PreStartTime < 0) {
    2732            0 :                             PreStartTime = -0.1;
    2733              :                         }
    2734            0 :                         PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    2735            0 :                         if (PreStartTimeTmr < 0) {
    2736            0 :                             PreStartTimeTmr += 24.0;
    2737            0 :                             OverNightStartFlag = true;
    2738              :                         } else {
    2739            0 :                             OverNightStartFlag = false;
    2740              :                         }
    2741            0 :                         if (!OverNightStartFlag) {
    2742            0 :                             if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
    2743            0 :                                 availStatus = Status::NoAction;
    2744            0 :                                 CycleOnFlag = false;
    2745            0 :                                 OSReportVarFlag = true;
    2746            0 :                             } else if (CycleOnFlag) {
    2747            0 :                                 availStatus = Status::CycleOn;
    2748            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2749            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    2750            0 :                                 if (OSReportVarFlag) {
    2751            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    2752            0 :                                     OSReportVarFlag = false;
    2753              :                                 }
    2754            0 :                                 availStatus = Status::CycleOn;
    2755            0 :                                 CycleOnFlag = true;
    2756            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2757              :                             } else {
    2758            0 :                                 availStatus = Status::NoAction;
    2759            0 :                                 CycleOnFlag = false;
    2760            0 :                                 OSReportVarFlag = true;
    2761              :                             }
    2762              :                         } else {
    2763            0 :                             if (FanStartTime == 0.0 ||
    2764            0 :                                 (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    2765            0 :                                 availStatus = Status::NoAction;
    2766            0 :                                 CycleOnFlag = false;
    2767            0 :                                 OSReportVarFlag = true;
    2768            0 :                             } else if (CycleOnFlag) {
    2769            0 :                                 availStatus = Status::CycleOn;
    2770            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2771            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    2772            0 :                                 if (OSReportVarFlag) {
    2773            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    2774            0 :                                     OSReportVarFlag = false;
    2775              :                                 }
    2776            0 :                                 availStatus = Status::CycleOn;
    2777            0 :                                 CycleOnFlag = true;
    2778            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2779              :                             } else {
    2780            0 :                                 availStatus = Status::NoAction;
    2781            0 :                                 CycleOnFlag = false;
    2782            0 :                                 OSReportVarFlag = true;
    2783              :                             }
    2784              :                         }
    2785              :                     } else {
    2786            0 :                         availStatus = Status::NoAction;
    2787            0 :                         CycleOnFlag = false;
    2788              :                     }
    2789              :                 } else {
    2790            0 :                     availStatus = Status::NoAction;
    2791              :                 }
    2792            0 :             } break;
    2793              : 
    2794           18 :             case ControlAlgorithm::AdaptiveTemperatureGradient: {
    2795              : 
    2796           18 :                 if (OptStartMgr.optimumStartControlType == OptimumStartControlType::ControlZone) {
    2797           12 :                     ZoneNum = OptStartMgr.ZoneNum;
    2798           12 :                     if (!allocated(state.dataHeatBalFanSys->TempTstatAir) || !allocated(state.dataHeatBalFanSys->zoneTstatSetpts)) {
    2799            0 :                         TempDiff = 0.0;
    2800              :                     } else {
    2801           12 :                         if (!CycleOnFlag) {
    2802            8 :                             if (allocated(state.dataZoneCtrls->OccRoomTSetPointHeat) && allocated(state.dataZoneCtrls->OccRoomTSetPointCool)) {
    2803            8 :                                 TempDiffHi = state.dataHeatBalFanSys->TempTstatAir(ZoneNum) - state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum);
    2804            8 :                                 TempDiffLo = state.dataHeatBalFanSys->TempTstatAir(ZoneNum) - state.dataZoneCtrls->OccRoomTSetPointHeat(ZoneNum);
    2805              :                             } else {
    2806            0 :                                 TempDiffHi = 0.0;
    2807            0 :                                 TempDiffLo = 0.0;
    2808              :                             }
    2809              :                         }
    2810              :                     }
    2811              :                     // Store adaptive temperature gradients for previous days and calculate the adaptive temp gradients
    2812              :                     //-----------------------------------------------------------------------------
    2813           12 :                     if (state.dataGlobal->WarmupFlag) {
    2814            2 :                         AdaTempGradHeat = OptStartMgr.InitTGradHeat;
    2815            2 :                         AdaTempGradCool = OptStartMgr.InitTGradCool;
    2816           10 :                     } else if (state.dataGlobal->DayOfSim == 1 && state.dataGlobal->BeginDayFlag) {
    2817            0 :                         state.dataAvail->OptStart_AdaTempGradTrdHeat = OptStartMgr.InitTGradHeat;
    2818            0 :                         AdaTempGradHeat = OptStartMgr.InitTGradHeat;
    2819            0 :                         state.dataAvail->OptStart_AdaTempGradTrdCool = OptStartMgr.InitTGradCool;
    2820            0 :                         AdaTempGradCool = OptStartMgr.InitTGradCool;
    2821              :                     } else {
    2822           10 :                         if (state.dataGlobal->BeginDayFlag && FirstTimeATGFlag) {
    2823            0 :                             FirstTimeATGFlag = false;
    2824            0 :                             AdaTempGradHeat += state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) / NumPreDays -
    2825            0 :                                                state.dataAvail->OptStart_AdaTempGradTrdHeat(1) / NumPreDays;
    2826            0 :                             AdaTempGradCool += state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) / NumPreDays -
    2827            0 :                                                state.dataAvail->OptStart_AdaTempGradTrdCool(1) / NumPreDays;
    2828            0 :                             if (FanStartTime > 0) {
    2829            0 :                                 for (ATGCounter = 1; ATGCounter <= NumPreDays - 1; ++ATGCounter) {
    2830            0 :                                     state.dataAvail->OptStart_AdaTempGradTrdHeat(ATGCounter) =
    2831            0 :                                         state.dataAvail->OptStart_AdaTempGradTrdHeat(ATGCounter + 1);
    2832            0 :                                     state.dataAvail->OptStart_AdaTempGradTrdCool(ATGCounter) =
    2833            0 :                                         state.dataAvail->OptStart_AdaTempGradTrdCool(ATGCounter + 1);
    2834              :                                 }
    2835              :                             }
    2836              :                         }
    2837              :                     }
    2838              : 
    2839           12 :                     if (state.dataGlobal->CurrentTime >= 1.0) {
    2840           12 :                         FirstTimeATGFlag = true;
    2841              :                     }
    2842              :                     //------------------------------------------------------------------------------
    2843              : 
    2844           12 :                     if (TempDiffHi < 0.0) {
    2845           12 :                         TempDiff = TempDiffLo;
    2846           12 :                         if (TempDiff < 0.0) { // Heating Mode
    2847           12 :                             TempDiff = std::abs(TempDiff);
    2848           12 :                             DeltaTime = TempDiff / AdaTempGradHeat;
    2849           12 :                             if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    2850            6 :                                 DeltaTime = OptStartMgr.MaxOptStartTime;
    2851              :                             }
    2852           12 :                             PreStartTime = FanStartTime - DeltaTime;
    2853           12 :                             if (PreStartTime < 0.0) {
    2854            0 :                                 PreStartTime = -0.1;
    2855              :                             }
    2856           12 :                             PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    2857           12 :                             if (PreStartTimeTmr < 0.0) {
    2858            0 :                                 PreStartTimeTmr += 24.0;
    2859            0 :                                 OverNightStartFlag = true;
    2860              :                             } else {
    2861           12 :                                 OverNightStartFlag = false;
    2862              :                             }
    2863           12 :                             if (!OverNightStartFlag) {
    2864           12 :                                 if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
    2865            3 :                                     availStatus = Status::NoAction;
    2866            3 :                                     CycleOnFlag = false;
    2867            3 :                                     OSReportVarFlag = true;
    2868            9 :                                 } else if (CycleOnFlag) {
    2869            2 :                                     availStatus = Status::CycleOn;
    2870            2 :                                     OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2871            2 :                                     if (state.dataGlobal->CurrentTime > FanStartTime) {
    2872            0 :                                         CycleOnFlag = false;
    2873              :                                     }
    2874              :                                     // Calculate the current day actual temperature gradient --------------------------
    2875            2 :                                     if (!state.dataGlobal->WarmupFlag) {
    2876            2 :                                         if (ATGUpdateFlag1) {
    2877            1 :                                             ATGUpdateTime1 = state.dataGlobal->CurrentTime;
    2878            1 :                                             ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
    2879            1 :                                             ATGUpdateFlag1 = false;
    2880              :                                         }
    2881            2 :                                         if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) >= state.dataZoneCtrls->OccRoomTSetPointHeat(ZoneNum) &&
    2882              :                                             ATGUpdateFlag2) {
    2883            0 :                                             ATGUpdateTime2 = state.dataGlobal->CurrentTime;
    2884            0 :                                             ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
    2885            0 :                                             ATGUpdateFlag2 = false;
    2886            0 :                                             if (std::abs(ATGUpdateTime2 - ATGUpdateTime1) > 1.e-10) {
    2887            0 :                                                 state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) =
    2888            0 :                                                     (ATGUpdateTemp2 - ATGUpdateTemp1) / (ATGUpdateTime2 - ATGUpdateTime1);
    2889              :                                             } else {
    2890            0 :                                                 state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) =
    2891            0 :                                                     (ATGUpdateTemp2 - ATGUpdateTemp1) * state.dataGlobal->TimeStepsInHour;
    2892              :                                             }
    2893              :                                         }
    2894              :                                     }
    2895              :                                     //---------------------------------------------------------------------------------
    2896            7 :                                 } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    2897            2 :                                     if (OSReportVarFlag) {
    2898            2 :                                         NumHoursBeforeOccupancy = DeltaTime;
    2899            2 :                                         OSReportVarFlag = false;
    2900              :                                     }
    2901            2 :                                     availStatus = Status::CycleOn;
    2902            2 :                                     CycleOnFlag = true;
    2903            2 :                                     ATGUpdateFlag1 = true;
    2904            2 :                                     ATGUpdateFlag2 = true;
    2905            2 :                                     OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2906              :                                 } else {
    2907            5 :                                     availStatus = Status::NoAction;
    2908            5 :                                     CycleOnFlag = false;
    2909            5 :                                     OSReportVarFlag = true;
    2910              :                                 }
    2911              :                             } else {
    2912            0 :                                 if (FanStartTime == 0.0 ||
    2913            0 :                                     (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    2914            0 :                                     availStatus = Status::NoAction;
    2915            0 :                                     CycleOnFlag = false;
    2916            0 :                                     OSReportVarFlag = true;
    2917            0 :                                 } else if (CycleOnFlag) {
    2918            0 :                                     availStatus = Status::CycleOn;
    2919            0 :                                     OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2920            0 :                                     if (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime < PreStartTimeTmr) {
    2921            0 :                                         CycleOnFlag = false;
    2922              :                                     }
    2923              :                                     // Calculate the current day actual temperature gradient --------------------------
    2924            0 :                                     if (!state.dataGlobal->WarmupFlag) {
    2925            0 :                                         if (ATGUpdateFlag1) {
    2926            0 :                                             ATGUpdateTime1 = state.dataGlobal->CurrentTime;
    2927            0 :                                             ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
    2928            0 :                                             ATGUpdateFlag1 = false;
    2929              :                                         }
    2930            0 :                                         if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) >= state.dataZoneCtrls->OccRoomTSetPointHeat(ZoneNum) &&
    2931              :                                             ATGUpdateFlag2) {
    2932            0 :                                             ATGUpdateTime2 = state.dataGlobal->CurrentTime;
    2933            0 :                                             ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
    2934            0 :                                             ATGUpdateFlag2 = false;
    2935            0 :                                             if (std::abs(ATGUpdateTime2 - ATGUpdateTime1 + 24.0) > 1.e-10) {
    2936            0 :                                                 state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) =
    2937            0 :                                                     (ATGUpdateTemp2 - ATGUpdateTemp1) / (ATGUpdateTime2 - ATGUpdateTime1 + 24.0);
    2938              :                                             } else {
    2939            0 :                                                 state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) =
    2940            0 :                                                     (ATGUpdateTemp2 - ATGUpdateTemp1) * state.dataGlobal->TimeStepsInHour;
    2941              :                                             }
    2942              :                                         }
    2943              :                                     }
    2944              :                                     //---------------------------------------------------------------------------------
    2945            0 :                                 } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    2946            0 :                                     if (OSReportVarFlag) {
    2947            0 :                                         NumHoursBeforeOccupancy = DeltaTime;
    2948            0 :                                         OSReportVarFlag = false;
    2949              :                                     }
    2950            0 :                                     availStatus = Status::CycleOn;
    2951            0 :                                     CycleOnFlag = true;
    2952            0 :                                     ATGUpdateFlag1 = true;
    2953            0 :                                     ATGUpdateFlag2 = true;
    2954            0 :                                     OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2955              :                                 } else {
    2956            0 :                                     availStatus = Status::NoAction;
    2957            0 :                                     CycleOnFlag = false;
    2958            0 :                                     OSReportVarFlag = true;
    2959              :                                 }
    2960              :                             }
    2961              :                         } else {
    2962            0 :                             availStatus = Status::NoAction;
    2963            0 :                             CycleOnFlag = false;
    2964              :                         }
    2965            0 :                     } else if (state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum) < 50.0) { // Cooling Mode
    2966            0 :                         TempDiff = TempDiffHi;
    2967            0 :                         DeltaTime = TempDiff / AdaTempGradCool;
    2968            0 :                         if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    2969            0 :                             DeltaTime = OptStartMgr.MaxOptStartTime;
    2970              :                         }
    2971            0 :                         PreStartTime = FanStartTime - DeltaTime;
    2972            0 :                         if (PreStartTime < 0.0) {
    2973            0 :                             PreStartTime = -0.1;
    2974              :                         }
    2975            0 :                         PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    2976            0 :                         if (PreStartTimeTmr < 0.0) {
    2977            0 :                             PreStartTimeTmr += 24.0;
    2978            0 :                             OverNightStartFlag = true;
    2979              :                         } else {
    2980            0 :                             OverNightStartFlag = false;
    2981              :                         }
    2982            0 :                         if (!OverNightStartFlag) {
    2983            0 :                             if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
    2984            0 :                                 availStatus = Status::NoAction;
    2985            0 :                                 CycleOnFlag = false;
    2986            0 :                                 OSReportVarFlag = true;
    2987            0 :                             } else if (CycleOnFlag) {
    2988            0 :                                 if (OSReportVarFlag) {
    2989            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    2990            0 :                                     OSReportVarFlag = false;
    2991              :                                 }
    2992            0 :                                 availStatus = Status::CycleOn;
    2993            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    2994            0 :                                 if (!state.dataGlobal->WarmupFlag) {
    2995            0 :                                     if (ATGUpdateFlag1) {
    2996            0 :                                         ATGUpdateTime1 = state.dataGlobal->CurrentTime;
    2997            0 :                                         ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
    2998            0 :                                         ATGUpdateFlag1 = false;
    2999              :                                     }
    3000            0 :                                     if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <= state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum) &&
    3001              :                                         ATGUpdateFlag2) {
    3002            0 :                                         ATGUpdateTime2 = state.dataGlobal->CurrentTime;
    3003            0 :                                         ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
    3004            0 :                                         ATGUpdateFlag2 = false;
    3005            0 :                                         if (std::abs(ATGUpdateTime2 - ATGUpdateTime1) > 1.e-10) {
    3006            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) =
    3007            0 :                                                 (ATGUpdateTemp1 - ATGUpdateTemp2) / (ATGUpdateTime2 - ATGUpdateTime1);
    3008              :                                         } else {
    3009            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) =
    3010            0 :                                                 (ATGUpdateTemp1 - ATGUpdateTemp2) * state.dataGlobal->TimeStepsInHour;
    3011              :                                         }
    3012              :                                     }
    3013              :                                 }
    3014            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    3015            0 :                                 availStatus = Status::CycleOn;
    3016            0 :                                 CycleOnFlag = true;
    3017            0 :                                 ATGUpdateFlag1 = true;
    3018            0 :                                 ATGUpdateFlag2 = true;
    3019            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3020              :                             } else {
    3021            0 :                                 availStatus = Status::NoAction;
    3022            0 :                                 CycleOnFlag = false;
    3023            0 :                                 OSReportVarFlag = true;
    3024              :                             }
    3025              :                         } else {
    3026            0 :                             if (FanStartTime == 0.0 ||
    3027            0 :                                 (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    3028            0 :                                 availStatus = Status::NoAction;
    3029            0 :                                 CycleOnFlag = false;
    3030            0 :                                 OSReportVarFlag = true;
    3031            0 :                             } else if (CycleOnFlag) {
    3032            0 :                                 availStatus = Status::CycleOn;
    3033            0 :                                 if (!state.dataGlobal->WarmupFlag) {
    3034            0 :                                     if (ATGUpdateFlag1) {
    3035            0 :                                         ATGUpdateTime1 = state.dataGlobal->CurrentTime;
    3036            0 :                                         ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
    3037            0 :                                         ATGUpdateFlag1 = false;
    3038              :                                     }
    3039            0 :                                     if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <= state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum) &&
    3040              :                                         ATGUpdateFlag2) {
    3041            0 :                                         ATGUpdateTime2 = state.dataGlobal->CurrentTime;
    3042            0 :                                         ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
    3043            0 :                                         ATGUpdateFlag2 = false;
    3044            0 :                                         if (std::abs(ATGUpdateTime2 - ATGUpdateTime1 + 24.0) > 1.e-10) {
    3045            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) =
    3046            0 :                                                 (ATGUpdateTemp1 - ATGUpdateTemp2) / (ATGUpdateTime2 - ATGUpdateTime1 + 24.0);
    3047              :                                         } else {
    3048            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) =
    3049            0 :                                                 (ATGUpdateTemp1 - ATGUpdateTemp2) * state.dataGlobal->TimeStepsInHour;
    3050              :                                         }
    3051              :                                     }
    3052              :                                 }
    3053            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3054            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    3055            0 :                                 if (OSReportVarFlag) {
    3056            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    3057            0 :                                     OSReportVarFlag = false;
    3058              :                                 }
    3059            0 :                                 availStatus = Status::CycleOn;
    3060            0 :                                 CycleOnFlag = true;
    3061            0 :                                 ATGUpdateFlag1 = true;
    3062            0 :                                 ATGUpdateFlag2 = true;
    3063            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3064              :                             } else {
    3065            0 :                                 availStatus = Status::NoAction;
    3066            0 :                                 CycleOnFlag = false;
    3067            0 :                                 OSReportVarFlag = true;
    3068              :                             }
    3069              :                         }
    3070              :                     } else { // Not heating nor cooling mode
    3071            0 :                         availStatus = Status::NoAction;
    3072            0 :                         CycleOnFlag = false;
    3073              :                     }
    3074            6 :                 } else if (OptStartMgr.optimumStartControlType == OptimumStartControlType::MaximumOfZoneList) {
    3075              : 
    3076            6 :                     NumOfZonesInList = OptStartMgr.NumOfZones;
    3077            6 :                     ATGWCZoneNumHi = OptStartMgr.ZonePtrs(1);
    3078            6 :                     ATGWCZoneNumLo = OptStartMgr.ZonePtrs(1);
    3079            6 :                     if (!allocated(state.dataHeatBalFanSys->TempTstatAir) || !allocated(state.dataHeatBalFanSys->zoneTstatSetpts)) {
    3080            0 :                         TempDiff = 0.0;
    3081              :                     } else {
    3082            6 :                         if (!CycleOnFlag) {
    3083            3 :                             if (allocated(state.dataZoneCtrls->OccRoomTSetPointHeat) && allocated(state.dataZoneCtrls->OccRoomTSetPointCool)) {
    3084            3 :                                 TempDiffHi = 0.0;
    3085            3 :                                 TempDiffLo = 0.0;
    3086            3 :                                 ATGWCZoneNumHi = OptStartMgr.ZonePtrs(1);
    3087            3 :                                 ATGWCZoneNumLo = OptStartMgr.ZonePtrs(1);
    3088           12 :                                 for (ZoneNum = 1; ZoneNum <= NumOfZonesInList; ++ZoneNum) {
    3089            9 :                                     TempDiff = state.dataHeatBalFanSys->TempTstatAir(OptStartMgr.ZonePtrs(ZoneNum)) -
    3090            9 :                                                state.dataZoneCtrls->OccRoomTSetPointCool(OptStartMgr.ZonePtrs(ZoneNum));
    3091            9 :                                     TempDiffHi = max(TempDiffHi, TempDiff);
    3092              :                                     // Store the worse case zone number for actual temperature gradient calculation
    3093            9 :                                     if (TempDiff == TempDiffHi) {
    3094            0 :                                         ATGWCZoneNumHi = OptStartMgr.ZonePtrs(ZoneNum);
    3095              :                                     }
    3096            9 :                                     TempDiff = state.dataHeatBalFanSys->TempTstatAir(OptStartMgr.ZonePtrs(ZoneNum)) -
    3097            9 :                                                state.dataZoneCtrls->OccRoomTSetPointHeat(OptStartMgr.ZonePtrs(ZoneNum));
    3098            9 :                                     TempDiffLo = min(TempDiffLo, TempDiff);
    3099            9 :                                     if (TempDiff == TempDiffLo) {
    3100            9 :                                         ATGWCZoneNumLo = OptStartMgr.ZonePtrs(ZoneNum);
    3101              :                                     }
    3102              :                                 }
    3103              :                             } else {
    3104            0 :                                 TempDiffHi = 0.0;
    3105            0 :                                 TempDiffLo = 0.0;
    3106              :                             }
    3107              :                         }
    3108              :                     }
    3109              :                     // Store adaptive temperature gradients for previous days and calculate the adaptive temp gradients
    3110              :                     //-----------------------------------------------------------------------------
    3111            6 :                     if (state.dataGlobal->WarmupFlag) {
    3112            1 :                         AdaTempGradHeat = OptStartMgr.InitTGradHeat;
    3113            1 :                         AdaTempGradCool = OptStartMgr.InitTGradCool;
    3114            5 :                     } else if (state.dataGlobal->DayOfSim == 1 && state.dataGlobal->BeginDayFlag) {
    3115            0 :                         state.dataAvail->OptStart_AdaTempGradTrdHeat = OptStartMgr.InitTGradHeat;
    3116            0 :                         AdaTempGradHeat = OptStartMgr.InitTGradHeat;
    3117            0 :                         state.dataAvail->OptStart_AdaTempGradTrdCool = OptStartMgr.InitTGradCool;
    3118            0 :                         AdaTempGradCool = OptStartMgr.InitTGradCool;
    3119              :                     } else {
    3120            5 :                         if (state.dataGlobal->BeginDayFlag && FirstTimeATGFlag) {
    3121            0 :                             FirstTimeATGFlag = false;
    3122            0 :                             AdaTempGradHeat += state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) / NumPreDays -
    3123            0 :                                                state.dataAvail->OptStart_AdaTempGradTrdHeat(1) / NumPreDays;
    3124            0 :                             AdaTempGradCool += state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) / NumPreDays -
    3125            0 :                                                state.dataAvail->OptStart_AdaTempGradTrdCool(1) / NumPreDays;
    3126            0 :                             if (FanStartTime > 0) {
    3127            0 :                                 for (ATGCounter = 1; ATGCounter <= NumPreDays - 1; ++ATGCounter) {
    3128            0 :                                     state.dataAvail->OptStart_AdaTempGradTrdHeat(ATGCounter) =
    3129            0 :                                         state.dataAvail->OptStart_AdaTempGradTrdHeat(ATGCounter + 1);
    3130            0 :                                     state.dataAvail->OptStart_AdaTempGradTrdCool(ATGCounter) =
    3131            0 :                                         state.dataAvail->OptStart_AdaTempGradTrdCool(ATGCounter + 1);
    3132              :                                 }
    3133              :                             }
    3134              :                         }
    3135              :                     }
    3136              : 
    3137            6 :                     if (state.dataGlobal->CurrentTime >= 1.0) {
    3138            6 :                         FirstTimeATGFlag = true;
    3139              :                     }
    3140              :                     //------------------------------------------------------------------------------
    3141              : 
    3142            6 :                     if ((TempDiffHi < 0.0 && TempDiffLo < 0.0) || (std::abs(TempDiffLo) > std::abs(TempDiffHi) && TempDiffLo < 0.0)) { // Heating Mode
    3143            6 :                         TempDiff = TempDiffLo;
    3144            6 :                         TempDiff = std::abs(TempDiff);
    3145            6 :                         DeltaTime = TempDiff / AdaTempGradHeat;
    3146            6 :                         if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    3147            0 :                             DeltaTime = OptStartMgr.MaxOptStartTime;
    3148              :                         }
    3149            6 :                         PreStartTime = FanStartTime - DeltaTime;
    3150            6 :                         if (PreStartTime < 0.0) {
    3151            0 :                             PreStartTime = -0.1;
    3152              :                         }
    3153            6 :                         PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    3154            6 :                         if (PreStartTimeTmr < 0.0) {
    3155            0 :                             PreStartTimeTmr += 24.0;
    3156            0 :                             OverNightStartFlag = true;
    3157              :                         } else {
    3158            6 :                             OverNightStartFlag = false;
    3159              :                         }
    3160            6 :                         if (!OverNightStartFlag) {
    3161            6 :                             if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
    3162            1 :                                 OSReportVarFlag = true;
    3163            1 :                                 availStatus = Status::NoAction;
    3164            1 :                                 CycleOnFlag = false;
    3165            5 :                             } else if (CycleOnFlag) {
    3166            2 :                                 availStatus = Status::CycleOn;
    3167            2 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3168            2 :                                 if (state.dataGlobal->CurrentTime > FanStartTime) {
    3169            0 :                                     CycleOnFlag = false;
    3170              :                                 }
    3171              :                                 // Calculate the current day actual temperature gradient --------------------------
    3172            2 :                                 if (!state.dataGlobal->WarmupFlag) {
    3173            2 :                                     if (ATGUpdateFlag1) {
    3174            1 :                                         ATGUpdateTime1 = state.dataGlobal->CurrentTime;
    3175            1 :                                         ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo);
    3176            1 :                                         ATGUpdateFlag1 = false;
    3177              :                                     }
    3178            2 :                                     if (state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo) >=
    3179            2 :                                             state.dataZoneCtrls->OccRoomTSetPointHeat(ATGWCZoneNumLo) &&
    3180              :                                         ATGUpdateFlag2) {
    3181            0 :                                         ATGUpdateTime2 = state.dataGlobal->CurrentTime;
    3182            0 :                                         ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo);
    3183            0 :                                         ATGUpdateFlag2 = false;
    3184            0 :                                         if (std::abs(ATGUpdateTime2 - ATGUpdateTime1) > 1.e-10) {
    3185            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) =
    3186            0 :                                                 (ATGUpdateTemp2 - ATGUpdateTemp1) / (ATGUpdateTime2 - ATGUpdateTime1);
    3187              :                                         } else {
    3188            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) =
    3189            0 :                                                 (ATGUpdateTemp2 - ATGUpdateTemp1) * state.dataGlobal->TimeStepsInHour;
    3190              :                                         }
    3191              :                                     }
    3192              :                                 }
    3193              :                                 //---------------------------------------------------------------------------------
    3194            3 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    3195            1 :                                 if (OSReportVarFlag) {
    3196            1 :                                     NumHoursBeforeOccupancy = DeltaTime;
    3197            1 :                                     OSReportVarFlag = false;
    3198              :                                 }
    3199            1 :                                 availStatus = Status::CycleOn;
    3200            1 :                                 CycleOnFlag = true;
    3201            1 :                                 ATGUpdateFlag1 = true;
    3202            1 :                                 ATGUpdateFlag2 = true;
    3203            1 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3204              :                             } else {
    3205            2 :                                 availStatus = Status::NoAction;
    3206            2 :                                 CycleOnFlag = false;
    3207            2 :                                 OSReportVarFlag = true;
    3208              :                             }
    3209              :                         } else {
    3210            0 :                             if (FanStartTime == 0.0 ||
    3211            0 :                                 (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    3212            0 :                                 availStatus = Status::NoAction;
    3213            0 :                                 CycleOnFlag = false;
    3214            0 :                                 OSReportVarFlag = true;
    3215            0 :                             } else if (CycleOnFlag) {
    3216            0 :                                 availStatus = Status::CycleOn;
    3217              :                                 // Calculate the current day actual temperature gradient --------------------------
    3218            0 :                                 if (!state.dataGlobal->WarmupFlag) {
    3219            0 :                                     if (ATGUpdateFlag1) {
    3220            0 :                                         ATGUpdateTime1 = state.dataGlobal->CurrentTime;
    3221            0 :                                         ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo);
    3222            0 :                                         ATGUpdateFlag1 = false;
    3223              :                                     }
    3224            0 :                                     if (state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo) >=
    3225            0 :                                             state.dataZoneCtrls->OccRoomTSetPointHeat(ATGWCZoneNumLo) &&
    3226              :                                         ATGUpdateFlag2) {
    3227            0 :                                         ATGUpdateTime2 = state.dataGlobal->CurrentTime;
    3228            0 :                                         ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo);
    3229            0 :                                         ATGUpdateFlag2 = false;
    3230            0 :                                         if (std::abs(ATGUpdateTime2 - ATGUpdateTime1 + 24.0) > 1.e-10) {
    3231            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) =
    3232            0 :                                                 (ATGUpdateTemp2 - ATGUpdateTemp1) / (ATGUpdateTime2 - ATGUpdateTime1 + 24.0);
    3233              :                                         } else {
    3234            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdHeat(NumPreDays) =
    3235            0 :                                                 (ATGUpdateTemp2 - ATGUpdateTemp1) * state.dataGlobal->TimeStepsInHour;
    3236              :                                         }
    3237              :                                     }
    3238              :                                 }
    3239              :                                 //---------------------------------------------------------------------------------
    3240            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3241            0 :                                 if (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime < PreStartTimeTmr) {
    3242            0 :                                     CycleOnFlag = false;
    3243              :                                 }
    3244            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    3245            0 :                                 if (OSReportVarFlag) {
    3246            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    3247            0 :                                     OSReportVarFlag = false;
    3248              :                                 }
    3249            0 :                                 availStatus = Status::CycleOn;
    3250            0 :                                 CycleOnFlag = true;
    3251            0 :                                 ATGUpdateFlag1 = true;
    3252            0 :                                 ATGUpdateFlag2 = true;
    3253            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3254              :                             } else {
    3255            0 :                                 availStatus = Status::NoAction;
    3256            0 :                                 CycleOnFlag = false;
    3257            0 :                                 OSReportVarFlag = true;
    3258              :                             }
    3259              :                         }
    3260            0 :                     } else if (TempDiffHi <= 0.0 && TempDiffLo >= 0.0) { // not heating and not cooling
    3261            0 :                         availStatus = Status::NoAction;
    3262            0 :                         CycleOnFlag = false;
    3263            0 :                         TempDiffHi = 0.0;
    3264            0 :                         TempDiffLo = 0.0;
    3265            0 :                     } else if (TempDiffHi < 30.0) { // Cooling Mode
    3266            0 :                         TempDiff = TempDiffHi;
    3267            0 :                         DeltaTime = TempDiff / AdaTempGradCool;
    3268            0 :                         if (DeltaTime > OptStartMgr.MaxOptStartTime) {
    3269            0 :                             DeltaTime = OptStartMgr.MaxOptStartTime;
    3270              :                         }
    3271            0 :                         PreStartTime = FanStartTime - DeltaTime;
    3272            0 :                         if (PreStartTime < 0) {
    3273            0 :                             PreStartTime = -0.1;
    3274              :                         }
    3275            0 :                         PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
    3276            0 :                         if (PreStartTimeTmr < 0) {
    3277            0 :                             PreStartTimeTmr += 24.0;
    3278            0 :                             OverNightStartFlag = true;
    3279              :                         } else {
    3280            0 :                             OverNightStartFlag = false;
    3281              :                         }
    3282            0 :                         if (!OverNightStartFlag) {
    3283            0 :                             if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
    3284            0 :                                 availStatus = Status::NoAction;
    3285            0 :                                 CycleOnFlag = false;
    3286            0 :                                 OSReportVarFlag = true;
    3287            0 :                             } else if (CycleOnFlag) {
    3288            0 :                                 availStatus = Status::CycleOn;
    3289              :                                 // Calculate the current day actual temperature gradient --------------------------
    3290            0 :                                 if (!state.dataGlobal->WarmupFlag) {
    3291            0 :                                     if (ATGUpdateFlag1) {
    3292            0 :                                         ATGUpdateTime1 = state.dataGlobal->CurrentTime;
    3293            0 :                                         ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi);
    3294            0 :                                         ATGUpdateFlag1 = false;
    3295              :                                     }
    3296            0 :                                     if (state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi) <=
    3297            0 :                                             state.dataZoneCtrls->OccRoomTSetPointCool(ATGWCZoneNumHi) &&
    3298              :                                         ATGUpdateFlag2) {
    3299            0 :                                         ATGUpdateTime2 = state.dataGlobal->CurrentTime;
    3300            0 :                                         ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi);
    3301            0 :                                         ATGUpdateFlag2 = false;
    3302            0 :                                         if (std::abs(ATGUpdateTime2 - ATGUpdateTime1) > 1.e-10) {
    3303            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) =
    3304            0 :                                                 (ATGUpdateTemp1 - ATGUpdateTemp2) / (ATGUpdateTime2 - ATGUpdateTime1);
    3305              :                                         } else {
    3306            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) =
    3307            0 :                                                 (ATGUpdateTemp1 - ATGUpdateTemp2) * state.dataGlobal->TimeStepsInHour;
    3308              :                                         }
    3309              :                                     }
    3310              :                                 }
    3311              :                                 //---------------------------------------------------------------------------------
    3312            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3313            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime) {
    3314            0 :                                 if (OSReportVarFlag) {
    3315            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    3316            0 :                                     OSReportVarFlag = false;
    3317              :                                 }
    3318            0 :                                 availStatus = Status::CycleOn;
    3319            0 :                                 CycleOnFlag = true;
    3320            0 :                                 ATGUpdateFlag1 = true;
    3321            0 :                                 ATGUpdateFlag2 = true;
    3322            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3323              :                             } else {
    3324            0 :                                 availStatus = Status::NoAction;
    3325            0 :                                 CycleOnFlag = false;
    3326            0 :                                 OSReportVarFlag = true;
    3327              :                             }
    3328              :                         } else {
    3329            0 :                             if (FanStartTime == 0.0 ||
    3330            0 :                                 (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
    3331            0 :                                 availStatus = Status::NoAction;
    3332            0 :                                 CycleOnFlag = false;
    3333            0 :                                 OSReportVarFlag = true;
    3334            0 :                             } else if (CycleOnFlag) {
    3335            0 :                                 availStatus = Status::CycleOn;
    3336              :                                 // Calculate the current day actual temperature gradient --------------------------
    3337            0 :                                 if (!state.dataGlobal->WarmupFlag) {
    3338            0 :                                     if (ATGUpdateFlag1) {
    3339            0 :                                         ATGUpdateTime1 = state.dataGlobal->CurrentTime;
    3340            0 :                                         ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi);
    3341            0 :                                         ATGUpdateFlag1 = false;
    3342              :                                     }
    3343            0 :                                     if (state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi) <=
    3344            0 :                                             state.dataZoneCtrls->OccRoomTSetPointCool(ATGWCZoneNumHi) &&
    3345              :                                         ATGUpdateFlag2) {
    3346            0 :                                         ATGUpdateTime2 = state.dataGlobal->CurrentTime;
    3347            0 :                                         ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi);
    3348            0 :                                         ATGUpdateFlag2 = false;
    3349            0 :                                         if (std::abs(ATGUpdateTime2 - ATGUpdateTime1 + 24.0) > 1.e-10) {
    3350            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) =
    3351            0 :                                                 (ATGUpdateTemp1 - ATGUpdateTemp2) / (ATGUpdateTime2 - ATGUpdateTime1 + 24.0);
    3352              :                                         } else {
    3353            0 :                                             state.dataAvail->OptStart_AdaTempGradTrdCool(NumPreDays) =
    3354            0 :                                                 (ATGUpdateTemp1 - ATGUpdateTemp2) * state.dataGlobal->TimeStepsInHour;
    3355              :                                         }
    3356              :                                     }
    3357              :                                 }
    3358              :                                 //---------------------------------------------------------------------------------
    3359            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3360            0 :                             } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
    3361            0 :                                 if (OSReportVarFlag) {
    3362            0 :                                     NumHoursBeforeOccupancy = DeltaTime;
    3363            0 :                                     OSReportVarFlag = false;
    3364              :                                 }
    3365            0 :                                 availStatus = Status::CycleOn;
    3366            0 :                                 CycleOnFlag = true;
    3367            0 :                                 ATGUpdateFlag2 = true;
    3368            0 :                                 ATGUpdateFlag1 = true;
    3369            0 :                                 OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
    3370              :                             } else {
    3371            0 :                                 availStatus = Status::NoAction;
    3372            0 :                                 CycleOnFlag = false;
    3373            0 :                                 OSReportVarFlag = true;
    3374              :                             }
    3375              :                         }
    3376              :                     } else {
    3377            0 :                         availStatus = Status::NoAction;
    3378            0 :                         CycleOnFlag = false;
    3379              :                     }
    3380              :                 } else {
    3381            0 :                     availStatus = Status::NoAction;
    3382              :                 }
    3383           18 :             } break;
    3384            0 :             case ControlAlgorithm::AdaptiveASHRAE: {
    3385            0 :                 availStatus = Status::NoAction;
    3386            0 :             } break;
    3387            0 :             default:
    3388            0 :                 break;
    3389              :             }
    3390              :         }
    3391              : 
    3392           18 :         OptStartMgr.availStatus = availStatus;
    3393           18 :         OptStartMgr.NumHoursBeforeOccupancy = NumHoursBeforeOccupancy;
    3394           18 :         OptStartMgr.TempDiffLo = TempDiffLo;
    3395           18 :         OptStartMgr.TempDiffHi = TempDiffHi;
    3396           18 :         OptStartMgr.ATGWCZoneNumLo = ATGWCZoneNumLo;
    3397           18 :         OptStartMgr.ATGWCZoneNumHi = ATGWCZoneNumHi;
    3398           18 :         OptStartMgr.CycleOnFlag = CycleOnFlag;
    3399           18 :         OptStartMgr.ATGUpdateFlag1 = ATGUpdateFlag1;
    3400           18 :         OptStartMgr.ATGUpdateFlag2 = ATGUpdateFlag2;
    3401           18 :         OptStartMgr.FirstTimeATGFlag = FirstTimeATGFlag;
    3402           18 :         OptStartMgr.OverNightStartFlag = OverNightStartFlag;
    3403           18 :         OptStartMgr.OSReportVarFlag = OSReportVarFlag;
    3404           18 :         if (OptStartMgr.controlAlgorithm == ControlAlgorithm::AdaptiveTemperatureGradient) {
    3405           18 :             OptStartMgr.AdaTempGradTrdHeat = state.dataAvail->OptStart_AdaTempGradTrdHeat;
    3406           18 :             OptStartMgr.AdaTempGradTrdCool = state.dataAvail->OptStart_AdaTempGradTrdCool;
    3407           18 :             OptStartMgr.AdaTempGradHeat = AdaTempGradHeat;
    3408           18 :             OptStartMgr.AdaTempGradCool = AdaTempGradCool;
    3409           18 :             OptStartMgr.ATGUpdateTime1 = ATGUpdateTime1;
    3410           18 :             OptStartMgr.ATGUpdateTime2 = ATGUpdateTime2;
    3411           18 :             OptStartMgr.ATGUpdateTemp1 = ATGUpdateTemp1;
    3412           18 :             OptStartMgr.ATGUpdateTemp2 = ATGUpdateTemp2;
    3413              :         }
    3414              : 
    3415           18 :         return availStatus;
    3416           18 :     }
    3417              : 
    3418            7 :     void SysAvailManagerOptimumStart::SetOptStartFlag(EnergyPlusData &state, int const AirLoopNum)
    3419              :     {
    3420              :         // Set the OptStartFlag true for all zones on the air loop
    3421            7 :         auto const &thisAirToZoneNodeInfo = state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum);
    3422           23 :         for (int counter = 1; counter <= thisAirToZoneNodeInfo.NumZonesCooled; ++counter) {
    3423           16 :             state.dataAvail->OptStart(thisAirToZoneNodeInfo.CoolCtrlZoneNums(counter)).OptStartFlag = true;
    3424              :         }
    3425            7 :         for (int counter = 1; counter <= thisAirToZoneNodeInfo.NumZonesHeated; ++counter) {
    3426            0 :             state.dataAvail->OptStart(thisAirToZoneNodeInfo.HeatCtrlZoneNums(counter)).OptStartFlag = true;
    3427              :         }
    3428            7 :     }
    3429              : 
    3430            0 :     Status CalcNVentSysAvailMgr(EnergyPlusData &state,
    3431              :                                 int const SysAvailNum,     // number of the current scheduled system availability manager
    3432              :                                 int const PriAirSysNum,    // number of the primary air system affected by this Avail. Manager
    3433              :                                 bool const isZoneEquipType // Type of zone equipment component
    3434              :     )
    3435              :     {
    3436              : 
    3437              :         // SUBROUTINE INFORMATION:
    3438              :         //       AUTHOR         Fred Buhl
    3439              :         //       DATE WRITTEN   December 2004
    3440              :         //       MODIFIED       March 2011, Chandan Sharma - FSEC: Allowed night ventilation
    3441              :         //                             availability manager to work for zone component
    3442              :         //       RE-ENGINEERED  na
    3443              : 
    3444              :         // PURPOSE OF THIS SUBROUTINE:
    3445              :         // Set AvailStatus indicator for a primary air loop and ZoneHVAC component and sets a specified flow
    3446              :         // rate fraction for the air loop for use during night ventilation.
    3447              : 
    3448              :         // METHODOLOGY EMPLOYED:
    3449              :         // Looks at outside and indoor conditions to determine if night ventilation
    3450              :         // is beneficial. If it is and it is scheduled on the AvailStatus is set to cycle
    3451              :         // on and the loop flow rate fractionis set to the specified night ventilation
    3452              :         // value.
    3453              : 
    3454              :         using namespace DataAirLoop;
    3455              : 
    3456              :         int ZoneInSysNum;
    3457              :         bool TempCheck;   // TRUE if one zone's temperature is above the value of the vent temp sched
    3458              :         bool DelTCheck;   // TRUE if the control zone temperature - outside temperature > VentDelT
    3459              :         bool LowLimCheck; // TRUE if one zones's air temperature is below this value
    3460              :         Real64 VentTemp;  // value of the ventilation temperature schedule
    3461              : 
    3462              :         Status availStatus;
    3463              : 
    3464            0 :         TempCheck = false;
    3465            0 :         DelTCheck = false;
    3466            0 :         LowLimCheck = false;
    3467              :         // check if night venting allowed: not allowed if avail sched is off or fan sched is on
    3468              :         // CR 7913 changed to allow during warmup
    3469            0 :         auto &nightVentMgr = state.dataAvail->NightVentData(SysAvailNum);
    3470            0 :         if ((nightVentMgr.availSched->getCurrentVal() <= 0.0) || (nightVentMgr.fanSched->getCurrentVal() > 0.0)) {
    3471            0 :             availStatus = Status::NoAction;
    3472              :         } else {
    3473              : 
    3474            0 :             VentTemp = nightVentMgr.ventTempSched->getCurrentVal();
    3475            0 :             int ControlZoneNum = nightVentMgr.ZoneNum;
    3476              : 
    3477            0 :             if (isZoneEquipType) {
    3478              :                 // if the room temperature is greater than the vent temp sched value, set the vent temp check to TRUE
    3479            0 :                 if (state.dataHeatBalFanSys->TempTstatAir(ControlZoneNum) > VentTemp) {
    3480            0 :                     TempCheck = true;
    3481              :                 }
    3482              :                 // if the room temperature is less than the low limit set the low limit check to TRUE
    3483            0 :                 if (state.dataHeatBalFanSys->TempTstatAir(ControlZoneNum) < nightVentMgr.VentTempLowLim) {
    3484            0 :                     LowLimCheck = true;
    3485              :                 }
    3486              :             } else {
    3487            0 :                 for (ZoneInSysNum = 1; ZoneInSysNum <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesCooled;
    3488              :                      ++ZoneInSysNum) { // loop over zones in system
    3489              : 
    3490            0 :                     int ZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).CoolCtrlZoneNums(ZoneInSysNum);
    3491              :                     // if the room temperature is greater than the vent temp sched value, set the vent temp check to TRUE
    3492            0 :                     if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > VentTemp) {
    3493            0 :                         TempCheck = true;
    3494              :                     }
    3495              :                     // if the room temperature is less than the low limit set the low limit check to TRUE
    3496            0 :                     if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < nightVentMgr.VentTempLowLim) {
    3497            0 :                         LowLimCheck = true;
    3498              :                     }
    3499              :                 }
    3500              :             }
    3501              :             // If the difference between the control zone temperature and the outside temperature is greater than
    3502              :             // the specified night venting delta T then set the delta T check to TRUE
    3503            0 :             if ((state.dataHeatBalFanSys->TempTstatAir(ControlZoneNum) - state.dataEnvrn->OutDryBulbTemp) > nightVentMgr.VentDelT) {
    3504            0 :                 DelTCheck = true;
    3505              :             }
    3506              :             // If the limit requirements are met turn on night ventilation
    3507            0 :             if (TempCheck && DelTCheck && !LowLimCheck) {
    3508            0 :                 availStatus = Status::CycleOn;
    3509              :             } else {
    3510            0 :                 availStatus = Status::NoAction;
    3511              :             }
    3512              :         }
    3513              : 
    3514            0 :         if (!isZoneEquipType) {
    3515            0 :             if (availStatus == Status::CycleOn) {
    3516            0 :                 state.dataAirLoop->AirLoopControlInfo(PriAirSysNum).LoopFlowRateSet = true;
    3517            0 :                 state.dataAirLoop->AirLoopControlInfo(PriAirSysNum).NightVent = true;
    3518            0 :                 state.dataAirLoop->AirLoopFlow(PriAirSysNum).ReqSupplyFrac = nightVentMgr.VentFlowFrac;
    3519              :             }
    3520              :         }
    3521              : 
    3522            0 :         nightVentMgr.availStatus = availStatus;
    3523            0 :         return availStatus;
    3524              :     }
    3525              : 
    3526            0 :     Status CalcDiffTSysAvailMgr(EnergyPlusData &state,
    3527              :                                 int const SysAvailNum,      // Number of the current scheduled system availability manager
    3528              :                                 Status const previousStatus // System status for the previous timestep
    3529              :     )
    3530              :     {
    3531              : 
    3532              :         // SUBROUTINE INFORMATION:
    3533              :         //       AUTHOR         Peter Graham Ellis
    3534              :         //       DATE WRITTEN   February 2004
    3535              :         //       MODIFIED       na
    3536              :         //       RE-ENGINEERED  na
    3537              : 
    3538              :         // PURPOSE OF THIS SUBROUTINE:
    3539              :         // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
    3540              : 
    3541              :         // METHODOLOGY EMPLOYED:
    3542              : 
    3543              :         Status availStatus;
    3544              : 
    3545            0 :         auto &diffThermoMgr = state.dataAvail->DiffThermoData(SysAvailNum);
    3546            0 :         Real64 DeltaTemp = state.dataLoopNodes->Node(diffThermoMgr.HotNode).Temp - state.dataLoopNodes->Node(diffThermoMgr.ColdNode).Temp;
    3547              : 
    3548            0 :         if (DeltaTemp >= diffThermoMgr.TempDiffOn) {
    3549            0 :             availStatus = Status::CycleOn;
    3550            0 :         } else if (DeltaTemp <= diffThermoMgr.TempDiffOff) {
    3551            0 :             availStatus = Status::ForceOff;
    3552            0 :         } else if (previousStatus == Status::NoAction) {
    3553            0 :             availStatus = Status::ForceOff;
    3554              :         } else {
    3555            0 :             availStatus = previousStatus; // No change, but not "NoAction"; it should always be on or off.
    3556              :         }
    3557              : 
    3558            0 :         diffThermoMgr.availStatus = availStatus;
    3559            0 :         return availStatus;
    3560              :     }
    3561              : 
    3562            0 :     Status CalcHiTurnOffSysAvailMgr(EnergyPlusData &state,
    3563              :                                     int const SysAvailNum // Number of the current scheduled system availability manager
    3564              :     )
    3565              :     {
    3566              : 
    3567              :         // SUBROUTINE INFORMATION:
    3568              :         //       AUTHOR         Peter Graham Ellis
    3569              :         //       DATE WRITTEN   February 2004
    3570              :         //       MODIFIED       na
    3571              :         //       RE-ENGINEERED  na
    3572              : 
    3573              :         // PURPOSE OF THIS SUBROUTINE:
    3574              :         // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
    3575              :         Status availStatus;
    3576            0 :         if (state.dataLoopNodes->Node(state.dataAvail->HiTurnOffData(SysAvailNum).Node).Temp >= state.dataAvail->HiTurnOffData(SysAvailNum).Temp) {
    3577            0 :             availStatus = Status::ForceOff;
    3578              :         } else {
    3579            0 :             availStatus = Status::NoAction;
    3580              :         }
    3581              : 
    3582            0 :         state.dataAvail->HiTurnOffData(SysAvailNum).availStatus = availStatus;
    3583            0 :         return availStatus;
    3584              :     }
    3585              : 
    3586            0 :     Status CalcHiTurnOnSysAvailMgr(EnergyPlusData &state,
    3587              :                                    int const SysAvailNum // Number of the current scheduled system availability manager
    3588              :     )
    3589              :     {
    3590              : 
    3591              :         // SUBROUTINE INFORMATION:
    3592              :         //       AUTHOR         Peter Graham Ellis
    3593              :         //       DATE WRITTEN   February 2004
    3594              :         //       MODIFIED       na
    3595              :         //       RE-ENGINEERED  na
    3596              : 
    3597              :         // PURPOSE OF THIS SUBROUTINE:
    3598              :         // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
    3599              : 
    3600              :         Status availStatus;
    3601            0 :         if (state.dataLoopNodes->Node(state.dataAvail->HiTurnOnData(SysAvailNum).Node).Temp >= state.dataAvail->HiTurnOnData(SysAvailNum).Temp) {
    3602            0 :             availStatus = Status::CycleOn;
    3603              :         } else {
    3604            0 :             availStatus = Status::NoAction;
    3605              :         }
    3606              : 
    3607            0 :         state.dataAvail->HiTurnOnData(SysAvailNum).availStatus = availStatus;
    3608            0 :         return availStatus;
    3609              :     }
    3610              : 
    3611          178 :     Status CalcLoTurnOffSysAvailMgr(EnergyPlusData &state,
    3612              :                                     int const SysAvailNum // Number of the current scheduled system availability manager
    3613              :     )
    3614              :     {
    3615              : 
    3616              :         // SUBROUTINE INFORMATION:
    3617              :         //       AUTHOR         Peter Graham Ellis
    3618              :         //       DATE WRITTEN   February 2004
    3619              :         //       MODIFIED       na
    3620              :         //       RE-ENGINEERED  na
    3621              : 
    3622              :         // PURPOSE OF THIS SUBROUTINE:
    3623              :         // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
    3624              : 
    3625              :         Status availStatus;
    3626              :         // If applicability schedule is off, then availability manager is inactive, return no action
    3627          178 :         auto &loTurnOffMgr = state.dataAvail->LoTurnOffData(SysAvailNum);
    3628          178 :         if (loTurnOffMgr.availSched != nullptr) {
    3629            0 :             if (loTurnOffMgr.availSched->getCurrentVal() <= 0.0) {
    3630            0 :                 availStatus = Status::NoAction;
    3631            0 :                 loTurnOffMgr.availStatus = availStatus;
    3632            0 :                 return availStatus;
    3633              :             }
    3634              :         }
    3635              : 
    3636              :         // Availability manager is active, check temperature limit
    3637          178 :         if (state.dataLoopNodes->Node(loTurnOffMgr.Node).Temp <= loTurnOffMgr.Temp) {
    3638          178 :             availStatus = Status::ForceOff;
    3639              :         } else {
    3640            0 :             availStatus = Status::NoAction;
    3641              :         }
    3642              : 
    3643          178 :         loTurnOffMgr.availStatus = availStatus;
    3644          178 :         return availStatus;
    3645              :     }
    3646              : 
    3647            0 :     Status CalcLoTurnOnSysAvailMgr(EnergyPlusData &state,
    3648              :                                    int const SysAvailNum // Number of the current scheduled system availability manager
    3649              :     )
    3650              :     {
    3651              : 
    3652              :         // SUBROUTINE INFORMATION:
    3653              :         //       AUTHOR         Peter Graham Ellis
    3654              :         //       DATE WRITTEN   February 2004
    3655              :         //       MODIFIED       na
    3656              :         //       RE-ENGINEERED  na
    3657              : 
    3658              :         // PURPOSE OF THIS SUBROUTINE:
    3659              :         // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
    3660              :         Status availStatus;
    3661            0 :         if (state.dataLoopNodes->Node(state.dataAvail->LoTurnOnData(SysAvailNum).Node).Temp <= state.dataAvail->LoTurnOnData(SysAvailNum).Temp) {
    3662            0 :             availStatus = Status::CycleOn;
    3663              :         } else {
    3664            0 :             availStatus = Status::NoAction;
    3665              :         }
    3666              : 
    3667            0 :         state.dataAvail->LoTurnOnData(SysAvailNum).availStatus = availStatus;
    3668            0 :         return availStatus;
    3669              :     }
    3670              : 
    3671       297256 :     void ManageHybridVentilation(EnergyPlusData &state)
    3672              :     {
    3673              :         // SUBROUTINE INFORMATION:
    3674              :         //       AUTHOR         Lixing Gu
    3675              :         //       DATE WRITTEN   March 2007
    3676              :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    3677              :         //       RE-ENGINEERED  na
    3678              : 
    3679              :         // PURPOSE OF THIS SUBROUTINE:
    3680              :         // Manage the simulation of the Hybrid Ventilation Control System Availability Managers
    3681              : 
    3682              :         using namespace DataLoopNode;
    3683              :         using namespace DataAirLoop;
    3684              : 
    3685              :         int PriAirSysNum; // Primary Air System index
    3686              : 
    3687       297256 :         if (state.dataAvail->GetHybridInputFlag) {
    3688          102 :             GetHybridVentilationInputs(state);
    3689          102 :             state.dataAvail->GetHybridInputFlag = false;
    3690              :         }
    3691              : 
    3692       297256 :         if (state.dataAvail->NumHybridVentSysAvailMgrs == 0) {
    3693       297256 :             return;
    3694              :         }
    3695              : 
    3696            0 :         InitHybridVentSysAvailMgr(state);
    3697              : 
    3698            0 :         for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    3699            0 :             if (state.dataAvail->HybridVentData(SysAvailNum).HybridVentMgrConnectedToAirLoop) {
    3700            0 :                 for (PriAirSysNum = 1; PriAirSysNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++PriAirSysNum) {
    3701            0 :                     if (state.dataAvail->HybridVentData(SysAvailNum).AirLoopNum == PriAirSysNum) {
    3702            0 :                         CalcHybridVentSysAvailMgr(state, SysAvailNum, PriAirSysNum);
    3703              :                     }
    3704              :                 }
    3705              :             } else {
    3706              :                 // Hybrid ventilation manager is applied to zone component
    3707            0 :                 if (state.dataAvail->HybridVentData(SysAvailNum).SimHybridVentSysAvailMgr) {
    3708            0 :                     CalcHybridVentSysAvailMgr(state, SysAvailNum);
    3709              :                 }
    3710              :             }
    3711              :         }
    3712              :     }
    3713              : 
    3714          103 :     void GetHybridVentilationInputs(EnergyPlusData &state)
    3715              :     {
    3716              : 
    3717              :         // SUBROUTINE INFORMATION:
    3718              :         //       AUTHOR         Lixing Gu
    3719              :         //       DATE WRITTEN   March 2007
    3720              :         //       MODIFIED       L. GU, 6/23/08, Added more controls, including simple airflow objects
    3721              :         //       RE-ENGINEERED  na
    3722              : 
    3723              :         // PURPOSE OF THIS SUBROUTINE:
    3724              :         // Obtains input data for Hybrid Ventilation Control System Availability Managers and stores it in
    3725              :         // appropriate data structures.
    3726              : 
    3727              :         // METHODOLOGY EMPLOYED:
    3728              :         // Uses InputProcessor "Get" routines to obtain data.
    3729              : 
    3730              :         // Using/Aliasing
    3731              :         using NodeInputManager::GetOnlySingleNode;
    3732              :         using NodeInputManager::MarkNode;
    3733              :         using namespace DataLoopNode;
    3734              : 
    3735              :         using Curve::CurveValue;
    3736              :         using Curve::GetCurveIndex;
    3737              :         using Curve::GetCurveMinMaxValues;
    3738              : 
    3739              :         // SUBROUTINE PARAMETER DEFINITIONS:
    3740              :         static constexpr std::string_view RoutineName("GetHybridVentilationInputs: "); // include trailing blank
    3741              :         static constexpr std::string_view routineName = "GetHybridVentilationInputs";
    3742              : 
    3743              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3744              :         int NumAlphas;           // Number of Alphas for each GetObjectItem call
    3745              :         int NumNumbers;          // Number of Numbers for each GetObjectItem call
    3746              :         int IOStatus;            // Used in GetObjectItem
    3747          103 :         bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
    3748              :         Real64 SchedMin;         // Minimum value specified in a schedule
    3749              :         Real64 SchedMax;         // Maximum value specified in a schedule
    3750              :         Real64 CurveMin;         // Minimum value specified in a curve
    3751              :         Real64 CurveMax;         // Maximum value specified in a curve
    3752              :         Real64 CurveVal;         // Curve value
    3753              : 
    3754          103 :         auto &ipsc = state.dataIPShortCut;
    3755              : 
    3756              :         // Get the number of occurrences of each type of System Availability Manager
    3757          103 :         std::string_view cCurrentModuleObject = managerTypeNames[(int)ManagerType::HybridVent];
    3758          103 :         state.dataAvail->NumHybridVentSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    3759              : 
    3760          103 :         if (state.dataAvail->NumHybridVentSysAvailMgrs == 0) {
    3761          103 :             return;
    3762              :         }
    3763              : 
    3764              :         // Allocate the data arrays
    3765            0 :         state.dataAvail->HybridVentData.allocate(state.dataAvail->NumHybridVentSysAvailMgrs);
    3766              : 
    3767            0 :         for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    3768              : 
    3769            0 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    3770              :                                                                      cCurrentModuleObject,
    3771              :                                                                      SysAvailNum,
    3772            0 :                                                                      ipsc->cAlphaArgs,
    3773              :                                                                      NumAlphas,
    3774            0 :                                                                      ipsc->rNumericArgs,
    3775              :                                                                      NumNumbers,
    3776              :                                                                      IOStatus,
    3777            0 :                                                                      ipsc->lNumericFieldBlanks,
    3778            0 :                                                                      ipsc->lAlphaFieldBlanks,
    3779            0 :                                                                      ipsc->cAlphaFieldNames,
    3780            0 :                                                                      ipsc->cNumericFieldNames);
    3781              : 
    3782            0 :             ErrorObjectHeader eoh{routineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)};
    3783            0 :             auto &hybridVentMgr = state.dataAvail->HybridVentData(SysAvailNum);
    3784            0 :             hybridVentMgr.Name = ipsc->cAlphaArgs(1);
    3785            0 :             hybridVentMgr.type = ManagerType::HybridVent;
    3786              : 
    3787            0 :             hybridVentMgr.AirLoopName = ipsc->cAlphaArgs(2);
    3788              : 
    3789            0 :             if (ipsc->lAlphaFieldBlanks(2)) { // Hybrid ventilation manager applied to zone
    3790            0 :                 hybridVentMgr.HybridVentMgrConnectedToAirLoop = false;
    3791              :             }
    3792            0 :             hybridVentMgr.ControlZoneName = ipsc->cAlphaArgs(3);
    3793              :             // Check zone number
    3794            0 :             hybridVentMgr.ControlledZoneNum = Util::FindItemInList(ipsc->cAlphaArgs(3), state.dataHeatBal->Zone);
    3795            0 :             if (hybridVentMgr.ControlledZoneNum == 0) {
    3796            0 :                 ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(3), ipsc->cAlphaArgs(3));
    3797            0 :                 ErrorsFound = true;
    3798              :             }
    3799              : 
    3800            0 :             if (ipsc->lAlphaFieldBlanks(4)) {
    3801            0 :                 ShowSevereEmptyField(state, eoh, ipsc->cAlphaFieldNames(4));
    3802            0 :                 ErrorsFound = true;
    3803            0 :             } else if ((hybridVentMgr.controlModeSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(4))) == nullptr) {
    3804            0 :                 ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(4), ipsc->cAlphaArgs(4));
    3805            0 :                 ErrorsFound = true;
    3806              :             }
    3807              : 
    3808              :             // Check schedule values
    3809            0 :             SchedMin = hybridVentMgr.controlModeSched->getMinVal(state);
    3810            0 :             SchedMax = hybridVentMgr.controlModeSched->getMaxVal(state);
    3811            0 :             if (SchedMin == 0 && SchedMax == 0) {
    3812            0 :                 ShowWarningCustomField(state,
    3813              :                                        eoh,
    3814            0 :                                        ipsc->cAlphaFieldNames(4),
    3815            0 :                                        ipsc->cAlphaArgs(4),
    3816              :                                        "Schedule specifies control mode 0 for all entries, "
    3817              :                                        "All zones using this schedule have no hybrid ventilation control.");
    3818              :             }
    3819            0 :             if (SchedMax > 7.0) {
    3820            0 :                 ShowSevereCustomField(state,
    3821              :                                       eoh,
    3822            0 :                                       ipsc->cAlphaFieldNames(4),
    3823            0 :                                       ipsc->cAlphaArgs(4),
    3824            0 :                                       format("Maximum value should be 7. However, the maximum value in the schedule is {:.1T}", SchedMax));
    3825            0 :                 ErrorsFound = true;
    3826              :             }
    3827              : 
    3828            0 :             if (SchedMin < 0.0) {
    3829            0 :                 ShowSevereCustomField(state,
    3830              :                                       eoh,
    3831            0 :                                       ipsc->cAlphaFieldNames(4),
    3832            0 :                                       ipsc->cAlphaArgs(4),
    3833            0 :                                       format("Minimum value should be 0. However, the minimum value in the schedule is {:.1T}", SchedMin));
    3834            0 :                 ErrorsFound = true;
    3835              :             }
    3836              : 
    3837            0 :             if (SchedMax == 7.0 && !state.dataContaminantBalance->Contaminant.CO2Simulation) {
    3838            0 :                 ShowSevereCustomField(state,
    3839              :                                       eoh,
    3840            0 :                                       ipsc->cAlphaFieldNames(4),
    3841            0 :                                       ipsc->cAlphaArgs(4),
    3842              :                                       "When the schedule value is 7, carbon dioxide (CO2) control is requested."
    3843              :                                       "However, CO2 simulation is not enabled. Please use ZoneAirContaminantBalance object to simulate CO2.");
    3844            0 :                 ErrorsFound = true;
    3845              :             }
    3846              : 
    3847              :             // Read use weather rain indicator
    3848            0 :             BooleanSwitch b = static_cast<BooleanSwitch>(getYesNoValue(ipsc->cAlphaArgs(5)));
    3849            0 :             if (b == BooleanSwitch::Invalid) {
    3850            0 :                 ShowSevereInvalidKey(state, eoh, ipsc->cAlphaFieldNames(5), ipsc->cAlphaArgs(5));
    3851            0 :                 ErrorsFound = true;
    3852              :             } else {
    3853            0 :                 hybridVentMgr.UseRainIndicator = static_cast<bool>(b);
    3854              :             }
    3855              : 
    3856              :             // Check max wind speed
    3857            0 :             if (NumNumbers > 0) {
    3858            0 :                 hybridVentMgr.MaxWindSpeed = ipsc->rNumericArgs(1);
    3859            0 :                 if (ipsc->rNumericArgs(1) > 40.0 || ipsc->rNumericArgs(1) < 0.0) {
    3860            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    3861            0 :                     ShowContinueError(state, format("{} is beyond the range.", ipsc->cNumericFieldNames(1)));
    3862            0 :                     ShowContinueError(state,
    3863            0 :                                       format("The input value is {:.0T}. The allowed value must be >= 0 and <= 40 m/s", ipsc->rNumericArgs(1)));
    3864            0 :                     ErrorsFound = true;
    3865              :                 }
    3866              :             }
    3867              : 
    3868              :             // Read Max and Min outdoor temperature
    3869            0 :             if (NumNumbers > 1) {
    3870            0 :                 hybridVentMgr.MinOutdoorTemp = ipsc->rNumericArgs(2);
    3871            0 :                 if (ipsc->rNumericArgs(2) > 100.0 || ipsc->rNumericArgs(2) < -100.0) {
    3872            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    3873            0 :                     ShowContinueError(state, format("{} is beyond the range.", ipsc->cNumericFieldNames(2)));
    3874            0 :                     ShowContinueError(
    3875            0 :                         state, format("The input value is {:.0T}. The allowed value must be between -100 C and +100 C", ipsc->rNumericArgs(2)));
    3876            0 :                     ErrorsFound = true;
    3877              :                 }
    3878              :             }
    3879            0 :             if (NumNumbers > 2) {
    3880            0 :                 hybridVentMgr.MaxOutdoorTemp = ipsc->rNumericArgs(3);
    3881            0 :                 if (ipsc->rNumericArgs(3) > 100.0 || ipsc->rNumericArgs(3) < -100.0) {
    3882            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    3883            0 :                     ShowContinueError(state, format("{} is beyond the range.", ipsc->cNumericFieldNames(3)));
    3884            0 :                     ShowContinueError(
    3885            0 :                         state, format("The input value is {:.0T}. The allowed value must be between -100 C and +100 C", ipsc->rNumericArgs(3)));
    3886            0 :                     ErrorsFound = true;
    3887              :                 }
    3888              :             }
    3889              :             // Ensure MaxTemp >= MinTemp
    3890            0 :             if (ipsc->rNumericArgs(2) >= ipsc->rNumericArgs(3)) {
    3891            0 :                 ShowSevereError(state,
    3892            0 :                                 format("{}{}=\"{}\" The {} must be less than the {}",
    3893              :                                        RoutineName,
    3894              :                                        cCurrentModuleObject,
    3895            0 :                                        ipsc->cAlphaArgs(1),
    3896            0 :                                        ipsc->cNumericFieldNames(2),
    3897            0 :                                        ipsc->cNumericFieldNames(3)));
    3898            0 :                 ShowContinueError(state,
    3899            0 :                                   format("The {} is {:.0T}. The {} is {:.0T}.",
    3900            0 :                                          ipsc->cNumericFieldNames(2),
    3901            0 :                                          ipsc->rNumericArgs(2),
    3902            0 :                                          ipsc->cNumericFieldNames(3),
    3903            0 :                                          ipsc->rNumericArgs(3)));
    3904            0 :                 ErrorsFound = true;
    3905              :             }
    3906              : 
    3907              :             // Read Max and Min outdoor enthalpy
    3908            0 :             if (NumNumbers > 3) {
    3909            0 :                 hybridVentMgr.MinOutdoorEnth = ipsc->rNumericArgs(4);
    3910            0 :                 if (ipsc->rNumericArgs(4) > 300000.0 || ipsc->rNumericArgs(4) < 0.0) {
    3911            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    3912            0 :                     ShowContinueError(state, format("{} is beyond the range.", ipsc->cNumericFieldNames(4)));
    3913            0 :                     ShowContinueError(
    3914            0 :                         state, format("The input value is {:.0T}. The allowed value must be between 0 and 300000 J/kg", ipsc->rNumericArgs(4)));
    3915            0 :                     ErrorsFound = true;
    3916              :                 }
    3917              :             }
    3918            0 :             if (NumNumbers > 4) {
    3919            0 :                 hybridVentMgr.MaxOutdoorEnth = ipsc->rNumericArgs(5);
    3920            0 :                 if (ipsc->rNumericArgs(5) > 300000.0 || ipsc->rNumericArgs(5) < 0.0) {
    3921            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    3922            0 :                     ShowContinueError(state, format("{} is beyond the range.", ipsc->cNumericFieldNames(5)));
    3923            0 :                     ShowContinueError(
    3924            0 :                         state, format("The input value is {:.0T}. The allowed value must be between 0 and 300000 J/kg", ipsc->rNumericArgs(5)));
    3925            0 :                     ErrorsFound = true;
    3926              :                 }
    3927              :             }
    3928              :             // Ensure MaxEnth >= MiniEnth
    3929            0 :             if (ipsc->rNumericArgs(4) >= ipsc->rNumericArgs(5)) {
    3930            0 :                 ShowSevereError(state,
    3931            0 :                                 format("{}{}=\"{}\" The {} must be less than the {}",
    3932              :                                        RoutineName,
    3933              :                                        cCurrentModuleObject,
    3934            0 :                                        ipsc->cAlphaArgs(1),
    3935            0 :                                        ipsc->cNumericFieldNames(4),
    3936            0 :                                        ipsc->cNumericFieldNames(5)));
    3937            0 :                 ShowContinueError(state,
    3938            0 :                                   format("The {} is {:.0T}. The {} is {:.0T}.",
    3939            0 :                                          ipsc->cNumericFieldNames(4),
    3940            0 :                                          ipsc->rNumericArgs(4),
    3941            0 :                                          ipsc->cNumericFieldNames(5),
    3942            0 :                                          ipsc->rNumericArgs(5)));
    3943            0 :                 ErrorsFound = true;
    3944              :             }
    3945              : 
    3946              :             // Read Max and Min outdoor dew point
    3947            0 :             if (NumNumbers > 5) {
    3948            0 :                 hybridVentMgr.MinOutdoorDewPoint = ipsc->rNumericArgs(6);
    3949            0 :                 if (ipsc->rNumericArgs(6) > 100.0 || ipsc->rNumericArgs(6) < -100.0) {
    3950            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    3951            0 :                     ShowContinueError(state, format("{} is beyond the range.", ipsc->cNumericFieldNames(6)));
    3952            0 :                     ShowContinueError(
    3953            0 :                         state, format("The input value is {:.0T}. The allowed value must be between -100 C and +100 C", ipsc->rNumericArgs(6)));
    3954            0 :                     ErrorsFound = true;
    3955              :                 }
    3956              :             }
    3957            0 :             if (NumNumbers > 6) {
    3958            0 :                 hybridVentMgr.MaxOutdoorDewPoint = ipsc->rNumericArgs(7);
    3959            0 :                 if (ipsc->rNumericArgs(7) > 100.0 || ipsc->rNumericArgs(7) < -100.0) {
    3960            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    3961            0 :                     ShowContinueError(state, format("{} is beyond the range.", ipsc->cNumericFieldNames(7)));
    3962            0 :                     ShowContinueError(
    3963            0 :                         state, format("The input value is {:.0T}. The allowed value must be between -100 C and +100 C", ipsc->rNumericArgs(7)));
    3964            0 :                     ErrorsFound = true;
    3965              :                 }
    3966              :             }
    3967              :             // Ensure MaxTemp >= MinTemp
    3968            0 :             if (ipsc->rNumericArgs(6) >= ipsc->rNumericArgs(7)) {
    3969            0 :                 ShowSevereError(state,
    3970            0 :                                 format("{}{}=\"{}\" The {} must be less than the {}",
    3971              :                                        RoutineName,
    3972              :                                        cCurrentModuleObject,
    3973            0 :                                        ipsc->cAlphaArgs(1),
    3974            0 :                                        ipsc->cNumericFieldNames(6),
    3975            0 :                                        ipsc->cNumericFieldNames(7)));
    3976            0 :                 ShowContinueError(state,
    3977            0 :                                   format("The {} is {:.0T}. The {} is {:.0T}.",
    3978            0 :                                          ipsc->cNumericFieldNames(6),
    3979            0 :                                          ipsc->rNumericArgs(6),
    3980            0 :                                          ipsc->cNumericFieldNames(7),
    3981            0 :                                          ipsc->rNumericArgs(7)));
    3982            0 :                 ErrorsFound = true;
    3983              :             }
    3984              : 
    3985            0 :             if (ipsc->lAlphaFieldBlanks(6)) {
    3986            0 :                 ShowSevereEmptyField(state, eoh, ipsc->cAlphaFieldNames(6));
    3987            0 :                 ErrorsFound = true;
    3988            0 :             } else if ((hybridVentMgr.minOASched = Sched::GetSchedule(state, ipsc->cAlphaArgs(6))) == nullptr) {
    3989            0 :                 ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(6), ipsc->cAlphaArgs(6));
    3990            0 :                 ErrorsFound = true;
    3991            0 :             } else if (!hybridVentMgr.minOASched->checkMinVal(state, Clusive::In, 0.0)) {
    3992            0 :                 Sched::ShowSevereBadMin(state, eoh, ipsc->cAlphaFieldNames(6), ipsc->cAlphaArgs(6), Clusive::In, 0.0);
    3993            0 :                 ErrorsFound = true;
    3994              :             }
    3995              : 
    3996            0 :             if (!ipsc->lAlphaFieldBlanks(7)) {
    3997            0 :                 hybridVentMgr.OpeningFactorFWS = GetCurveIndex(state, ipsc->cAlphaArgs(7));
    3998            0 :                 if (hybridVentMgr.OpeningFactorFWS <= 0) {
    3999            0 :                     ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(7), ipsc->cAlphaArgs(7));
    4000            0 :                     ErrorsFound = true;
    4001              :                 } else {
    4002            0 :                     GetCurveMinMaxValues(state, hybridVentMgr.OpeningFactorFWS, CurveMin, CurveMax);
    4003            0 :                     if (CurveMin < 0.0) {
    4004            0 :                         ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    4005            0 :                         ShowContinueError(state,
    4006            0 :                                           format("The minimum wind speed used in {}=\"{}should be greater than or equal to 0.0 (m/s)",
    4007            0 :                                                  ipsc->cAlphaFieldNames(7),
    4008            0 :                                                  ipsc->cAlphaArgs(7)));
    4009            0 :                         ShowContinueError(state, "Curve minimum value appears to be less than 0.");
    4010            0 :                         ErrorsFound = true;
    4011              :                     }
    4012            0 :                     CurveVal = CurveValue(state, hybridVentMgr.OpeningFactorFWS, CurveMin);
    4013            0 :                     if (CurveVal < 0.0) {
    4014            0 :                         ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    4015            0 :                         ShowContinueError(state,
    4016            0 :                                           format("The minimum value of {} must be greater than or equal to 0.0 at the minimum value of wind speed.",
    4017            0 :                                                  ipsc->cAlphaFieldNames(7)));
    4018            0 :                         ShowContinueError(state, format("{}=\"{}\".", ipsc->cAlphaFieldNames(7), ipsc->cAlphaArgs(7)));
    4019            0 :                         ShowContinueError(state, format("Curve output at the minimum wind speed = {:.3T}", CurveVal));
    4020            0 :                         ErrorsFound = true;
    4021              :                     }
    4022            0 :                     CurveVal = CurveValue(state, hybridVentMgr.OpeningFactorFWS, CurveMax);
    4023            0 :                     if (CurveVal > 1.0) {
    4024            0 :                         ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    4025            0 :                         ShowContinueError(state,
    4026            0 :                                           format("The maximum value of {} must be less than or equal to 1.0 at the maximum value of wind speed.",
    4027            0 :                                                  ipsc->cAlphaFieldNames(7)));
    4028            0 :                         ShowContinueError(state, format("{}=\"{}\".", ipsc->cAlphaFieldNames(7), ipsc->cAlphaArgs(7)));
    4029            0 :                         ShowContinueError(state, format("Curve output at the maximum wind speed = {:.3T}", CurveVal));
    4030            0 :                         ErrorsFound = true;
    4031              :                     }
    4032              :                     // Check curve type
    4033            0 :                     ErrorsFound |= Curve::CheckCurveDims(state,
    4034              :                                                          hybridVentMgr.OpeningFactorFWS, // Curve index
    4035              :                                                          {1},                            // Valid dimensions
    4036              :                                                          RoutineName,                    // Routine name
    4037              :                                                          cCurrentModuleObject,           // Object Type
    4038              :                                                          hybridVentMgr.Name,             // Object Name
    4039            0 :                                                          ipsc->cAlphaFieldNames(7));     // Field Name
    4040              :                 }
    4041              :             }
    4042              : 
    4043            0 :             if (ipsc->lAlphaFieldBlanks(8)) {
    4044            0 :             } else if ((hybridVentMgr.afnControlTypeSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(8))) == nullptr) {
    4045            0 :                 ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(8), ipsc->cAlphaArgs(8));
    4046            0 :                 ErrorsFound = true;
    4047            0 :             } else if (!hybridVentMgr.afnControlTypeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 1.0)) {
    4048            0 :                 Sched::ShowSevereBadMinMax(state, eoh, ipsc->cAlphaFieldNames(8), ipsc->cAlphaArgs(8), Clusive::In, 0.0, Clusive::In, 1.0);
    4049            0 :                 ErrorsFound = true;
    4050              :             } else {
    4051            0 :                 hybridVentMgr.Master = hybridVentMgr.ControlledZoneNum;
    4052            0 :                 hybridVentMgr.afnControlStatus = hybridVentMgr.afnControlTypeSched->getCurrentVal(); // this was ANControlTypeSchedPtr!!
    4053              :             }
    4054              : 
    4055            0 :             if (ipsc->lAlphaFieldBlanks(9)) {
    4056            0 :             } else if ((hybridVentMgr.simpleControlTypeSched = Sched::GetSchedule(state, ipsc->cAlphaArgs(9))) == nullptr) {
    4057            0 :                 ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(9), ipsc->cAlphaArgs(9));
    4058            0 :                 ErrorsFound = true;
    4059            0 :             } else if (hybridVentMgr.afnControlTypeSched != nullptr) {
    4060            0 :                 ShowWarningCustom(state,
    4061              :                                   eoh,
    4062            0 :                                   format("{} and {} cannot be used at the same time, {} is disabled.",
    4063            0 :                                          ipsc->cAlphaFieldNames(8),
    4064            0 :                                          ipsc->cAlphaFieldNames(9),
    4065            0 :                                          ipsc->cAlphaFieldNames(9)));
    4066            0 :                 hybridVentMgr.simpleControlTypeSched = nullptr;
    4067            0 :             } else if (!hybridVentMgr.simpleControlTypeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 1.0)) {
    4068            0 :                 Sched::ShowSevereBadMinMax(state, eoh, ipsc->cAlphaFieldNames(9), ipsc->cAlphaArgs(9), Clusive::In, 0.0, Clusive::In, 1.0);
    4069            0 :                 ErrorsFound = true;
    4070              :             }
    4071              : 
    4072            0 :             if (hybridVentMgr.simpleControlTypeSched != nullptr) {
    4073              : 
    4074            0 :                 hybridVentMgr.VentilationName = ipsc->cAlphaArgs(10);
    4075            0 :                 if (state.dataHeatBal->TotVentilation > 0) {
    4076              : 
    4077            0 :                     hybridVentMgr.VentilationPtr = Util::FindItemInList(ipsc->cAlphaArgs(10), state.dataHeatBal->Ventilation);
    4078            0 :                     hybridVentMgr.Master = hybridVentMgr.VentilationPtr;
    4079              : 
    4080            0 :                     if (hybridVentMgr.VentilationPtr <= 0) {
    4081            0 :                         if (int(hybridVentMgr.simpleControlTypeSched->getMaxVal(state)) == 1) {
    4082            0 :                             ShowSevereItemNotFound(state, eoh, ipsc->cAlphaFieldNames(10), ipsc->cAlphaArgs(10));
    4083            0 :                             ErrorsFound = true;
    4084              :                         }
    4085              : 
    4086            0 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    4087            0 :                             ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, hybridVentMgr.Name));
    4088            0 :                             ShowContinueError(state, "The Airflow Network model is not available for Hybrid Ventilation Control.");
    4089            0 :                         } else if (state.afn->simulation_control.type ==
    4090              :                                    AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
    4091            0 :                             ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, hybridVentMgr.Name));
    4092            0 :                             ShowContinueError(state, "Please check the AirflowNetwork Control field in the AirflowNetwork:SimulationControl object.");
    4093            0 :                             ShowContinueError(state, "The suggested choices are MultizoneWithDistribution or MultizoneWithoutDistribution.");
    4094              :                         }
    4095              : 
    4096              :                     } else { // hybridVentMgr.VentilationPtr > 0
    4097            0 :                         if (hybridVentMgr.ControlledZoneNum != state.dataHeatBal->Ventilation(hybridVentMgr.VentilationPtr).ZonePtr) {
    4098            0 :                             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, ipsc->cAlphaArgs(1)));
    4099            0 :                             ShowContinueError(
    4100              :                                 state,
    4101            0 :                                 format("The Zone name specified in the Ventilation object {}",
    4102            0 :                                        state.dataHeatBal->Zone(state.dataHeatBal->Ventilation(hybridVentMgr.VentilationPtr).ZonePtr).Name));
    4103            0 :                             ShowContinueError(state, format("is not equal to the {}=\"{}\".", ipsc->cAlphaFieldNames(3), ipsc->cAlphaArgs(3)));
    4104            0 :                             ErrorsFound = true;
    4105              :                         }
    4106              : 
    4107            0 :                         if (state.afn->simulation_control.type != AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    4108            0 :                             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, hybridVentMgr.Name));
    4109            0 :                             ShowContinueError(state, "The simple airflow objects are used for natural ventilation calculation.");
    4110            0 :                             ShowContinueError(
    4111              :                                 state,
    4112              :                                 "The Airflow Network model is not allowed to perform. Please set the control type = NoMultizoneOrDistribution");
    4113            0 :                             ErrorsFound = true;
    4114              :                         }
    4115              :                     }
    4116              :                 }
    4117              :             }
    4118              : 
    4119              :             // Disallow combination of simple control and OA control mode
    4120            0 :             if (hybridVentMgr.simpleControlTypeSched != nullptr && hybridVentMgr.controlModeSched->getMaxVal(state) == 4.0) {
    4121            0 :                 ShowSevereCustom(state,
    4122              :                                  eoh,
    4123            0 :                                  format("The outdoor ventilation air control type defined in {} cannot work together with {}",
    4124            0 :                                         ipsc->cAlphaArgs(4),
    4125            0 :                                         ipsc->cAlphaFieldNames(9)));
    4126            0 :                 ErrorsFound = true;
    4127              :             }
    4128              : 
    4129            0 :             if (!ipsc->lNumericFieldBlanks(8)) {
    4130            0 :                 hybridVentMgr.MinOperTime = ipsc->rNumericArgs(8);
    4131              :             }
    4132            0 :             if (!ipsc->lNumericFieldBlanks(9)) {
    4133            0 :                 hybridVentMgr.MinVentTime = ipsc->rNumericArgs(9);
    4134              :             }
    4135              : 
    4136              :         } // SysAvailNum
    4137              : 
    4138            0 :         if (state.dataAvail->NumHybridVentSysAvailMgrs > 1) {
    4139            0 :             for (int SysAvailNum = 2; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    4140            0 :                 if (state.dataAvail->HybridVentData(SysAvailNum - 1).afnControlTypeSched != nullptr) {
    4141            0 :                     if (state.dataAvail->HybridVentData(SysAvailNum).simpleControlTypeSched != nullptr) {
    4142            0 :                         ShowSevereError(state,
    4143            0 :                                         format("The AirflowNetwork model is used for natural ventilation calculation in {}=\"{}\"",
    4144              :                                                cCurrentModuleObject,
    4145            0 :                                                state.dataAvail->HybridVentData(SysAvailNum - 1).Name));
    4146            0 :                         ShowContinueError(state,
    4147            0 :                                           format("The simple airflow objects are used for natural ventilation calculation in {}=\"{}\"",
    4148              :                                                  cCurrentModuleObject,
    4149            0 :                                                  state.dataAvail->HybridVentData(SysAvailNum).Name));
    4150            0 :                         ShowContinueError(state, "The hybrid ventilation control requires the same models to calculate natural ventilation");
    4151            0 :                         ErrorsFound = true;
    4152              :                     }
    4153              :                 }
    4154            0 :                 if (state.dataAvail->HybridVentData(SysAvailNum - 1).simpleControlTypeSched != nullptr) {
    4155            0 :                     if (state.dataAvail->HybridVentData(SysAvailNum).afnControlTypeSched != nullptr) {
    4156            0 :                         ShowSevereError(state,
    4157            0 :                                         format("The Airflow Network model is used for natural ventilation calculation in {}=\"{}\"",
    4158              :                                                cCurrentModuleObject,
    4159            0 :                                                state.dataAvail->HybridVentData(SysAvailNum).Name));
    4160            0 :                         ShowContinueError(state,
    4161            0 :                                           format("The simple airflow objects are used for natural ventilation calculation in {}=\"{}\"",
    4162              :                                                  cCurrentModuleObject,
    4163            0 :                                                  state.dataAvail->HybridVentData(SysAvailNum - 1).Name));
    4164            0 :                         ShowContinueError(state, "The hybrid ventilation control requires the same models to calculate natural ventilation");
    4165            0 :                         ErrorsFound = true;
    4166              :                     }
    4167              :                 }
    4168              :             } // SysAvailNum
    4169              :         }
    4170              : 
    4171            0 :         if (ErrorsFound) {
    4172            0 :             ShowFatalError(state, format("{} Errors found in input.  Preceding condition(s) cause termination.", RoutineName));
    4173              :         }
    4174              : 
    4175              :         // Set up output variables
    4176            0 :         for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    4177            0 :             if (state.dataAvail->HybridVentData(SysAvailNum).HybridVentMgrConnectedToAirLoop) {
    4178            0 :                 SetupOutputVariable(state,
    4179              :                                     "Availability Manager Hybrid Ventilation Control Status",
    4180              :                                     Constant::Units::None,
    4181            0 :                                     (int &)state.dataAvail->HybridVentData(SysAvailNum).ctrlStatus,
    4182              :                                     OutputProcessor::TimeStepType::System,
    4183              :                                     OutputProcessor::StoreType::Average,
    4184            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).AirLoopName);
    4185            0 :                 SetupOutputVariable(state,
    4186              :                                     "Availability Manager Hybrid Ventilation Control Mode",
    4187              :                                     Constant::Units::None,
    4188            0 :                                     (int &)state.dataAvail->HybridVentData(SysAvailNum).ctrlType,
    4189              :                                     OutputProcessor::TimeStepType::System,
    4190              :                                     OutputProcessor::StoreType::Average,
    4191            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).AirLoopName);
    4192              :             } else {
    4193            0 :                 SetupOutputVariable(state,
    4194              :                                     "Availability Manager Hybrid Ventilation Control Status",
    4195              :                                     Constant::Units::None,
    4196            0 :                                     (int &)state.dataAvail->HybridVentData(SysAvailNum).ctrlStatus,
    4197              :                                     OutputProcessor::TimeStepType::System,
    4198              :                                     OutputProcessor::StoreType::Average,
    4199            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).ControlZoneName);
    4200            0 :                 SetupOutputVariable(state,
    4201              :                                     "Availability Manager Hybrid Ventilation Control Mode",
    4202              :                                     Constant::Units::None,
    4203            0 :                                     (int &)state.dataAvail->HybridVentData(SysAvailNum).ctrlType,
    4204              :                                     OutputProcessor::TimeStepType::System,
    4205              :                                     OutputProcessor::StoreType::Average,
    4206            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).ControlZoneName);
    4207              :             }
    4208              : 
    4209            0 :             if (state.dataAvail->HybridVentData(SysAvailNum).MinOperTime > 0) {
    4210            0 :                 SetupOutputVariable(state,
    4211              :                                     "Hybrid Ventilation Control HVAC System Operation Elapsed Time",
    4212              :                                     Constant::Units::min,
    4213            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).TimeOperDuration,
    4214              :                                     OutputProcessor::TimeStepType::System,
    4215              :                                     OutputProcessor::StoreType::Average,
    4216            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).Name);
    4217              :             }
    4218              : 
    4219            0 :             if (state.dataAvail->HybridVentData(SysAvailNum).MinVentTime > 0) {
    4220            0 :                 SetupOutputVariable(state,
    4221              :                                     "Hybrid Ventilation Control Natural Ventilation Elapsed Time",
    4222              :                                     Constant::Units::min,
    4223            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).TimeVentDuration,
    4224              :                                     OutputProcessor::TimeStepType::System,
    4225              :                                     OutputProcessor::StoreType::Average,
    4226            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).Name);
    4227              :             }
    4228              : 
    4229            0 :             if (state.dataAvail->HybridVentData(SysAvailNum).controlModeSched->hasVal(state, (int)VentCtrlType::OperT80) ||
    4230            0 :                 state.dataAvail->HybridVentData(SysAvailNum).controlModeSched->hasVal(state, (int)VentCtrlType::OperT90)) {
    4231            0 :                 SetupOutputVariable(state,
    4232              :                                     "Hybrid Ventilation Operative Temperature",
    4233              :                                     Constant::Units::C,
    4234            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).OperativeTemp,
    4235              :                                     OutputProcessor::TimeStepType::System,
    4236              :                                     OutputProcessor::StoreType::Average,
    4237            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).Name);
    4238            0 :                 SetupOutputVariable(state,
    4239              :                                     "Hybrid Ventilation Lower Limit Operative Temperature",
    4240              :                                     Constant::Units::C,
    4241            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).minAdaTem,
    4242              :                                     OutputProcessor::TimeStepType::System,
    4243              :                                     OutputProcessor::StoreType::Average,
    4244            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).Name);
    4245            0 :                 SetupOutputVariable(state,
    4246              :                                     "Hybrid Ventilation Upper Limit Operative Temperature",
    4247              :                                     Constant::Units::C,
    4248            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).maxAdaTem,
    4249              :                                     OutputProcessor::TimeStepType::System,
    4250              :                                     OutputProcessor::StoreType::Average,
    4251            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).Name);
    4252              :             }
    4253              : 
    4254            0 :             if (state.dataAvail->HybridVentData(SysAvailNum).controlModeSched->hasVal(state, (int)VentCtrlType::CO2)) {
    4255            0 :                 SetupOutputVariable(state,
    4256              :                                     "Hybrid Ventilation CO2 Concentration",
    4257              :                                     Constant::Units::ppm,
    4258            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).CO2,
    4259              :                                     OutputProcessor::TimeStepType::System,
    4260              :                                     OutputProcessor::StoreType::Average,
    4261            0 :                                     state.dataAvail->HybridVentData(SysAvailNum).Name);
    4262              :             }
    4263              :         }
    4264              :     }
    4265              : 
    4266            0 :     void InitHybridVentSysAvailMgr(EnergyPlusData &state)
    4267              :     {
    4268              : 
    4269              :         // SUBROUTINE INFORMATION:
    4270              :         //       AUTHOR         Lixing Gu
    4271              :         //       DATE WRITTEN   March 2007
    4272              :         //       MODIFIED       na
    4273              :         //       RE-ENGINEERED  na
    4274              : 
    4275              :         // PURPOSE OF THIS SUBROUTINE:
    4276              :         // This subroutine is for initializations of the Hybrid Ventilation Control System Availability Manager
    4277              : 
    4278              :         // METHODOLOGY EMPLOYED:
    4279              :         // Uses the status flags to trigger initializations.
    4280              : 
    4281              :         // Using/Aliasing
    4282              :         using DataZoneEquipment::NumValidSysAvailZoneComponents;
    4283              : 
    4284              :         static constexpr std::string_view routineName = "InitHybridVentSysAvailMgr";
    4285              : 
    4286              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4287            0 :         bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
    4288              :         int AirLoopNum;          // Air loop number
    4289              :         int AirLoopCount;        // Air loop name count
    4290              :         int SysAvailIndex;       // Hybrid Ventilation Sys Avail Manager index
    4291              :         int ZoneEquipType;
    4292              :         int HybridVentNum;
    4293              : 
    4294              :         // One time initializations
    4295            0 :         if (state.dataAvail->MyOneTimeFlag && allocated(state.dataZoneEquip->ZoneEquipConfig) &&
    4296            0 :             allocated(state.dataAirSystemsData->PrimaryAirSystems)) {
    4297              : 
    4298              :             // Ensure the controlled zone is listed and defined in an HVAC Air Loop
    4299            0 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    4300            0 :                 auto &hybridVentMgr = state.dataAvail->HybridVentData(SysAvailNum);
    4301            0 :                 ErrorObjectHeader eoh{routineName, managerTypeNames[(int)ManagerType::HybridVent], hybridVentMgr.Name};
    4302            0 :                 if (hybridVentMgr.simpleControlTypeSched != nullptr && state.dataHeatBal->TotVentilation > 0 && hybridVentMgr.VentilationPtr == 0) {
    4303            0 :                     hybridVentMgr.VentilationPtr = Util::FindItemInList(hybridVentMgr.VentilationName, state.dataHeatBal->Ventilation);
    4304            0 :                     hybridVentMgr.Master = hybridVentMgr.VentilationPtr;
    4305            0 :                     if (hybridVentMgr.VentilationPtr <= 0 && int(hybridVentMgr.simpleControlTypeSched->getMaxVal(state)) == 1) {
    4306            0 :                         ShowSevereItemNotFound(state, eoh, "ZoneVentilation Object Name", hybridVentMgr.VentilationName);
    4307            0 :                         ErrorsFound = true;
    4308              :                     }
    4309              :                 }
    4310              :                 // Check air loop number
    4311            0 :                 for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) { // loop over the primary air systems
    4312            0 :                     if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Name, hybridVentMgr.AirLoopName)) {
    4313            0 :                         hybridVentMgr.AirLoopNum = AirLoopNum;
    4314              :                     }
    4315              :                 }
    4316              : 
    4317            0 :                 bool zoneFound = false;
    4318            0 :                 int ControlledZoneNum = hybridVentMgr.ControlledZoneNum;
    4319            0 :                 if (hybridVentMgr.HybridVentMgrConnectedToAirLoop) {
    4320            0 :                     if (hybridVentMgr.ControlledZoneNum > 0) {
    4321            0 :                         for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    4322            0 :                             if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode) == hybridVentMgr.AirLoopNum) {
    4323            0 :                                 zoneFound = true;
    4324              :                             }
    4325              :                         }
    4326            0 :                         if (!zoneFound) {
    4327            0 :                             ShowSevereError(state,
    4328            0 :                                             format("{}, The controlled zone ={} is not served by this Air Loop={}",
    4329            0 :                                                    managerTypeNames[(int)hybridVentMgr.type],
    4330            0 :                                                    hybridVentMgr.ControlZoneName,
    4331            0 :                                                    hybridVentMgr.AirLoopName));
    4332            0 :                             ErrorsFound = true;
    4333              :                         }
    4334              :                     }
    4335              :                 }
    4336            0 :                 if (std::any_of(state.dataAvail->HybridVentData.begin(),
    4337            0 :                                 state.dataAvail->HybridVentData.end(),
    4338            0 :                                 [](SysAvailManagerHybridVent const &e) { return e.HybridVentMgrConnectedToAirLoop; })) {
    4339            0 :                     for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    4340            0 :                         if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode) == hybridVentMgr.AirLoopNum &&
    4341            0 :                             hybridVentMgr.AirLoopNum > 0) {
    4342            0 :                             for (HybridVentNum = 1; HybridVentNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++HybridVentNum) {
    4343            0 :                                 if (!state.dataAvail->HybridVentData(HybridVentNum).HybridVentMgrConnectedToAirLoop &&
    4344              :                                     (HybridVentNum != SysAvailNum)) {
    4345            0 :                                     if (ControlledZoneNum == state.dataAvail->HybridVentData(HybridVentNum).ControlledZoneNum &&
    4346              :                                         ControlledZoneNum > 0) {
    4347            0 :                                         ShowWarningError(
    4348              :                                             state,
    4349            0 :                                             format("AvailabilityManager:HybridVentilation = \"{}\" has the controlled zone name = \"{}\".",
    4350            0 :                                                    state.dataAvail->HybridVentData(HybridVentNum).Name,
    4351            0 :                                                    state.dataAvail->HybridVentData(HybridVentNum).ControlZoneName));
    4352            0 :                                         ShowContinueError(
    4353              :                                             state,
    4354            0 :                                             format("This controlled zone already has hybrid ventilation control through this air loop = \"{}\".",
    4355            0 :                                                    hybridVentMgr.AirLoopName));
    4356            0 :                                         ShowContinueError(
    4357              :                                             state,
    4358            0 :                                             format("Only AvailabilityManager:HybridVentilation = \"{}\" will be simulated. Simulation continues...",
    4359            0 :                                                    hybridVentMgr.Name));
    4360              :                                     } else {
    4361            0 :                                         state.dataAvail->HybridVentData(HybridVentNum).SimHybridVentSysAvailMgr = true;
    4362              :                                     }
    4363              :                                 }
    4364              :                             }
    4365              :                         }
    4366              :                     }
    4367              :                 } else {
    4368            0 :                     for (auto &e : state.dataAvail->HybridVentData) {
    4369            0 :                         e.SimHybridVentSysAvailMgr = true;
    4370            0 :                     }
    4371              :                 }
    4372              : 
    4373            0 :                 if (hybridVentMgr.ControlledZoneNum == 0) {
    4374            0 :                     ShowSevereError(state,
    4375            0 :                                     format("{}, The controlled zone is not defined correctly ={}",
    4376            0 :                                            managerTypeNames[(int)hybridVentMgr.type],
    4377            0 :                                            hybridVentMgr.ControlZoneName));
    4378            0 :                     ErrorsFound = true;
    4379              :                 }
    4380              :                 // check schedule value for adaptive temperature control
    4381            0 :                 if (hybridVentMgr.controlModeSched->hasVal(state, 5.0) || hybridVentMgr.controlModeSched->hasVal(state, 6.0)) {
    4382            0 :                     if (!state.dataHeatBal->AdaptiveComfortRequested_ASH55) {
    4383            0 :                         ShowSevereError(state,
    4384            0 :                                         format("GetHybridVentilationInputs: AvailabilityManager:HybridVentilation =\"{}\"", hybridVentMgr.Name));
    4385            0 :                         ShowContinueError(state,
    4386            0 :                                           format("Ventilation Control Mode Schedule Name =\"{}\", When the schedule value is 5 or 6, operative "
    4387              :                                                  "temperature control is requested. ",
    4388            0 :                                                  hybridVentMgr.controlModeSched->Name));
    4389            0 :                         ShowContinueError(state,
    4390              :                                           "However, AdaptiveASH55 is not entered in the Thermal Comfort Model Type fields in the People object.");
    4391            0 :                         ErrorsFound = true;
    4392              :                     }
    4393              :                 }
    4394              :             }
    4395              : 
    4396              :             // Ensure an airloop name is not used more than once in the hybrid ventilation control objects
    4397            0 :             for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) { // loop over the primary air systems
    4398            0 :                 AirLoopCount = 0;
    4399            0 :                 for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    4400            0 :                     if (Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Name,
    4401            0 :                                          state.dataAvail->HybridVentData(SysAvailNum).AirLoopName)) {
    4402            0 :                         ++AirLoopCount;
    4403            0 :                         if (AirLoopCount > 1) {
    4404            0 :                             SysAvailIndex = SysAvailNum;
    4405              :                         }
    4406              :                     }
    4407              :                 }
    4408            0 :                 if (AirLoopCount > 1) {
    4409            0 :                     ShowSevereError(state,
    4410            0 :                                     format("{}, The AirLoopHVAC name found more than once={}",
    4411            0 :                                            managerTypeNames[(int)state.dataAvail->HybridVentData(SysAvailIndex).type],
    4412            0 :                                            state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Name));
    4413            0 :                     ShowContinueError(state, "Each AirLoopHVAC allows one hybrid ventilation control object.");
    4414            0 :                     ErrorsFound = true;
    4415              :                 }
    4416              :             }
    4417              : 
    4418            0 :             if (ErrorsFound) {
    4419            0 :                 ShowFatalError(state, "Errors found in getting AvailabilityManager:* inputs");
    4420              :             }
    4421              : 
    4422            0 :             state.dataAvail->MyOneTimeFlag = false;
    4423              : 
    4424              :         } // end 1 time initializations
    4425              : 
    4426            0 :         for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    4427            0 :             auto &hybridVentMgr = state.dataAvail->HybridVentData(SysAvailNum);
    4428            0 :             hybridVentMgr.ctrlType = static_cast<VentCtrlType>(hybridVentMgr.controlModeSched->getCurrentVal());
    4429              :             // -1 means that the value will be determined inside CalcHybridVentSysAvailMgr.
    4430              :             // IF the value is still -1, the program will stop.
    4431              :             // hybridVentMgr.ctrlStatus = VentCtrlStatus::Invalid; // Not sure what this is for
    4432            0 :             hybridVentMgr.WindModifier = -1.0;
    4433              :         }
    4434              : 
    4435            0 :         if (allocated(state.dataAvail->HybridVentData)) {
    4436            0 :             for (auto &e : state.dataAvail->HybridVentData) {
    4437            0 :                 e.availStatus = Status::NoAction;
    4438            0 :             }
    4439              :         }
    4440              : 
    4441            0 :         if (allocated(state.dataAvail->ZoneComp)) {
    4442            0 :             for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) { // loop over the zone equipment types
    4443            0 :                 if (state.dataAvail->ZoneComp(ZoneEquipType).TotalNumComp > 0) {
    4444            0 :                     for (auto &e : state.dataAvail->ZoneComp(ZoneEquipType).ZoneCompAvailMgrs) {
    4445            0 :                         e.availStatus = Status::NoAction;
    4446              :                     }
    4447              :                 }
    4448              :             }
    4449              :         }
    4450              : 
    4451            0 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataAvail->MyEnvrnFlag) {
    4452            0 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    4453            0 :                 state.dataAvail->HybridVentData(SysAvailNum).TimeVentDuration = 0.0;
    4454            0 :                 state.dataAvail->HybridVentData(SysAvailNum).TimeOperDuration = 0.0;
    4455              :             }
    4456            0 :             state.dataAvail->MyEnvrnFlag = false;
    4457              :         }
    4458            0 :         if (!state.dataGlobal->BeginEnvrnFlag) {
    4459            0 :             state.dataAvail->MyEnvrnFlag = true;
    4460              :         }
    4461              :         // check minimum operation time
    4462            0 :         state.dataAvail->CurrentEndTime = state.dataGlobal->CurrentTime + state.dataHVACGlobal->SysTimeElapsed;
    4463            0 :         if (state.dataAvail->CurrentEndTime > state.dataAvail->CurrentEndTimeLast &&
    4464            0 :             state.dataHVACGlobal->TimeStepSys >= state.dataAvail->TimeStepSysLast) {
    4465            0 :             for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    4466            0 :                 auto &hybridVentMgr = state.dataAvail->HybridVentData(SysAvailNum);
    4467            0 :                 if (hybridVentMgr.ctrlStatus == VentCtrlStatus::NoAction) {
    4468            0 :                     hybridVentMgr.TimeOperDuration = 0.0;
    4469            0 :                     hybridVentMgr.TimeVentDuration = 0.0;
    4470              :                 }
    4471            0 :                 if (hybridVentMgr.MinVentTime > 0.0) {
    4472            0 :                     if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Open) {
    4473            0 :                         hybridVentMgr.TimeVentDuration += (state.dataAvail->CurrentEndTime - state.dataAvail->CurrentEndTimeLast) * 60.0;
    4474            0 :                         hybridVentMgr.TimeOperDuration = 0.0;
    4475              :                     }
    4476              :                 }
    4477            0 :                 if (hybridVentMgr.MinOperTime > 0.0) {
    4478            0 :                     if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Close) {
    4479            0 :                         hybridVentMgr.TimeOperDuration += (state.dataAvail->CurrentEndTime - state.dataAvail->CurrentEndTimeLast) * 60.0;
    4480            0 :                         hybridVentMgr.TimeVentDuration = 0.0;
    4481              :                     }
    4482              :                 }
    4483              :             }
    4484              :         }
    4485            0 :         state.dataAvail->TimeStepSysLast = state.dataHVACGlobal->TimeStepSys;
    4486            0 :         state.dataAvail->CurrentEndTimeLast = state.dataAvail->CurrentEndTime;
    4487            0 :     }
    4488              : 
    4489           13 :     void CalcHybridVentSysAvailMgr(EnergyPlusData &state,
    4490              :                                    int const SysAvailNum,                     // number of the current scheduled system availability manager
    4491              :                                    ObjexxFCL::Optional_int_const PriAirSysNum // number of the primary air system affected by this Avail. Manager
    4492              :     )
    4493              :     {
    4494              : 
    4495              :         // SUBROUTINE INFORMATION:
    4496              :         //       AUTHOR         Lixing Gu
    4497              :         //       DATE WRITTEN   March 2007
    4498              :         //       MODIFIED       July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
    4499              :         //       RE-ENGINEERED  na
    4500              : 
    4501              :         // PURPOSE OF THIS SUBROUTINE:
    4502              :         // Set AvailStatus indicator for a primary air loop and AirflowNetwork model to prevent
    4503              :         // windows or doors open during HVAC system operation
    4504              : 
    4505              :         // METHODOLOGY EMPLOYED:
    4506              :         // Looks at outside and indoor conditions to determine if hybrid ventilation
    4507              :         // is beneficial. If it is and it is scheduled on the AvailStatus is set to cycle
    4508              :         // on and open windows or doors.
    4509              : 
    4510              :         using namespace DataAirLoop;
    4511              :         using Curve::CurveValue;
    4512              :         using DataZoneEquipment::NumValidSysAvailZoneComponents;
    4513              :         using Psychrometrics::PsyHFnTdbW;
    4514              :         using Psychrometrics::PsyRhFnTdbWPb;
    4515              :         using Psychrometrics::PsyTdpFnWPb;
    4516              :         using Psychrometrics::PsyWFnTdbRhPb;
    4517              : 
    4518              :         int HStatZoneNum;                   // Humidity control zone number
    4519              :         Real64 ZoneAirEnthalpy;             // Zone air enthalpy
    4520              :         Real64 ZoneAirDewPoint;             // Zone air dew point temperature
    4521              :         Real64 ZoneAirRH;                   // Zone air relative humidity
    4522              :         Real64 TempExt;                     // Outdoor dry bulb temperature at zone height
    4523              :         Real64 WindExt;                     // Outdoor wind speed at zone height
    4524              :         Real64 WSetPoint;                   // Humidity ratio setpoint from a given RH setpoint schedule
    4525              :         Real64 OASetPoint;                  // Outdoor air setpoint from a given OA setpoint schedule
    4526              :         Real64 ACH;                         // Zone air change per hour
    4527              :         bool found;                         // Used for humidistat object
    4528              :         bool HybridVentModeOA;              // USed to check whether HybridVentModeOA is allowed
    4529              :         Real64 ZoneRHHumidifyingSetPoint;   // Zone humidifying setpoint (%)
    4530              :         Real64 ZoneRHDehumidifyingSetPoint; // Zone dehumidifying setpoint (%)
    4531              :         int SimpleControlType;              // Simple control type from a schedule: 0 individual, 1 global
    4532              :         int i;                              // Array index
    4533              :         Real64 minAdaTem;                   // minimum adaptive temperature for adaptive temperature control
    4534              :         Real64 maxAdaTem;                   // maximum adaptive temperature for adaptive temperature control
    4535              :         bool KeepStatus;                    // true, if minimum time operation is needed
    4536              :         int ZoneEquipType;
    4537              :         int ZoneCompNum;
    4538              :         int AirLoopNum;
    4539              :         int Num;
    4540              :         Status availStatus;
    4541              : 
    4542           13 :         KeepStatus = false;
    4543           13 :         auto &hybridVentMgr = state.dataAvail->HybridVentData(SysAvailNum);
    4544           13 :         if (hybridVentMgr.TimeVentDuration > 0.0 && hybridVentMgr.TimeVentDuration <= hybridVentMgr.MinVentTime) {
    4545            1 :             KeepStatus = true;
    4546              :         }
    4547           13 :         if (hybridVentMgr.TimeOperDuration > 0.0 && hybridVentMgr.TimeOperDuration <= hybridVentMgr.MinOperTime) {
    4548            1 :             KeepStatus = true;
    4549              :         }
    4550              : 
    4551           13 :         int ZoneNum = hybridVentMgr.ControlledZoneNum;
    4552           13 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    4553           13 :         if (!KeepStatus) {
    4554           11 :             hybridVentMgr.ctrlStatus = VentCtrlStatus::NoAction;
    4555              :         }
    4556           13 :         TempExt = state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp;
    4557           13 :         WindExt = state.dataHeatBal->Zone(ZoneNum).WindSpeed;
    4558           13 :         hybridVentMgr.OperativeTemp = 0.0;
    4559           13 :         hybridVentMgr.minAdaTem = 0.0;
    4560           13 :         hybridVentMgr.maxAdaTem = 0.0;
    4561              : 
    4562           13 :         if (!KeepStatus) {
    4563           11 :             switch (hybridVentMgr.ctrlType) {
    4564              : 
    4565            0 :             case VentCtrlType::No: {
    4566            0 :                 hybridVentMgr.ctrlStatus = VentCtrlStatus::NoAction;
    4567              : 
    4568              :                 // Temperature control
    4569            0 :             } break;
    4570              : 
    4571            2 :             case VentCtrlType::Temp: {
    4572            2 :                 if (TempExt >= hybridVentMgr.MinOutdoorTemp && TempExt <= hybridVentMgr.MaxOutdoorTemp) {
    4573            1 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4574              :                 } else {
    4575            1 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4576              :                 }
    4577              : 
    4578              :                 // Enthalpy control
    4579            2 :             } break;
    4580              : 
    4581            0 :             case VentCtrlType::Enth: {
    4582            0 :                 ZoneAirEnthalpy = PsyHFnTdbW(thisZoneHB.MAT, thisZoneHB.airHumRat);
    4583            0 :                 if (state.dataEnvrn->OutEnthalpy >= hybridVentMgr.MinOutdoorEnth && state.dataEnvrn->OutEnthalpy <= hybridVentMgr.MaxOutdoorEnth) {
    4584            0 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4585              :                 } else {
    4586            0 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4587              :                 }
    4588              : 
    4589              :                 // Dew point control
    4590            0 :             } break;
    4591              : 
    4592            0 :             case VentCtrlType::DewPoint: {
    4593            0 :                 if (state.dataEnvrn->OutDewPointTemp >= hybridVentMgr.MinOutdoorDewPoint &&
    4594            0 :                     state.dataEnvrn->OutDewPointTemp <= hybridVentMgr.MaxOutdoorDewPoint) {
    4595            0 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4596              :                 } else {
    4597            0 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4598              :                 }
    4599              : 
    4600            0 :             } break;
    4601              : 
    4602            0 :             case VentCtrlType::OA: {
    4603            0 :                 OASetPoint = hybridVentMgr.minOASched->getCurrentVal();
    4604            0 :                 ACH = 0.0;
    4605            0 :                 HybridVentModeOA = true;
    4606            0 :                 if (!hybridVentMgr.HybridVentMgrConnectedToAirLoop) {
    4607            0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    4608            0 :                         HybridVentModeOA = false;
    4609              :                     }
    4610              :                 }
    4611              : 
    4612            0 :                 if (hybridVentMgr.afnControlTypeSched != nullptr && HybridVentModeOA) {
    4613            0 :                     state.afn->manage_balance(true);
    4614            0 :                     ACH = state.afn->zone_OA_change_rate(ZoneNum);
    4615              :                 }
    4616            0 :                 if (ACH > OASetPoint) {
    4617            0 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4618              :                 } else {
    4619            0 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4620              :                 }
    4621              : 
    4622            0 :             } break;
    4623              : 
    4624            2 :             case VentCtrlType::OperT80: {
    4625            2 :                 if (state.dataThermalComforts->runningAverageASH >= 10.0 && state.dataThermalComforts->runningAverageASH <= 33.5) {
    4626            2 :                     hybridVentMgr.OperativeTemp = 0.5 * (thisZoneHB.MAT + thisZoneHB.MRT);
    4627            2 :                     minAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 14.3;
    4628            2 :                     maxAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 21.3;
    4629            2 :                     hybridVentMgr.minAdaTem = minAdaTem;
    4630            2 :                     hybridVentMgr.maxAdaTem = maxAdaTem;
    4631            2 :                     if (hybridVentMgr.OperativeTemp <= maxAdaTem && hybridVentMgr.OperativeTemp >= minAdaTem) {
    4632            1 :                         hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4633              :                     } else {
    4634            1 :                         hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4635              :                     }
    4636              :                 } else {
    4637            0 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4638              :                 }
    4639              : 
    4640            2 :             } break;
    4641              : 
    4642            2 :             case VentCtrlType::OperT90: {
    4643            2 :                 if (state.dataThermalComforts->runningAverageASH >= 10.0 && state.dataThermalComforts->runningAverageASH <= 33.5) {
    4644            2 :                     hybridVentMgr.OperativeTemp = 0.5 * (thisZoneHB.MAT + thisZoneHB.MRT);
    4645            2 :                     minAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 15.3;
    4646            2 :                     maxAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 20.3;
    4647            2 :                     hybridVentMgr.minAdaTem = minAdaTem;
    4648            2 :                     hybridVentMgr.maxAdaTem = maxAdaTem;
    4649            2 :                     if (hybridVentMgr.OperativeTemp <= maxAdaTem && hybridVentMgr.OperativeTemp >= minAdaTem) {
    4650            1 :                         hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4651              :                     } else {
    4652            1 :                         hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4653              :                     }
    4654              :                 } else {
    4655            0 :                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4656              :                 }
    4657              : 
    4658            2 :             } break;
    4659            5 :             case VentCtrlType::CO2: {
    4660            5 :                 hybridVentMgr.CO2 = state.dataContaminantBalance->ZoneAirCO2(ZoneNum);
    4661            5 :                 if (state.dataContaminantBalance->ZoneAirCO2(ZoneNum) > state.dataContaminantBalance->ZoneCO2SetPoint(ZoneNum)) {
    4662            4 :                     if (hybridVentMgr.HybridVentMgrConnectedToAirLoop) {
    4663            2 :                         AirLoopNum = hybridVentMgr.AirLoopNum;
    4664            4 :                         for (Num = 1; Num <= state.dataAirLoop->PriAirSysAvailMgr(hybridVentMgr.AirLoopNum).NumAvailManagers; ++Num) {
    4665            4 :                             availStatus = SimSysAvailManager(state,
    4666            2 :                                                              state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).availManagers(Num).type,
    4667            2 :                                                              state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).availManagers(Num).Name,
    4668            2 :                                                              state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).availManagers(Num).Num,
    4669              :                                                              AirLoopNum,
    4670            2 :                                                              state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).availStatus);
    4671              :                         }
    4672            2 :                         if (availStatus == Status::CycleOn) {
    4673            1 :                             hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4674              :                         } else {
    4675            1 :                             hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4676              :                         }
    4677            2 :                     } else if (hybridVentMgr.SimHybridVentSysAvailMgr) {
    4678            2 :                         hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4679           30 :                         for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) {
    4680           29 :                             for (ZoneCompNum = 1; ZoneCompNum <= state.dataAvail->ZoneComp(ZoneEquipType).TotalNumComp; ++ZoneCompNum) {
    4681            2 :                                 if (state.dataAvail->ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(ZoneCompNum).availStatus == Status::CycleOn) {
    4682            1 :                                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4683            1 :                                     break;
    4684              :                                 }
    4685              :                             }
    4686              :                         }
    4687              :                     } else {
    4688            0 :                         hybridVentMgr.ctrlStatus = VentCtrlStatus::Open;
    4689              :                     }
    4690              :                 }
    4691            5 :             } break;
    4692            0 :             default: {
    4693            0 :                 ShowSevereError(state,
    4694            0 :                                 format("{}: incorrect Control Type: {}", managerTypeNames[(int)hybridVentMgr.type], hybridVentMgr.AirLoopName));
    4695            0 :                 ShowFatalError(state, format("Errors found in getting {} Control mode value", managerTypeNames[(int)hybridVentMgr.type]));
    4696              :             }
    4697              :             }
    4698              : 
    4699           11 :             if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Open) {
    4700              : 
    4701            5 :                 auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
    4702              :                 // Temperature and enthalpy control
    4703            5 :                 if (hybridVentMgr.ctrlType == VentCtrlType::Temp || hybridVentMgr.ctrlType == VentCtrlType::Enth) {
    4704              : 
    4705            1 :                     switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
    4706              : 
    4707            1 :                     case HVAC::SetptType::SingleHeat: {
    4708            1 :                         if (thisZoneHB.MAT < zoneTstatSetpt.setpt) {
    4709            0 :                             hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4710              :                         }
    4711              : 
    4712            1 :                     } break;
    4713            0 :                     case HVAC::SetptType::SingleCool: {
    4714            0 :                         if (thisZoneHB.MAT > zoneTstatSetpt.setpt) {
    4715            0 :                             hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4716              :                         }
    4717              : 
    4718            0 :                     } break;
    4719            0 :                     case HVAC::SetptType::SingleHeatCool: {
    4720            0 :                         hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4721            0 :                         ++hybridVentMgr.SingleHCErrCount;
    4722            0 :                         if (hybridVentMgr.SingleHCErrCount < 2) {
    4723            0 :                             ShowWarningError(state,
    4724            0 :                                              format("Hybrid ventilation control: {}: The zone temperature control type is "
    4725              :                                                     "ThermostatSetpoint:SingleHeatingOrCooling. Natural ventilation is not allowed.",
    4726            0 :                                                     hybridVentMgr.AirLoopName));
    4727            0 :                             ShowContinueErrorTimeStamp(state, "");
    4728              :                         } else {
    4729            0 :                             ShowRecurringWarningErrorAtEnd(
    4730              :                                 state,
    4731            0 :                                 "Hybrid ventilation control: " + hybridVentMgr.AirLoopName +
    4732              :                                     ": No natural ventilation continues with a ThermostatSetpoint:SingleHeatingOrCooling type...",
    4733            0 :                                 hybridVentMgr.SingleHCErrIndex,
    4734            0 :                                 double(hybridVentMgr.ctrlType),
    4735            0 :                                 double(hybridVentMgr.ctrlType));
    4736              :                         }
    4737              : 
    4738            0 :                     } break;
    4739              : 
    4740            0 :                     case HVAC::SetptType::DualHeatCool: {
    4741            0 :                         if (thisZoneHB.MAT < zoneTstatSetpt.setptLo || thisZoneHB.MAT > zoneTstatSetpt.setptHi) {
    4742            0 :                             hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4743              :                         }
    4744              : 
    4745            0 :                     } break;
    4746            0 :                     default:
    4747            0 :                         break;
    4748              :                     } // end select on thermostat control
    4749              :                 }
    4750              : 
    4751              :                 // Dew point control mode
    4752            5 :                 if (hybridVentMgr.ctrlType == VentCtrlType::DewPoint) {
    4753            0 :                     ZoneAirRH = PsyRhFnTdbWPb(state, thisZoneHB.MAT, thisZoneHB.airHumRat, state.dataEnvrn->OutBaroPress) * 100.0;
    4754            0 :                     ZoneAirDewPoint = PsyTdpFnWPb(state, thisZoneHB.airHumRat, state.dataEnvrn->OutBaroPress);
    4755            0 :                     if (state.dataZoneCtrls->NumHumidityControlZones == 0) {
    4756            0 :                         ++hybridVentMgr.DewPointNoRHErrCount;
    4757            0 :                         if (hybridVentMgr.DewPointNoRHErrCount < 2) {
    4758            0 :                             ShowWarningError(
    4759              :                                 state,
    4760            0 :                                 format("Hybrid ventilation control: Dew point control mode is selected, but no ZoneControl:Humidistat object={}",
    4761            0 :                                        hybridVentMgr.AirLoopName));
    4762            0 :                             ShowContinueError(state, "The hybrid ventilation control is triggered by outdoor min and max dewpoint only.");
    4763            0 :                             ShowContinueError(state, "HVAC system may turn off when outdoor dewpoint is between min and max dewpoint.");
    4764            0 :                             ShowContinueErrorTimeStamp(state, "");
    4765              :                         } else {
    4766            0 :                             ShowRecurringWarningErrorAtEnd(state,
    4767            0 :                                                            "Hybrid ventilation control: " + hybridVentMgr.AirLoopName +
    4768              :                                                                ": no ZoneControl:Humidistat object continues...",
    4769            0 :                                                            hybridVentMgr.DewPointNoRHErrIndex,
    4770            0 :                                                            double(hybridVentMgr.ctrlType),
    4771            0 :                                                            double(hybridVentMgr.ctrlType));
    4772              :                         }
    4773              :                     }
    4774            0 :                     found = false;
    4775            0 :                     for (HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
    4776            0 :                         if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum == ZoneNum) {
    4777            0 :                             found = true;
    4778            0 :                             ZoneRHHumidifyingSetPoint = state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).humidifyingSched->getCurrentVal();
    4779            0 :                             ZoneRHDehumidifyingSetPoint = state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).dehumidifyingSched->getCurrentVal();
    4780            0 :                             if (ZoneAirRH > ZoneRHDehumidifyingSetPoint) { // Need dehumidification
    4781              :                                 WSetPoint =
    4782            0 :                                     PsyWFnTdbRhPb(state, thisZoneHB.MAT, (ZoneRHDehumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress);
    4783            0 :                                 if (WSetPoint < state.dataEnvrn->OutHumRat) {
    4784            0 :                                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4785              :                                 }
    4786            0 :                             } else if (ZoneAirRH < ZoneRHHumidifyingSetPoint) { // Need humidification
    4787            0 :                                 WSetPoint = PsyWFnTdbRhPb(state, thisZoneHB.MAT, (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress);
    4788            0 :                                 if (WSetPoint > state.dataEnvrn->OutHumRat) {
    4789            0 :                                     hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4790              :                                 }
    4791              :                             } else {
    4792            0 :                                 hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4793              :                             }
    4794              :                         }
    4795              :                     }
    4796            0 :                     if (!found && state.dataZoneCtrls->NumHumidityControlZones > 0) {
    4797            0 :                         ++hybridVentMgr.DewPointErrCount;
    4798            0 :                         if (hybridVentMgr.DewPointErrCount < 2) {
    4799            0 :                             ShowWarningError(state,
    4800            0 :                                              format("Hybrid ventilation control: The zone for dew point control mode is different from the zone for "
    4801              :                                                     "ZoneControl:Humidistat={}",
    4802            0 :                                                     hybridVentMgr.AirLoopName));
    4803            0 :                             ShowContinueError(
    4804              :                                 state,
    4805            0 :                                 format("The Zone name for hybrid control is {}. Humidistat has no impact", state.dataHeatBal->Zone(ZoneNum).Name));
    4806            0 :                             ShowContinueError(state, "HVAC system may turn off when outdoor dewpoint is between min and max dewpoint.");
    4807            0 :                             ShowContinueErrorTimeStamp(state, "");
    4808              :                         } else {
    4809            0 :                             ShowRecurringWarningErrorAtEnd(state,
    4810            0 :                                                            "Hybrid ventilation control: " + hybridVentMgr.AirLoopName +
    4811              :                                                                " No humidistat control impact continues...",
    4812            0 :                                                            hybridVentMgr.DewPointErrIndex,
    4813            0 :                                                            double(hybridVentMgr.ctrlType),
    4814            0 :                                                            double(hybridVentMgr.ctrlType));
    4815              :                         }
    4816              :                     }
    4817              :                 }
    4818              : 
    4819              :                 // Outdoor ventilation air control mode
    4820            5 :                 if (hybridVentMgr.ctrlType == VentCtrlType::OA) {
    4821              :                 }
    4822              :             }
    4823              :         }
    4824              : 
    4825           13 :         if (WindExt > hybridVentMgr.MaxWindSpeed) {
    4826            0 :             hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4827              :         }
    4828              : 
    4829           13 :         if (state.dataEnvrn->IsRain && hybridVentMgr.UseRainIndicator) {
    4830            0 :             hybridVentMgr.ctrlStatus = VentCtrlStatus::Close;
    4831              :         }
    4832              :         // Sent a signal to the AirflowNetwork to ensure large onpenings are close or open based on this logic
    4833           13 :         if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Invalid) {
    4834              :             // Fatal error
    4835            0 :             ShowFatalError(state,
    4836              :                            "Hybrid ventilation control: the ventilation control status is beyond the range. Please check input of control "
    4837              :                            "mode schedule");
    4838              :         }
    4839              : 
    4840           13 :         if (hybridVentMgr.HybridVentMgrConnectedToAirLoop) {
    4841            7 :             if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Close) {
    4842            3 :                 state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).availStatus = Status::CycleOn;
    4843              :             }
    4844              :         }
    4845              : 
    4846           13 :         if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Open && hybridVentMgr.afnControlTypeSched != nullptr && hybridVentMgr.OpeningFactorFWS > 0) {
    4847            0 :             hybridVentMgr.WindModifier = CurveValue(state, hybridVentMgr.OpeningFactorFWS, WindExt);
    4848              :         }
    4849              : 
    4850              :         // Set up flags to control simple airflow objects
    4851           13 :         if (hybridVentMgr.AirLoopNum > 0 && hybridVentMgr.simpleControlTypeSched != nullptr) {
    4852            0 :             SimpleControlType = hybridVentMgr.simpleControlTypeSched->getCurrentVal();
    4853            0 :             for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
    4854            0 :                 for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
    4855            0 :                     if (hybridVentMgr.AirLoopNum == state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode)) {
    4856              :                         // Setup flag for ventilation objects
    4857            0 :                         for (i = 1; i <= state.dataHeatBal->TotVentilation; ++i) {
    4858            0 :                             if (state.dataHeatBal->Ventilation(i).ZonePtr == ControlledZoneNum) {
    4859            0 :                                 state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Indiv;
    4860            0 :                                 if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Close) {
    4861            0 :                                     state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Close;
    4862              :                                 } else {
    4863            0 :                                     if (SimpleControlType == 1) {
    4864            0 :                                         state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Global;
    4865            0 :                                         state.dataHeatBal->Ventilation(i).HybridControlMasterNum = hybridVentMgr.VentilationPtr;
    4866              :                                     }
    4867              :                                 }
    4868              :                             }
    4869              :                         }
    4870              :                         // Setup flag for Mixing objects
    4871            0 :                         for (i = 1; i <= state.dataHeatBal->TotMixing; ++i) {
    4872            0 :                             if (state.dataHeatBal->Mixing(i).ZonePtr == ControlledZoneNum) {
    4873            0 :                                 state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Indiv;
    4874            0 :                                 if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Close) {
    4875            0 :                                     state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Close;
    4876              :                                 } else {
    4877            0 :                                     if (SimpleControlType == 1) {
    4878            0 :                                         state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Global;
    4879            0 :                                         state.dataHeatBal->Mixing(i).HybridControlMasterNum = hybridVentMgr.VentilationPtr;
    4880              :                                     }
    4881              :                                 }
    4882              :                             }
    4883              :                         }
    4884              :                     }
    4885              :                 }
    4886              :             }
    4887           13 :         } else if (hybridVentMgr.simpleControlTypeSched != nullptr) {
    4888            0 :             SimpleControlType = hybridVentMgr.simpleControlTypeSched->getCurrentVal();
    4889              :             // Hybrid ventilation manager is applied to zone component
    4890              :             // setup flag for ventilation objects
    4891            0 :             for (i = 1; i <= state.dataHeatBal->TotVentilation; ++i) {
    4892            0 :                 if (state.dataHeatBal->Ventilation(i).ZonePtr == hybridVentMgr.ControlledZoneNum) {
    4893            0 :                     state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Indiv;
    4894            0 :                     if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Close) {
    4895            0 :                         state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Close;
    4896              :                     } else {
    4897            0 :                         if (SimpleControlType == 1) {
    4898            0 :                             state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Global;
    4899            0 :                             state.dataHeatBal->Ventilation(i).HybridControlMasterNum = hybridVentMgr.VentilationPtr;
    4900              :                         }
    4901              :                     }
    4902              :                 }
    4903              :             }
    4904              :             // Setup flag for Mixing objects
    4905            0 :             for (i = 1; i <= state.dataHeatBal->TotMixing; ++i) {
    4906            0 :                 if (state.dataHeatBal->Mixing(i).ZonePtr == hybridVentMgr.ControlledZoneNum) {
    4907            0 :                     state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Indiv;
    4908            0 :                     if (hybridVentMgr.ctrlStatus == VentCtrlStatus::Close) {
    4909            0 :                         state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Close;
    4910              :                     } else {
    4911            0 :                         if (SimpleControlType == 1) {
    4912            0 :                             state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Global;
    4913            0 :                             state.dataHeatBal->Mixing(i).HybridControlMasterNum = hybridVentMgr.VentilationPtr;
    4914              :                         }
    4915              :                     }
    4916              :                 }
    4917              :             }
    4918              :         }
    4919           13 :     }
    4920              : 
    4921            2 :     bool GetHybridVentilationControlStatus(EnergyPlusData &state, int const ZoneNum) // Index of zone
    4922              :     {
    4923              : 
    4924              :         // SUBROUTINE INFORMATION:
    4925              :         //       AUTHOR         Lixing Gu
    4926              :         //       DATE WRITTEN   July 2010
    4927              :         //       MODIFIED       na
    4928              :         //       RE-ENGINEERED  na
    4929              : 
    4930              :         // PURPOSE OF THIS SUBROUTINE:
    4931              :         // This routine was designed to find whether this zone is controlled by hybrid ventilation
    4932              :         // ventilation control option.
    4933              : 
    4934              :         // Return value
    4935              :         bool VentControl; // Set to true if ventilation control in the same zone
    4936              : 
    4937            2 :         if (state.dataAvail->GetHybridInputFlag) { // First time subroutine has been entered
    4938            1 :             GetHybridVentilationInputs(state);
    4939            1 :             state.dataAvail->GetHybridInputFlag = false;
    4940              :         }
    4941              : 
    4942            2 :         VentControl = false;
    4943              : 
    4944            2 :         for (int SysAvailNum = 1; SysAvailNum <= state.dataAvail->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
    4945            0 :             if (state.dataAvail->HybridVentData(SysAvailNum).ControlledZoneNum == ZoneNum) {
    4946            0 :                 if (state.dataAvail->HybridVentData(SysAvailNum).simpleControlTypeSched != nullptr) {
    4947            0 :                     VentControl = true;
    4948              :                 }
    4949              :             }
    4950              :         }
    4951              : 
    4952            2 :         return VentControl;
    4953              :     }
    4954              : 
    4955              : } // namespace Avail
    4956              : 
    4957              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1