LCOV - code coverage report
Current view: top level - EnergyPlus - SystemAvailabilityManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 1486 2631 56.5 %
Date: 2024-08-24 18:31:18 Functions: 28 28 100.0 %

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

Generated by: LCOV version 1.14