LCOV - code coverage report
Current view: top level - EnergyPlus - SingleDuct.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 2383 3513 67.8 %
Date: 2023-01-17 19:17:23 Functions: 27 31 87.1 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cmath>
      50             : 
      51             : // ObjexxFCL Headers
      52             : #include <ObjexxFCL/Array.functions.hh>
      53             : #include <ObjexxFCL/Fmath.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <AirflowNetwork/Solver.hpp>
      57             : #include <EnergyPlus/Autosizing/Base.hh>
      58             : #include <EnergyPlus/BranchNodeConnections.hh>
      59             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      60             : #include <EnergyPlus/DataContaminantBalance.hh>
      61             : #include <EnergyPlus/DataConvergParams.hh>
      62             : #include <EnergyPlus/DataDefineEquip.hh>
      63             : #include <EnergyPlus/DataEnvironment.hh>
      64             : #include <EnergyPlus/DataHVACGlobals.hh>
      65             : #include <EnergyPlus/DataHeatBalFanSys.hh>
      66             : #include <EnergyPlus/DataHeatBalance.hh>
      67             : #include <EnergyPlus/DataIPShortCuts.hh>
      68             : #include <EnergyPlus/DataLoopNode.hh>
      69             : #include <EnergyPlus/DataSizing.hh>
      70             : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      71             : #include <EnergyPlus/DataZoneEquipment.hh>
      72             : #include <EnergyPlus/EMSManager.hh>
      73             : #include <EnergyPlus/Fans.hh>
      74             : #include <EnergyPlus/FluidProperties.hh>
      75             : #include <EnergyPlus/General.hh>
      76             : #include <EnergyPlus/GeneralRoutines.hh>
      77             : #include <EnergyPlus/GlobalNames.hh>
      78             : #include <EnergyPlus/HVACFan.hh>
      79             : #include <EnergyPlus/HeatingCoils.hh>
      80             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      81             : #include <EnergyPlus/NodeInputManager.hh>
      82             : #include <EnergyPlus/OutputProcessor.hh>
      83             : #include <EnergyPlus/Plant/DataPlant.hh>
      84             : #include <EnergyPlus/PlantUtilities.hh>
      85             : #include <EnergyPlus/Psychrometrics.hh>
      86             : #include <EnergyPlus/ReportCoilSelection.hh>
      87             : #include <EnergyPlus/ScheduleManager.hh>
      88             : #include <EnergyPlus/SingleDuct.hh>
      89             : #include <EnergyPlus/SteamCoils.hh>
      90             : #include <EnergyPlus/UtilityRoutines.hh>
      91             : #include <EnergyPlus/WaterCoils.hh>
      92             : #include <EnergyPlus/ZoneAirLoopEquipmentManager.hh>
      93             : 
      94             : namespace EnergyPlus::SingleDuct {
      95             : 
      96             : // Module containing the Single Duct Systems as a single component/ or really a single driver
      97             : 
      98             : // MODULE INFORMATION:
      99             : //       AUTHOR         Richard J. Liesen
     100             : //       DATE WRITTEN   January 2000
     101             : //       MODIFIED       na
     102             : //       RE-ENGINEERED  na
     103             : 
     104             : // PURPOSE OF THIS MODULE:
     105             : // To encapsulate the data and algorithms required to
     106             : // simulate single duct systems as a single driver or inter-connecting controllers.
     107             : 
     108             : // Using/Aliasing
     109             : using namespace DataLoopNode;
     110             : using BranchNodeConnections::SetUpCompSets;
     111             : using BranchNodeConnections::TestCompSet;
     112             : using DataHVACGlobals::ATMixer_InletSide;
     113             : using DataHVACGlobals::ATMixer_SupplySide;
     114             : using DataHVACGlobals::SmallAirVolFlow;
     115             : using DataHVACGlobals::SmallLoad;
     116             : using DataHVACGlobals::SmallMassFlow;
     117             : using namespace DataSizing;
     118             : using Psychrometrics::PsyCpAirFnW;
     119             : using Psychrometrics::PsyRhoAirFnPbTdbW;
     120             : using namespace FluidProperties;
     121             : using namespace ScheduleManager;
     122             : using namespace SteamCoils;
     123             : 
     124             : static constexpr std::string_view fluidNameSteam("STEAM");
     125             : static constexpr std::string_view fluidNameWater("WATER");
     126             : 
     127    32682712 : void SimulateSingleDuct(
     128             :     EnergyPlusData &state, std::string_view CompName, bool const FirstHVACIteration, int const ZoneNum, int const ZoneNodeNum, int &CompIndex)
     129             : {
     130             : 
     131             :     // SUBROUTINE INFORMATION:
     132             :     //       AUTHOR         Richard Liesen
     133             :     //       DATE WRITTEN   January 2000
     134             :     //       MODIFIED       na
     135             :     //       RE-ENGINEERED  na
     136             : 
     137             :     // PURPOSE OF THIS SUBROUTINE:
     138             :     // This subroutine manages Sys system simulation.
     139             :     // It is called from the ManageZoneEquip
     140             :     // at the system time step.
     141             : 
     142             :     // Using/Aliasing
     143             : 
     144             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     145             :     int SysNum; // The Sys that you are currently loading input into
     146             : 
     147             :     // Obtains and Allocates Sys related parameters from input file
     148    32682712 :     if (state.dataSingleDuct->GetInputFlag) { // First time subroutine has been entered
     149         504 :         GetSysInput(state);
     150         504 :         state.dataSingleDuct->GetInputFlag = false;
     151             :     }
     152             : 
     153             :     // Find the correct SysNumber with the Component Name
     154    32682712 :     if (CompIndex == 0) {
     155        3309 :         SysNum = UtilityRoutines::FindItemInList(CompName, state.dataSingleDuct->sd_airterminal, &SingleDuctAirTerminal::SysName);
     156        3309 :         if (SysNum == 0) {
     157           0 :             ShowFatalError(state, "SimulateSingleDuct: System not found=" + std::string{CompName});
     158             :         }
     159        3309 :         CompIndex = SysNum;
     160             :     } else {
     161    32679403 :         SysNum = CompIndex;
     162    32679403 :         if (SysNum > state.dataSingleDuct->NumSDAirTerminal || SysNum < 1) {
     163           0 :             ShowFatalError(state,
     164           0 :                            format("SimulateSingleDuct: Invalid CompIndex passed={}, Number of Systems={}, System name={}",
     165             :                                   CompIndex,
     166           0 :                                   state.dataSingleDuct->NumSDAirTerminal,
     167           0 :                                   CompName));
     168             :         }
     169    32679403 :         if (state.dataSingleDuct->CheckEquipName(SysNum)) {
     170        3304 :             if (CompName != state.dataSingleDuct->sd_airterminal(SysNum).SysName) {
     171           0 :                 ShowFatalError(state,
     172           0 :                                format("SimulateSingleDuct: Invalid CompIndex passed={}, System name={}, stored System Name for that index={}",
     173             :                                       CompIndex,
     174             :                                       CompName,
     175           0 :                                       state.dataSingleDuct->sd_airterminal(SysNum).SysName));
     176             :             }
     177        3304 :             state.dataSingleDuct->CheckEquipName(SysNum) = false;
     178             :         }
     179             :     }
     180             : 
     181    32682712 :     auto &thisATU(state.dataSingleDuct->sd_airterminal(SysNum));
     182             : 
     183    32682712 :     state.dataSize->TermUnitSingDuct = true;
     184    32682712 :     state.dataSize->CurTermUnitSizingNum = state.dataDefineEquipment->AirDistUnit(thisATU.ADUNum).TermUnitSizingNum;
     185             : 
     186             :     // With the correct SysNum Initialize the system
     187    32682712 :     thisATU.InitSys(state, FirstHVACIteration); // Initialize all Sys related parameters
     188             : 
     189             :     // Calculate the Correct Sys Model with the current SysNum
     190    32682712 :     switch (thisATU.SysType_Num) {
     191     1679042 :     case SysType::SingleDuctConstVolReheat: // AirTerminal:SingleDuct:ConstantVolume:Reheat
     192     1679042 :         thisATU.SimConstVol(state, FirstHVACIteration, ZoneNum, ZoneNodeNum);
     193     1679042 :         break;
     194     7471141 :     case SysType::SingleDuctConstVolNoReheat: // AirTerminal:SingleDuct:ConstantVolume:NoReheat
     195     7471141 :         thisATU.SimConstVolNoReheat(state);
     196     7471141 :         break;
     197    23432728 :     case SysType::SingleDuctVAVReheat:   // SINGLE DUCT:VAV:REHEAT
     198             :     case SysType::SingleDuctVAVNoReheat: // SINGLE DUCT:VAV:NOREHEAT
     199    23432728 :         thisATU.SimVAV(state, FirstHVACIteration, ZoneNum, ZoneNodeNum);
     200    23432728 :         break;
     201       31064 :     case SysType::SingleDuctVAVReheatVSFan: // SINGLE DUCT:VAV:REHEAT:VS FAN
     202       31064 :         thisATU.SimVAVVS(state, FirstHVACIteration, ZoneNum, ZoneNodeNum);
     203       31064 :         break;
     204       68737 :     case SysType::SingleDuctCBVAVReheat:   // SINGLE DUCT:VAVHEATANDCOOL:REHEAT
     205             :     case SysType::SingleDuctCBVAVNoReheat: // SINGLE DUCT:VAVHEATANDCOOL:NOREHEAT
     206       68737 :         thisATU.SimCBVAV(state, FirstHVACIteration, ZoneNum, ZoneNodeNum);
     207       68737 :         break;
     208           0 :     default:
     209             :         // assert(false);
     210           0 :         break;
     211             :     }
     212             : 
     213             :     // Report the current Sys
     214    32682712 :     thisATU.ReportSys(state);
     215             : 
     216    32682712 :     state.dataSize->TermUnitSingDuct = false;
     217    32682712 : }
     218             : 
     219             : // Get Input Section of the Module
     220             : //******************************************************************************
     221             : 
     222         504 : void GetSysInput(EnergyPlusData &state)
     223             : {
     224             : 
     225             :     // SUBROUTINE INFORMATION:
     226             :     //       AUTHOR         Richard Liesen
     227             :     //       DATE WRITTEN   April 1998
     228             :     //       MODIFIED       na
     229             :     //       RE-ENGINEERED  na
     230             : 
     231             :     // PURPOSE OF THIS SUBROUTINE:
     232             :     // This subroutine is the main routine to call other input routines and Get routines
     233             : 
     234             :     // METHODOLOGY EMPLOYED:
     235             :     // Uses the status flags to trigger events.
     236             : 
     237             :     // Using/Aliasing
     238             :     using NodeInputManager::GetOnlySingleNode;
     239             :     using SteamCoils::GetCoilAirOutletNode;
     240             :     using SteamCoils::GetCoilSteamInletNode;
     241             :     using SteamCoils::GetSteamCoilIndex;
     242             :     using WaterCoils::GetCoilOutletNode;
     243             :     using WaterCoils::GetCoilWaterInletNode;
     244         504 :     auto &GetHeatingCoilCapacity(HeatingCoils::GetCoilCapacity);
     245         504 :     auto &GetHeatingCoilOutletNode(HeatingCoils::GetCoilOutletNode);
     246             :     using Fans::GetFanInletNode;
     247             :     using Fans::GetFanOutletNode;
     248             :     using namespace DataHeatBalance;
     249             : 
     250             :     // SUBROUTINE PARAMETER DEFINITIONS:
     251             :     static constexpr std::string_view RoutineName("GetSysInput: "); // include trailing blank
     252             : 
     253             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     254             : 
     255             :     int NumZoneSiz;
     256             :     int ZoneSizIndex;
     257             :     int IOStat;
     258         504 :     bool ErrorsFound(false);         // If errors detected in input
     259             :     bool IsNotOK;                    // Flag to verify name
     260             :     int CtrlZone;                    // controlled zone do loop index
     261             :     int SupAirIn;                    // controlled zone supply air inlet index
     262             :     int ADUNum;                      // air distribution unit index
     263        1008 :     std::string CurrentModuleObject; // for ease in getting objects
     264        1008 :     Array1D_string Alphas;           // Alpha input items for object
     265        1008 :     Array1D_string cAlphaFields;     // Alpha field names
     266        1008 :     Array1D_string cNumericFields;   // Numeric field names
     267        1008 :     Array1D<Real64> Numbers;         // Numeric input items for object
     268        1008 :     Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     269        1008 :     Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     270             : 
     271             :     //  certain object in the input file
     272        1008 :     std::string AirTermSysInletNodeName;  // air terminal single duct system inlet node name
     273        1008 :     std::string AirTermSysOutletNodeName; // air terminal single duct system outlet node name
     274             : 
     275         504 :     state.dataSingleDuct->NumVAVSysGSI = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirTerminal:SingleDuct:VAV:Reheat");
     276         504 :     state.dataSingleDuct->NumNoRHVAVSysGSI =
     277        1008 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirTerminal:SingleDuct:VAV:NoReheat");
     278         504 :     state.dataSingleDuct->NumConstVolSys =
     279        1008 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirTerminal:SingleDuct:ConstantVolume:Reheat");
     280         504 :     state.dataSingleDuct->NumCVNoReheatSysGSI =
     281        1008 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirTerminal:SingleDuct:ConstantVolume:NoReheat");
     282         504 :     state.dataSingleDuct->NumVAVVSGSI =
     283        1008 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirTerminal:SingleDuct:VAV:Reheat:VariableSpeedFan");
     284         504 :     state.dataSingleDuct->NumCBVAVSysGSI =
     285        1008 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat");
     286         504 :     state.dataSingleDuct->NumNoRHCBVAVSysGSI =
     287        1008 :         state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat");
     288        1512 :     state.dataSingleDuct->NumSDAirTerminal = state.dataSingleDuct->NumVAVSysGSI + state.dataSingleDuct->NumConstVolSys +
     289        1512 :                                              state.dataSingleDuct->NumCVNoReheatSysGSI + state.dataSingleDuct->NumNoRHVAVSysGSI +
     290        1512 :                                              state.dataSingleDuct->NumVAVVSGSI + state.dataSingleDuct->NumCBVAVSysGSI +
     291         504 :                                              state.dataSingleDuct->NumNoRHCBVAVSysGSI;
     292             : 
     293         504 :     state.dataSingleDuct->sd_airterminal.allocate(state.dataSingleDuct->NumSDAirTerminal);
     294         504 :     state.dataSingleDuct->SysUniqueNames.reserve(static_cast<unsigned>(state.dataSingleDuct->NumSDAirTerminal));
     295         504 :     state.dataSingleDuct->CheckEquipName.dimension(state.dataSingleDuct->NumSDAirTerminal, true);
     296             : 
     297        2520 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state,
     298             :                                                                    "AirTerminal:SingleDuct:VAV:Reheat",
     299         504 :                                                                    state.dataSingleDuct->TotalArgsGSI,
     300         504 :                                                                    state.dataSingleDuct->NumAlphasGSI,
     301        1008 :                                                                    state.dataSingleDuct->NumNumsGSI);
     302         504 :     state.dataSingleDuct->MaxNumsGSI = max(state.dataSingleDuct->MaxNumsGSI, state.dataSingleDuct->NumNumsGSI);
     303         504 :     state.dataSingleDuct->MaxAlphasGSI = max(state.dataSingleDuct->MaxAlphasGSI, state.dataSingleDuct->NumAlphasGSI);
     304        2520 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state,
     305             :                                                                    "AirTerminal:SingleDuct:VAV:NoReheat",
     306         504 :                                                                    state.dataSingleDuct->TotalArgsGSI,
     307         504 :                                                                    state.dataSingleDuct->NumAlphasGSI,
     308        1008 :                                                                    state.dataSingleDuct->NumNumsGSI);
     309         504 :     state.dataSingleDuct->MaxNumsGSI = max(state.dataSingleDuct->MaxNumsGSI, state.dataSingleDuct->NumNumsGSI);
     310         504 :     state.dataSingleDuct->MaxAlphasGSI = max(state.dataSingleDuct->MaxAlphasGSI, state.dataSingleDuct->NumAlphasGSI);
     311        2520 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state,
     312             :                                                                    "AirTerminal:SingleDuct:ConstantVolume:Reheat",
     313         504 :                                                                    state.dataSingleDuct->TotalArgsGSI,
     314         504 :                                                                    state.dataSingleDuct->NumAlphasGSI,
     315        1008 :                                                                    state.dataSingleDuct->NumNumsGSI);
     316         504 :     state.dataSingleDuct->MaxNumsGSI = max(state.dataSingleDuct->MaxNumsGSI, state.dataSingleDuct->NumNumsGSI);
     317         504 :     state.dataSingleDuct->MaxAlphasGSI = max(state.dataSingleDuct->MaxAlphasGSI, state.dataSingleDuct->NumAlphasGSI);
     318        2520 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state,
     319             :                                                                    "AirTerminal:SingleDuct:ConstantVolume:NoReheat",
     320         504 :                                                                    state.dataSingleDuct->TotalArgsGSI,
     321         504 :                                                                    state.dataSingleDuct->NumAlphasGSI,
     322        1008 :                                                                    state.dataSingleDuct->NumNumsGSI);
     323         504 :     state.dataSingleDuct->MaxNumsGSI = max(state.dataSingleDuct->MaxNumsGSI, state.dataSingleDuct->NumNumsGSI);
     324         504 :     state.dataSingleDuct->MaxAlphasGSI = max(state.dataSingleDuct->MaxAlphasGSI, state.dataSingleDuct->NumAlphasGSI);
     325        2520 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state,
     326             :                                                                    "AirTerminal:SingleDuct:VAV:Reheat:VariableSpeedFan",
     327         504 :                                                                    state.dataSingleDuct->TotalArgsGSI,
     328         504 :                                                                    state.dataSingleDuct->NumAlphasGSI,
     329        1008 :                                                                    state.dataSingleDuct->NumNumsGSI);
     330         504 :     state.dataSingleDuct->MaxNumsGSI = max(state.dataSingleDuct->MaxNumsGSI, state.dataSingleDuct->NumNumsGSI);
     331         504 :     state.dataSingleDuct->MaxAlphasGSI = max(state.dataSingleDuct->MaxAlphasGSI, state.dataSingleDuct->NumAlphasGSI);
     332        2520 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state,
     333             :                                                                    "AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat",
     334         504 :                                                                    state.dataSingleDuct->TotalArgsGSI,
     335         504 :                                                                    state.dataSingleDuct->NumAlphasGSI,
     336        1008 :                                                                    state.dataSingleDuct->NumNumsGSI);
     337         504 :     state.dataSingleDuct->MaxNumsGSI = max(state.dataSingleDuct->MaxNumsGSI, state.dataSingleDuct->NumNumsGSI);
     338         504 :     state.dataSingleDuct->MaxAlphasGSI = max(state.dataSingleDuct->MaxAlphasGSI, state.dataSingleDuct->NumAlphasGSI);
     339        2520 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state,
     340             :                                                                    "AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat",
     341         504 :                                                                    state.dataSingleDuct->TotalArgsGSI,
     342         504 :                                                                    state.dataSingleDuct->NumAlphasGSI,
     343        1008 :                                                                    state.dataSingleDuct->NumNumsGSI);
     344         504 :     state.dataSingleDuct->MaxNumsGSI = max(state.dataSingleDuct->MaxNumsGSI, state.dataSingleDuct->NumNumsGSI);
     345         504 :     state.dataSingleDuct->MaxAlphasGSI = max(state.dataSingleDuct->MaxAlphasGSI, state.dataSingleDuct->NumAlphasGSI);
     346             : 
     347         504 :     Alphas.allocate(state.dataSingleDuct->MaxAlphasGSI);
     348         504 :     cAlphaFields.allocate(state.dataSingleDuct->MaxAlphasGSI);
     349         504 :     cNumericFields.allocate(state.dataSingleDuct->MaxNumsGSI);
     350         504 :     Numbers.dimension(state.dataSingleDuct->MaxNumsGSI, 0.0);
     351         504 :     lAlphaBlanks.dimension(state.dataSingleDuct->MaxAlphasGSI, true);
     352         504 :     lNumericBlanks.dimension(state.dataSingleDuct->MaxNumsGSI, true);
     353             : 
     354             :     // Start Loading the System Input
     355        2604 :     for (state.dataSingleDuct->SysIndexGSI = 1; state.dataSingleDuct->SysIndexGSI <= state.dataSingleDuct->NumVAVSysGSI;
     356        2100 :          ++state.dataSingleDuct->SysIndexGSI) {
     357             : 
     358        2100 :         CurrentModuleObject = "AirTerminal:SingleDuct:VAV:Reheat";
     359             : 
     360        8400 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     361             :                                                                  CurrentModuleObject,
     362        2100 :                                                                  state.dataSingleDuct->SysIndexGSI,
     363             :                                                                  Alphas,
     364        2100 :                                                                  state.dataSingleDuct->NumAlphasGSI,
     365             :                                                                  Numbers,
     366        2100 :                                                                  state.dataSingleDuct->NumNumsGSI,
     367             :                                                                  IOStat,
     368             :                                                                  lNumericBlanks,
     369             :                                                                  lAlphaBlanks,
     370             :                                                                  cAlphaFields,
     371             :                                                                  cNumericFields);
     372             : 
     373        2100 :         state.dataSingleDuct->SysNumGSI = state.dataSingleDuct->SysIndexGSI;
     374        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysNum = state.dataSingleDuct->SysNumGSI;
     375        4200 :         GlobalNames::VerifyUniqueInterObjectName(
     376        4200 :             state, state.dataSingleDuct->SysUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
     377        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName = Alphas(1);
     378        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType = CurrentModuleObject;
     379        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysType_Num = SysType::SingleDuctVAVReheat;
     380        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp = Alphas(7);
     381        2100 :         if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp, "Coil:Heating:Fuel")) {
     382          57 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::Gas;
     383        2043 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     384        2043 :                                                "Coil:Heating:Electric")) {
     385         259 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::Electric;
     386        1784 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     387        1784 :                                                "Coil:Heating:Water")) {
     388        1776 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::SimpleHeating;
     389        1776 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_PlantType =
     390             :                 DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
     391           8 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     392           8 :                                                "Coil:Heating:Steam")) {
     393           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::SteamAirHeating;
     394           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_PlantType =
     395             :                 DataPlant::PlantEquipmentType::CoilSteamAirHeating;
     396           0 :         } else if (!state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp.empty()) {
     397           0 :             ShowSevereError(
     398           0 :                 state, "Illegal " + cAlphaFields(8) + " = " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp + '.');
     399           0 :             ShowContinueError(state,
     400           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     401           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     402           0 :             ErrorsFound = true;
     403             :         }
     404        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName = Alphas(8);
     405        6300 :         ValidateComponent(state,
     406        2100 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     407        2100 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
     408             :                           IsNotOK,
     409        2100 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType);
     410        2100 :         if (IsNotOK) {
     411           0 :             ShowContinueError(state,
     412           0 :                               "In " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     413           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     414           0 :             ErrorsFound = true;
     415             :         }
     416        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Schedule = Alphas(2);
     417        2100 :         if (lAlphaBlanks(2)) {
     418          23 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     419             :         } else {
     420        2077 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = GetScheduleIndex(state, Alphas(2));
     421        2077 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr == 0) {
     422           0 :                 ShowSevereError(state, cAlphaFields(2) + " = " + Alphas(2) + " not found.");
     423           0 :                 ShowContinueError(state,
     424           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     425           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     426           0 :                 ErrorsFound = true;
     427             :             }
     428             :         }
     429             :         // For node connections, this object is both a parent and a non-parent, because the
     430             :         // VAV damper is not called out as a separate component, its nodes must be connected
     431             :         // as ObjectIsNotParent.  But for the reheat coil, the nodes are connected as ObjectIsParent
     432        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum =
     433        4200 :             GetOnlySingleNode(state,
     434        2100 :                               Alphas(3),
     435             :                               ErrorsFound,
     436             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVReheat,
     437        2100 :                               Alphas(1),
     438             :                               DataLoopNode::NodeFluidType::Air,
     439             :                               DataLoopNode::ConnectionType::Outlet,
     440             :                               NodeInputManager::CompFluidStream::Primary,
     441             :                               ObjectIsNotParent,
     442        2100 :                               cAlphaFields(3));
     443        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum =
     444        4200 :             GetOnlySingleNode(state,
     445        2100 :                               Alphas(4),
     446             :                               ErrorsFound,
     447             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVReheat,
     448        2100 :                               Alphas(1),
     449             :                               DataLoopNode::NodeFluidType::Air,
     450             :                               DataLoopNode::ConnectionType::Inlet,
     451             :                               NodeInputManager::CompFluidStream::Primary,
     452             :                               ObjectIsNotParent,
     453        2100 :                               cAlphaFields(4));
     454        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRate = Numbers(1);
     455             : 
     456        2100 :         if (UtilityRoutines::SameString(Alphas(5), "Constant")) {
     457        2064 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod = MinFlowFraction::Constant;
     458          36 :         } else if (UtilityRoutines::SameString(Alphas(5), "FixedFlowRate")) {
     459           3 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod = MinFlowFraction::Fixed;
     460          33 :         } else if (UtilityRoutines::SameString(Alphas(5), "Scheduled")) {
     461          33 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod = MinFlowFraction::Scheduled;
     462             :         } else {
     463           0 :             ShowSevereError(state, cAlphaFields(5) + " = " + Alphas(5) + " not found.");
     464           0 :             ShowContinueError(state,
     465           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     466           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     467           0 :             ErrorsFound = true;
     468             :         }
     469             : 
     470        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = Numbers(2);
     471        2100 :         if (lNumericBlanks(2)) {
     472          52 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ConstantMinAirFracSetByUser = false;
     473          52 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DesignMinAirFrac = 0.0;
     474             :         } else {
     475        2048 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ConstantMinAirFracSetByUser = true;
     476        2048 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DesignMinAirFrac = Numbers(2);
     477        2048 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod == MinFlowFraction::Fixed) {
     478           1 :                 ShowWarningError(state, "Since " + cAlphaFields(5) + " = " + Alphas(5) + ", input for " + cNumericFields(2) + " will be ignored.");
     479           3 :                 ShowContinueError(state,
     480           2 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     481           1 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     482           1 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 0.0;
     483             :             }
     484             :         }
     485             : 
     486        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFixedMinAir = Numbers(3);
     487        2100 :         if (lNumericBlanks(3)) {
     488        2097 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FixedMinAirSetByUser = false;
     489        2097 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DesignMinAirFrac = 0.0;
     490             :         } else {
     491           3 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FixedMinAirSetByUser = true;
     492           3 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DesignMinAirFrac = Numbers(3);
     493           3 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod == MinFlowFraction::Constant) {
     494           0 :                 ShowWarningError(state, "Since " + cAlphaFields(5) + " = " + Alphas(5) + ", input for " + cNumericFields(3) + " will be ignored.");
     495           0 :                 ShowContinueError(state,
     496           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     497           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     498           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFixedMinAir = 0.0;
     499             :             }
     500             :         }
     501             : 
     502        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracSchPtr = GetScheduleIndex(state, Alphas(6));
     503        4167 :         if ((state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracSchPtr == 0) &&
     504        2067 :             (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod == MinFlowFraction::Scheduled)) {
     505           0 :             ShowSevereError(state, cAlphaFields(6) + " = " + Alphas(6) + " not found.");
     506           0 :             ShowContinueError(state,
     507           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     508           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     509           0 :             ShowContinueError(state, "A valid schedule is required");
     510           0 :             ErrorsFound = true;
     511        2133 :         } else if ((state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracSchPtr > 0) &&
     512          33 :                    (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod == MinFlowFraction::Scheduled)) {
     513             :             // check range of values in schedule
     514          66 :             if (!CheckScheduleValueMinMax(
     515          33 :                     state, state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracSchPtr, ">=", 0.0, "<=", 1.0)) {
     516           0 :                 ShowSevereError(state, "Error found in " + cAlphaFields(6) + " = " + Alphas(6));
     517           0 :                 ShowContinueError(state,
     518           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     519           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     520           0 :                 ShowContinueError(state, "Schedule values must be (>=0., <=1.)");
     521             :             }
     522             :         }
     523             : 
     524             :         // The reheat coil control node is necessary for hot water and steam reheat, but not necessary for
     525             :         // electric or gas reheat.
     526        4143 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num != HeatingCoilType::Gas &&
     527        2043 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num != HeatingCoilType::Electric) {
     528        1784 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
     529           8 :                 IsNotOK = false;
     530           8 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode =
     531          16 :                     GetCoilSteamInletNode(state,
     532           8 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     533           8 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
     534             :                                           IsNotOK);
     535           8 :                 if (IsNotOK) {
     536           0 :                     ShowContinueError(state,
     537           0 :                                       "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     538           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     539           0 :                     ErrorsFound = true;
     540             :                 }
     541             :             } else {
     542        1776 :                 IsNotOK = false;
     543        1776 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode =
     544        3552 :                     GetCoilWaterInletNode(state,
     545        1776 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     546        1776 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
     547             :                                           IsNotOK);
     548        1776 :                 if (IsNotOK) {
     549           0 :                     ShowContinueError(state,
     550           0 :                                       "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     551           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     552           0 :                     ErrorsFound = true;
     553             :                 }
     554             :             }
     555             :         }
     556        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
     557        4200 :             GetOnlySingleNode(state,
     558        2100 :                               Alphas(9),
     559             :                               ErrorsFound,
     560             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVReheat,
     561        2100 :                               Alphas(1),
     562             :                               DataLoopNode::NodeFluidType::Air,
     563             :                               DataLoopNode::ConnectionType::Outlet,
     564             :                               NodeInputManager::CompFluidStream::Primary,
     565             :                               ObjectIsParent,
     566        2100 :                               cAlphaFields(9));
     567        2100 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
     568           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatSteamVolFlow = Numbers(4);
     569           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatSteamVolFlow = Numbers(5);
     570             :         } else {
     571        2092 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatWaterVolFlow = Numbers(4);
     572        2092 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatWaterVolFlow = Numbers(5);
     573             :         }
     574        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = Numbers(6);
     575             :         // Set default convergence tolerance
     576        2100 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset <= 0.0) {
     577           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = 0.001;
     578             :         }
     579        2100 :         if (UtilityRoutines::SameString(Alphas(10), "Reverse")) {
     580          52 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::Reverse;
     581        2048 :         } else if (UtilityRoutines::SameString(Alphas(10), "Normal")) {
     582         937 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::Normal;
     583        1111 :         } else if (UtilityRoutines::SameString(Alphas(10), "ReverseWithLimits")) {
     584        1111 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::ReverseWithLimits;
     585             :         } else {
     586           0 :             ShowSevereError(state, cAlphaFields(10) + " = " + Alphas(10) + " not found.");
     587           0 :             ShowContinueError(state,
     588           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     589           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     590           0 :             ErrorsFound = true;
     591             :         }
     592             : 
     593             :         // Register component set data
     594        6300 :         TestCompSet(state,
     595        2100 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
     596        2100 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
     597        2100 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum),
     598        2100 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode),
     599             :                     "Air Nodes");
     600             : 
     601       42048 :         for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
     602       84096 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
     603       42048 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
     604        2100 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum =
     605        2100 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
     606        2100 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum = ADUNum;
     607        2100 :                 break;
     608             :             }
     609             :         }
     610             :         // one assumes if there isn't one assigned, it's an error?
     611        2100 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum == 0) {
     612           0 :             ShowSevereError(state,
     613           0 :                             std::string{RoutineName} + "No matching Air Distribution Unit, for System = [" +
     614           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + ',' +
     615           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "].");
     616           0 :             ShowContinueError(
     617             :                 state,
     618           0 :                 "...should have outlet node = " +
     619           0 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode));
     620           0 :             ErrorsFound = true;
     621             :         } else {
     622             : 
     623             :             // Fill the Zone Equipment data with the inlet node number of this unit.
     624       89497 :             for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
     625       87397 :                 if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
     626      164732 :                 for (SupAirIn = 1; SupAirIn <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++SupAirIn) {
     627      165096 :                     if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
     628       82548 :                         state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(SupAirIn)) {
     629        2100 :                         if (state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode > 0) {
     630           0 :                             ShowSevereError(state, "Error in connecting a terminal unit to a zone");
     631           0 :                             ShowContinueError(state,
     632           0 :                                               state.dataLoopNodes->NodeID(
     633           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode) +
     634             :                                                   " already connects to another zone");
     635           0 :                             ShowContinueError(state,
     636           0 :                                               "Occurs for terminal unit " +
     637           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     638           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     639           0 :                             ShowContinueError(state, "Check terminal unit node names for errors");
     640           0 :                             ErrorsFound = true;
     641             :                         } else {
     642        2100 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).InNode =
     643        2100 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
     644        2100 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode =
     645        2100 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode;
     646        2100 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
     647        4200 :                                 .TermUnitSizingNum = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
     648        2100 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
     649        4200 :                                 .ZoneEqNum = CtrlZone;
     650             :                         }
     651             : 
     652        2100 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneNum = CtrlZone;
     653        2100 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneInNodeIndex = SupAirIn;
     654        2100 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFloorArea =
     655        4200 :                             state.dataHeatBal->Zone(CtrlZone).FloorArea * state.dataHeatBal->Zone(CtrlZone).Multiplier *
     656        2100 :                             state.dataHeatBal->Zone(CtrlZone).ListMultiplier;
     657             :                     }
     658             :                 }
     659             :             }
     660             :         }
     661        2100 :         if (Numbers(7) == DataGlobalConstants::AutoCalculate) {
     662        2077 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRateDuringReheat = Numbers(7);
     663             :         } else {
     664          23 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRateDuringReheat =
     665          23 :                 Numbers(7) * state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFloorArea;
     666             :         }
     667             : 
     668        2100 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFractionDuringReheat = Numbers(8);
     669             : 
     670        2100 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction != Action::ReverseWithLimits) {
     671         989 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRateDuringReheat > 0.0) {
     672           0 :                 ShowWarningError(state, "Since " + cAlphaFields(10) + " = " + Alphas(10) + ", input for " + cNumericFields(7) + " will be ignored.");
     673           0 :                 ShowContinueError(state,
     674           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     675           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     676             :             }
     677         989 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFractionDuringReheat > 0.0) {
     678          15 :                 ShowWarningError(state, "Since " + cAlphaFields(10) + " = " + Alphas(10) + ", input for " + cNumericFields(8) + " will be ignored.");
     679          45 :                 ShowContinueError(state,
     680          30 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     681          15 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     682             :             }
     683             :         }
     684             : 
     685             :         // Maximum reheat air temperature, i.e. the maximum supply air temperature leaving the reheat coil
     686        2100 :         if (!lNumericBlanks(9)) {
     687         367 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTemp = Numbers(9);
     688         367 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTempSetByUser = true;
     689             :         } else {
     690             :             // user does not specify maximum supply air temperature
     691             :             // sd_airterminal(SysNum)%MaxReheatTemp = 35.0D0 !C
     692        1733 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTempSetByUser = false;
     693             :         }
     694             : 
     695        2100 :         if (!lAlphaBlanks(11)) {
     696         290 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OARequirementsPtr =
     697         290 :                 UtilityRoutines::FindItemInList(Alphas(11), state.dataSize->OARequirements);
     698         290 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OARequirementsPtr == 0) {
     699           0 :                 ShowSevereError(state, cAlphaFields(11) + " = " + Alphas(11) + " not found.");
     700           0 :                 ShowContinueError(state,
     701           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     702           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     703           0 :                 ErrorsFound = true;
     704             :             } else {
     705         290 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).NoOAFlowInputFromUser = false;
     706             :             }
     707             :         }
     708             : 
     709        2100 :         if (lAlphaBlanks(12)) {
     710        2095 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFrac = 1.0;
     711        2095 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = false;
     712             :         } else {
     713           5 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr = GetScheduleIndex(state, Alphas(12));
     714           5 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr == 0) {
     715           0 :                 ShowSevereError(state, cAlphaFields(12) + " = " + Alphas(12) + " not found.");
     716           0 :                 ShowContinueError(state,
     717           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     718           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     719           0 :                 ErrorsFound = true;
     720             :             }
     721           5 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = true;
     722             :         }
     723             : 
     724        2100 :         ValidateComponent(state, Alphas(7), Alphas(8), IsNotOK, state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType);
     725        2100 :         if (IsNotOK) {
     726           0 :             ShowContinueError(state,
     727           0 :                               "In " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     728           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     729           0 :             ErrorsFound = true;
     730             :         }
     731             : 
     732             :         // Add reheat coil to component sets array
     733       12600 :         SetUpCompSets(state,
     734        2100 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
     735        2100 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
     736        2100 :                       Alphas(7),
     737        2100 :                       Alphas(8),
     738        2100 :                       Alphas(3),
     739        2100 :                       Alphas(9));
     740             : 
     741             :         // Setup the Average damper Position output variable
     742        8400 :         SetupOutputVariable(state,
     743             :                             "Zone Air Terminal VAV Damper Position",
     744             :                             OutputProcessor::Unit::None,
     745        2100 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperPosition,
     746             :                             OutputProcessor::SOVTimeStepType::System,
     747             :                             OutputProcessor::SOVStoreType::Average,
     748        4200 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     749        8400 :         SetupOutputVariable(state,
     750             :                             "Zone Air Terminal Minimum Air Flow Fraction",
     751             :                             OutputProcessor::Unit::None,
     752        2100 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracReport,
     753             :                             OutputProcessor::SOVTimeStepType::System,
     754             :                             OutputProcessor::SOVStoreType::Average,
     755        4200 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     756             : 
     757             :     } // end Number of Sys Loop
     758             : 
     759         513 :     for (state.dataSingleDuct->SysIndexGSI = 1; state.dataSingleDuct->SysIndexGSI <= state.dataSingleDuct->NumCBVAVSysGSI;
     760           9 :          ++state.dataSingleDuct->SysIndexGSI) {
     761             : 
     762           9 :         CurrentModuleObject = "AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat";
     763             : 
     764          36 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     765             :                                                                  CurrentModuleObject,
     766           9 :                                                                  state.dataSingleDuct->SysIndexGSI,
     767             :                                                                  Alphas,
     768           9 :                                                                  state.dataSingleDuct->NumAlphasGSI,
     769             :                                                                  Numbers,
     770           9 :                                                                  state.dataSingleDuct->NumNumsGSI,
     771             :                                                                  IOStat,
     772             :                                                                  lNumericBlanks,
     773             :                                                                  lAlphaBlanks,
     774             :                                                                  cAlphaFields,
     775             :                                                                  cNumericFields);
     776             : 
     777           9 :         state.dataSingleDuct->SysNumGSI = state.dataSingleDuct->SysIndexGSI + state.dataSingleDuct->NumVAVSysGSI;
     778           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysNum = state.dataSingleDuct->SysNumGSI;
     779          18 :         GlobalNames::VerifyUniqueInterObjectName(
     780          18 :             state, state.dataSingleDuct->SysUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
     781           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName = Alphas(1);
     782           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType = CurrentModuleObject;
     783           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysType_Num = SysType::SingleDuctCBVAVReheat;
     784           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp = Alphas(5);
     785           9 :         if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp, "Coil:Heating:Fuel")) {
     786           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::Gas;
     787           9 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     788           9 :                                                "Coil:Heating:Electric")) {
     789           9 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::Electric;
     790           0 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     791           0 :                                                "Coil:Heating:Water")) {
     792           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::SimpleHeating;
     793           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_PlantType =
     794             :                 DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
     795           0 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     796           0 :                                                "Coil:Heating:Steam")) {
     797           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::SteamAirHeating;
     798           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_PlantType =
     799             :                 DataPlant::PlantEquipmentType::CoilSteamAirHeating;
     800           0 :         } else if (!state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp.empty()) {
     801           0 :             ShowSevereError(
     802           0 :                 state, "Illegal " + cAlphaFields(5) + " = " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp + '.');
     803           0 :             ShowContinueError(state,
     804           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     805           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     806           0 :             ErrorsFound = true;
     807             :         }
     808           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName = Alphas(6);
     809          27 :         ValidateComponent(state,
     810           9 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     811           9 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
     812             :                           IsNotOK,
     813           9 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType);
     814           9 :         if (IsNotOK) {
     815           0 :             ShowContinueError(state,
     816           0 :                               "In " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     817           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     818           0 :             ErrorsFound = true;
     819             :         }
     820           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Schedule = Alphas(2);
     821           9 :         if (lAlphaBlanks(2)) {
     822           1 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     823             :         } else {
     824           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = GetScheduleIndex(state, Alphas(2));
     825           8 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr == 0) {
     826           0 :                 ShowSevereError(state, cAlphaFields(2) + " = " + Alphas(2) + " not found.");
     827           0 :                 ShowContinueError(state,
     828           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     829           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     830           0 :                 ErrorsFound = true;
     831             :             }
     832             :         }
     833             :         // For node connections, this object is both a parent and a non-parent, because the
     834             :         // VAV damper is not called out as a separate component, its nodes must be connected
     835             :         // as ObjectIsNotParent.  But for the reheat coil, the nodes are connected as ObjectIsParent
     836           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum =
     837          18 :             GetOnlySingleNode(state,
     838           9 :                               Alphas(3),
     839             :                               ErrorsFound,
     840             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVHeatAndCoolReheat,
     841           9 :                               Alphas(1),
     842             :                               DataLoopNode::NodeFluidType::Air,
     843             :                               DataLoopNode::ConnectionType::Outlet,
     844             :                               NodeInputManager::CompFluidStream::Primary,
     845             :                               ObjectIsNotParent,
     846           9 :                               cAlphaFields(3));
     847           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum =
     848          18 :             GetOnlySingleNode(state,
     849           9 :                               Alphas(4),
     850             :                               ErrorsFound,
     851             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVHeatAndCoolReheat,
     852           9 :                               Alphas(1),
     853             :                               DataLoopNode::NodeFluidType::Air,
     854             :                               DataLoopNode::ConnectionType::Inlet,
     855             :                               NodeInputManager::CompFluidStream::Primary,
     856             :                               ObjectIsNotParent,
     857           9 :                               cAlphaFields(4));
     858           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRate = Numbers(1);
     859           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = Numbers(2);
     860           9 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes < 0.0) {
     861           0 :             ShowWarningError(state,
     862           0 :                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " \"" +
     863           0 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "\"");
     864           0 :             ShowContinueError(state, cNumericFields(2) + " must be greater than or equal to 0. Resetting to 0 and the simulation continues.");
     865           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 0.0;
     866             :         }
     867           9 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes > 1.0) {
     868           0 :             ShowWarningError(state,
     869           0 :                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " \"" +
     870           0 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "\"");
     871           0 :             ShowContinueError(state, cNumericFields(2) + " must be less than or equal to 1. Resetting to 1 and the simulation continues.");
     872           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 1.0;
     873             :         }
     874             :         // The reheat coil control node is necessary for hot water and steam reheat, but not necessary for
     875             :         // electric or gas reheat.
     876          18 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::Gas ||
     877           9 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::Electric) {
     878             :         } else {
     879           0 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
     880           0 :                 IsNotOK = false;
     881           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode =
     882           0 :                     GetCoilSteamInletNode(state,
     883           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     884           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
     885             :                                           IsNotOK);
     886           0 :                 if (IsNotOK) {
     887           0 :                     ShowContinueError(state,
     888           0 :                                       "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     889           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     890           0 :                     ErrorsFound = true;
     891             :                 }
     892             :             } else {
     893           0 :                 IsNotOK = false;
     894           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode =
     895           0 :                     GetCoilWaterInletNode(state,
     896           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
     897           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
     898             :                                           IsNotOK);
     899           0 :                 if (IsNotOK) {
     900           0 :                     ShowContinueError(state,
     901           0 :                                       "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     902           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     903           0 :                     ErrorsFound = true;
     904             :                 }
     905             :             }
     906             :             //  END IF
     907             :         }
     908           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
     909          18 :             GetOnlySingleNode(state,
     910           9 :                               Alphas(7),
     911             :                               ErrorsFound,
     912             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVHeatAndCoolReheat,
     913           9 :                               Alphas(1),
     914             :                               DataLoopNode::NodeFluidType::Air,
     915             :                               DataLoopNode::ConnectionType::Outlet,
     916             :                               NodeInputManager::CompFluidStream::Primary,
     917             :                               ObjectIsParent,
     918           9 :                               cAlphaFields(7));
     919           9 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
     920           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatSteamVolFlow = Numbers(3);
     921           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatSteamVolFlow = Numbers(4);
     922             :         } else {
     923           9 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatWaterVolFlow = Numbers(3);
     924           9 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatWaterVolFlow = Numbers(4);
     925             :         }
     926           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = Numbers(5);
     927             :         // Set default convergence tolerance
     928           9 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset <= 0.0) {
     929           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = 0.001;
     930             :         }
     931             : 
     932           9 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::Reverse;
     933             : 
     934             :         // Register component set data
     935          27 :         TestCompSet(state,
     936           9 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
     937           9 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
     938           9 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum),
     939           9 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode),
     940             :                     "Air Nodes");
     941             : 
     942          17 :         for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
     943          34 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
     944          17 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
     945           9 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum =
     946           9 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
     947           9 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum = ADUNum;
     948           9 :                 break;
     949             :             }
     950             :         }
     951             :         // one assumes if there isn't one assigned, it's an error?
     952           9 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum == 0) {
     953           0 :             ShowSevereError(state,
     954           0 :                             std::string{RoutineName} + "No matching Air Distribution Unit, for System = [" +
     955           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + ',' +
     956           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "].");
     957           0 :             ShowContinueError(
     958             :                 state,
     959           0 :                 "...should have outlet node = " +
     960           0 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode));
     961           0 :             ErrorsFound = true;
     962             :         } else {
     963             : 
     964             :             // Fill the Zone Equipment data with the inlet node number of this unit
     965          39 :             for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
     966          30 :                 if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
     967          58 :                 for (SupAirIn = 1; SupAirIn <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++SupAirIn) {
     968          58 :                     if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
     969          29 :                         state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(SupAirIn)) {
     970           9 :                         if (state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode > 0) {
     971           0 :                             ShowSevereError(state, "Error in connecting a terminal unit to a zone");
     972           0 :                             ShowContinueError(state,
     973           0 :                                               state.dataLoopNodes->NodeID(
     974           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode) +
     975             :                                                   " already connects to another zone");
     976           0 :                             ShowContinueError(state,
     977           0 :                                               "Occurs for terminal unit " +
     978           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
     979           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
     980           0 :                             ShowContinueError(state, "Check terminal unit node names for errors");
     981           0 :                             ErrorsFound = true;
     982             :                         } else {
     983           9 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).InNode =
     984           9 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
     985           9 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode =
     986           9 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode;
     987           9 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
     988          18 :                                 .TermUnitSizingNum = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
     989           9 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
     990          18 :                                 .ZoneEqNum = CtrlZone;
     991             :                         }
     992           9 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneNum = CtrlZone;
     993           9 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneInNodeIndex = SupAirIn;
     994           9 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFloorArea =
     995          18 :                             state.dataHeatBal->Zone(CtrlZone).FloorArea * state.dataHeatBal->Zone(CtrlZone).Multiplier *
     996           9 :                             state.dataHeatBal->Zone(CtrlZone).ListMultiplier;
     997             :                     }
     998             :                 }
     999             :             }
    1000             :         }
    1001           9 :         if (!lNumericBlanks(6)) {
    1002           3 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTemp = Numbers(6);
    1003           3 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTempSetByUser = true;
    1004             :         } else {
    1005             :             // user does not specify maximum supply air temperature
    1006             :             // sd_airterminal(SysNum)%MaxReheatTemp = 35.0D0 !C
    1007           6 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTempSetByUser = false;
    1008             :         }
    1009             : 
    1010           9 :         ValidateComponent(state, Alphas(5), Alphas(6), IsNotOK, state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType);
    1011           9 :         if (IsNotOK) {
    1012           0 :             ShowContinueError(state,
    1013           0 :                               "In " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1014           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1015           0 :             ErrorsFound = true;
    1016             :         }
    1017             : 
    1018           9 :         if (lAlphaBlanks(8)) {
    1019           9 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFrac = 1.0;
    1020           9 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = false;
    1021             :         } else {
    1022           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr = GetScheduleIndex(state, Alphas(8));
    1023           0 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr == 0) {
    1024           0 :                 ShowSevereError(state, cAlphaFields(8) + " = " + Alphas(8) + " not found.");
    1025           0 :                 ShowContinueError(state,
    1026           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1027           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1028           0 :                 ErrorsFound = true;
    1029             :             }
    1030           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = true;
    1031             :         }
    1032             : 
    1033             :         // Add reheat coil to component sets array
    1034          54 :         SetUpCompSets(state,
    1035           9 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    1036           9 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    1037           9 :                       Alphas(5),
    1038           9 :                       Alphas(6),
    1039           9 :                       Alphas(3),
    1040           9 :                       Alphas(7));
    1041             : 
    1042             :         // Setup the Average damper Position output variable
    1043          36 :         SetupOutputVariable(state,
    1044             :                             "Zone Air Terminal VAV Damper Position",
    1045             :                             OutputProcessor::Unit::None,
    1046           9 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperPosition,
    1047             :                             OutputProcessor::SOVTimeStepType::System,
    1048             :                             OutputProcessor::SOVStoreType::Average,
    1049          18 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1050             : 
    1051             :     } // end Number of VAVHeatandCool Sys Loop
    1052             : 
    1053         504 :     CurrentModuleObject = "AirTerminal:SingleDuct:ConstantVolume:Reheat";
    1054             : 
    1055         769 :     for (state.dataSingleDuct->SysIndexGSI = 1; state.dataSingleDuct->SysIndexGSI <= state.dataSingleDuct->NumConstVolSys;
    1056         265 :          ++state.dataSingleDuct->SysIndexGSI) {
    1057             : 
    1058        1060 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1059             :                                                                  CurrentModuleObject,
    1060         265 :                                                                  state.dataSingleDuct->SysIndexGSI,
    1061             :                                                                  Alphas,
    1062         265 :                                                                  state.dataSingleDuct->NumAlphasGSI,
    1063             :                                                                  Numbers,
    1064         265 :                                                                  state.dataSingleDuct->NumNumsGSI,
    1065             :                                                                  IOStat,
    1066             :                                                                  lNumericBlanks,
    1067             :                                                                  lAlphaBlanks,
    1068             :                                                                  cAlphaFields,
    1069             :                                                                  cNumericFields);
    1070             : 
    1071         265 :         state.dataSingleDuct->SysNumGSI =
    1072         265 :             state.dataSingleDuct->SysIndexGSI + state.dataSingleDuct->NumVAVSysGSI + state.dataSingleDuct->NumCBVAVSysGSI;
    1073         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysNum = state.dataSingleDuct->SysNumGSI;
    1074         530 :         GlobalNames::VerifyUniqueInterObjectName(
    1075         530 :             state, state.dataSingleDuct->SysUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    1076         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName = Alphas(1);
    1077         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType = CurrentModuleObject;
    1078         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysType_Num = SysType::SingleDuctConstVolReheat;
    1079         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp = Alphas(5);
    1080         265 :         if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp, "Coil:Heating:Fuel")) {
    1081          38 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::Gas;
    1082         227 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1083         227 :                                                "Coil:Heating:Electric")) {
    1084           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::Electric;
    1085         223 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1086         223 :                                                "Coil:Heating:Water")) {
    1087         223 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::SimpleHeating;
    1088         223 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_PlantType =
    1089             :                 DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
    1090           0 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1091           0 :                                                "Coil:Heating:Steam")) {
    1092           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::SteamAirHeating;
    1093           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_PlantType =
    1094             :                 DataPlant::PlantEquipmentType::CoilSteamAirHeating;
    1095             :         } else {
    1096           0 :             ShowSevereError(
    1097           0 :                 state, "Illegal " + cAlphaFields(5) + " = " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp + '.');
    1098           0 :             ShowContinueError(state,
    1099           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1100           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1101           0 :             ErrorsFound = true;
    1102             :         }
    1103         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName = Alphas(6);
    1104         795 :         ValidateComponent(state,
    1105         265 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1106         265 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    1107             :                           IsNotOK,
    1108         265 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType);
    1109         265 :         if (IsNotOK) {
    1110           0 :             ShowContinueError(state,
    1111           0 :                               "In " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1112           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1113           0 :             ErrorsFound = true;
    1114             :         }
    1115         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Schedule = Alphas(2);
    1116         265 :         if (lAlphaBlanks(2)) {
    1117           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
    1118             :         } else {
    1119         261 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = GetScheduleIndex(state, Alphas(2));
    1120         261 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr == 0) {
    1121           0 :                 ShowSevereError(state, cAlphaFields(2) + " = " + Alphas(2) + " not found.");
    1122           0 :                 ShowContinueError(state,
    1123           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1124           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1125           0 :                 ErrorsFound = true;
    1126             :             }
    1127             :         }
    1128         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum =
    1129         530 :             GetOnlySingleNode(state,
    1130         265 :                               Alphas(3),
    1131             :                               ErrorsFound,
    1132             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeReheat,
    1133         265 :                               Alphas(1),
    1134             :                               DataLoopNode::NodeFluidType::Air,
    1135             :                               DataLoopNode::ConnectionType::Outlet,
    1136             :                               NodeInputManager::CompFluidStream::Primary,
    1137             :                               ObjectIsParent,
    1138         265 :                               cAlphaFields(3));
    1139         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum =
    1140         530 :             GetOnlySingleNode(state,
    1141         265 :                               Alphas(4),
    1142             :                               ErrorsFound,
    1143             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeReheat,
    1144         265 :                               Alphas(1),
    1145             :                               DataLoopNode::NodeFluidType::Air,
    1146             :                               DataLoopNode::ConnectionType::Inlet,
    1147             :                               NodeInputManager::CompFluidStream::Primary,
    1148             :                               ObjectIsParent,
    1149         265 :                               cAlphaFields(4));
    1150             :         // The reheat coil control node is necessary for hot water reheat, but not necessary for
    1151             :         // electric or gas reheat.
    1152         492 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::Gas ||
    1153         227 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::Electric) {
    1154             :         } else {
    1155         223 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
    1156           0 :                 IsNotOK = false;
    1157           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode =
    1158           0 :                     GetCoilSteamInletNode(state,
    1159           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1160           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    1161             :                                           IsNotOK);
    1162           0 :                 if (IsNotOK) {
    1163           0 :                     ShowContinueError(state,
    1164           0 :                                       "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1165           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1166           0 :                     ErrorsFound = true;
    1167             :                 }
    1168             :             } else {
    1169         223 :                 IsNotOK = false;
    1170         223 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode =
    1171         446 :                     GetCoilWaterInletNode(state,
    1172         223 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1173         223 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    1174             :                                           IsNotOK);
    1175         223 :                 if (IsNotOK) {
    1176           0 :                     ShowContinueError(state,
    1177           0 :                                       "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1178           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1179           0 :                     ErrorsFound = true;
    1180             :                 }
    1181             :             }
    1182             :         }
    1183         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
    1184         265 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum;
    1185         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRate = Numbers(1);
    1186         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 0.0;
    1187         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod = MinFlowFraction::MinFracNotUsed;
    1188         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::HeatingNotUsed;
    1189         265 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
    1190           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatSteamVolFlow = Numbers(2);
    1191           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatSteamVolFlow = Numbers(3);
    1192             :         } else {
    1193         265 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatWaterVolFlow = Numbers(2);
    1194         265 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatWaterVolFlow = Numbers(3);
    1195             :         }
    1196         265 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = Numbers(4);
    1197             :         // Set default convergence tolerance
    1198         265 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset <= 0.0) {
    1199           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = 0.001;
    1200             :         }
    1201             : 
    1202             :         // Maximum reheat air temperature, i.e. the maximum supply air temperature leaving the reheat coil
    1203         265 :         if (!lNumericBlanks(5)) {
    1204           3 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTemp = Numbers(5);
    1205           3 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTempSetByUser = true;
    1206             :         } else {
    1207             :             // user does not specify maximum supply air temperature
    1208             :             // sd_airterminal(SysNum)%MaxReheatTemp = 35.0D0 !C
    1209         262 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatTempSetByUser = false;
    1210             :         }
    1211             :         // Register component set data
    1212         795 :         TestCompSet(state,
    1213         265 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    1214         265 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    1215         265 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum),
    1216         265 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum),
    1217             :                     "Air Nodes");
    1218             : 
    1219         549 :         for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
    1220        1098 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
    1221         549 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
    1222         265 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum =
    1223         265 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    1224         265 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum = ADUNum;
    1225         265 :                 break;
    1226             :             }
    1227             :         }
    1228             :         // one assumes if there isn't one assigned, it's an error?
    1229         265 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum == 0) {
    1230           0 :             ShowSevereError(state,
    1231           0 :                             std::string{RoutineName} + "No matching Air Distribution Unit, for System = [" +
    1232           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + ',' +
    1233           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "].");
    1234           0 :             ShowContinueError(
    1235             :                 state,
    1236           0 :                 "...should have outlet node = " +
    1237           0 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode));
    1238           0 :             ErrorsFound = true;
    1239             :         } else {
    1240             : 
    1241             :             // Fill the Zone Equipment data with the inlet node number of this unit.
    1242        1185 :             for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    1243         920 :                 if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
    1244        1710 :                 for (SupAirIn = 1; SupAirIn <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++SupAirIn) {
    1245        1710 :                     if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum ==
    1246         855 :                         state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(SupAirIn)) {
    1247         265 :                         if (state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode > 0) {
    1248           0 :                             ShowSevereError(state, "Error in connecting a terminal unit to a zone");
    1249           0 :                             ShowContinueError(
    1250             :                                 state,
    1251           0 :                                 state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum) +
    1252             :                                     " already connects to another zone");
    1253           0 :                             ShowContinueError(state,
    1254           0 :                                               "Occurs for terminal unit " +
    1255           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1256           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1257           0 :                             ShowContinueError(state, "Check terminal unit node names for errors");
    1258           0 :                             ErrorsFound = true;
    1259             :                         } else {
    1260         265 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).InNode =
    1261         265 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    1262         265 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode =
    1263         265 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum;
    1264         265 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    1265         530 :                                 .TermUnitSizingNum = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
    1266         265 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    1267         530 :                                 .ZoneEqNum = CtrlZone;
    1268             :                         }
    1269         265 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneNum = CtrlZone;
    1270         265 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneInNodeIndex = SupAirIn;
    1271         265 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFloorArea =
    1272         530 :                             state.dataHeatBal->Zone(CtrlZone).FloorArea * state.dataHeatBal->Zone(CtrlZone).Multiplier *
    1273         265 :                             state.dataHeatBal->Zone(CtrlZone).ListMultiplier;
    1274             :                     }
    1275             :                 }
    1276             :             }
    1277             :         }
    1278             : 
    1279         265 :         ValidateComponent(state, Alphas(5), Alphas(6), IsNotOK, state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType);
    1280         265 :         if (IsNotOK) {
    1281           0 :             ShowContinueError(state,
    1282           0 :                               "In " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1283           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1284           0 :             ErrorsFound = true;
    1285             :         }
    1286             : 
    1287             :         // Add reheat coil to component sets array
    1288        1590 :         SetUpCompSets(state,
    1289         265 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    1290         265 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    1291         265 :                       Alphas(5),
    1292         265 :                       Alphas(6),
    1293         265 :                       Alphas(4),
    1294         265 :                       Alphas(3));
    1295             : 
    1296             :         // Setup the Average damper Position output variable
    1297             :         // BG removed 9-10-2009 during work on CR 7770, constant volume has no damper
    1298             :         //  CALL SetupOutputVariable(state, 'Damper Position', Sys(SysNum)%DamperPosition, &
    1299             :         //                        'System','Average',Sys(SysNum)%SysName)
    1300             : 
    1301             :     } // End Number of Sys Loop
    1302             : 
    1303         504 :     CurrentModuleObject = "AirTerminal:SingleDuct:ConstantVolume:NoReheat";
    1304             : 
    1305        1342 :     for (state.dataSingleDuct->SysIndexGSI = 1; state.dataSingleDuct->SysIndexGSI <= state.dataSingleDuct->NumCVNoReheatSysGSI;
    1306         838 :          ++state.dataSingleDuct->SysIndexGSI) {
    1307             : 
    1308        3352 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1309             :                                                                  CurrentModuleObject,
    1310         838 :                                                                  state.dataSingleDuct->SysIndexGSI,
    1311             :                                                                  Alphas,
    1312         838 :                                                                  state.dataSingleDuct->NumAlphasGSI,
    1313             :                                                                  Numbers,
    1314         838 :                                                                  state.dataSingleDuct->NumNumsGSI,
    1315             :                                                                  IOStat,
    1316             :                                                                  lNumericBlanks,
    1317             :                                                                  lAlphaBlanks,
    1318             :                                                                  cAlphaFields,
    1319             :                                                                  cNumericFields);
    1320             : 
    1321        2514 :         state.dataSingleDuct->SysNumGSI = state.dataSingleDuct->SysIndexGSI + state.dataSingleDuct->NumVAVSysGSI +
    1322        1676 :                                           state.dataSingleDuct->NumCBVAVSysGSI + state.dataSingleDuct->NumConstVolSys;
    1323         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysNum = state.dataSingleDuct->SysNumGSI;
    1324        1676 :         GlobalNames::VerifyUniqueInterObjectName(
    1325        1676 :             state, state.dataSingleDuct->SysUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    1326         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName = Alphas(1);
    1327         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType = CurrentModuleObject;
    1328         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysType_Num = SysType::SingleDuctConstVolNoReheat;
    1329             : 
    1330         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Schedule = Alphas(2);
    1331         838 :         if (lAlphaBlanks(2)) {
    1332         110 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
    1333             :         } else {
    1334         728 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = GetScheduleIndex(state, Alphas(2));
    1335         728 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr == 0) {
    1336           0 :                 ShowSevereError(state, cAlphaFields(2) + " = " + Alphas(2) + " not found.");
    1337           0 :                 ShowContinueError(state,
    1338           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1339           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1340           0 :                 ErrorsFound = true;
    1341             :             }
    1342             :         }
    1343         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum =
    1344        1676 :             GetOnlySingleNode(state,
    1345         838 :                               Alphas(3),
    1346             :                               ErrorsFound,
    1347             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeNoReheat,
    1348         838 :                               Alphas(1),
    1349             :                               DataLoopNode::NodeFluidType::Air,
    1350             :                               DataLoopNode::ConnectionType::Inlet,
    1351             :                               NodeInputManager::CompFluidStream::Primary,
    1352             :                               ObjectIsNotParent,
    1353         838 :                               cAlphaFields(3));
    1354         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum =
    1355        1676 :             GetOnlySingleNode(state,
    1356         838 :                               Alphas(4),
    1357             :                               ErrorsFound,
    1358             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeNoReheat,
    1359         838 :                               Alphas(1),
    1360             :                               DataLoopNode::NodeFluidType::Air,
    1361             :                               DataLoopNode::ConnectionType::Outlet,
    1362             :                               NodeInputManager::CompFluidStream::Primary,
    1363             :                               ObjectIsNotParent,
    1364         838 :                               cAlphaFields(4));
    1365             : 
    1366         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRate = Numbers(1);
    1367         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 0.0;
    1368         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod = MinFlowFraction::MinFracNotUsed;
    1369         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::HeatingNotUsed;
    1370             : 
    1371         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode = 0;
    1372         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
    1373         838 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum;
    1374         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatWaterVolFlow = 0.0;
    1375         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatSteamVolFlow = 0.0;
    1376         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatWaterVolFlow = 0.0;
    1377         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatSteamVolFlow = 0.0;
    1378         838 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = 0.000001;
    1379             : 
    1380             :         // Register component set data
    1381        2514 :         TestCompSet(state,
    1382         838 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    1383         838 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    1384         838 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum),
    1385         838 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum),
    1386             :                     "Air Nodes");
    1387             : 
    1388        6745 :         for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
    1389       13490 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum ==
    1390        6745 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
    1391         838 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum =
    1392         838 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    1393         838 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum = ADUNum;
    1394         838 :                 break;
    1395             :             }
    1396             :         }
    1397             :         // one assumes if there isn't one assigned, it's an error?
    1398         838 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum == 0) {
    1399           0 :             ShowSevereError(state,
    1400           0 :                             std::string{RoutineName} + "No matching Air Distribution Unit, for System = [" +
    1401           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + ',' +
    1402           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "].");
    1403           0 :             ShowContinueError(state,
    1404           0 :                               "...should have outlet node = " +
    1405           0 :                                   state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum));
    1406           0 :             ErrorsFound = true;
    1407             :         } else {
    1408             : 
    1409             :             // Fill the Zone Equipment data with the inlet node number of this unit.
    1410       16557 :             for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    1411       15719 :                 if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
    1412       35186 :                 for (SupAirIn = 1; SupAirIn <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++SupAirIn) {
    1413       42270 :                     if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum ==
    1414       21135 :                         state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(SupAirIn)) {
    1415         838 :                         if (state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode > 0) {
    1416           0 :                             ShowSevereError(state, "Error in connecting a terminal unit to a zone");
    1417           0 :                             ShowContinueError(
    1418             :                                 state,
    1419           0 :                                 state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum) +
    1420             :                                     " already connects to another zone");
    1421           0 :                             ShowContinueError(state,
    1422           0 :                                               "Occurs for terminal unit " +
    1423           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1424           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1425           0 :                             ShowContinueError(state, "Check terminal unit node names for errors");
    1426           0 :                             ErrorsFound = true;
    1427             :                         } else {
    1428         838 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).InNode =
    1429         838 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    1430         838 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode =
    1431         838 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum;
    1432         838 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    1433        1676 :                                 .TermUnitSizingNum = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
    1434         838 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    1435        1676 :                                 .ZoneEqNum = CtrlZone;
    1436             :                         }
    1437         838 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneNum = CtrlZone;
    1438         838 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneInNodeIndex = SupAirIn;
    1439         838 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFloorArea =
    1440        1676 :                             state.dataHeatBal->Zone(CtrlZone).FloorArea * state.dataHeatBal->Zone(CtrlZone).Multiplier *
    1441         838 :                             state.dataHeatBal->Zone(CtrlZone).ListMultiplier;
    1442             :                     }
    1443             :                 }
    1444             :             }
    1445             :         }
    1446             : 
    1447         838 :         if (lAlphaBlanks(5)) {
    1448         836 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).NoOAFlowInputFromUser = true;
    1449             :         } else {
    1450           2 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OARequirementsPtr =
    1451           2 :                 UtilityRoutines::FindItemInList(Alphas(5), state.dataSize->OARequirements);
    1452           2 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OARequirementsPtr == 0) {
    1453           0 :                 ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", invalid data.");
    1454           0 :                 ShowContinueError(state, "..invalid " + cAlphaFields(5) + "=\"" + Alphas(5) + "\".");
    1455           0 :                 ErrorsFound = true;
    1456             :             } else {
    1457           2 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).NoOAFlowInputFromUser = false;
    1458             :             }
    1459             :         }
    1460             : 
    1461         838 :         if (lAlphaBlanks(6)) {
    1462         837 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OAPerPersonMode =
    1463             :                 DataZoneEquipment::PerPersonVentRateMode::DCVByCurrentLevel;
    1464             :         } else {
    1465           1 :             if (Alphas(6) == "CURRENTOCCUPANCY") {
    1466           1 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OAPerPersonMode =
    1467             :                     DataZoneEquipment::PerPersonVentRateMode::DCVByCurrentLevel;
    1468           0 :             } else if (Alphas(6) == "DESIGNOCCUPANCY") {
    1469           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OAPerPersonMode =
    1470             :                     DataZoneEquipment::PerPersonVentRateMode::ByDesignLevel;
    1471             :             } else {
    1472           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OAPerPersonMode =
    1473             :                     DataZoneEquipment::PerPersonVentRateMode::DCVByCurrentLevel;
    1474           0 :                 ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + Alphas(1) + "\", invalid data.");
    1475           0 :                 ShowContinueError(state,
    1476           0 :                                   "..invalid " + cAlphaFields(6) + "=\"" + Alphas(6) + "\". The default input of CurrentOccupancy is assigned");
    1477             :             }
    1478             :         }
    1479             : 
    1480         838 :         if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1481             :             // model results related actuators
    1482        1036 :             SetupEMSActuator(state,
    1483             :                              "AirTerminal:SingleDuct:ConstantVolume:NoReheat",
    1484         259 :                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    1485             :                              "Mass Flow Rate",
    1486             :                              "[kg/s]",
    1487         259 :                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).EMSOverrideAirFlow,
    1488         777 :                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).EMSMassFlowRateValue);
    1489             :             // model input related internal variables
    1490         777 :             SetupEMSInternalVariable(state,
    1491             :                                      "AirTerminal:SingleDuct:ConstantVolume:NoReheat Maximum Mass Flow Rate",
    1492         259 :                                      state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    1493             :                                      "[kg/s]",
    1494         777 :                                      state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).AirMassFlowRateMax);
    1495             :         }
    1496             : 
    1497             :     } // End Number of Sys Loop
    1498             : 
    1499         589 :     for (state.dataSingleDuct->SysIndexGSI = 1; state.dataSingleDuct->SysIndexGSI <= state.dataSingleDuct->NumNoRHVAVSysGSI;
    1500          85 :          ++state.dataSingleDuct->SysIndexGSI) {
    1501             : 
    1502          85 :         CurrentModuleObject = "AirTerminal:SingleDuct:VAV:NoReheat";
    1503             : 
    1504         340 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1505             :                                                                  CurrentModuleObject,
    1506          85 :                                                                  state.dataSingleDuct->SysIndexGSI,
    1507             :                                                                  Alphas,
    1508          85 :                                                                  state.dataSingleDuct->NumAlphasGSI,
    1509             :                                                                  Numbers,
    1510          85 :                                                                  state.dataSingleDuct->NumNumsGSI,
    1511             :                                                                  IOStat,
    1512             :                                                                  lNumericBlanks,
    1513             :                                                                  lAlphaBlanks,
    1514             :                                                                  cAlphaFields,
    1515             :                                                                  cNumericFields);
    1516             : 
    1517         255 :         state.dataSingleDuct->SysNumGSI = state.dataSingleDuct->SysIndexGSI + state.dataSingleDuct->NumVAVSysGSI +
    1518         255 :                                           state.dataSingleDuct->NumCBVAVSysGSI + state.dataSingleDuct->NumConstVolSys +
    1519          85 :                                           state.dataSingleDuct->NumCVNoReheatSysGSI;
    1520          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysNum = state.dataSingleDuct->SysNumGSI;
    1521         170 :         GlobalNames::VerifyUniqueInterObjectName(
    1522         170 :             state, state.dataSingleDuct->SysUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    1523          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName = Alphas(1);
    1524          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType = CurrentModuleObject;
    1525          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysType_Num = SysType::SingleDuctVAVNoReheat;
    1526          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp = "";
    1527          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName = "";
    1528          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Schedule = Alphas(2);
    1529          85 :         if (lAlphaBlanks(2)) {
    1530          25 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
    1531             :         } else {
    1532          60 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = GetScheduleIndex(state, Alphas(2));
    1533          60 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr == 0) {
    1534           0 :                 ShowSevereError(state, cAlphaFields(2) + " = " + Alphas(2) + " not found.");
    1535           0 :                 ShowContinueError(state,
    1536           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1537           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1538           0 :                 ErrorsFound = true;
    1539             :             }
    1540             :         }
    1541          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum =
    1542         170 :             GetOnlySingleNode(state,
    1543          85 :                               Alphas(3),
    1544             :                               ErrorsFound,
    1545             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVNoReheat,
    1546          85 :                               Alphas(1),
    1547             :                               DataLoopNode::NodeFluidType::Air,
    1548             :                               DataLoopNode::ConnectionType::Outlet,
    1549             :                               NodeInputManager::CompFluidStream::Primary,
    1550             :                               ObjectIsNotParent,
    1551          85 :                               cAlphaFields(3));
    1552          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum =
    1553         170 :             GetOnlySingleNode(state,
    1554          85 :                               Alphas(4),
    1555             :                               ErrorsFound,
    1556             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVNoReheat,
    1557          85 :                               Alphas(1),
    1558             :                               DataLoopNode::NodeFluidType::Air,
    1559             :                               DataLoopNode::ConnectionType::Inlet,
    1560             :                               NodeInputManager::CompFluidStream::Primary,
    1561             :                               ObjectIsNotParent,
    1562          85 :                               cAlphaFields(4));
    1563          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRate = Numbers(1);
    1564             : 
    1565          85 :         if (UtilityRoutines::SameString(Alphas(5), "Constant")) {
    1566          85 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod = MinFlowFraction::Constant;
    1567           0 :         } else if (UtilityRoutines::SameString(Alphas(5), "FixedFlowRate")) {
    1568           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod = MinFlowFraction::Fixed;
    1569           0 :         } else if (UtilityRoutines::SameString(Alphas(5), "Scheduled")) {
    1570           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod = MinFlowFraction::Scheduled;
    1571             :         } else {
    1572           0 :             ShowSevereError(state, cAlphaFields(5) + " = " + Alphas(5) + " not found.");
    1573           0 :             ShowContinueError(state,
    1574           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1575           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1576           0 :             ErrorsFound = true;
    1577             :         }
    1578             : 
    1579          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = Numbers(2);
    1580          85 :         if (lNumericBlanks(2)) {
    1581           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ConstantMinAirFracSetByUser = false;
    1582           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 0.0;
    1583             :         } else {
    1584          85 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ConstantMinAirFracSetByUser = true;
    1585          85 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = Numbers(2);
    1586          85 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod == MinFlowFraction::Fixed) {
    1587           0 :                 ShowWarningError(state, "Since " + cAlphaFields(5) + " = " + Alphas(5) + ", input for " + cNumericFields(2) + " will be ignored.");
    1588           0 :                 ShowContinueError(state,
    1589           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1590           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1591           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 0.0;
    1592             :             }
    1593             :         }
    1594             : 
    1595          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFixedMinAir = Numbers(3);
    1596          85 :         if (lNumericBlanks(3)) {
    1597          85 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FixedMinAirSetByUser = false;
    1598          85 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DesignFixedMinAir = 0.0;
    1599             :         } else {
    1600           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FixedMinAirSetByUser = true;
    1601           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DesignFixedMinAir = Numbers(3);
    1602           0 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod == MinFlowFraction::Constant) {
    1603           0 :                 ShowWarningError(state, "Since " + cAlphaFields(5) + " = " + Alphas(5) + ", input for " + cNumericFields(3) + " will be ignored.");
    1604           0 :                 ShowContinueError(state,
    1605           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1606           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1607           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFixedMinAir = 0.0;
    1608             :             }
    1609             :         }
    1610          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracSchPtr = GetScheduleIndex(state, Alphas(6));
    1611         170 :         if ((state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracSchPtr == 0) &&
    1612          85 :             (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod == MinFlowFraction::Scheduled)) {
    1613           0 :             ShowSevereError(state, cAlphaFields(6) + " = " + Alphas(6) + " not found.");
    1614           0 :             ShowContinueError(state,
    1615           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1616           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1617           0 :             ShowContinueError(state, "A valid schedule is required");
    1618           0 :             ErrorsFound = true;
    1619          85 :         } else if ((state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracSchPtr > 0) &&
    1620           0 :                    (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracMethod == MinFlowFraction::Scheduled)) {
    1621             :             // check range of values in schedule
    1622           0 :             if (!CheckScheduleValueMinMax(
    1623           0 :                     state, state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracSchPtr, ">=", 0.0, "<=", 1.0)) {
    1624           0 :                 ShowSevereError(state, "Error found in " + cAlphaFields(6) + " = " + Alphas(6));
    1625           0 :                 ShowContinueError(state,
    1626           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1627           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1628           0 :                 ShowContinueError(state, "Schedule values must be (>=0., <=1.)");
    1629             :             }
    1630             :         }
    1631             : 
    1632          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode = 0;
    1633          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
    1634          85 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum;
    1635          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatWaterVolFlow = 0.0;
    1636          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatSteamVolFlow = 0.0;
    1637          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatWaterVolFlow = 0.0;
    1638          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatSteamVolFlow = 0.0;
    1639          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = 0.000001;
    1640          85 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::HeatingNotUsed;
    1641             : 
    1642             :         // Register component set data
    1643         255 :         TestCompSet(state,
    1644          85 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    1645          85 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    1646          85 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum),
    1647          85 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum),
    1648             :                     "Air Nodes");
    1649             : 
    1650         312 :         for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
    1651         624 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum ==
    1652         312 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
    1653          85 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum =
    1654          85 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    1655          85 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum = ADUNum;
    1656          85 :                 break;
    1657             :             }
    1658             :         }
    1659             :         // one assumes if there isn't one assigned, it's an error?
    1660          85 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum == 0) {
    1661           0 :             ShowSevereError(state,
    1662           0 :                             std::string{RoutineName} + "No matching Air Distribution Unit, for System = [" +
    1663           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + ',' +
    1664           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "].");
    1665           0 :             ShowContinueError(
    1666             :                 state,
    1667           0 :                 "...should have outlet node = " +
    1668           0 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode));
    1669           0 :             ErrorsFound = true;
    1670             :         } else {
    1671             : 
    1672             :             // Fill the Zone Equipment data with the inlet node number of this unit.
    1673         566 :             for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    1674         481 :                 if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
    1675        1094 :                 for (SupAirIn = 1; SupAirIn <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++SupAirIn) {
    1676        1394 :                     if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
    1677         697 :                         state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(SupAirIn)) {
    1678          85 :                         if (state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode > 0) {
    1679           0 :                             ShowSevereError(state, "Error in connecting a terminal unit to a zone");
    1680           0 :                             ShowContinueError(state,
    1681           0 :                                               state.dataLoopNodes->NodeID(
    1682           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode) +
    1683             :                                                   " already connects to another zone");
    1684           0 :                             ShowContinueError(state,
    1685           0 :                                               "Occurs for terminal unit " +
    1686           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1687           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1688           0 :                             ShowContinueError(state, "Check terminal unit node names for errors");
    1689           0 :                             ErrorsFound = true;
    1690             :                         } else {
    1691          85 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).InNode =
    1692          85 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    1693          85 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode =
    1694          85 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode;
    1695          85 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    1696         170 :                                 .TermUnitSizingNum = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
    1697          85 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    1698         170 :                                 .ZoneEqNum = CtrlZone;
    1699             :                         }
    1700             : 
    1701          85 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneNum = CtrlZone;
    1702          85 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneInNodeIndex = SupAirIn;
    1703          85 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFloorArea =
    1704         170 :                             state.dataHeatBal->Zone(CtrlZone).FloorArea * state.dataHeatBal->Zone(CtrlZone).Multiplier *
    1705          85 :                             state.dataHeatBal->Zone(CtrlZone).ListMultiplier;
    1706             :                     }
    1707             :                 }
    1708             :             }
    1709             :         }
    1710          85 :         if (!lAlphaBlanks(7)) {
    1711           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OARequirementsPtr =
    1712           0 :                 UtilityRoutines::FindItemInList(Alphas(7), state.dataSize->OARequirements);
    1713           0 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OARequirementsPtr == 0) {
    1714           0 :                 ShowSevereError(state, cAlphaFields(7) + " = " + Alphas(7) + " not found.");
    1715           0 :                 ShowContinueError(state,
    1716           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1717           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1718           0 :                 ErrorsFound = true;
    1719             :             } else {
    1720           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).NoOAFlowInputFromUser = false;
    1721             :             }
    1722             :         }
    1723             : 
    1724          85 :         if (lAlphaBlanks(8)) {
    1725          85 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFrac = 1.0;
    1726          85 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = false;
    1727             :         } else {
    1728           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr = GetScheduleIndex(state, Alphas(8));
    1729           0 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr == 0) {
    1730           0 :                 ShowSevereError(state, cAlphaFields(8) + " = " + Alphas(8) + " not found.");
    1731           0 :                 ShowContinueError(state,
    1732           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1733           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1734           0 :                 ErrorsFound = true;
    1735             :             }
    1736           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = true;
    1737             :         }
    1738             : 
    1739             :         // Setup the Average damper Position output variable
    1740         340 :         SetupOutputVariable(state,
    1741             :                             "Zone Air Terminal VAV Damper Position",
    1742             :                             OutputProcessor::Unit::None,
    1743          85 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperPosition,
    1744             :                             OutputProcessor::SOVTimeStepType::System,
    1745             :                             OutputProcessor::SOVStoreType::Average,
    1746         170 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1747         340 :         SetupOutputVariable(state,
    1748             :                             "Zone Air Terminal Minimum Air Flow Fraction",
    1749             :                             OutputProcessor::Unit::None,
    1750          85 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracReport,
    1751             :                             OutputProcessor::SOVTimeStepType::System,
    1752             :                             OutputProcessor::SOVStoreType::Average,
    1753         170 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1754             : 
    1755             :     } // end Number of Sys Loop
    1756             : 
    1757         508 :     for (state.dataSingleDuct->SysIndexGSI = 1; state.dataSingleDuct->SysIndexGSI <= state.dataSingleDuct->NumNoRHCBVAVSysGSI;
    1758           4 :          ++state.dataSingleDuct->SysIndexGSI) {
    1759             : 
    1760           4 :         CurrentModuleObject = "AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat";
    1761             : 
    1762          16 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1763             :                                                                  CurrentModuleObject,
    1764           4 :                                                                  state.dataSingleDuct->SysIndexGSI,
    1765             :                                                                  Alphas,
    1766           4 :                                                                  state.dataSingleDuct->NumAlphasGSI,
    1767             :                                                                  Numbers,
    1768           4 :                                                                  state.dataSingleDuct->NumNumsGSI,
    1769             :                                                                  IOStat,
    1770             :                                                                  lNumericBlanks,
    1771             :                                                                  lAlphaBlanks,
    1772             :                                                                  cAlphaFields,
    1773             :                                                                  cNumericFields);
    1774             : 
    1775          12 :         state.dataSingleDuct->SysNumGSI = state.dataSingleDuct->SysIndexGSI + state.dataSingleDuct->NumVAVSysGSI +
    1776          12 :                                           state.dataSingleDuct->NumCBVAVSysGSI + state.dataSingleDuct->NumConstVolSys +
    1777           8 :                                           state.dataSingleDuct->NumCVNoReheatSysGSI + state.dataSingleDuct->NumNoRHVAVSysGSI;
    1778           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysNum = state.dataSingleDuct->SysNumGSI;
    1779           8 :         GlobalNames::VerifyUniqueInterObjectName(
    1780           8 :             state, state.dataSingleDuct->SysUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    1781           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName = Alphas(1);
    1782           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType = CurrentModuleObject;
    1783           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysType_Num = SysType::SingleDuctCBVAVNoReheat;
    1784           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp = "";
    1785           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName = "";
    1786           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Schedule = Alphas(2);
    1787           4 :         if (lAlphaBlanks(2)) {
    1788           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
    1789             :         } else {
    1790           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = GetScheduleIndex(state, Alphas(2));
    1791           4 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr == 0) {
    1792           0 :                 ShowSevereError(state, cAlphaFields(2) + " = " + Alphas(2) + " not found.");
    1793           0 :                 ShowContinueError(state,
    1794           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1795           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1796           0 :                 ErrorsFound = true;
    1797             :             }
    1798             :         }
    1799           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum =
    1800           8 :             GetOnlySingleNode(state,
    1801           4 :                               Alphas(3),
    1802             :                               ErrorsFound,
    1803             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVHeatAndCoolNoReheat,
    1804           4 :                               Alphas(1),
    1805             :                               DataLoopNode::NodeFluidType::Air,
    1806             :                               DataLoopNode::ConnectionType::Outlet,
    1807             :                               NodeInputManager::CompFluidStream::Primary,
    1808             :                               ObjectIsNotParent,
    1809           4 :                               cAlphaFields(3));
    1810           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum =
    1811           8 :             GetOnlySingleNode(state,
    1812           4 :                               Alphas(4),
    1813             :                               ErrorsFound,
    1814             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctVAVHeatAndCoolNoReheat,
    1815           4 :                               Alphas(1),
    1816             :                               DataLoopNode::NodeFluidType::Air,
    1817             :                               DataLoopNode::ConnectionType::Inlet,
    1818             :                               NodeInputManager::CompFluidStream::Primary,
    1819             :                               ObjectIsNotParent,
    1820           4 :                               cAlphaFields(4));
    1821           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRate = Numbers(1);
    1822           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = Numbers(2);
    1823           4 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes < 0.0) {
    1824           0 :             ShowWarningError(state,
    1825           0 :                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = \"" +
    1826           0 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1827           0 :             ShowContinueError(state, cNumericFields(2) + " must be greater than or equal to 0. Resetting to 0 and the simulation continues.");
    1828           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 0.0;
    1829             :         }
    1830           4 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes > 1.0) {
    1831           0 :             ShowWarningError(state,
    1832           0 :                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = \"" +
    1833           0 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1834           0 :             ShowContinueError(state, cNumericFields(2) + " must be less than or equal to 1. Resetting to 1 and the simulation continues.");
    1835           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = 1.0;
    1836             :         }
    1837             : 
    1838           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode = 0;
    1839           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
    1840           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum;
    1841           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatWaterVolFlow = 0.0;
    1842           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatSteamVolFlow = 0.0;
    1843           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatWaterVolFlow = 0.0;
    1844           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatSteamVolFlow = 0.0;
    1845           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = 0.000001;
    1846           4 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::HeatingNotUsed;
    1847             : 
    1848             :         // Register component set data
    1849          12 :         TestCompSet(state,
    1850           4 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    1851           4 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    1852           4 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum),
    1853           4 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum),
    1854             :                     "Air Nodes");
    1855             : 
    1856          12 :         for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
    1857          24 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum ==
    1858          12 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
    1859           4 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum =
    1860           4 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    1861           4 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum = ADUNum;
    1862           4 :                 break;
    1863             :             }
    1864             :         }
    1865             :         // one assumes if there isn't one assigned, it's an error?
    1866           4 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum == 0) {
    1867           0 :             ShowSevereError(state,
    1868           0 :                             std::string{RoutineName} + "No matching Air Distribution Unit, for System = [" +
    1869           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + ',' +
    1870           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "].");
    1871           0 :             ShowContinueError(
    1872             :                 state,
    1873           0 :                 "...should have outlet node = " +
    1874           0 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode));
    1875           0 :             ErrorsFound = true;
    1876             :         } else {
    1877             : 
    1878             :             // Fill the Zone Equipment data with the inlet node number of this unit.
    1879          16 :             for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    1880          12 :                 if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
    1881          24 :                 for (SupAirIn = 1; SupAirIn <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++SupAirIn) {
    1882          24 :                     if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
    1883          12 :                         state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(SupAirIn)) {
    1884           4 :                         if (state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode > 0) {
    1885           0 :                             ShowSevereError(state, "Error in connecting a terminal unit to a zone");
    1886           0 :                             ShowContinueError(state,
    1887           0 :                                               state.dataLoopNodes->NodeID(
    1888           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode) +
    1889             :                                                   " already connects to another zone");
    1890           0 :                             ShowContinueError(state,
    1891           0 :                                               "Occurs for terminal unit " +
    1892           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1893           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1894           0 :                             ShowContinueError(state, "Check terminal unit node names for errors");
    1895           0 :                             ErrorsFound = true;
    1896             :                         } else {
    1897           4 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).InNode =
    1898           4 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    1899           4 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode =
    1900           4 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode;
    1901           4 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    1902           8 :                                 .TermUnitSizingNum = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
    1903           4 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    1904           8 :                                 .ZoneEqNum = CtrlZone;
    1905             :                         }
    1906           4 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneNum = CtrlZone;
    1907           4 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneInNodeIndex = SupAirIn;
    1908           4 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFloorArea =
    1909           8 :                             state.dataHeatBal->Zone(CtrlZone).FloorArea * state.dataHeatBal->Zone(CtrlZone).Multiplier *
    1910           4 :                             state.dataHeatBal->Zone(CtrlZone).ListMultiplier;
    1911             :                     }
    1912             :                 }
    1913             :             }
    1914             :         }
    1915             : 
    1916           4 :         if (lAlphaBlanks(5)) {
    1917           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFrac = 1.0;
    1918           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = false;
    1919             :         } else {
    1920           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr = GetScheduleIndex(state, Alphas(5));
    1921           0 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr == 0) {
    1922           0 :                 ShowSevereError(state, cAlphaFields(5) + " = " + Alphas(5) + " not found.");
    1923           0 :                 ShowContinueError(state,
    1924           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    1925           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1926           0 :                 ErrorsFound = true;
    1927             :             }
    1928           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = true;
    1929             :         }
    1930             : 
    1931             :         // Setup the Average damper Position output variable
    1932          16 :         SetupOutputVariable(state,
    1933             :                             "Zone Air Terminal VAV Damper Position",
    1934             :                             OutputProcessor::Unit::None,
    1935           4 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperPosition,
    1936             :                             OutputProcessor::SOVTimeStepType::System,
    1937             :                             OutputProcessor::SOVStoreType::Average,
    1938           8 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1939             : 
    1940             :     } // end Number of VAVHeatandCool:NoReheat Sys Loop
    1941             : 
    1942             :     // read in the SINGLE DUCT:VAV:REHEAT:VS FAN data
    1943         512 :     for (state.dataSingleDuct->SysIndexGSI = 1; state.dataSingleDuct->SysIndexGSI <= state.dataSingleDuct->NumVAVVSGSI;
    1944           8 :          ++state.dataSingleDuct->SysIndexGSI) {
    1945             : 
    1946           8 :         CurrentModuleObject = "AirTerminal:SingleDuct:VAV:Reheat:VariableSpeedFan";
    1947             : 
    1948          32 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1949             :                                                                  CurrentModuleObject,
    1950           8 :                                                                  state.dataSingleDuct->SysIndexGSI,
    1951             :                                                                  Alphas,
    1952           8 :                                                                  state.dataSingleDuct->NumAlphasGSI,
    1953             :                                                                  Numbers,
    1954           8 :                                                                  state.dataSingleDuct->NumNumsGSI,
    1955             :                                                                  IOStat,
    1956             :                                                                  lNumericBlanks,
    1957             :                                                                  lAlphaBlanks,
    1958             :                                                                  cAlphaFields,
    1959             :                                                                  cNumericFields);
    1960             : 
    1961          24 :         state.dataSingleDuct->SysNumGSI = state.dataSingleDuct->SysIndexGSI + state.dataSingleDuct->NumVAVSysGSI +
    1962          24 :                                           state.dataSingleDuct->NumCBVAVSysGSI + state.dataSingleDuct->NumConstVolSys +
    1963          24 :                                           state.dataSingleDuct->NumCVNoReheatSysGSI + state.dataSingleDuct->NumNoRHVAVSysGSI +
    1964           8 :                                           state.dataSingleDuct->NumNoRHCBVAVSysGSI;
    1965           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysNum = state.dataSingleDuct->SysNumGSI;
    1966          16 :         GlobalNames::VerifyUniqueInterObjectName(
    1967          16 :             state, state.dataSingleDuct->SysUniqueNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
    1968           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName = Alphas(1);
    1969           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType = CurrentModuleObject;
    1970           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysType_Num = SysType::SingleDuctVAVReheatVSFan;
    1971           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp = Alphas(7);
    1972           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName = Alphas(8);
    1973           8 :         IsNotOK = false;
    1974           8 :         if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp, "Coil:Heating:Fuel")) {
    1975           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::Gas;
    1976           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
    1977           0 :                 GetHeatingCoilOutletNode(state,
    1978           0 :                                          state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1979           0 :                                          state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    1980             :                                          IsNotOK);
    1981           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatCoilMaxCapacity =
    1982           0 :                 GetHeatingCoilCapacity(state,
    1983           0 :                                        state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1984           0 :                                        state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    1985             :                                        IsNotOK);
    1986           0 :             if (IsNotOK)
    1987           0 :                 ShowContinueError(state,
    1988           0 :                                   "Occurs for terminal unit " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType +
    1989           0 :                                       " = " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    1990           8 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1991           8 :                                                "Coil:Heating:Electric")) {
    1992           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::Electric;
    1993           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
    1994           0 :                 GetHeatingCoilOutletNode(state,
    1995           0 :                                          state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    1996           0 :                                          state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    1997             :                                          IsNotOK);
    1998           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatCoilMaxCapacity =
    1999           0 :                 GetHeatingCoilCapacity(state,
    2000           0 :                                        state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    2001           0 :                                        state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    2002             :                                        IsNotOK);
    2003           0 :             if (IsNotOK)
    2004           0 :                 ShowContinueError(state,
    2005           0 :                                   "Occurs for terminal unit " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType +
    2006           0 :                                       " = " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2007           8 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    2008           8 :                                                "Coil:Heating:Water")) {
    2009           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::SimpleHeating;
    2010           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_PlantType =
    2011             :                 DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
    2012           0 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    2013           0 :                                                "Coil:Heating:Steam")) {
    2014           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num = HeatingCoilType::SteamAirHeating;
    2015           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_PlantType =
    2016             :                 DataPlant::PlantEquipmentType::CoilSteamAirHeating;
    2017           0 :         } else if (!state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp.empty()) {
    2018           0 :             ShowSevereError(
    2019           0 :                 state, "Illegal " + cAlphaFields(7) + " = " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp + '.');
    2020           0 :             ShowContinueError(state,
    2021           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2022           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2023           0 :             ErrorsFound = true;
    2024             :         }
    2025          24 :         ValidateComponent(state,
    2026           8 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    2027           8 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    2028             :                           IsNotOK,
    2029           8 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType);
    2030           8 :         if (IsNotOK) {
    2031           0 :             ShowContinueError(state,
    2032           0 :                               "In " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2033           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2034           0 :             ErrorsFound = true;
    2035             :         }
    2036           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanType = Alphas(5);
    2037           8 :         if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanType, "Fan:VariableVolume")) {
    2038           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Fan_Num = DataHVACGlobals::FanType_SimpleVAV;
    2039           4 :         } else if (UtilityRoutines::SameString(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanType, "Fan:SystemModel")) {
    2040           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Fan_Num = DataHVACGlobals::FanType_SystemModelObject;
    2041           0 :         } else if (!state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanType.empty()) {
    2042           0 :             ShowSevereError(
    2043           0 :                 state, "Illegal " + cAlphaFields(5) + " = " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanType + '.');
    2044           0 :             ShowContinueError(state,
    2045           0 :                               "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2046           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2047           0 :             ErrorsFound = true;
    2048             :         }
    2049           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanName = Alphas(6);
    2050          24 :         ValidateComponent(state,
    2051           8 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanType,
    2052           8 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanName,
    2053             :                           IsNotOK,
    2054           8 :                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType);
    2055           8 :         if (IsNotOK) {
    2056           0 :             ShowContinueError(state,
    2057           0 :                               "In " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2058           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2059           0 :             ErrorsFound = true;
    2060             :         }
    2061           8 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Fan_Num == DataHVACGlobals::FanType_SystemModelObject) {
    2062           8 :             state.dataHVACFan->fanObjs.emplace_back(
    2063          12 :                 new HVACFan::FanSystem(state,
    2064           4 :                                        state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI)
    2065           8 :                                            .FanName)); // call constructor, safe here because get input is not using DataIPShortCuts.
    2066           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Fan_Index =
    2067           4 :                 HVACFan::getFanObjectVectorIndex(state, state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanName);
    2068           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum =
    2069           4 :                 state.dataHVACFan->fanObjs[state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Fan_Index]->outletNodeNum;
    2070           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum =
    2071           4 :                 state.dataHVACFan->fanObjs[state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Fan_Index]->inletNodeNum;
    2072           4 :             state.dataHVACFan->fanObjs[state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Fan_Index]->fanIsSecondaryDriver = true;
    2073           4 :         } else if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Fan_Num == DataHVACGlobals::FanType_SimpleVAV) {
    2074           4 :             IsNotOK = false;
    2075             : 
    2076           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum =
    2077           8 :                 GetFanOutletNode(state,
    2078           4 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanType,
    2079           4 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanName,
    2080             :                                  IsNotOK);
    2081           4 :             if (IsNotOK) {
    2082           0 :                 ShowContinueError(state,
    2083           0 :                                   "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2084           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2085           0 :                 ErrorsFound = true;
    2086             :             }
    2087             : 
    2088           4 :             IsNotOK = false;
    2089           4 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum =
    2090           8 :                 GetFanInletNode(state,
    2091           4 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanType,
    2092           4 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).FanName,
    2093             :                                 IsNotOK);
    2094           4 :             if (IsNotOK) {
    2095           0 :                 ShowContinueError(state,
    2096           0 :                                   "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2097           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2098           0 :                 ErrorsFound = true;
    2099             :             }
    2100             :         }
    2101             : 
    2102           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).Schedule = Alphas(2);
    2103           8 :         if (lAlphaBlanks(2)) {
    2104           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
    2105             :         } else {
    2106           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr = GetScheduleIndex(state, Alphas(2));
    2107           8 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SchedPtr == 0) {
    2108           0 :                 ShowSevereError(state, cAlphaFields(2) + " = " + Alphas(2) + " not found.");
    2109           0 :                 ShowContinueError(state,
    2110           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2111           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2112           0 :                 ErrorsFound = true;
    2113             :             }
    2114             :         }
    2115             : 
    2116           8 :         AirTermSysInletNodeName = state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum);
    2117           8 :         if (!UtilityRoutines::SameString(Alphas(3), AirTermSysInletNodeName)) {
    2118           0 :             ShowWarningError(state,
    2119           0 :                              std::string{RoutineName} + "Invalid air terminal object air inlet node name in " +
    2120           0 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2121           0 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2122           0 :             ShowContinueError(state, " Specified air inlet node name is = " + Alphas(3) + ".");
    2123           0 :             ShowContinueError(state, " Expected air inlet node name is = " + AirTermSysInletNodeName + ".");
    2124             :             // ErrorsFound = true;
    2125             :         }
    2126             : 
    2127           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxAirVolFlowRate = Numbers(1);
    2128           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxHeatAirVolFlowRate = Numbers(2);
    2129           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneMinAirFracDes = Numbers(3);
    2130             :         // The reheat coil control node is necessary for hot water reheat, but not necessary for
    2131             :         // electric or gas reheat.
    2132          16 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::Gas ||
    2133           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::Electric) {
    2134             :             //          IF(.NOT. lAlphaBlanks(6)) THEN
    2135             :             //            CALL ShowWarningError(state, 'In '//TRIM(sd_airterminal(SysNum)%SysType)//' = ' // TRIM(sd_airterminal(SysNum)%SysName) &
    2136             :             //                                 // ' the '//TRIM(cAlphaFields(6))//' is not needed and will be ignored.')
    2137             :             //            CALL ShowContinueError(state, '  It is used for hot water reheat coils only.')
    2138             :             //          END IF
    2139             :         } else {
    2140             :             //          IF(lAlphaBlanks(6)) THEN
    2141             :             //            CALL ShowSevereError(state, 'In '//TRIM(sd_airterminal(SysNum)%SysType)//' = ' // TRIM(sd_airterminal(SysNum)%SysName) &
    2142             :             //                                 // ' the '//TRIM(cAlphaFields(6))//' is undefined')
    2143             :             //            ErrorsFound=.TRUE.
    2144             :             //          END IF
    2145           8 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
    2146           0 :                 IsNotOK = false;
    2147           0 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode =
    2148           0 :                     GetCoilSteamInletNode(state,
    2149           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    2150           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    2151             :                                           IsNotOK);
    2152           0 :                 if (IsNotOK) {
    2153           0 :                     ShowContinueError(state,
    2154           0 :                                       "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2155           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2156           0 :                     ErrorsFound = true;
    2157             :                 } else {
    2158             :                     //  A4,     \field Unit supply air outlet node
    2159             :                     //          \note same as heating coil air outlet node
    2160             :                     //          \note same as zone inlet node
    2161             :                     //          \type alpha
    2162           0 :                     IsNotOK = false;
    2163           0 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
    2164           0 :                         GetCoilAirOutletNode(state,
    2165           0 :                                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    2166           0 :                                              state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    2167             :                                              IsNotOK);
    2168           0 :                     if (IsNotOK) {
    2169           0 :                         ShowContinueError(state,
    2170           0 :                                           "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2171           0 :                                               state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2172           0 :                         ErrorsFound = true;
    2173             :                     }
    2174             :                 }
    2175             :                 //               GetOnlySingleNode(state, Alphas(6),ErrorsFound,sd_airterminal(SysNum)%SysType,Alphas(1), &
    2176             :                 //                                DataLoopNode::NodeFluidType::Steam,DataLoopNode::NodeConnectionType::Actuator,1,ObjectIsParent)
    2177             :             } else {
    2178           8 :                 IsNotOK = false;
    2179           8 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatControlNode =
    2180          16 :                     GetCoilWaterInletNode(state,
    2181           8 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    2182           8 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    2183             :                                           IsNotOK);
    2184           8 :                 if (IsNotOK) {
    2185           0 :                     ShowContinueError(state,
    2186           0 :                                       "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2187           0 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2188           0 :                     ErrorsFound = true;
    2189             :                 } else {
    2190             :                     //  A4,     \field Unit supply air outlet node
    2191             :                     //          \note same as heating coil air outlet node
    2192             :                     //          \note same as zone inlet node
    2193             :                     //          \type alpha
    2194           8 :                     IsNotOK = false;
    2195           8 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode =
    2196          16 :                         GetCoilOutletNode(state,
    2197           8 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp,
    2198           8 :                                           state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatName,
    2199             :                                           IsNotOK);
    2200           8 :                     if (IsNotOK) {
    2201           0 :                         ShowContinueError(state,
    2202           0 :                                           "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2203           0 :                                               state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2204           0 :                         ErrorsFound = true;
    2205             :                     }
    2206             :                 }
    2207             :                 //               GetOnlySingleNode(state, Alphas(6),ErrorsFound,sd_airterminal(SysNum)%SysType,Alphas(1), &
    2208             :                 //                                DataLoopNode::NodeFluidType::Water,DataLoopNode::NodeConnectionType::Actuator,1,ObjectIsParent)
    2209             :             }
    2210             :         }
    2211             :         //  A4,     \field Unit supply air outlet node
    2212             :         //          \note same as heating coil air outlet node
    2213             :         //          \note same as zone inlet node
    2214             :         //          \type alpha
    2215             :         //        sd_airterminal(SysNum)%ReheatAirOutletNode  = &
    2216             :         //               GetOnlySingleNode(state, Alphas(4),ErrorsFound,sd_airterminal(SysNum)%SysType,Alphas(1), &
    2217             :         //                            DataLoopNode::NodeFluidType::Air,DataLoopNode::NodeConnectionType::Outlet,1,ObjectIsParent)
    2218           8 :         AirTermSysOutletNodeName =
    2219           8 :             state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode);
    2220           8 :         if (!UtilityRoutines::SameString(Alphas(4), AirTermSysOutletNodeName)) {
    2221           0 :             ShowWarningError(state,
    2222           0 :                              std::string{RoutineName} + "Invalid air terminal object air outlet node name in " +
    2223           0 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2224           0 :                                  state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2225           0 :             ShowContinueError(state, " Specified air outlet node name is = " + Alphas(4) + ".");
    2226           0 :             ShowContinueError(state, " Expected air outlet node name is = " + AirTermSysOutletNodeName + ".");
    2227             :             // ErrorsFound = true;
    2228             :         }
    2229             : 
    2230           8 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
    2231           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatSteamVolFlow = Numbers(4);
    2232           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatSteamVolFlow = Numbers(5);
    2233             :         } else {
    2234           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MaxReheatWaterVolFlow = Numbers(4);
    2235           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).MinReheatWaterVolFlow = Numbers(5);
    2236             :         }
    2237           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = Numbers(6);
    2238             :         // Set default convergence tolerance
    2239           8 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset <= 0.0) {
    2240           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ControllerOffset = 0.001;
    2241             :         }
    2242           8 :         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperHeatingAction = Action::HeatingNotUsed;
    2243             : 
    2244             :         // Register component set data
    2245          24 :         TestCompSet(state,
    2246           8 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    2247           8 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    2248           8 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum),
    2249           8 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode),
    2250             :                     "Air Nodes");
    2251             : 
    2252          20 :         for (ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
    2253          40 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
    2254          20 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
    2255           8 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum =
    2256           8 :                     state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    2257           8 :                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum = ADUNum;
    2258           8 :                 break;
    2259             :             }
    2260             :         }
    2261             :         // one assumes if there isn't one assigned, it's an error?
    2262           8 :         if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum == 0) {
    2263           0 :             ShowSevereError(state,
    2264           0 :                             std::string{RoutineName} + "No matching Air Distribution Unit, for System = [" +
    2265           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + ',' +
    2266           0 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName + "].");
    2267           0 :             ShowContinueError(
    2268             :                 state,
    2269           0 :                 "...should have outlet node = " +
    2270           0 :                     state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode));
    2271           0 :             ErrorsFound = true;
    2272             :         } else {
    2273             : 
    2274             :             // Fill the Zone Equipment data with the inlet node number of this unit.
    2275             :             // what if not found?  error?
    2276           8 :             IsNotOK = true;
    2277          64 :             for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    2278          56 :                 if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
    2279          80 :                 for (SupAirIn = 1; SupAirIn <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++SupAirIn) {
    2280          80 :                     if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode ==
    2281          40 :                         state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(SupAirIn)) {
    2282           8 :                         IsNotOK = false;
    2283           8 :                         if (state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode > 0) {
    2284           0 :                             ShowSevereError(state, "Error in connecting a terminal unit to a zone");
    2285           0 :                             ShowContinueError(state,
    2286           0 :                                               state.dataLoopNodes->NodeID(
    2287           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode) +
    2288             :                                                   " already connects to another zone");
    2289           0 :                             ShowContinueError(state,
    2290           0 :                                               "Occurs for terminal unit " +
    2291           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2292           0 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2293           0 :                             ShowContinueError(state, "Check terminal unit node names for errors");
    2294           0 :                             ErrorsFound = true;
    2295             :                         } else {
    2296           8 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).InNode =
    2297           8 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum;
    2298           8 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).OutNode =
    2299           8 :                                 state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode;
    2300           8 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    2301          16 :                                 .TermUnitSizingNum = state.dataZoneEquip->ZoneEquipConfig(CtrlZone).AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
    2302           8 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ADUNum)
    2303          16 :                                 .ZoneEqNum = CtrlZone;
    2304             :                         }
    2305           8 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneNum = CtrlZone;
    2306           8 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).CtrlZoneInNodeIndex = SupAirIn;
    2307           8 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneFloorArea =
    2308          16 :                             state.dataHeatBal->Zone(CtrlZone).FloorArea * state.dataHeatBal->Zone(CtrlZone).Multiplier *
    2309           8 :                             state.dataHeatBal->Zone(CtrlZone).ListMultiplier;
    2310             :                     }
    2311             :                 }
    2312             :             }
    2313             :         }
    2314           8 :         if (IsNotOK) {
    2315           0 :             ShowWarningError(state, "Did not Match Supply Air Outlet Node to any Zone Node");
    2316           0 :             ShowContinueError(state,
    2317           0 :                               "..Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2318           0 :                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2319             :         }
    2320             : 
    2321           8 :         if (lAlphaBlanks(9)) {
    2322           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFrac = 1.0;
    2323           8 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = false;
    2324             :         } else {
    2325           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr = GetScheduleIndex(state, Alphas(9));
    2326           0 :             if (state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchPtr == 0) {
    2327           0 :                 ShowSevereError(state, cAlphaFields(9) + " = " + Alphas(9) + " not found.");
    2328           0 :                 ShowContinueError(state,
    2329           0 :                                   "Occurs in " + state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType + " = " +
    2330           0 :                                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2331           0 :                 ErrorsFound = true;
    2332             :             }
    2333           0 :             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ZoneTurndownMinAirFracSchExist = true;
    2334             :         }
    2335             : 
    2336             :         // Add reheat coil to component sets array
    2337          48 :         SetUpCompSets(state,
    2338           8 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    2339           8 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    2340           8 :                       Alphas(7),
    2341           8 :                       Alphas(8),
    2342           8 :                       state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum),
    2343           8 :                       state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).ReheatAirOutletNode));
    2344             :         // Add fan to component sets array
    2345          48 :         SetUpCompSets(state,
    2346           8 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).sysType,
    2347           8 :                       state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName,
    2348           8 :                       Alphas(5),
    2349           8 :                       Alphas(6),
    2350           8 :                       state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).InletNodeNum),
    2351           8 :                       state.dataLoopNodes->NodeID(state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).OutletNodeNum));
    2352             : 
    2353             :         // Setup the Average damper Position output variable
    2354          32 :         SetupOutputVariable(state,
    2355             :                             "Zone Air Terminal VAV Damper Position",
    2356             :                             OutputProcessor::Unit::None,
    2357           8 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).DamperPosition,
    2358             :                             OutputProcessor::SOVTimeStepType::System,
    2359             :                             OutputProcessor::SOVStoreType::Average,
    2360          16 :                             state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysNumGSI).SysName);
    2361             :     }
    2362             : 
    2363             :     // common report variable for all single duct air terminals
    2364        3813 :     for (int sdIndex = 1; sdIndex <= state.dataSingleDuct->NumSDAirTerminal; ++sdIndex) {
    2365       13236 :         SetupOutputVariable(state,
    2366             :                             "Zone Air Terminal Outdoor Air Volume Flow Rate",
    2367             :                             OutputProcessor::Unit::m3_s,
    2368        3309 :                             state.dataSingleDuct->sd_airterminal(sdIndex).OutdoorAirFlowRate,
    2369             :                             OutputProcessor::SOVTimeStepType::System,
    2370             :                             OutputProcessor::SOVStoreType::Average,
    2371        6618 :                             state.dataSingleDuct->sd_airterminal(sdIndex).SysName);
    2372             :     }
    2373             : 
    2374             :     // Error check to see if a single duct air terminal is assigned to zone that has zone secondary recirculation
    2375             :     // specified in the Sizing:Zone object
    2376             : 
    2377         504 :     NumZoneSiz = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Sizing:Zone");
    2378         504 :     if (NumZoneSiz > 0) {
    2379        3199 :         for (state.dataSingleDuct->SysIndexGSI = 1; state.dataSingleDuct->SysIndexGSI <= state.dataSingleDuct->NumSDAirTerminal;
    2380        2861 :              ++state.dataSingleDuct->SysIndexGSI) {
    2381       98707 :             for (ZoneSizIndex = 1; ZoneSizIndex <= NumZoneSiz; ++ZoneSizIndex) {
    2382       95850 :                 if (state.dataGlobal->DoZoneSizing) {
    2383      191146 :                     if (state.dataSize->FinalZoneSizing(ZoneSizIndex).ZoneNum ==
    2384       95573 :                         state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysIndexGSI).CtrlZoneNum) {
    2385        2509 :                         if (state.dataSize->FinalZoneSizing(ZoneSizIndex).ZoneSecondaryRecirculation > 0.0) {
    2386          12 :                             ShowWarningError(state,
    2387           8 :                                              std::string{RoutineName} + "A zone secondary recirculation fraction is specified for zone served by ");
    2388          12 :                             ShowContinueError(state,
    2389           8 :                                               "...terminal unit \"" +
    2390          12 :                                                   state.dataSingleDuct->sd_airterminal(state.dataSingleDuct->SysIndexGSI).SysName +
    2391             :                                                   "\" , that indicates a single path system");
    2392           4 :                             ShowContinueError(state, "...The zone secondary recirculation for that zone was set to 0.0");
    2393           4 :                             state.dataSize->FinalZoneSizing(ZoneSizIndex).ZoneSecondaryRecirculation = 0.0;
    2394           4 :                             goto SizLoop_exit;
    2395             :                         }
    2396             :                     }
    2397             :                 }
    2398             :             }
    2399        2857 :         SizLoop_exit:;
    2400             :         }
    2401             :     }
    2402             : 
    2403         504 :     Alphas.deallocate();
    2404         504 :     cAlphaFields.deallocate();
    2405         504 :     cNumericFields.deallocate();
    2406         504 :     Numbers.deallocate();
    2407         504 :     lAlphaBlanks.deallocate();
    2408         504 :     lNumericBlanks.deallocate();
    2409             : 
    2410         504 :     if (ErrorsFound) {
    2411           0 :         ShowFatalError(state, std::string{RoutineName} + "Errors found in input.  Preceding condition(s) cause termination.");
    2412             :     }
    2413         504 : }
    2414             : 
    2415             : // End of Get Input subroutines for the Module
    2416             : //******************************************************************************
    2417             : 
    2418             : // Beginning Initialization Section of the Module
    2419             : //******************************************************************************
    2420             : 
    2421    32682712 : void SingleDuctAirTerminal::InitSys(EnergyPlusData &state, bool const FirstHVACIteration)
    2422             : {
    2423             : 
    2424             :     // SUBROUTINE INFORMATION:
    2425             :     //       AUTHOR         Richard J. Liesen
    2426             :     //       DATE WRITTEN   January 2000
    2427             :     //       MODIFIED       na
    2428             :     //       RE-ENGINEERED  na
    2429             : 
    2430             :     // PURPOSE OF THIS SUBROUTINE:
    2431             :     // This subroutine is for  initializations of the Sys Components.
    2432             : 
    2433             :     // METHODOLOGY EMPLOYED:
    2434             :     // Uses the status flags to trigger events.
    2435             : 
    2436             :     // Using/Aliasing
    2437             : 
    2438             :     using DataZoneEquipment::CheckZoneEquipmentList;
    2439             :     using PlantUtilities::InitComponentNodes;
    2440             :     using PlantUtilities::ScanPlantLoopsForObject;
    2441    32682712 :     auto &GetHeatingCoilCapacity(HeatingCoils::GetCoilCapacity);
    2442             : 
    2443             :     // SUBROUTINE PARAMETER DEFINITIONS:
    2444             :     static constexpr std::string_view RoutineName("InitSys");
    2445             :     static constexpr std::string_view RoutineNameFull("InitHVACSingleDuct");
    2446             : 
    2447             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2448             :     int InletNode;
    2449             :     int OutletNode;
    2450             :     int SysIndex;
    2451             :     // static Array1D_bool MyEnvrnFlag;
    2452             :     // static Array1D_bool MySizeFlag;
    2453             :     // static Array1D_bool GetGasElecHeatCoilCap; // Gets autosized value of coil capacity
    2454             :     Real64 SteamTemp;
    2455             :     Real64 SteamDensity;
    2456             :     Real64 rho;
    2457             :     bool errFlag;
    2458             : 
    2459             :     // static Array1D_bool PlantLoopScanFlag;
    2460             : 
    2461             :     // Do the Begin Simulation initializations
    2462    32682712 :     if (state.dataSingleDuct->InitSysFlag) {
    2463             : 
    2464             :         // MyEnvrnFlag.allocate(NumSDAirTerminal);
    2465             :         // MySizeFlag.allocate(NumSDAirTerminal);
    2466             :         // PlantLoopScanFlag.allocate(NumSDAirTerminal);
    2467             :         // GetGasElecHeatCoilCap.allocate(NumSDAirTerminal);
    2468             :         // MyEnvrnFlag = true;
    2469             :         // MySizeFlag = true;
    2470             :         // PlantLoopScanFlag = true;
    2471             :         // GetGasElecHeatCoilCap = true;
    2472         504 :         state.dataSingleDuct->InitSysFlag = false;
    2473             :     }
    2474             : 
    2475    32682712 :     if (this->PlantLoopScanFlag && allocated(state.dataPlnt->PlantLoop)) {
    2476        4611 :         if ((this->ReheatComp_PlantType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) ||
    2477        1302 :             (this->ReheatComp_PlantType == DataPlant::PlantEquipmentType::CoilSteamAirHeating)) {
    2478             :             // setup plant topology indices for plant fed heating coils
    2479        2015 :             errFlag = false;
    2480        2015 :             ScanPlantLoopsForObject(state, this->ReheatName, this->ReheatComp_PlantType, this->HWplantLoc, errFlag, _, _, _, _, _);
    2481             : 
    2482        2015 :             if (errFlag) {
    2483           0 :                 ShowContinueError(state, "Reference Unit=\"" + this->SysName + "\", type=" + this->sysType);
    2484           0 :                 ShowFatalError(state, "InitSys: Program terminated for previous conditions.");
    2485             :             }
    2486             : 
    2487        2015 :             this->ReheatCoilOutletNode = DataPlant::CompData::getPlantComponent(state, this->HWplantLoc).NodeNumOut;
    2488             : 
    2489        2015 :             this->PlantLoopScanFlag = false;
    2490             :         } else {
    2491        1294 :             this->PlantLoopScanFlag = false;
    2492             :         }
    2493    32679403 :     } else if (this->PlantLoopScanFlag && !state.dataGlobal->AnyPlantInModel) {
    2494           0 :         this->PlantLoopScanFlag = false;
    2495             :     }
    2496             : 
    2497    32682712 :     if (!state.dataSingleDuct->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
    2498         504 :         state.dataSingleDuct->ZoneEquipmentListChecked = true;
    2499             :         // Check to see if there is a Air Distribution Unit on the Zone Equipment List
    2500        3813 :         for (SysIndex = 1; SysIndex <= state.dataSingleDuct->NumSDAirTerminal; ++SysIndex) {
    2501        3309 :             if (state.dataSingleDuct->sd_airterminal(SysIndex).ADUNum == 0) continue;
    2502        9927 :             if (CheckZoneEquipmentList(state,
    2503             :                                        "ZoneHVAC:AirDistributionUnit",
    2504        6618 :                                        state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(SysIndex).ADUNum).Name))
    2505        3309 :                 continue;
    2506           0 :             ShowSevereError(state,
    2507           0 :                             "InitSingleDuctSystems: ADU=[Air Distribution Unit," +
    2508           0 :                                 state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->sd_airterminal(SysIndex).ADUNum).Name +
    2509             :                                 "] is not on any ZoneHVAC:EquipmentList.");
    2510           0 :             ShowContinueError(state,
    2511           0 :                               "...System=[" + state.dataSingleDuct->sd_airterminal(SysIndex).sysType + ',' +
    2512           0 :                                   state.dataSingleDuct->sd_airterminal(SysIndex).SysName + "] will not be simulated.");
    2513             :         }
    2514             :     }
    2515             : 
    2516             :     // get current time step air terminal box turndown minimum flow fraction
    2517    32682712 :     if (this->ZoneTurndownMinAirFracSchExist) {
    2518       18720 :         this->ZoneTurndownMinAirFrac = ScheduleManager::GetCurrentScheduleValue(state, this->ZoneTurndownMinAirFracSchPtr);
    2519             :     } else {
    2520    32663992 :         this->ZoneTurndownMinAirFrac = 1.0;
    2521             :     }
    2522             : 
    2523    32682712 :     if (!state.dataGlobal->SysSizingCalc && this->MySizeFlag) {
    2524             : 
    2525        3304 :         this->SizeSys(state);
    2526             : 
    2527        3304 :         this->MySizeFlag = false;
    2528             :     }
    2529             : 
    2530    32682712 :     if (this->GetGasElecHeatCoilCap) {
    2531        3309 :         if (this->ReheatComp_Num == HeatingCoilType::Electric || this->ReheatComp_Num == HeatingCoilType::Gas) {
    2532         367 :             if (this->ReheatCoilMaxCapacity == AutoSize) {
    2533           0 :                 errFlag = false;
    2534           0 :                 this->ReheatCoilMaxCapacity = GetHeatingCoilCapacity(state, this->ReheatComp, this->ReheatName, errFlag);
    2535           0 :                 if (errFlag) ShowContinueError(state, "Occurs for terminal unit " + this->sysType + " = " + this->SysName);
    2536             :             }
    2537         734 :             if (this->ReheatCoilMaxCapacity != AutoSize) {
    2538         367 :                 this->GetGasElecHeatCoilCap = false;
    2539             :             }
    2540             :         } else {
    2541        2942 :             this->GetGasElecHeatCoilCap = false;
    2542             :         }
    2543             :     }
    2544             : 
    2545             :     // Do the Begin Environment initializations
    2546    32682712 :     if (state.dataGlobal->BeginEnvrnFlag && this->MyEnvrnFlag) {
    2547             : 
    2548             :         // Set the outlet node max mass flow rate to the Max Air Flow specified for the Sys
    2549       21199 :         OutletNode = this->OutletNodeNum;
    2550       21199 :         InletNode = this->InletNodeNum;
    2551       21199 :         state.dataLoopNodes->Node(OutletNode).MassFlowRateMax = this->MaxAirVolFlowRate * state.dataEnvrn->StdRhoAir;
    2552       21199 :         this->AirMassFlowRateMax = this->MaxAirVolFlowRate * state.dataEnvrn->StdRhoAir;
    2553       21199 :         this->HeatAirMassFlowRateMax = this->MaxHeatAirVolFlowRate * state.dataEnvrn->StdRhoAir;
    2554       21199 :         state.dataLoopNodes->Node(InletNode).MassFlowRateMax = this->MaxAirVolFlowRate * state.dataEnvrn->StdRhoAir;
    2555       21199 :         this->MassFlowDiff = 1.0e-10 * this->AirMassFlowRateMax;
    2556             : 
    2557       21199 :         if (this->HWplantLoc.loopNum > 0 && this->ReheatComp_Num != HeatingCoilType::SteamAirHeating) { // protect early calls before plant is setup
    2558       27066 :             rho = GetDensityGlycol(state,
    2559       13533 :                                    state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).FluidName,
    2560             :                                    DataGlobalConstants::HWInitConvTemp,
    2561       13533 :                                    state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).FluidIndex,
    2562             :                                    RoutineName);
    2563             :         } else {
    2564        7666 :             rho = 1000.0;
    2565             :         }
    2566             : 
    2567       21199 :         this->MaxReheatWaterFlow = rho * this->MaxReheatWaterVolFlow;
    2568       21199 :         this->MinReheatWaterFlow = rho * this->MinReheatWaterVolFlow;
    2569             : 
    2570       21199 :         this->AirMassFlowDuringReheatMax = this->MaxAirVolFlowRateDuringReheat * state.dataEnvrn->StdRhoAir;
    2571             : 
    2572             :         // set the upstream leakage flowrate - remove from here - done in ZoneAirLoopEquipmentManager::SimZoneAirLoopEquipment
    2573             : 
    2574       21199 :         if (this->ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
    2575          48 :             SteamTemp = 100.0;
    2576          48 :             SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, SteamTemp, 1.0, this->FluidIndex, RoutineNameFull);
    2577          48 :             this->MaxReheatSteamFlow = SteamDensity * this->MaxReheatSteamVolFlow;
    2578          48 :             this->MinReheatSteamFlow = SteamDensity * this->MinReheatSteamVolFlow;
    2579             :         }
    2580             : 
    2581             :         // get current environment air terminal box turndown minimum flow fraction
    2582       21199 :         Real64 CurrentEnvZoneTurndownMinAirFrac = 1.0;
    2583       21199 :         if (this->ZoneTurndownMinAirFracSchExist) {
    2584          80 :             CurrentEnvZoneTurndownMinAirFrac = ScheduleManager::GetScheduleMinValue(state, this->ZoneTurndownMinAirFracSchPtr);
    2585             :         }
    2586       28325 :         if ((this->SysType_Num == SysType::SingleDuctVAVReheat || this->SysType_Num == SysType::SingleDuctCBVAVReheat) ||
    2587        7126 :             (this->SysType_Num == SysType::SingleDuctCBVAVNoReheat)) {
    2588             :             // need the lowest schedule value
    2589       14093 :             if (this->ZoneMinAirFracMethod == MinFlowFraction::Scheduled) {
    2590         218 :                 this->ZoneMinAirFracDes = GetScheduleMinValue(state, this->ZoneMinAirFracSchPtr);
    2591             :             }
    2592       14093 :             state.dataLoopNodes->Node(OutletNode).MassFlowRateMin =
    2593       14093 :                 state.dataLoopNodes->Node(OutletNode).MassFlowRateMax * this->ZoneMinAirFracDes * CurrentEnvZoneTurndownMinAirFrac;
    2594       14093 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMin =
    2595       14093 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMax * this->ZoneMinAirFracDes * CurrentEnvZoneTurndownMinAirFrac;
    2596             :         } else {
    2597        7106 :             state.dataLoopNodes->Node(OutletNode).MassFlowRateMin = 0.0;
    2598        7106 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMin = 0.0;
    2599             :         }
    2600       21199 :         if ((this->ReheatControlNode > 0) && !this->PlantLoopScanFlag) {
    2601       13581 :             if (this->ReheatComp_Num == HeatingCoilType::SteamAirHeating) {
    2602          48 :                 InitComponentNodes(state, this->MinReheatSteamFlow, this->MaxReheatSteamFlow, this->ReheatControlNode, this->ReheatCoilOutletNode);
    2603             :             } else {
    2604       13533 :                 InitComponentNodes(state, this->MinReheatWaterFlow, this->MaxReheatWaterFlow, this->ReheatControlNode, this->ReheatCoilOutletNode);
    2605             :             }
    2606             :         }
    2607             :         // Find air loop associated with terminal unit
    2608       21199 :         if ((this->CtrlZoneNum > 0) && (this->CtrlZoneInNodeIndex > 0)) {
    2609       21199 :             this->AirLoopNum = state.dataZoneEquip->ZoneEquipConfig(this->CtrlZoneNum).InletNodeAirLoopNum(this->CtrlZoneInNodeIndex);
    2610       21199 :             state.dataDefineEquipment->AirDistUnit(this->ADUNum).AirLoopNum = this->AirLoopNum;
    2611             :         }
    2612             : 
    2613       21199 :         this->MyEnvrnFlag = false;
    2614             :     }
    2615             : 
    2616    32682712 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    2617    32532951 :         this->MyEnvrnFlag = true;
    2618             :     }
    2619             : 
    2620             :     // Initialize the Inlet Nodes of the air side of air terminal
    2621    32682712 :     InletNode = this->InletNodeNum;
    2622    32682712 :     OutletNode = this->OutletNodeNum;
    2623             : 
    2624    32682712 :     Real64 mDotFromOARequirement(0.0);
    2625             : 
    2626    32682712 :     if (this->SysType_Num == SysType::SingleDuctConstVolNoReheat) {
    2627     7471141 :         if (!this->NoOAFlowInputFromUser) {
    2628        6382 :             mDotFromOARequirement = this->AirMassFlowRateMax;
    2629        6382 :             int airLoopNum(0);
    2630        6382 :             Real64 airLoopOAFrac(0.0);
    2631        6382 :             airLoopNum = this->AirLoopNum;
    2632        6382 :             if (airLoopNum > 0) {
    2633        6373 :                 airLoopOAFrac = state.dataAirLoop->AirLoopFlow(airLoopNum).OAFrac;
    2634        6373 :                 bool UseOccSchFlag = false;
    2635        6373 :                 if (this->OAPerPersonMode == DataZoneEquipment::PerPersonVentRateMode::DCVByCurrentLevel) UseOccSchFlag = true;
    2636        6373 :                 if (airLoopOAFrac > 0.0) {
    2637             :                     Real64 vDotOAReq =
    2638        6357 :                         DataSizing::calcDesignSpecificationOutdoorAir(state, this->OARequirementsPtr, this->CtrlZoneNum, UseOccSchFlag, true);
    2639        6357 :                     mDotFromOARequirement = vDotOAReq * state.dataEnvrn->StdRhoAir / airLoopOAFrac;
    2640        6357 :                     mDotFromOARequirement = min(mDotFromOARequirement, this->AirMassFlowRateMax);
    2641             :                 } else {
    2642          16 :                     mDotFromOARequirement = this->AirMassFlowRateMax;
    2643             :                 }
    2644             :             }
    2645             :         }
    2646             :     }
    2647             : 
    2648    32682712 :     if (this->ZoneMinAirFracMethod == MinFlowFraction::Scheduled) {
    2649      292010 :         this->ZoneMinAirFracDes = GetCurrentScheduleValue(state, this->ZoneMinAirFracSchPtr);
    2650             :         // now reset inlet node min avail
    2651      292010 :         state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = this->AirMassFlowRateMax * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac;
    2652             :     }
    2653             : 
    2654    32682712 :     if (FirstHVACIteration) {
    2655             :         // The first time through set the mass flow rate to the Max
    2656    12654999 :         if ((state.dataLoopNodes->Node(InletNode).MassFlowRate > 0.0) && (GetCurrentScheduleValue(state, this->SchedPtr) > 0.0)) {
    2657    10088615 :             if (!(state.afn->distribution_simulated && state.afn->AirflowNetworkFanActivated)) {
    2658    10088599 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = this->AirMassFlowRateMax;
    2659             :             }
    2660             :         } else {
    2661     2566384 :             state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
    2662             :         }
    2663    12654999 :         if ((state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail > 0.0) && (GetCurrentScheduleValue(state, this->SchedPtr) > 0.0)) {
    2664    10088922 :             if (!(state.afn->distribution_simulated && state.afn->AirflowNetworkFanActivated)) {
    2665    10088906 :                 if (this->SysType_Num == SysType::SingleDuctConstVolNoReheat) {
    2666     2221516 :                     if (this->NoOAFlowInputFromUser) {
    2667     2218333 :                         state.dataLoopNodes->Node(InletNode).MassFlowRate = this->AirMassFlowRateMax;
    2668     2218333 :                         state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = this->AirMassFlowRateMax;
    2669             :                     } else {
    2670        3183 :                         state.dataLoopNodes->Node(InletNode).MassFlowRate = mDotFromOARequirement;
    2671        3183 :                         state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = mDotFromOARequirement;
    2672             :                     }
    2673     2221516 :                     if (this->EMSOverrideAirFlow) {
    2674           0 :                         state.dataLoopNodes->Node(InletNode).MassFlowRate = this->EMSMassFlowRateValue;
    2675           0 :                         state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = this->EMSMassFlowRateValue;
    2676             :                     }
    2677             :                 } else {
    2678     7867390 :                     state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = this->AirMassFlowRateMax;
    2679             :                 }
    2680             :             }
    2681             :         } else {
    2682     2566077 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = 0.0;
    2683             :         }
    2684             : 
    2685    12654999 :         if ((state.dataLoopNodes->Node(InletNode).MassFlowRate > 0.0) && (GetCurrentScheduleValue(state, this->SchedPtr) > 0.0)) {
    2686    10088625 :             if (!(state.afn->distribution_simulated && state.afn->AirflowNetworkFanActivated)) {
    2687    10088609 :                 state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail =
    2688    10088609 :                     this->AirMassFlowRateMax * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac;
    2689             :             }
    2690             :         } else {
    2691     2566374 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = 0.0;
    2692             :         }
    2693             :         // reset the mass flow rate histories
    2694    12654999 :         this->MassFlow1 = 0.0;
    2695    12654999 :         this->MassFlow2 = 0.0;
    2696    12654999 :         this->MassFlow3 = 0.0;
    2697    12654999 :         this->MassFlow3 = 0.0;
    2698             : 
    2699             :     } else {
    2700    20027713 :         if (this->SysType_Num == SysType::SingleDuctConstVolNoReheat) {
    2701     4662621 :             if (!this->EMSOverrideAirFlow) {
    2702     4662621 :                 if ((state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail > 0.0) && (GetCurrentScheduleValue(state, this->SchedPtr) > 0.0)) {
    2703     4017174 :                     if (this->NoOAFlowInputFromUser) {
    2704     4013996 :                         if (state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail < state.dataLoopNodes->Node(InletNode).MassFlowRateMax) {
    2705     1350735 :                             state.dataLoopNodes->Node(InletNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail;
    2706     2663261 :                         } else if (state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail > state.dataLoopNodes->Node(InletNode).MassFlowRateMin) {
    2707       50361 :                             state.dataLoopNodes->Node(InletNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail;
    2708             :                         } else {
    2709     2612900 :                             state.dataLoopNodes->Node(InletNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail;
    2710             :                         }
    2711             :                     } else {
    2712        3178 :                         state.dataLoopNodes->Node(InletNode).MassFlowRate = mDotFromOARequirement;
    2713             :                         // but also apply constraints
    2714        3178 :                         state.dataLoopNodes->Node(InletNode).MassFlowRate =
    2715        3178 :                             min(state.dataLoopNodes->Node(InletNode).MassFlowRate, state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail);
    2716        3178 :                         state.dataLoopNodes->Node(InletNode).MassFlowRate =
    2717        3178 :                             min(state.dataLoopNodes->Node(InletNode).MassFlowRate, state.dataLoopNodes->Node(InletNode).MassFlowRateMax);
    2718        3178 :                         state.dataLoopNodes->Node(InletNode).MassFlowRate =
    2719        3178 :                             max(state.dataLoopNodes->Node(InletNode).MassFlowRate, state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail);
    2720        3178 :                         state.dataLoopNodes->Node(InletNode).MassFlowRate =
    2721        3178 :                             max(state.dataLoopNodes->Node(InletNode).MassFlowRate, state.dataLoopNodes->Node(InletNode).MassFlowRateMin);
    2722             :                     }
    2723             :                 } else {
    2724      645447 :                     state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
    2725      645447 :                     state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = 0.0;
    2726      645447 :                     state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = 0.0;
    2727             :                 }
    2728             :             } else { // EMS override on
    2729           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate = this->EMSMassFlowRateValue;
    2730             :                 // but also apply constraints
    2731           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate =
    2732           0 :                     min(state.dataLoopNodes->Node(InletNode).MassFlowRate, state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail);
    2733           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate =
    2734           0 :                     min(state.dataLoopNodes->Node(InletNode).MassFlowRate, state.dataLoopNodes->Node(InletNode).MassFlowRateMax);
    2735           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate =
    2736           0 :                     max(state.dataLoopNodes->Node(InletNode).MassFlowRate, state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail);
    2737           0 :                 state.dataLoopNodes->Node(InletNode).MassFlowRate =
    2738           0 :                     max(state.dataLoopNodes->Node(InletNode).MassFlowRate, state.dataLoopNodes->Node(InletNode).MassFlowRateMin);
    2739             :             }
    2740             :         }
    2741             :     }
    2742             : 
    2743             :     // Do a check and make sure that the max and min available(control) flow is
    2744             :     //  between the physical max and min while operating.
    2745    32682712 :     this->sd_airterminalInlet.AirMassFlowRateMaxAvail = min(this->AirMassFlowRateMax, state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail);
    2746    32682712 :     this->sd_airterminalInlet.AirMassFlowRateMinAvail =
    2747    32682712 :         min(max(state.dataLoopNodes->Node(OutletNode).MassFlowRateMin, state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail),
    2748             :             this->sd_airterminalInlet.AirMassFlowRateMaxAvail);
    2749             : 
    2750             :     // Do the following initializations (every time step): This should be the info from
    2751             :     // the previous components outlets or the node data in this section.
    2752             :     // Load the node data in this section for the component simulation
    2753    32682712 :     this->sd_airterminalInlet.AirMassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRate;
    2754    32682712 :     this->sd_airterminalInlet.AirTemp = state.dataLoopNodes->Node(InletNode).Temp;
    2755    32682712 :     this->sd_airterminalInlet.AirHumRat = state.dataLoopNodes->Node(InletNode).HumRat;
    2756    32682712 :     this->sd_airterminalInlet.AirEnthalpy = state.dataLoopNodes->Node(InletNode).Enthalpy;
    2757             : 
    2758             :     // update to the current minimum air flow fraction
    2759    32682712 :     this->ZoneMinAirFrac = this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac;
    2760    32682712 : }
    2761             : 
    2762        3304 : void SingleDuctAirTerminal::SizeSys(EnergyPlusData &state)
    2763             : {
    2764             : 
    2765             :     // SUBROUTINE INFORMATION:
    2766             :     //       AUTHOR         Fred Buhl
    2767             :     //       DATE WRITTEN   September 2001
    2768             :     //       MODIFIED       August 2013 Daeho Kang, add component sizing table entries
    2769             : 
    2770             :     // PURPOSE OF THIS SUBROUTINE:
    2771             :     // This subroutine is for sizing Sys Components for which flow rates have not been
    2772             :     // specified in the input.
    2773             : 
    2774             :     // METHODOLOGY EMPLOYED:
    2775             :     // Obtains flow rates from the zone or system sizing arrays.
    2776             : 
    2777             :     // Using/Aliasing
    2778             :     using FluidProperties::GetDensityGlycol;
    2779             :     using FluidProperties::GetSpecificHeatGlycol;
    2780             :     using General::SafeDivide;
    2781             :     using PlantUtilities::MyPlantSizingIndex;
    2782             :     using SteamCoils::GetCoilSteamInletNode;
    2783             :     using SteamCoils::GetCoilSteamOutletNode;
    2784             :     using WaterCoils::GetCoilWaterInletNode;
    2785             :     using WaterCoils::GetCoilWaterOutletNode;
    2786             :     using WaterCoils::SetCoilDesFlow;
    2787             : 
    2788             :     // SUBROUTINE PARAMETER DEFINITIONS:
    2789             :     static constexpr std::string_view RoutineName("SizeSys");
    2790             :     static constexpr std::string_view RoutineNameFull("SizeHVACSingleDuct");
    2791             : 
    2792             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2793             :     int PltSizHeatNum; // index of plant sizing object for 1st heating loop
    2794             :     Real64 DesMassFlow;
    2795             :     Real64 TempSteamIn;
    2796             :     Real64 EnthSteamOutWet;
    2797             :     Real64 EnthSteamInDry;
    2798             :     Real64 LatentHeatSteam;
    2799             :     Real64 SteamDensity;
    2800             : 
    2801             :     bool ErrorsFound;
    2802             :     bool PlantSizingErrorsFound;
    2803             :     Real64 rho; // local fluid density
    2804             :     Real64 Cp;  // local fluid specific heat
    2805             :     bool IsAutoSize;
    2806             :     bool IsMaxFlowAutoSize;                   // Indicate if the maximum terminal flow is autosize
    2807             :     int AirLoopNum;                           // Air loop number
    2808             :     int SysSizNum;                            // System sizing number
    2809        3304 :     Real64 MinMinFlowRatio(0.0);              // the minimum minimum flow ratio
    2810             :     Real64 MaxAirVolFlowRateDes;              // Autosized maximum air flow rate for reporting
    2811             :     Real64 MaxAirVolFlowRateUser;             // Hardsized maximum air flow rate for reporting
    2812             :     Real64 MaxHeatAirVolFlowRateDes;          // Autosized maximum heating air flow rate for reporting
    2813             :     Real64 MaxHeatAirVolFlowRateUser;         // Hardsized maximum heating air flow rate for reporting
    2814             :     Real64 MinAirFlowFracDes;                 // Autosized minimum cooling air flow fraction for reporting
    2815             :     Real64 MinAirFlowFracUser;                // User input minimum cooling air flow fraction for reporting
    2816             :     Real64 FixedMinAirDes;                    // Autosized minimum cooling air flow rate for reporting [m3/s]
    2817             :     Real64 FixedMinAirUser;                   // User input minimum cooling air flow rate for reporting [m3/s]
    2818             :     Real64 MaxAirVolFlowRateDuringReheatDes;  // Autosized maximum air flow durign reheat for reporting
    2819             :     Real64 MaxAirVolFlowRateDuringReheatUser; // Hardsized maximum air flow durign reheat for reporting
    2820             :     Real64 MaxAirVolFractionDuringReheatDes;  // Autosized maximum air fraction durign reheat for reporting
    2821             :     Real64 MaxAirVolFractionDuringReheatUser; // Hardsized maximum air flow durign reheat for reporting
    2822             :     Real64 MaxReheatWaterVolFlowDes;          // Autosized reheat water flow or reporting
    2823             :     Real64 MaxReheatWaterVolFlowUser;         // Hardsized reheat water flow for reporting
    2824             :     Real64 MaxReheatSteamVolFlowDes;          // Autosized reheat steam flow for reporting
    2825             :     Real64 MaxReheatSteamVolFlowUser;         // Hardsized reheat steam flow for reporting
    2826             : 
    2827        3304 :     PltSizHeatNum = 0;
    2828        3304 :     DesMassFlow = 0.0;
    2829        3304 :     ErrorsFound = false;
    2830        3304 :     IsAutoSize = false;
    2831        3304 :     IsMaxFlowAutoSize = false;
    2832        3304 :     MaxAirVolFlowRateDes = 0.0;
    2833        3304 :     MaxAirVolFlowRateUser = 0.0;
    2834        3304 :     MaxHeatAirVolFlowRateDes = 0.0;
    2835        3304 :     MaxHeatAirVolFlowRateUser = 0.0;
    2836        3304 :     MinAirFlowFracDes = 0.0;
    2837        3304 :     MinAirFlowFracUser = 0.0;
    2838        3304 :     FixedMinAirDes = 0.0;
    2839        3304 :     FixedMinAirUser = 0.0;
    2840        3304 :     MaxAirVolFlowRateDuringReheatDes = 0.0;
    2841        3304 :     MaxAirVolFlowRateDuringReheatUser = 0.0;
    2842        3304 :     MaxAirVolFractionDuringReheatDes = 0.0;
    2843        3304 :     MaxAirVolFractionDuringReheatUser = 0.0;
    2844        3304 :     MaxReheatWaterVolFlowDes = 0.0;
    2845        3304 :     MaxReheatWaterVolFlowUser = 0.0;
    2846        3304 :     MaxReheatSteamVolFlowDes = 0.0;
    2847        3304 :     MaxReheatSteamVolFlowUser = 0.0;
    2848        3304 :     MinMinFlowRatio = 0.0;
    2849        3304 :     AirLoopNum = 0;
    2850        3304 :     SysSizNum = 0;
    2851             : 
    2852        3304 :     int ZoneNum = this->CtrlZoneNum;
    2853             : 
    2854        3304 :     auto &TermUnitSizing(state.dataSize->TermUnitSizing);
    2855             : 
    2856        3304 :     if (this->MaxAirVolFlowRate == AutoSize) {
    2857        2738 :         IsAutoSize = true;
    2858             :     }
    2859             : 
    2860        3304 :     if (state.dataSize->CurTermUnitSizingNum > 0) {
    2861        3304 :         if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
    2862         507 :             if (this->MaxAirVolFlowRate > 0.0) {
    2863        1014 :                 BaseSizer::reportSizerOutput(
    2864         507 :                     state, this->sysType, this->SysName, "User-Specified Maximum Air Flow Rate [m3/s]", this->MaxAirVolFlowRate);
    2865             :             }
    2866             :         } else { // Autosize or hard-size with sizing run
    2867             : 
    2868        2797 :             CheckZoneSizing(state, this->sysType, this->SysName);
    2869             : 
    2870        2797 :             MaxAirVolFlowRateDes = max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlow,
    2871        2797 :                                        state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow);
    2872             : 
    2873        2797 :             if (MaxAirVolFlowRateDes < SmallAirVolFlow) {
    2874           0 :                 MaxAirVolFlowRateDes = 0.0;
    2875             :             }
    2876        2797 :             if (IsAutoSize) {
    2877        2738 :                 this->MaxAirVolFlowRate = MaxAirVolFlowRateDes;
    2878        2738 :                 IsMaxFlowAutoSize = true;
    2879        2738 :                 BaseSizer::reportSizerOutput(state, this->sysType, this->SysName, "Design Size Maximum Air Flow Rate [m3/s]", MaxAirVolFlowRateDes);
    2880             :             } else { // Hard-size with sizing data
    2881          59 :                 if (this->MaxAirVolFlowRate > 0.0 && MaxAirVolFlowRateDes > 0.0) {
    2882          59 :                     MaxAirVolFlowRateUser = this->MaxAirVolFlowRate;
    2883         118 :                     BaseSizer::reportSizerOutput(state,
    2884             :                                                  this->sysType,
    2885             :                                                  this->SysName,
    2886             :                                                  "Design Size Maximum Air Flow Rate [m3/s]",
    2887             :                                                  MaxAirVolFlowRateDes,
    2888             :                                                  "User-Specified Maximum Air Flow Rate [m3/s]",
    2889          59 :                                                  MaxAirVolFlowRateUser);
    2890          59 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    2891           0 :                         if ((std::abs(MaxAirVolFlowRateDes - MaxAirVolFlowRateUser) / MaxAirVolFlowRateUser) >
    2892           0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    2893           0 :                             ShowMessage(state,
    2894           0 :                                         "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" + this->SysName +
    2895             :                                             "\".");
    2896           0 :                             ShowContinueError(state, format("User-Specified Maximum Air Flow Rate of {:.5R} [m3/s]", MaxAirVolFlowRateUser));
    2897           0 :                             ShowContinueError(state, format("differs from Design Size Maximum Air Flow Rate of {:.5R} [m3/s]", MaxAirVolFlowRateDes));
    2898           0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    2899           0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    2900             :                         }
    2901             :                     }
    2902             :                 }
    2903             :             }
    2904             :         }
    2905             :     }
    2906             : 
    2907        3304 :     IsAutoSize = false;
    2908        3304 :     if (this->MaxHeatAirVolFlowRate == AutoSize) {
    2909           8 :         IsAutoSize = true;
    2910             :     }
    2911        3304 :     if (state.dataSize->CurTermUnitSizingNum > 0) {
    2912        3304 :         if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation should continue
    2913         507 :             state.dataSingleDuct->UserInputMaxHeatAirVolFlowRateSS = this->MaxHeatAirVolFlowRate;
    2914         507 :             if (this->MaxHeatAirVolFlowRate > 0.0) {
    2915           0 :                 BaseSizer::reportSizerOutput(
    2916           0 :                     state, this->sysType, this->SysName, "User-Specified Maximum Heating Air Flow Rate [m3/s]", this->MaxHeatAirVolFlowRate);
    2917             :             }
    2918             :         } else {
    2919        2797 :             CheckZoneSizing(state, this->sysType, this->SysName);
    2920        2797 :             MaxHeatAirVolFlowRateDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow;
    2921        2797 :             if (MaxHeatAirVolFlowRateDes < SmallAirVolFlow) {
    2922           9 :                 MaxHeatAirVolFlowRateDes = 0.0;
    2923             :             }
    2924        2797 :             if (IsAutoSize) {
    2925           8 :                 this->MaxHeatAirVolFlowRate = MaxHeatAirVolFlowRateDes;
    2926           8 :                 state.dataSingleDuct->UserInputMaxHeatAirVolFlowRateSS = 0.0;
    2927          16 :                 BaseSizer::reportSizerOutput(
    2928           8 :                     state, this->sysType, this->SysName, "Design Size Maximum Heating Air Flow Rate [m3/s]", MaxHeatAirVolFlowRateDes);
    2929             :             } else { // Hard-size with sizing data
    2930        2789 :                 if (this->MaxHeatAirVolFlowRate > 0.0 && MaxHeatAirVolFlowRateDes > 0.0) {
    2931           0 :                     MaxHeatAirVolFlowRateUser = this->MaxHeatAirVolFlowRate;
    2932           0 :                     state.dataSingleDuct->UserInputMaxHeatAirVolFlowRateSS = this->MaxHeatAirVolFlowRate;
    2933           0 :                     BaseSizer::reportSizerOutput(state,
    2934             :                                                  this->sysType,
    2935             :                                                  this->SysName,
    2936             :                                                  "Design Size Maximum Heating Air Flow Rate [m3/s]",
    2937             :                                                  MaxHeatAirVolFlowRateDes,
    2938             :                                                  "User-Specified Maximum Heating Air Flow Rate [m3/s]",
    2939           0 :                                                  MaxHeatAirVolFlowRateUser);
    2940           0 :                     if (state.dataGlobal->DisplayExtraWarnings) {
    2941           0 :                         if ((std::abs(MaxHeatAirVolFlowRateDes - MaxHeatAirVolFlowRateUser) / MaxHeatAirVolFlowRateUser) >
    2942           0 :                             state.dataSize->AutoVsHardSizingThreshold) {
    2943           0 :                             ShowMessage(state,
    2944           0 :                                         "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" + this->SysName +
    2945             :                                             "\".");
    2946           0 :                             ShowContinueError(state,
    2947           0 :                                               format("User-Specified Maximum Heating Air Flow Rate of {:.5R} [m3/s]", MaxHeatAirVolFlowRateUser));
    2948           0 :                             ShowContinueError(
    2949           0 :                                 state, format("differs from Design Size Maximum Heating Air Flow Rate of {:.5R} [m3/s]", MaxHeatAirVolFlowRateDes));
    2950           0 :                             ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    2951           0 :                             ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    2952             :                         }
    2953             :                     }
    2954             :                 }
    2955             :             }
    2956             :         }
    2957             :     }
    2958             : 
    2959             :     // get design day terminal unit turndown minimum flow fraction
    2960        3304 :     if (this->ZoneTurndownMinAirFracSchExist) {
    2961           5 :         this->ZoneTurndownMinAirFrac = ScheduleManager::GetCurrentScheduleValue(state, this->ZoneTurndownMinAirFracSchPtr);
    2962             :     } else {
    2963        3299 :         this->ZoneTurndownMinAirFrac = 1.0;
    2964             :     }
    2965             : 
    2966             :     // if a sizing run has been done, check if system sizing has been done for this system
    2967        3304 :     bool SizingDesRunThisAirSys = false;
    2968        3304 :     if (state.dataSize->SysSizingRunDone) {
    2969        2772 :         AirLoopNum = state.dataZoneEquip->ZoneEquipConfig(this->CtrlZoneNum).InletNodeAirLoopNum(this->CtrlZoneInNodeIndex);
    2970        2772 :         if (AirLoopNum > 0) {
    2971        2772 :             CheckThisAirSystemForSizing(state, AirLoopNum, SizingDesRunThisAirSys);
    2972             :         }
    2973             : 
    2974             :         // get system sizing id if a sizing run has been done for this system
    2975        2772 :         if (SizingDesRunThisAirSys) {
    2976        5536 :             SysSizNum = UtilityRoutines::FindItemInList(
    2977        5536 :                 state.dataSize->FinalSysSizing(AirLoopNum).AirPriLoopName, state.dataSize->SysSizInput, &SystemSizingInputData::AirPriLoopName);
    2978        2768 :             if (SysSizNum == 0) SysSizNum = 1; // use first when none applicable
    2979             :         }
    2980             :     }
    2981             : 
    2982        3304 :     IsAutoSize = false;
    2983        3304 :     if (this->ZoneMinAirFracDes == AutoSize) {
    2984          45 :         IsAutoSize = true;
    2985             :     }
    2986        3304 :     if (this->ZoneMinAirFracMethod == MinFlowFraction::Constant) {
    2987        2170 :         if (state.dataSize->ZoneSizingRunDone) {
    2988        2123 :             if (state.dataSize->CurTermUnitSizingNum > 0) {
    2989             :                 // use the combined defaults or other user inputs stored in DesCoolVolFlowMin
    2990        2123 :                 if (this->MaxAirVolFlowRate > 0.0) {
    2991        2123 :                     MinAirFlowFracDes = min(1.0,
    2992        2123 :                                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlowMin /
    2993        2123 :                                                 this->MaxAirVolFlowRate);
    2994             :                 } else {
    2995           0 :                     MinAirFlowFracDes = 0.0;
    2996             :                 }
    2997             :             }
    2998             :         } else {
    2999             :             // if no zone sizing values available; use max of min frac = 0.2 and 0.000762 [m3/s-m2]
    3000          47 :             if (this->MaxAirVolFlowRate > 0.0) {
    3001         141 :                 MinMinFlowRatio = (0.000762 * state.dataHeatBal->Zone(ZoneNum).FloorArea * state.dataHeatBal->Zone(ZoneNum).Multiplier *
    3002          47 :                                    state.dataHeatBal->Zone(ZoneNum).ListMultiplier) /
    3003          47 :                                   this->MaxAirVolFlowRate;
    3004          47 :                 MinAirFlowFracDes = max(0.2, MinMinFlowRatio);
    3005             :             } else {
    3006           0 :                 MinAirFlowFracDes = 0.0;
    3007             :             }
    3008             :         }
    3009        2170 :         if (SizingDesRunThisAirSys) {
    3010        2123 :             if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
    3011           4 :                 if (this->MaxAirVolFlowRate > 0.0) {
    3012           8 :                     MinAirFlowFracDes = 1.5 *
    3013           4 :                                         max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).VozClgByZone,
    3014           8 :                                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).VozHtgByZone) /
    3015           4 :                                         this->MaxAirVolFlowRate;
    3016             : 
    3017             :                     // adjust maximum flow rate
    3018           4 :                     if (MinAirFlowFracDes > 1.0 && IsMaxFlowAutoSize) {
    3019           0 :                         this->MaxAirVolFlowRate *= MinAirFlowFracDes;
    3020           0 :                         MinAirFlowFracDes = 1.0;
    3021           0 :                         ShowWarningError(state,
    3022           0 :                                          "SingleDuctSystem:SizeSys: Autosized maximum air flow rate for " + this->SysName +
    3023             :                                              " was increased to meet the zone primary air flow determined according to the ASHRAE Standard 62.1 "
    3024             :                                              "Simplified Procedure.");
    3025           4 :                     } else if (MinAirFlowFracDes > 1.0) {
    3026           0 :                         ShowWarningError(state, "SingleDuctSystem:SizeSys: Maximum air flow rate for " + this->SysName + " is potentially too low.");
    3027           0 :                         ShowContinueError(
    3028             :                             state,
    3029             :                             "The flow is lower than the minimum flow rate calculated following the ASHRAE Standard 62.1 Simplified Procedure:");
    3030           0 :                         ShowContinueError(state, format(" User-specified maximum air flow rate: {:.3R} m3/s.", this->MaxAirVolFlowRate));
    3031           0 :                         ShowContinueError(state,
    3032           0 :                                           format(" Calculated minimum air flow rate: {:.3R} m3/s.", this->MaxAirVolFlowRate * MinAirFlowFracDes));
    3033           0 :                         MinAirFlowFracDes = 1.0;
    3034             :                     }
    3035             :                 }
    3036             :             }
    3037             :         }
    3038        2170 :         if (IsAutoSize) {
    3039             :             // report out autosized result and save value in Sys array
    3040         129 :             BaseSizer::reportSizerOutput(state,
    3041             :                                          this->sysType,
    3042             :                                          this->SysName,
    3043             :                                          "Design Size Constant Minimum Air Flow Fraction",
    3044          86 :                                          MinAirFlowFracDes * this->ZoneTurndownMinAirFrac);
    3045          43 :             if (SizingDesRunThisAirSys) {
    3046          43 :                 if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::SP) {
    3047           4 :                     state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).VpzMinByZoneSPSized = true;
    3048             :                 }
    3049             :             }
    3050          43 :             this->ZoneMinAirFracDes = MinAirFlowFracDes;
    3051             :         } else {
    3052             :             // report out hard (user set) value and issue warning if appropriate
    3053        2127 :             MinAirFlowFracUser = this->ZoneMinAirFracDes;
    3054        6381 :             BaseSizer::reportSizerOutput(state,
    3055             :                                          this->sysType,
    3056             :                                          this->SysName,
    3057             :                                          "Design Size Constant Minimum Air Flow Fraction",
    3058        2127 :                                          MinAirFlowFracDes * this->ZoneTurndownMinAirFrac,
    3059             :                                          "User-Specified Constant Minimum Air Flow Fraction",
    3060        6381 :                                          MinAirFlowFracUser * this->ZoneTurndownMinAirFrac);
    3061        2127 :             if (state.dataGlobal->DisplayExtraWarnings) {
    3062          55 :                 if ((std::abs(MinAirFlowFracDes - MinAirFlowFracUser) / MinAirFlowFracUser) > state.dataSize->AutoVsHardSizingThreshold) {
    3063         153 :                     ShowMessage(state,
    3064         102 :                                 "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" + this->SysName + "\".");
    3065          51 :                     ShowContinueError(state, format("User-Specified Minimum Cooling Air Flow Fraction of {:.5R} [m3/s]", MinAirFlowFracUser));
    3066         153 :                     ShowContinueError(state,
    3067         102 :                                       format("differs from Design Size Minimum Cooling Air Flow Fraction of {:.5R} [m3/s]", MinAirFlowFracDes));
    3068          51 :                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3069          51 :                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3070             :                 }
    3071             :             }
    3072             :         }
    3073             :         // report out the min air flow rate set by min air flow frac
    3074        6510 :         BaseSizer::reportSizerOutput(state,
    3075             :                                      this->sysType,
    3076             :                                      this->SysName,
    3077             :                                      "Design Size Minimum Air Flow Rate [m3/s]",
    3078        4340 :                                      this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac);
    3079             :     } else {
    3080        1134 :         if (IsAutoSize) {
    3081           2 :             this->ZoneMinAirFracDes = 0.0;
    3082             :         }
    3083             :     }
    3084             : 
    3085        3304 :     IsAutoSize = false;
    3086        3304 :     if (this->ZoneFixedMinAir == AutoSize) {
    3087        2124 :         IsAutoSize = true;
    3088             :     }
    3089        3304 :     if (this->ZoneMinAirFracMethod == MinFlowFraction::Fixed) {
    3090           3 :         if (state.dataSize->ZoneSizingRunDone) {
    3091           2 :             if (state.dataSize->CurTermUnitSizingNum > 0) {
    3092             :                 // use the combined defaults or other user inputs stored in DesCoolVolFlowMin
    3093           2 :                 if (this->MaxAirVolFlowRate > 0.0) {
    3094           2 :                     FixedMinAirDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlowMin;
    3095             :                 } else {
    3096           0 :                     MinAirFlowFracDes = 0.0;
    3097             :                 }
    3098             :             }
    3099             :         } else {
    3100             :             // if no zone sizing values available; use max of min frac = 0.2 and 0.000762 [m3/s-m2]
    3101           1 :             if (this->MaxAirVolFlowRate > 0.0) {
    3102           1 :                 FixedMinAirDes = max(0.2 * this->MaxAirVolFlowRate,
    3103           1 :                                      0.000762 * state.dataHeatBal->Zone(ZoneNum).FloorArea * state.dataHeatBal->Zone(ZoneNum).Multiplier *
    3104           1 :                                          state.dataHeatBal->Zone(ZoneNum).ListMultiplier);
    3105             :             } else {
    3106           0 :                 MinAirFlowFracDes = 0.0;
    3107             :             }
    3108             :         }
    3109           3 :         if (SizingDesRunThisAirSys) {
    3110           2 :             if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::SP) { // 62.1 simplified procedure
    3111           2 :                 if (this->MaxAirVolFlowRate > 0.0) {
    3112           2 :                     FixedMinAirDes = 1.5 * max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).VozClgByZone,
    3113           2 :                                                state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).VozHtgByZone);
    3114             : 
    3115             :                     // adjust maximum flow rate
    3116           2 :                     if (FixedMinAirDes > this->MaxAirVolFlowRate && IsMaxFlowAutoSize) {
    3117           0 :                         this->MaxAirVolFlowRate = FixedMinAirDes;
    3118           0 :                         ShowWarningError(state,
    3119           0 :                                          "SingleDuctSystem:SizeSys: Autosized maximum air flow rate for " + this->SysName +
    3120             :                                              " was increased to meet the zone primary air flow determined according to the ASHRAE Standard 62.1 "
    3121             :                                              "Simplified Procedure.");
    3122           2 :                     } else if (FixedMinAirDes > this->MaxAirVolFlowRate) {
    3123           0 :                         ShowWarningError(state, "SingleDuctSystem:SizeSys: Maximum air flow rate for " + this->SysName + " is potentially too low.");
    3124           0 :                         ShowContinueError(
    3125             :                             state,
    3126             :                             "The flow is lower than the minimum flow rate calculated following the ASHRAE Standard 62.1 Simplified Procedure:");
    3127           0 :                         ShowContinueError(state, format(" User-specified maximum air flow rate: {:.3R} m3/s.", this->MaxAirVolFlowRate));
    3128           0 :                         ShowContinueError(state, format(" Calculated minimum air flow rate: {:.3R} m3/s.", FixedMinAirDes));
    3129           0 :                         FixedMinAirDes = this->MaxAirVolFlowRate;
    3130             :                     }
    3131             :                 }
    3132             :             }
    3133             :         }
    3134           3 :         if (IsAutoSize) {
    3135             :             // report out autosized result and save value in Sys array
    3136           6 :             BaseSizer::reportSizerOutput(
    3137           4 :                 state, this->sysType, this->SysName, "Design Size Fixed Minimum Air Flow Rate [m3/s]", FixedMinAirDes * this->ZoneTurndownMinAirFrac);
    3138           2 :             if (SizingDesRunThisAirSys) {
    3139           2 :                 if (state.dataSize->SysSizInput(SysSizNum).SystemOAMethod == SysOAMethod::SP) {
    3140           2 :                     state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).VpzMinByZoneSPSized = true;
    3141             :                 }
    3142             :             }
    3143           2 :             this->ZoneFixedMinAir = FixedMinAirDes;
    3144             :         } else {
    3145             :             // report out hard (user set) value and issue warning if appropriate
    3146           1 :             FixedMinAirUser = this->ZoneFixedMinAir;
    3147           3 :             BaseSizer::reportSizerOutput(state,
    3148             :                                          this->sysType,
    3149             :                                          this->SysName,
    3150             :                                          "Design Size Fixed Minimum Air Flow Rate [m3/s]",
    3151           1 :                                          FixedMinAirDes * this->ZoneTurndownMinAirFrac,
    3152             :                                          "User-Specified Fixed Minimum Air Flow Rate [m3/s]",
    3153           3 :                                          FixedMinAirUser * this->ZoneTurndownMinAirFrac);
    3154           1 :             if (state.dataGlobal->DisplayExtraWarnings) {
    3155           0 :                 if ((std::abs(FixedMinAirDes - FixedMinAirUser) / FixedMinAirUser) > state.dataSize->AutoVsHardSizingThreshold) {
    3156           0 :                     ShowMessage(state,
    3157           0 :                                 "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" + this->SysName + "\".");
    3158           0 :                     ShowContinueError(state, format("User-Specified Minimum Cooling Air Flow Rate of {:.5R} [m3/s]", FixedMinAirUser));
    3159           0 :                     ShowContinueError(state, format("differs from Design Size Minimum Cooling Air Flow Rate of {:.5R} [m3/s]", FixedMinAirDes));
    3160           0 :                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3161           0 :                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3162             :                 }
    3163             :             }
    3164             :         }
    3165             :         // report out the min air flow frac set by the min air flow rate
    3166           3 :         if (this->MaxAirVolFlowRate > 0.0) {
    3167           9 :             BaseSizer::reportSizerOutput(state,
    3168             :                                          this->sysType,
    3169             :                                          this->SysName,
    3170             :                                          "Design Size Minimum Air Flow Fraction [m3/s]",
    3171           6 :                                          this->ZoneFixedMinAir * this->ZoneTurndownMinAirFrac / this->MaxAirVolFlowRate);
    3172             :         }
    3173             :     } else {
    3174        3301 :         if (IsAutoSize) {
    3175        2122 :             this->ZoneFixedMinAir = 0.0;
    3176             :         }
    3177             :     }
    3178             : 
    3179        3304 :     if (this->ZoneMinAirFracMethod == MinFlowFraction::Scheduled) {
    3180             :         // need a value for sizing.
    3181          33 :         if (this->ConstantMinAirFracSetByUser) {
    3182           3 :             this->ZoneMinAirFracDes = this->DesignMinAirFrac;
    3183             :             // if both inputs are defined, use the max
    3184           3 :             if (this->FixedMinAirSetByUser) {
    3185           0 :                 this->ZoneMinAirFracDes = min(1.0, max(this->ZoneMinAirFracDes, SafeDivide(this->DesignFixedMinAir, this->MaxAirVolFlowRate)));
    3186             :             }
    3187             :             // if only fixed is defined, use the value
    3188          30 :         } else if (this->FixedMinAirSetByUser) {
    3189           0 :             this->ZoneMinAirFracDes = min(1.0, SafeDivide(this->DesignFixedMinAir, this->MaxAirVolFlowRate));
    3190             :         } else {
    3191             :             // use an average of min and max in schedule
    3192          30 :             this->ZoneMinAirFracDes =
    3193          30 :                 (GetScheduleMinValue(state, this->ZoneMinAirFracSchPtr) + GetScheduleMaxValue(state, this->ZoneMinAirFracSchPtr)) / 2.0;
    3194             :         }
    3195             :     }
    3196             : 
    3197        3304 :     if (this->ZoneMinAirFracMethod == MinFlowFraction::Fixed) {
    3198             :         // need a value for sizing.
    3199           3 :         this->ZoneMinAirFracDes = min(1.0, SafeDivide(this->ZoneFixedMinAir, this->MaxAirVolFlowRate));
    3200             :     }
    3201             : 
    3202        3304 :     if (this->DamperHeatingAction == Action::ReverseWithLimits) {
    3203        1111 :         if (state.dataSize->ZoneSizingRunDone) {
    3204        1089 :             if (state.dataSize->CurTermUnitSizingNum > 0) {
    3205             :                 // if zone sizing run done, set the design max reheat air flow to the value from the design calcs
    3206        1089 :                 MaxAirVolFlowRateDuringReheatDes = state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlowMax;
    3207             :             }
    3208             :         } else {
    3209             :             // if no design calc use 0.002032 [m3/s-m2] times floor area. That's .40 cfm/ft2
    3210          22 :             MaxAirVolFlowRateDuringReheatDes = min(0.002032 * this->ZoneFloorArea, this->MaxAirVolFlowRate);
    3211             :         }
    3212             :         // check that result is not greater than the max flow or less than the min flow.
    3213        1111 :         MaxAirVolFlowRateDuringReheatDes = min(MaxAirVolFlowRateDuringReheatDes, this->MaxAirVolFlowRate);
    3214        1111 :         MaxAirVolFlowRateDuringReheatDes = max(MaxAirVolFlowRateDuringReheatDes, (this->MaxAirVolFlowRate * this->ZoneMinAirFracDes));
    3215        1111 :         if (this->MaxAirVolFlowRate > 0.0) {
    3216        1111 :             MaxAirVolFractionDuringReheatDes = MaxAirVolFlowRateDuringReheatDes / this->MaxAirVolFlowRate;
    3217             :         } else {
    3218           0 :             MaxAirVolFractionDuringReheatDes = 0.0;
    3219             :         }
    3220        2199 :         if (this->MaxAirVolFlowRateDuringReheat == DataGlobalConstants::AutoCalculate &&
    3221        1088 :             this->MaxAirVolFractionDuringReheat == DataGlobalConstants::AutoCalculate) {
    3222             :             // if both inputs are autosize (the default) report both out and save in the Sys array.
    3223        1474 :             BaseSizer::reportSizerOutput(
    3224         737 :                 state, this->sysType, this->SysName, "Design Size Maximum Flow Fraction during Reheat []", MaxAirVolFractionDuringReheatDes);
    3225         737 :             if (this->ZoneFloorArea > 0.0) {
    3226        2211 :                 BaseSizer::reportSizerOutput(state,
    3227             :                                              this->sysType,
    3228             :                                              this->SysName,
    3229             :                                              "Design Size Maximum Flow per Zone Floor Area during Reheat [m3/s-m2]",
    3230        1474 :                                              MaxAirVolFlowRateDuringReheatDes / this->ZoneFloorArea);
    3231             :             }
    3232         737 :             this->MaxAirVolFlowRateDuringReheat = MaxAirVolFlowRateDuringReheatDes;
    3233         737 :             this->MaxAirVolFractionDuringReheat = MaxAirVolFractionDuringReheatDes;
    3234         725 :         } else if (this->MaxAirVolFlowRateDuringReheat == DataGlobalConstants::AutoCalculate &&
    3235         351 :                    this->MaxAirVolFractionDuringReheat != DataGlobalConstants::AutoCalculate) {
    3236             :             // if max reheat flow fraction was input, set the max reheat flow design value correspondingly, report both out.
    3237             :             // Check for optional caution message that user input value is not within 10% of the design value.
    3238         351 :             MaxAirVolFlowRateDuringReheatDes = this->MaxAirVolFractionDuringReheat * this->MaxAirVolFlowRate;
    3239         351 :             MaxAirVolFractionDuringReheatUser = this->MaxAirVolFractionDuringReheat;
    3240         702 :             BaseSizer::reportSizerOutput(state,
    3241             :                                          this->sysType,
    3242             :                                          this->SysName,
    3243             :                                          "Design Size Maximum Flow Fraction during Reheat []",
    3244             :                                          MaxAirVolFractionDuringReheatDes,
    3245             :                                          "User-Specified Maximum Flow Fraction during Reheat []",
    3246         351 :                                          MaxAirVolFractionDuringReheatUser);
    3247         351 :             if (this->ZoneFloorArea > 0.0) {
    3248        1053 :                 BaseSizer::reportSizerOutput(state,
    3249             :                                              this->sysType,
    3250             :                                              this->SysName,
    3251             :                                              "Design Size Maximum Flow per Zone Floor Area during Reheat [m3/s-m2]",
    3252         702 :                                              MaxAirVolFlowRateDuringReheatDes / this->ZoneFloorArea);
    3253             :             }
    3254         351 :             this->MaxAirVolFlowRateDuringReheat = MaxAirVolFlowRateDuringReheatDes;
    3255         702 :             if (state.dataGlobal->DisplayExtraWarnings) {
    3256           0 :                 if ((std::abs(MaxAirVolFractionDuringReheatDes - MaxAirVolFractionDuringReheatUser) / MaxAirVolFractionDuringReheatUser) >
    3257           0 :                     state.dataSize->AutoVsHardSizingThreshold) {
    3258           0 :                     ShowMessage(state,
    3259           0 :                                 "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" + this->SysName + "\".");
    3260           0 :                     ShowContinueError(state,
    3261           0 :                                       format("User-Specified Maximum Flow Fraction during Reheat of {:.5R} []", MaxAirVolFractionDuringReheatUser));
    3262           0 :                     ShowContinueError(
    3263           0 :                         state, format("differs from Design Size Maximum Flow Fraction during Reheat of {:.5R} []", MaxAirVolFractionDuringReheatDes));
    3264           0 :                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3265           0 :                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3266             :                 }
    3267             :             }
    3268          46 :         } else if (this->MaxAirVolFlowRateDuringReheat != DataGlobalConstants::AutoCalculate &&
    3269          23 :                    this->MaxAirVolFractionDuringReheat == DataGlobalConstants::AutoCalculate) {
    3270             :             // if max reheat flow was input set the design max reheat flow frac to the corresponding value, report both out, save the design value
    3271             :             // of the flow frac in Sys. Check for optional caution message that user input value is not within 10% of the design value.
    3272          23 :             if (this->MaxAirVolFlowRate > 0.0) {
    3273          23 :                 MaxAirVolFractionDuringReheatDes = MaxAirVolFlowRateDuringReheatDes / this->MaxAirVolFlowRate;
    3274             :             } else {
    3275           0 :                 MaxAirVolFractionDuringReheatDes = 0.0;
    3276             :             }
    3277          23 :             MaxAirVolFlowRateDuringReheatUser = this->MaxAirVolFlowRateDuringReheat;
    3278          46 :             BaseSizer::reportSizerOutput(
    3279          23 :                 state, this->sysType, this->SysName, "Design Size Maximum Flow Fraction during Reheat []", MaxAirVolFractionDuringReheatDes);
    3280          23 :             if (this->ZoneFloorArea > 0.0) {
    3281          69 :                 BaseSizer::reportSizerOutput(state,
    3282             :                                              this->sysType,
    3283             :                                              this->SysName,
    3284             :                                              "Design Size Maximum Flow per Zone Floor Area during Reheat [ m3/s-m2 ]",
    3285          23 :                                              MaxAirVolFlowRateDuringReheatDes / this->ZoneFloorArea,
    3286             :                                              "User-Specified Maximum Flow per Zone Floor Area during Reheat [m3/s-m2]",
    3287          69 :                                              MaxAirVolFlowRateDuringReheatUser / this->ZoneFloorArea);
    3288             :             }
    3289          23 :             this->MaxAirVolFractionDuringReheat = MaxAirVolFractionDuringReheatDes;
    3290          46 :             if (state.dataGlobal->DisplayExtraWarnings) {
    3291           0 :                 if ((std::abs(MaxAirVolFlowRateDuringReheatDes - MaxAirVolFlowRateDuringReheatUser) / MaxAirVolFlowRateDuringReheatUser) >
    3292           0 :                     state.dataSize->AutoVsHardSizingThreshold) {
    3293           0 :                     ShowMessage(state,
    3294           0 :                                 "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" + this->SysName + "\".");
    3295           0 :                     ShowContinueError(state,
    3296           0 :                                       format("User-Specified Maximum Flow per Zone Floor Area during Reheat of {:.5R} [m3/s-m2]",
    3297           0 :                                              MaxAirVolFlowRateDuringReheatUser));
    3298           0 :                     ShowContinueError(state,
    3299           0 :                                       format("differs from Design Size Maximum Flow per Zone Floor Area during Reheat of {:.5R} [m3/s-m2]",
    3300           0 :                                              MaxAirVolFlowRateDuringReheatDes));
    3301           0 :                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3302           0 :                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3303             :                 }
    3304             :             }
    3305             :         } else {
    3306             :             // both fields have user input. Report both out, use the larger of the 2 values. Note that only sd_airterminal( SysNum
    3307             :             // ).MaxAirVolFlowRateDuringReheat is used subsequently. Check both inputs for optional caution message that user input value is not
    3308             :             // within 10% of the design value.
    3309           0 :             MaxAirVolFlowRateDuringReheatUser = this->MaxAirVolFlowRateDuringReheat;
    3310           0 :             MaxAirVolFractionDuringReheatUser = this->MaxAirVolFractionDuringReheat;
    3311           0 :             BaseSizer::reportSizerOutput(state,
    3312             :                                          this->sysType,
    3313             :                                          this->SysName,
    3314             :                                          "Design Size Maximum Flow Fraction during Reheat []",
    3315             :                                          MaxAirVolFractionDuringReheatDes,
    3316             :                                          "User-Specified Maximum Flow Fraction during Reheat []",
    3317           0 :                                          MaxAirVolFractionDuringReheatUser);
    3318           0 :             if (this->ZoneFloorArea > 0.0) {
    3319           0 :                 BaseSizer::reportSizerOutput(state,
    3320             :                                              this->sysType,
    3321             :                                              this->SysName,
    3322             :                                              "Design Size Maximum Flow per Zone Floor Area during Reheat [m3/s-m2]",
    3323           0 :                                              MaxAirVolFlowRateDuringReheatDes / this->ZoneFloorArea,
    3324             :                                              "User-Specified Maximum Flow per Zone Floor Area during Reheat [m3/s-m2]",
    3325           0 :                                              MaxAirVolFlowRateDuringReheatUser / this->ZoneFloorArea);
    3326             :             }
    3327           0 :             this->MaxAirVolFlowRateDuringReheat =
    3328           0 :                 max(this->MaxAirVolFlowRateDuringReheat, this->MaxAirVolFractionDuringReheat * this->MaxAirVolFlowRate);
    3329           0 :             if (state.dataGlobal->DisplayExtraWarnings) {
    3330           0 :                 if ((std::abs(MaxAirVolFractionDuringReheatDes - MaxAirVolFractionDuringReheatUser) / MaxAirVolFractionDuringReheatUser) >
    3331           0 :                     state.dataSize->AutoVsHardSizingThreshold) {
    3332           0 :                     ShowMessage(state,
    3333           0 :                                 "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" + this->SysName + "\".");
    3334           0 :                     ShowContinueError(state,
    3335           0 :                                       format("User-Specified Maximum Flow Fraction during Reheat of {:.5R} []", MaxAirVolFractionDuringReheatUser));
    3336           0 :                     ShowContinueError(
    3337           0 :                         state, format("differs from Design Size Maximum Flow Fraction during Reheat of {:.5R} []", MaxAirVolFractionDuringReheatDes));
    3338           0 :                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3339           0 :                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3340             :                 }
    3341             :             }
    3342           0 :             if (state.dataGlobal->DisplayExtraWarnings) {
    3343           0 :                 if ((std::abs(MaxAirVolFlowRateDuringReheatDes - MaxAirVolFlowRateDuringReheatUser) / MaxAirVolFlowRateDuringReheatUser) >
    3344           0 :                     state.dataSize->AutoVsHardSizingThreshold) {
    3345           0 :                     ShowMessage(state,
    3346           0 :                                 "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" + this->SysName + "\".");
    3347           0 :                     ShowContinueError(state,
    3348           0 :                                       format("User-Specified Maximum Flow per Zone Floor Area during Reheat of {:.5R} [m3/s-m2]",
    3349           0 :                                              MaxAirVolFlowRateDuringReheatUser));
    3350           0 :                     ShowContinueError(state,
    3351           0 :                                       format("differs from Design Size Maximum Flow per Zone Floor Area during Reheat of {:.5R} [m3/s-m2]",
    3352           0 :                                              MaxAirVolFlowRateDuringReheatDes));
    3353           0 :                     ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3354           0 :                     ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3355             :                 }
    3356             :             }
    3357             :         }
    3358             :         // check that MaxAirVolFlowRateDuringReheat is greater than the min and less than the max
    3359        1111 :         this->MaxAirVolFlowRateDuringReheat = min(MaxAirVolFlowRateDuringReheatDes, this->MaxAirVolFlowRate);
    3360        1111 :         this->MaxAirVolFlowRateDuringReheat = max(MaxAirVolFlowRateDuringReheatDes, (this->MaxAirVolFlowRate * this->ZoneMinAirFracDes));
    3361        2193 :     } else if (this->DamperHeatingAction == Action::Normal) {
    3362             :         // for Normal action, max reheat flow is equal to the minimum. Report it.
    3363         937 :         if (this->ZoneFloorArea > 0.0) {
    3364        2811 :             BaseSizer::reportSizerOutput(state,
    3365             :                                          this->sysType,
    3366             :                                          this->SysName,
    3367             :                                          "Design Size Maximum Flow per Zone Floor Area during Reheat [m3/s-m2]",
    3368        1874 :                                          (this->MaxAirVolFlowRate * this->ZoneMinAirFracDes) / this->ZoneFloorArea);
    3369             :         }
    3370        1874 :         BaseSizer::reportSizerOutput(
    3371         937 :             state, this->sysType, this->SysName, "Design Size Maximum Flow Fraction during Reheat []", this->ZoneMinAirFracDes);
    3372             :         // zero the ReverseActioWithLimits inputs
    3373         937 :         this->MaxAirVolFlowRateDuringReheat = max(this->MaxAirVolFlowRateDuringReheat, 0.0);
    3374         937 :         this->MaxAirVolFractionDuringReheat = max(this->MaxAirVolFractionDuringReheat, 0.0);
    3375        1256 :     } else if (this->DamperHeatingAction == Action::Reverse) {
    3376             :         // for ReverseAction, max reheat flow is equal to the maximum. Report it.
    3377          61 :         if (this->ZoneFloorArea > 0.0) {
    3378         183 :             BaseSizer::reportSizerOutput(state,
    3379             :                                          this->sysType,
    3380             :                                          this->SysName,
    3381             :                                          "Design Size Maximum Flow per Zone Floor Area during Reheat [m3/s-m2]",
    3382         122 :                                          this->MaxAirVolFlowRate / this->ZoneFloorArea);
    3383             :         }
    3384          61 :         BaseSizer::reportSizerOutput(state, this->sysType, this->SysName, "Design Size Maximum Flow Fraction during Reheat []", 1.0);
    3385             :         // zero the ReverseActioWithLimits inputs
    3386          61 :         this->MaxAirVolFlowRateDuringReheat = max(this->MaxAirVolFlowRateDuringReheat, 0.0);
    3387          61 :         this->MaxAirVolFractionDuringReheat = max(this->MaxAirVolFractionDuringReheat, 0.0);
    3388             :     }
    3389             : 
    3390        3304 :     if (state.dataSize->CurTermUnitSizingNum > 0) {
    3391        3304 :         TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult = 1.0;
    3392        3304 :         TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult = 1.0;
    3393        3304 :         if (state.dataSize->ZoneSizingRunDone) {
    3394             :             // set air flow rate used to size heating coils, ZoneTurndownMinAirFrac defaults to 1 for those TU types that do not use it
    3395        2797 :             if (this->SysType_Num == SysType::SingleDuctVAVReheatVSFan) {
    3396           8 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow =
    3397          16 :                     max(state.dataSingleDuct->UserInputMaxHeatAirVolFlowRateSS,
    3398           8 :                         state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatVolFlow,
    3399           8 :                         this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac);
    3400        2789 :             } else if (this->SysType_Num == SysType::SingleDuctConstVolReheat || this->SysType_Num == SysType::SingleDuctConstVolNoReheat) {
    3401         639 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow =
    3402         639 :                     max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatVolFlow,
    3403         639 :                         this->MaxAirVolFlowRate * this->ZoneTurndownMinAirFrac);
    3404             :             } else {
    3405        2150 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow =
    3406        2150 :                     max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatVolFlow,
    3407        2150 :                         this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac);
    3408             :             }
    3409             :         } else {
    3410         507 :             if (this->SysType_Num == SysType::SingleDuctVAVReheatVSFan) {
    3411           0 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow =
    3412           0 :                     max(this->MaxHeatAirVolFlowRate, this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac);
    3413         507 :             } else if (this->SysType_Num == SysType::SingleDuctConstVolReheat || this->SysType_Num == SysType::SingleDuctConstVolNoReheat) {
    3414         459 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow = this->MaxAirVolFlowRate;
    3415             :             } else {
    3416          48 :                 if (this->DamperHeatingAction == Action::Reverse) {
    3417           0 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow = this->MaxAirVolFlowRate;
    3418          48 :                 } else if (this->DamperHeatingAction == Action::ReverseWithLimits) {
    3419          22 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow =
    3420          22 :                         max(this->MaxAirVolFlowRateDuringReheat, (this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac));
    3421             :                 } else {
    3422          26 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow =
    3423          26 :                         this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac;
    3424             :                 }
    3425             :             }
    3426             :         }
    3427             : 
    3428        3304 :         if (TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow > SmallAirVolFlow) {
    3429        3304 :             if (this->DamperHeatingAction == Action::ReverseWithLimits) {
    3430        1111 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult =
    3431        2222 :                     min(this->MaxAirVolFlowRateDuringReheat, this->MaxAirVolFlowRate) /
    3432        1111 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow;
    3433        1111 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult =
    3434        1111 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult;
    3435        2193 :             } else if (this->DamperHeatingAction == Action::Reverse) {
    3436          61 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult =
    3437          61 :                     this->MaxAirVolFlowRate / TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow;
    3438          61 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult =
    3439          61 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult;
    3440        2132 :             } else if (this->DamperHeatingAction == Action::Normal && this->MaxAirVolFlowRateDuringReheat > 0.0) {
    3441           0 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult =
    3442           0 :                     min(this->MaxAirVolFlowRateDuringReheat, (this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac)) /
    3443           0 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow;
    3444           0 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult = 1.0;
    3445        2132 :             } else if (this->DamperHeatingAction == Action::Normal && this->MaxAirVolFlowRateDuringReheat == 0.0) {
    3446         937 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult =
    3447        1874 :                     (this->MaxAirVolFlowRate * this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac) /
    3448         937 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow;
    3449         937 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult = 1.0;
    3450             :             } else {
    3451        1195 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult =
    3452        1195 :                     this->MaxAirVolFlowRate / TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow;
    3453        1195 :                 TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult =
    3454        1195 :                     TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult;
    3455             :             }
    3456        3304 :             TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult =
    3457        3304 :                 max(1.0, TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult);
    3458        3304 :             TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult =
    3459        3304 :                 max(1.0, TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult);
    3460             :         } else {
    3461           0 :             TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult = 1.0;
    3462           0 :             TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult = 1.0;
    3463             :         }
    3464        3304 :         if (this->ReheatComp_Index > 0) {
    3465        3598 :             state.dataRptCoilSelection->coilSelectionReportObj->setCoilReheatMultiplier(
    3466        1799 :                 state, this->ReheatName, this->ReheatComp, TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatLoadMult);
    3467             :         }
    3468             :     }
    3469             : 
    3470        3304 :     IsAutoSize = false;
    3471        3304 :     if (this->MaxReheatWaterVolFlow == AutoSize) {
    3472        1991 :         IsAutoSize = true;
    3473             :     }
    3474        3304 :     if (state.dataSize->CurTermUnitSizingNum > 0) {
    3475        3304 :         if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    3476         507 :             if (this->MaxReheatWaterVolFlow > 0.0) {
    3477         432 :                 BaseSizer::reportSizerOutput(
    3478         216 :                     state, this->sysType, this->SysName, "User-Specified Maximum Reheat Water Flow Rate [m3/s]", this->MaxReheatWaterVolFlow);
    3479             :             }
    3480             :         } else {
    3481        2797 :             CheckZoneSizing(state, this->sysType, this->SysName);
    3482        2797 :             if (UtilityRoutines::SameString(this->ReheatComp, "Coil:Heating:Water")) {
    3483        1791 :                 state.dataSingleDuct->CoilWaterInletNodeSS = GetCoilWaterInletNode(state, "Coil:Heating:Water", this->ReheatName, ErrorsFound);
    3484        1791 :                 state.dataSingleDuct->CoilWaterOutletNodeSS = GetCoilWaterOutletNode(state, "Coil:Heating:Water", this->ReheatName, ErrorsFound);
    3485        1791 :                 if (IsAutoSize) {
    3486        1737 :                     PlantSizingErrorsFound = false;
    3487        5211 :                     PltSizHeatNum = MyPlantSizingIndex(state,
    3488             :                                                        "Coil:Heating:Water",
    3489             :                                                        this->ReheatName,
    3490        1737 :                                                        state.dataSingleDuct->CoilWaterInletNodeSS,
    3491        1737 :                                                        state.dataSingleDuct->CoilWaterOutletNodeSS,
    3492             :                                                        PlantSizingErrorsFound);
    3493        1737 :                     if (PlantSizingErrorsFound) {
    3494           0 :                         ShowContinueError(state, "...Occurs in " + this->sysType + ':' + this->SysName);
    3495           0 :                         ErrorsFound = true;
    3496             :                     }
    3497        1737 :                     if (PltSizHeatNum > 0) {
    3498        1737 :                         state.dataSingleDuct->CoilInTempSS =
    3499        1737 :                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU;
    3500        1737 :                         DesMassFlow = state.dataEnvrn->StdRhoAir * TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow;
    3501        1737 :                         state.dataSingleDuct->DesZoneHeatLoadSS =
    3502        1737 :                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatLoad;
    3503        1737 :                         state.dataSingleDuct->ZoneDesTempSS =
    3504        1737 :                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtHeatPeak;
    3505        1737 :                         state.dataSingleDuct->ZoneDesHumRatSS =
    3506        1737 :                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneHumRatAtHeatPeak;
    3507             :                         // the coil load is the zone design heating load plus (or minus!) the reheat load
    3508        1737 :                         state.dataSingleDuct->DesCoilLoadSS =
    3509        3474 :                             state.dataSingleDuct->DesZoneHeatLoadSS + PsyCpAirFnW(state.dataSingleDuct->ZoneDesHumRatSS) * DesMassFlow *
    3510        1737 :                                                                           (state.dataSingleDuct->ZoneDesTempSS - state.dataSingleDuct->CoilInTempSS);
    3511        1737 :                         if (state.dataSingleDuct->DesCoilLoadSS >= SmallLoad) {
    3512             : 
    3513        3474 :                             rho = GetDensityGlycol(state,
    3514        1737 :                                                    state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).FluidName,
    3515             :                                                    DataGlobalConstants::HWInitConvTemp,
    3516        1737 :                                                    state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).FluidIndex,
    3517             :                                                    RoutineName);
    3518             : 
    3519        3474 :                             Cp = GetSpecificHeatGlycol(state,
    3520        1737 :                                                        state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).FluidName,
    3521             :                                                        DataGlobalConstants::HWInitConvTemp,
    3522        1737 :                                                        state.dataPlnt->PlantLoop(this->HWplantLoc.loopNum).FluidIndex,
    3523             :                                                        RoutineName);
    3524             : 
    3525        1737 :                             MaxReheatWaterVolFlowDes =
    3526        1737 :                                 state.dataSingleDuct->DesCoilLoadSS / (state.dataSize->PlantSizData(PltSizHeatNum).DeltaT * Cp * rho);
    3527             :                         } else {
    3528           0 :                             MaxReheatWaterVolFlowDes = 0.0;
    3529             :                         }
    3530             :                     } else {
    3531           0 :                         ShowSevereError(state, "Autosizing of water flow requires a heating loop Sizing:Plant object");
    3532           0 :                         ShowContinueError(state, "Occurs in AirTerminal Object=" + this->SysName);
    3533           0 :                         ErrorsFound = true;
    3534             :                     }
    3535             :                 }
    3536        1791 :                 if (IsAutoSize) {
    3537        1737 :                     this->MaxReheatWaterVolFlow = MaxReheatWaterVolFlowDes;
    3538        3474 :                     BaseSizer::reportSizerOutput(
    3539        1737 :                         state, this->sysType, this->SysName, "Design Size Maximum Reheat Water Flow Rate [m3/s]", MaxReheatWaterVolFlowDes);
    3540        5211 :                     BaseSizer::reportSizerOutput(state,
    3541             :                                                  this->sysType,
    3542             :                                                  this->SysName,
    3543             :                                                  "Design Size Reheat Coil Sizing Air Volume Flow Rate [m3/s]",
    3544        3474 :                                                  TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow);
    3545        5211 :                     BaseSizer::reportSizerOutput(state,
    3546             :                                                  this->sysType,
    3547             :                                                  this->SysName,
    3548             :                                                  "Design Size Reheat Coil Sizing Inlet Air Temperature [C]",
    3549        3474 :                                                  state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU);
    3550        5211 :                     BaseSizer::reportSizerOutput(state,
    3551             :                                                  this->sysType,
    3552             :                                                  this->SysName,
    3553             :                                                  "Design Size Reheat Coil Sizing Inlet Air Humidity Ratio [kgWater/kgDryAir]",
    3554        3474 :                                                  state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInHumRatTU);
    3555             :                 } else { // Hard-size with sizing data
    3556          54 :                     if (this->MaxReheatWaterVolFlow > 0.0 && MaxReheatWaterVolFlowDes > 0.0) {
    3557           0 :                         MaxReheatWaterVolFlowUser = this->MaxReheatWaterVolFlow;
    3558           0 :                         BaseSizer::reportSizerOutput(state,
    3559             :                                                      this->sysType,
    3560             :                                                      this->SysName,
    3561             :                                                      "Design Size Maximum Reheat Water Flow Rate [m3/s]",
    3562             :                                                      MaxReheatWaterVolFlowDes,
    3563             :                                                      "User-Specified Maximum Reheat Water Flow Rate [m3/s]",
    3564           0 :                                                      MaxReheatWaterVolFlowUser);
    3565           0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    3566           0 :                             if ((std::abs(MaxReheatWaterVolFlowDes - MaxReheatWaterVolFlowUser) / MaxReheatWaterVolFlowUser) >
    3567           0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    3568           0 :                                 ShowMessage(state,
    3569           0 :                                             "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" +
    3570           0 :                                                 this->SysName + "\".");
    3571           0 :                                 ShowContinueError(
    3572           0 :                                     state, format("User-Specified Maximum Reheat Water Flow Rate of {:.5R} [m3/s]", MaxReheatWaterVolFlowUser));
    3573           0 :                                 ShowContinueError(
    3574             :                                     state,
    3575           0 :                                     format("differs from Design Size Maximum Reheat Water Flow Rate of {:.5R} [m3/s]", MaxReheatWaterVolFlowDes));
    3576           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3577           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3578             :                             }
    3579             :                         }
    3580             :                     }
    3581             :                 }
    3582             :             }
    3583             :         }
    3584             :     } else {
    3585           0 :         this->MaxReheatWaterVolFlow = 0.0;
    3586             :     }
    3587             : 
    3588        3304 :     IsAutoSize = false;
    3589        3304 :     if (this->MaxReheatSteamVolFlow == AutoSize) {
    3590           8 :         IsAutoSize = true;
    3591             :     }
    3592        3304 :     if (state.dataSize->CurTermUnitSizingNum > 0) {
    3593        3304 :         if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
    3594         507 :             if (this->MaxReheatSteamVolFlow > 0.0) {
    3595           0 :                 BaseSizer::reportSizerOutput(
    3596           0 :                     state, this->sysType, this->SysName, "User-Specified Maximum Reheat Steam Flow Rate [m3/s]", this->MaxReheatSteamVolFlow);
    3597             :             }
    3598             :         } else {
    3599        2797 :             CheckZoneSizing(state, this->sysType, this->SysName);
    3600        2797 :             if (UtilityRoutines::SameString(this->ReheatComp, "Coil:Heating:Steam")) {
    3601           8 :                 state.dataSingleDuct->CoilSteamInletNodeSS = GetCoilSteamInletNode(state, "Coil:Heating:Steam", this->ReheatName, ErrorsFound);
    3602           8 :                 state.dataSingleDuct->CoilSteamOutletNodeSS = GetCoilSteamOutletNode(state, "Coil:Heating:Steam", this->ReheatName, ErrorsFound);
    3603           8 :                 if (IsAutoSize) {
    3604           8 :                     PlantSizingErrorsFound = false;
    3605          24 :                     PltSizHeatNum = MyPlantSizingIndex(state,
    3606             :                                                        "Coil:Heating:Steam",
    3607             :                                                        this->ReheatName,
    3608           8 :                                                        state.dataSingleDuct->CoilSteamInletNodeSS,
    3609           8 :                                                        state.dataSingleDuct->CoilSteamOutletNodeSS,
    3610             :                                                        PlantSizingErrorsFound);
    3611           8 :                     if (PlantSizingErrorsFound) {
    3612           0 :                         ShowContinueError(state, "...Occurs in " + this->sysType + ':' + this->SysName);
    3613           0 :                         ErrorsFound = true;
    3614             :                     }
    3615           8 :                     if (PltSizHeatNum > 0) {
    3616           8 :                         state.dataSingleDuct->CoilInTempSS =
    3617           8 :                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU;
    3618           8 :                         DesMassFlow = state.dataEnvrn->StdRhoAir * TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow;
    3619           8 :                         state.dataSingleDuct->DesZoneHeatLoadSS =
    3620           8 :                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatLoad;
    3621           8 :                         state.dataSingleDuct->ZoneDesTempSS =
    3622           8 :                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtHeatPeak;
    3623           8 :                         state.dataSingleDuct->ZoneDesHumRatSS =
    3624           8 :                             state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneHumRatAtHeatPeak;
    3625             :                         // the coil load is the zone design heating load plus (or minus!) the reheat load
    3626           8 :                         state.dataSingleDuct->DesCoilLoadSS =
    3627          16 :                             state.dataSingleDuct->DesZoneHeatLoadSS + PsyCpAirFnW(state.dataSingleDuct->ZoneDesHumRatSS) * DesMassFlow *
    3628           8 :                                                                           (state.dataSingleDuct->ZoneDesTempSS - state.dataSingleDuct->CoilInTempSS);
    3629           8 :                         if (state.dataSingleDuct->DesCoilLoadSS >= SmallLoad) {
    3630           8 :                             TempSteamIn = 100.00;
    3631           8 :                             EnthSteamInDry = GetSatEnthalpyRefrig(state, fluidNameSteam, TempSteamIn, 1.0, this->FluidIndex, RoutineNameFull);
    3632           8 :                             EnthSteamOutWet = GetSatEnthalpyRefrig(state, fluidNameSteam, TempSteamIn, 0.0, this->FluidIndex, RoutineNameFull);
    3633           8 :                             LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
    3634           8 :                             SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, this->FluidIndex, RoutineNameFull);
    3635             : 
    3636          16 :                             Cp = GetSpecificHeatGlycol(state,
    3637             :                                                        fluidNameWater,
    3638           8 :                                                        state.dataSize->PlantSizData(PltSizHeatNum).ExitTemp,
    3639           8 :                                                        state.dataSingleDuct->DummyWaterIndexSS,
    3640             :                                                        RoutineName);
    3641          16 :                             MaxReheatSteamVolFlowDes = state.dataSingleDuct->DesCoilLoadSS /
    3642           8 :                                                        (SteamDensity * (LatentHeatSteam + state.dataSize->PlantSizData(PltSizHeatNum).DeltaT * Cp));
    3643             :                         } else {
    3644           0 :                             MaxReheatSteamVolFlowDes = 0.0;
    3645             :                         }
    3646             :                     } else {
    3647           0 :                         ShowSevereError(state, "Autosizing of Steam flow requires a heating loop Sizing:Plant object");
    3648           0 :                         ShowContinueError(state, "Occurs in AirTerminal:SingleDuct:ConstantVolume:Reheat Object=" + this->SysName);
    3649           0 :                         ErrorsFound = true;
    3650             :                     }
    3651             :                 }
    3652           8 :                 if (IsAutoSize) {
    3653           8 :                     this->MaxReheatSteamVolFlow = MaxReheatSteamVolFlowDes;
    3654          16 :                     BaseSizer::reportSizerOutput(
    3655           8 :                         state, this->sysType, this->SysName, "Design Size Maximum Reheat Steam Flow Rate [m3/s]", MaxReheatSteamVolFlowDes);
    3656             :                 } else {
    3657           0 :                     if (this->MaxReheatSteamVolFlow > 0.0 && MaxReheatSteamVolFlowDes > 0.0) {
    3658           0 :                         MaxReheatSteamVolFlowUser = this->MaxReheatSteamVolFlow;
    3659           0 :                         BaseSizer::reportSizerOutput(state,
    3660             :                                                      this->sysType,
    3661             :                                                      this->SysName,
    3662             :                                                      "Design Size Maximum Reheat Steam Flow Rate [m3/s]",
    3663             :                                                      MaxReheatSteamVolFlowDes,
    3664             :                                                      "User-Specified Maximum Reheat Steam Flow Rate [m3/s]",
    3665           0 :                                                      MaxReheatSteamVolFlowUser);
    3666           0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    3667           0 :                             if ((std::abs(MaxReheatSteamVolFlowDes - MaxReheatSteamVolFlowUser) / MaxReheatSteamVolFlowUser) >
    3668           0 :                                 state.dataSize->AutoVsHardSizingThreshold) {
    3669           0 :                                 ShowMessage(state,
    3670           0 :                                             "SizeHVACSingleDuct: Potential issue with equipment sizing for " + this->sysType + " = \"" +
    3671           0 :                                                 this->SysName + "\".");
    3672           0 :                                 ShowContinueError(
    3673           0 :                                     state, format("User-Specified Maximum Reheat Steam Flow Rate of {:.5R} [m3/s]", MaxReheatSteamVolFlowUser));
    3674           0 :                                 ShowContinueError(
    3675             :                                     state,
    3676           0 :                                     format("differs from Design Size Maximum Reheat Steam Flow Rate of {:.5R} [m3/s]", MaxReheatSteamVolFlowDes));
    3677           0 :                                 ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
    3678           0 :                                 ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
    3679             :                             }
    3680             :                         }
    3681             :                     }
    3682             :                 }
    3683             :             }
    3684             :         }
    3685             :     } else {
    3686           0 :         this->MaxReheatSteamVolFlow = 0.0;
    3687             :     }
    3688             : 
    3689        3304 :     if (state.dataSize->CurTermUnitSizingNum > 0) {
    3690        3304 :         TermUnitSizing(state.dataSize->CurTermUnitSizingNum).MinFlowFrac = this->ZoneMinAirFracDes * this->ZoneTurndownMinAirFrac;
    3691        3304 :         TermUnitSizing(state.dataSize->CurTermUnitSizingNum).MaxHWVolFlow = this->MaxReheatWaterVolFlow;
    3692        3304 :         TermUnitSizing(state.dataSize->CurTermUnitSizingNum).MaxSTVolFlow = this->MaxReheatSteamVolFlow;
    3693        3304 :         TermUnitSizing(state.dataSize->CurTermUnitSizingNum).DesHeatingLoad = state.dataSingleDuct->DesCoilLoadSS; // Coil Summary report
    3694        3304 :         if (this->ReheatComp_Num == HeatingCoilType::SimpleHeating) {
    3695        2007 :             if (this->DamperHeatingAction == Action::Normal) {
    3696         753 :                 SetCoilDesFlow(state, this->ReheatComp, this->ReheatName, this->ZoneMinAirFracDes * this->MaxAirVolFlowRate, ErrorsFound);
    3697             :             } else {
    3698        1254 :                 SetCoilDesFlow(
    3699        1254 :                     state, this->ReheatComp, this->ReheatName, TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow, ErrorsFound);
    3700             :             }
    3701             :         }
    3702             :     }
    3703             : 
    3704        3304 :     if (this->MaxAirVolFlowRateDuringReheat > 0.0) {
    3705             :         // check for inconsistent dual max input
    3706        1111 :         if (this->MaxAirVolFlowRateDuringReheat < (this->ZoneMinAirFracDes * this->MaxAirVolFlowRate)) {
    3707             :             // Only warn when really out of bounds
    3708           0 :             if ((this->ZoneMinAirFracDes * this->MaxAirVolFlowRate) - this->MaxAirVolFlowRateDuringReheat > 1.e-8) {
    3709           0 :                 ShowWarningError(state,
    3710             :                                  "SingleDuctSystem:SizeSys: Air Terminal Unit flow limits are not consistent, minimum flow limit is larger than "
    3711             :                                  "reheat maximum");
    3712           0 :                 ShowContinueError(state, "Air Terminal Unit name = " + this->SysName);
    3713           0 :                 ShowContinueError(state,
    3714           0 :                                   format("Maximum terminal flow during reheat = {:.6R} [m3/s] or flow fraction = {:.4R}",
    3715             :                                          this->MaxAirVolFlowRateDuringReheat,
    3716           0 :                                          (this->MaxAirVolFlowRateDuringReheat / this->MaxAirVolFlowRate)));
    3717           0 :                 ShowContinueError(state,
    3718           0 :                                   format("Minimum terminal flow = {:.6R} [m3/s] or flow fraction = {:.4R}",
    3719           0 :                                          (this->ZoneMinAirFracDes * this->MaxAirVolFlowRate),
    3720           0 :                                          this->ZoneMinAirFracDes));
    3721           0 :                 ShowContinueError(state, "The reheat maximum flow limit will be replaced by the minimum limit, and the simulation continues");
    3722             :             }
    3723           0 :             this->MaxAirVolFlowRateDuringReheat = (this->ZoneMinAirFracDes * this->MaxAirVolFlowRate);
    3724             :         }
    3725             :     }
    3726             : 
    3727        3304 :     if (ErrorsFound) {
    3728           0 :         ShowFatalError(state, "Preceding sizing errors cause program termination");
    3729             :     }
    3730        3304 : }
    3731             : 
    3732             : // End Initialization Section of the Module
    3733             : //******************************************************************************
    3734             : 
    3735             : // Begin Algorithm Section of the Module
    3736             : //******************************************************************************
    3737             : 
    3738    23432728 : void SingleDuctAirTerminal::SimVAV(EnergyPlusData &state, bool const FirstHVACIteration, int const ZoneNum, int const ZoneNodeNum)
    3739             : {
    3740             : 
    3741             :     // SUBROUTINE INFORMATION:
    3742             :     //       AUTHOR         Richard J. Liesen
    3743             :     //       DATE WRITTEN   January 2000
    3744             :     //       MODIFIED       Fred Buhl: added reverse action damper heating action: August 2001
    3745             :     //                      KHL/TH 7/2010: revise to support dual max
    3746             :     //                      FB/KHL/TH 9/2010: added maximum supply air temperature leaving reheat coil
    3747             :     //                      TH 3/2012: added supply air flow adjustment based on zone maximum outdoor
    3748             :     //                                 air fraction - a TRACE feature
    3749             :     //                      Brent Griffith, 5/2012, general cleanup, fix negatives CR 8767, fix phantom coil flows CR 8854
    3750             :     //       RE-ENGINEERED  na
    3751             : 
    3752             :     // PURPOSE OF THIS SUBROUTINE:
    3753             :     // This subroutine simulates the simple single duct volume VAV.
    3754             : 
    3755             :     // METHODOLOGY EMPLOYED:
    3756             :     // There is method to this madness.
    3757             : 
    3758             :     // REFERENCES:
    3759             :     // na
    3760             : 
    3761             :     // Using/Aliasing
    3762             :     using namespace DataZoneEnergyDemands;
    3763             :     // unused   USE DataHeatBalFanSys, ONLY: Mat
    3764             :     using DataHVACGlobals::SmallLoad;
    3765             :     using HeatingCoils::SimulateHeatingCoilComponents;
    3766             :     using PlantUtilities::SetActuatedBranchFlowRate;
    3767             :     using SteamCoils::SimulateSteamCoilComponents;
    3768             :     using WaterCoils::SimulateWaterCoilComponents;
    3769             : 
    3770             :     // Locals
    3771             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    3772             : 
    3773             :     // SUBROUTINE PARAMETER DEFINITIONS:
    3774             : 
    3775             :     // INTERFACE BLOCK SPECIFICATIONS
    3776             :     // na
    3777             : 
    3778             :     // DERIVED TYPE DEFINITIONS
    3779             :     // na
    3780             : 
    3781             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    3782             :     Real64 MassFlow;     // [kg/sec]   Total Mass Flow Rate from Hot & Cold Inlets
    3783             :     Real64 QTotLoad;     // [Watts] Remaining load required for this zone
    3784             :     Real64 QZnReq;       // [Watts] Load calculated for heating coil
    3785             :     Real64 QToHeatSetPt; // [W]  remaining load to heating setpoint
    3786             :     Real64 CpAirAvg;
    3787             :     Real64 DeltaTemp;
    3788             :     int SysOutletNode;        // The node number of the terminal unit outlet node
    3789             :     int SysInletNode;         // the node number of the terminal unit inlet node
    3790             :     int WaterControlNode;     // This is the Actuated Reheat Control Node
    3791             :     Real64 MaxFlowWater;      // This is the value passed to the Controller depending if FirstHVACIteration or not
    3792             :     Real64 MinFlowWater;      // This is the value passed to the Controller depending if FirstHVACIteration or not
    3793             :     Real64 QActualHeating;    // the heating load seen by the reheat coil
    3794             :     Real64 QHeatingDelivered; // the actual output from heating coil
    3795             :     Real64 LeakLoadMult;      // load multiplier to adjust for downstream leaks
    3796             :     Real64 MinFlowFrac;       // minimum flow fraction (and minimum damper position)
    3797             :     Real64 MassFlowBasedOnOA; // supply air mass flow rate based on zone OA requirements
    3798             :     Real64 AirLoopOAFrac;     // fraction of outside air entering air loop
    3799             :     Real64 DummyMdot;         // temporary mass flow rate argument
    3800             : 
    3801             :     // Note to the perplexed
    3802             :     // The SINGLE DUCT:VAV:REHEAT terminal unit originally contained 2 components: a damper
    3803             :     // and a reheat coil. The damper has become a virtual component - it consists only of
    3804             :     // an air inlet node and an air outlet node. The damper is upstream of the heating coil.
    3805             :     // sd_airterminal(SysNum)%InletNodeNum is the inlet node to the terminal unit and the damper
    3806             :     // sd_airterminal(SysNum)%OutletNodeNum is the outlet node of the damper and the inlet node of the heating coil
    3807             :     // sd_airterminal(SysNum)%ReheatAirOutletNode is the outlet node of the terminal unit and the heating coil
    3808             : 
    3809             :     // The calculated load from the Heat Balance
    3810    23432728 :     LeakLoadMult = state.dataDefineEquipment->AirDistUnit(this->ADUNum).LeakLoadMult;
    3811    23432728 :     QTotLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputRequired * LeakLoadMult;
    3812    23432728 :     QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToHeatSP * LeakLoadMult;
    3813    23432728 :     SysOutletNode = this->ReheatAirOutletNode;
    3814    23432728 :     SysInletNode = this->InletNodeNum;
    3815    23432728 :     CpAirAvg = PsyCpAirFnW(0.5 * (state.dataLoopNodes->Node(ZoneNodeNum).HumRat + this->sd_airterminalInlet.AirHumRat));
    3816    23432728 :     MinFlowFrac = this->ZoneMinAirFrac;
    3817    23432728 :     MassFlowBasedOnOA = 0.0;
    3818    23432728 :     state.dataSingleDuct->ZoneTempSDAT = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
    3819    23432728 :     state.dataSingleDuct->MinMassAirFlowSDAT = MinFlowFrac * state.dataEnvrn->StdRhoAir * this->MaxAirVolFlowRate;
    3820             : 
    3821             :     // Then depending on if the Load is for heating or cooling it is handled differently.  First
    3822             :     // the massflow rate for cooling is determined to meet the entire load.  Then
    3823             :     // if the massflow is below the minimum or greater than the Max it is set to either the Min
    3824             :     // or the Max as specified for the VAV model.
    3825    38296557 :     if ((QTotLoad < 0.0) && (this->sd_airterminalInlet.AirMassFlowRateMaxAvail > 0.0) &&
    3826    37896410 :         (state.dataHeatBalFanSys->TempControlType(ZoneNum) != DataHVACGlobals::ThermostatType::SingleHeating) &&
    3827     7223370 :         (GetCurrentScheduleValue(state, this->SchedPtr) > 0.0)) {
    3828             :         // Calculate the flow required for cooling
    3829             : 
    3830     7223370 :         DeltaTemp = CpAirAvg * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSDAT);
    3831             : 
    3832             :         // Need to check DeltaTemp and ensure that it is not zero
    3833     7223370 :         if (DeltaTemp != 0.0) {
    3834     7223042 :             MassFlow = QTotLoad / DeltaTemp;
    3835             :         } else {
    3836         328 :             MassFlow = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    3837             :         }
    3838             : 
    3839             :         // Apply the zone maximum outdoor air fraction FOR VAV boxes - a TRACE feature
    3840     7223370 :         if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).SupplyAirAdjustFactor > 1.0) {
    3841           0 :             MassFlow *= state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).SupplyAirAdjustFactor;
    3842             :         }
    3843             : 
    3844             :         // calculate supply air flow rate based on user specified OA requirement
    3845     7223370 :         this->CalcOAMassFlow(state, MassFlowBasedOnOA, AirLoopOAFrac);
    3846     7223370 :         MassFlow = max(MassFlow, MassFlowBasedOnOA);
    3847             : 
    3848             :         // used for normal acting damper
    3849     7223370 :         state.dataSingleDuct->MinMassAirFlowSDAT = max(state.dataSingleDuct->MinMassAirFlowSDAT, MassFlowBasedOnOA);
    3850     7223370 :         state.dataSingleDuct->MinMassAirFlowSDAT = max(state.dataSingleDuct->MinMassAirFlowSDAT, this->sd_airterminalInlet.AirMassFlowRateMinAvail);
    3851     7223370 :         state.dataSingleDuct->MinMassAirFlowSDAT = min(state.dataSingleDuct->MinMassAirFlowSDAT, this->sd_airterminalInlet.AirMassFlowRateMaxAvail);
    3852             : 
    3853             :         // limit the OA based supply air flow rate based on optional user input
    3854             :         // Check to see if the flow is < the Min or > the Max air Fraction to the zone; then set to min or max
    3855     7223370 :         MassFlow = max(MassFlow, this->sd_airterminalInlet.AirMassFlowRateMinAvail);
    3856     7223370 :         MassFlow = min(MassFlow, this->sd_airterminalInlet.AirMassFlowRateMaxAvail);
    3857             : 
    3858     7223370 :         if (state.afn->distribution_simulated && state.afn->AirflowNetworkFanActivated && state.afn->VAVTerminalRatio > 0.0) {
    3859           0 :             MassFlow *= state.afn->VAVTerminalRatio;
    3860           0 :             if (MassFlow > state.dataLoopNodes->Node(this->InletNodeNum).MassFlowRate) {
    3861           0 :                 MassFlow = state.dataLoopNodes->Node(this->InletNodeNum).MassFlowRate;
    3862             :             }
    3863             :         }
    3864             : 
    3865    45226567 :     } else if ((this->sd_airterminalInlet.AirMassFlowRateMaxAvail > 0.0) &&
    3866    29034151 :                (QTotLoad >= 0.0 || state.dataHeatBalFanSys->TempControlType(ZoneNum) == DataHVACGlobals::ThermostatType::SingleHeating) &&
    3867    12807851 :                (GetCurrentScheduleValue(state, this->SchedPtr) > 0.0)) {
    3868             :         //     IF (sd_airterminal(SysNum)%DamperHeatingAction .EQ. ReverseAction .AND. this->sd_airterminalInlet%AirMassFlowRateMinAvail <=
    3869             :         //     SmallMassFlow) THEN
    3870             :         // special case for heating: reverse action and damper allowed to close - set the minimum flow rate to a small but nonzero value
    3871             :         //       MassFlow = 0.01d0*this->sd_airterminalInlet%AirMassFlowRateMaxAvail
    3872             :         //     ELSE
    3873             :         // usual case for heating: set the air mass flow rate to the minimum
    3874    12807851 :         MassFlow = this->sd_airterminalInlet.AirMassFlowRateMinAvail;
    3875             :         //     END IF
    3876             : 
    3877             :         // Apply the zone maximum outdoor air fraction for VAV boxes - a TRACE feature
    3878    12807851 :         if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).SupplyAirAdjustFactor > 1.0) {
    3879           0 :             MassFlow *= state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).SupplyAirAdjustFactor;
    3880             :         }
    3881             : 
    3882             :         // calculate supply air flow rate based on user specified OA requirement
    3883    12807851 :         this->CalcOAMassFlow(state, MassFlowBasedOnOA, AirLoopOAFrac);
    3884    12807851 :         MassFlow = max(MassFlow, MassFlowBasedOnOA);
    3885             : 
    3886             :         // Check to see if the flow is < the Min or > the Max air Fraction to the zone; then set to min or max
    3887    12807851 :         if (MassFlow <= this->sd_airterminalInlet.AirMassFlowRateMinAvail) {
    3888    12409328 :             MassFlow = this->sd_airterminalInlet.AirMassFlowRateMinAvail;
    3889      398523 :         } else if (MassFlow >= this->sd_airterminalInlet.AirMassFlowRateMaxAvail) {
    3890      300189 :             MassFlow = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    3891             :         }
    3892             : 
    3893             :         // the AirflowNetwork model overrids the mass flow rate value
    3894    12807851 :         if (state.afn->distribution_simulated && state.afn->AirflowNetworkFanActivated && state.afn->VAVTerminalRatio > 0.0) {
    3895           0 :             MassFlow *= state.afn->VAVTerminalRatio;
    3896           0 :             if (MassFlow > state.dataLoopNodes->Node(this->InletNodeNum).MassFlowRate) {
    3897           0 :                 MassFlow = state.dataLoopNodes->Node(this->InletNodeNum).MassFlowRate;
    3898             :             }
    3899             :         }
    3900             : 
    3901             :     } else {
    3902             :         // System is Off set massflow to 0.0
    3903     3401507 :         MassFlow = 0.0;
    3904     3401507 :         AirLoopOAFrac = 0.0;
    3905             :     }
    3906             : 
    3907             :     // look for bang-bang condition: flow rate oscillating between 2 values during the air loop / zone
    3908             :     // equipment iteration. If detected, set flow rate to previous value.
    3909    29526932 :     if (((std::abs(MassFlow - this->MassFlow2) < this->MassFlowDiff) || (std::abs(MassFlow - this->MassFlow3) < this->MassFlowDiff)) &&
    3910     6094204 :         (std::abs(MassFlow - this->MassFlow1) >= this->MassFlowDiff)) {
    3911       14435 :         if (MassFlow > 0.0) MassFlow = this->MassFlow1;
    3912             :     }
    3913             : 
    3914             :     // Move data to the damper outlet node
    3915    23432728 :     this->sd_airterminalOutlet.AirTemp = this->sd_airterminalInlet.AirTemp;
    3916    23432728 :     this->sd_airterminalOutlet.AirHumRat = this->sd_airterminalInlet.AirHumRat;
    3917    23432728 :     this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    3918    23432728 :     this->sd_airterminalOutlet.AirMassFlowRateMaxAvail = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    3919    23432728 :     this->sd_airterminalOutlet.AirMassFlowRateMinAvail = this->sd_airterminalInlet.AirMassFlowRateMinAvail;
    3920    23432728 :     this->sd_airterminalOutlet.AirEnthalpy = this->sd_airterminalInlet.AirEnthalpy;
    3921             : 
    3922             :     //   ! Calculate the Damper Position when there is a Max air flow specified.
    3923             :     //  If (MassFlow == 0.0D0) THEN
    3924             :     //    sd_airterminal(SysNum)%DamperPosition = 0.0D0
    3925             :     //  ELSE IF (this->sd_airterminalInlet%AirMassFlowRateMaxAvail > this->sd_airterminalInlet%AirMassFlowRateMinAvail) THEN
    3926             :     //    sd_airterminal(SysNum)%DamperPosition = ((MassFlow-this->sd_airterminalInlet%AirMassFlowRateMinAvail) / &
    3927             :     //                                   (this->sd_airterminalInlet%AirMassFlowRateMaxAvail-this->sd_airterminalInlet%AirMassFlowRateMinAvail)) *
    3928             :     //                                   &
    3929             :     //                                  (1.0d0-MinFlowFrac) + MinFlowFrac
    3930             :     //  ELSE
    3931             :     //    sd_airterminal(SysNum)%DamperPosition = 1.0D0
    3932             :     //  END IF
    3933             : 
    3934    23432728 :     if (MassFlow == 0.0) {
    3935     3402227 :         this->DamperPosition = 0.0;
    3936     3402227 :         this->ZoneMinAirFracReport = 0.0;
    3937    20030501 :     } else if ((MassFlow > 0.0) && (MassFlow < this->AirMassFlowRateMax)) {
    3938    15601961 :         this->DamperPosition = MassFlow / this->AirMassFlowRateMax;
    3939    15601961 :         this->ZoneMinAirFracReport = this->ZoneMinAirFrac;
    3940     4428540 :     } else if (MassFlow == this->AirMassFlowRateMax) {
    3941     4428540 :         this->DamperPosition = 1.0;
    3942     4428540 :         this->ZoneMinAirFracReport = this->ZoneMinAirFrac;
    3943             :     }
    3944             : 
    3945             :     // Need to make sure that the damper outlets are passed to the coil inlet
    3946    23432728 :     this->UpdateSys(state);
    3947             : 
    3948             :     // At the current air mass flow rate, calculate heating coil load
    3949    23432728 :     QActualHeating = QToHeatSetPt - MassFlow * CpAirAvg * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSDAT); // reheat needed
    3950             : 
    3951             :     // do the reheat calculation if there's some air nass flow (or the damper action is "reverse action"), the flow is <= minimum ,
    3952             :     // there's a heating requirement, and there's a thermostat with a heating setpoint
    3953             :     // Reverse damper option is working only for water coils for now.
    3954    34710853 :     if ((MassFlow > SmallMassFlow) && (QActualHeating > 0.0) &&
    3955    11278125 :         (state.dataHeatBalFanSys->TempControlType(ZoneNum) != DataHVACGlobals::ThermostatType::SingleCooling)) {
    3956             :         // At this point we know that there is a heating requirement: i.e., the heating coil needs to
    3957             :         // be activated (there's a zone heating load or there's a reheat requirement). There are 3 possible
    3958             :         // situations: 1) the coil load can be met by variable temperature air (below the max heat temp) at
    3959             :         // the minimum air mass flow rate; 2) the coil load can be met by variable air flow rate with the air
    3960             :         // temperature fixed at the max heat temp; 3) the load cannot be met (we will run at max air temp and
    3961             :         // max air flow rate). We check for condition 2 by assuming the air temperatute is at the max heat temp
    3962             :         // and solving for the air mass flow rate that will meet the load. If the flow rate is between the min and
    3963             :         // max we are in condition 2.
    3964             : 
    3965    10274604 :         state.dataSingleDuct->QZoneMax2SDAT = QToHeatSetPt;
    3966             : 
    3967             :         // fill dual-max reheat flow limit, if any
    3968    10274604 :         if (this->DamperHeatingAction == Action::Reverse) {
    3969       86487 :             state.dataSingleDuct->MaxDeviceAirMassFlowReheatSDAT = this->AirMassFlowRateMax;
    3970    10188117 :         } else if (this->DamperHeatingAction == Action::ReverseWithLimits) {
    3971     5202128 :             state.dataSingleDuct->MaxDeviceAirMassFlowReheatSDAT = this->AirMassFlowDuringReheatMax;
    3972     4985989 :         } else if (this->DamperHeatingAction == Action::Normal) {
    3973     4914258 :             state.dataSingleDuct->MaxDeviceAirMassFlowReheatSDAT = this->ZoneMinAirFrac * this->AirMassFlowRateMax;
    3974             :         } else {
    3975             :             // used for AIRTERMINAL_SINGLEDUCT_VAV_NOREHEAT or SingleDuctVAVNoReheat
    3976       71731 :             state.dataSingleDuct->MaxDeviceAirMassFlowReheatSDAT = this->AirMassFlowRateMax;
    3977             :         }
    3978             : 
    3979             :         // determine flow based on leaving reheat temperature limit
    3980    10274604 :         if (this->MaxReheatTempSetByUser) {
    3981             : 
    3982     1908370 :             state.dataSingleDuct->MaxHeatTempSDAT = this->MaxReheatTemp;
    3983     1908370 :             if (QToHeatSetPt > SmallLoad) { // zone has a positive load to heating setpoint
    3984     1606096 :                 state.dataSingleDuct->MassFlowReqToLimitLeavingTempSDAT =
    3985     1606096 :                     QToHeatSetPt / (CpAirAvg * (state.dataSingleDuct->MaxHeatTempSDAT - state.dataSingleDuct->ZoneTempSDAT));
    3986             :             } else {
    3987      302274 :                 state.dataSingleDuct->MassFlowReqToLimitLeavingTempSDAT = 0.0;
    3988             :             }
    3989             :         }
    3990             : 
    3991             :         // (re)apply limits to find air mass flow
    3992    10274604 :         MassFlow = max(MassFlow, state.dataSingleDuct->MassFlowReqToLimitLeavingTempSDAT);
    3993    10274604 :         MassFlow = min(MassFlow, state.dataSingleDuct->MaxDeviceAirMassFlowReheatSDAT);
    3994    10274604 :         MassFlow = max(MassFlow, MassFlowBasedOnOA);
    3995    10274604 :         MassFlow = min(MassFlow, this->sd_airterminalInlet.AirMassFlowRateMaxAvail);
    3996    10274604 :         MassFlow = max(MassFlow, this->sd_airterminalInlet.AirMassFlowRateMinAvail);
    3997             : 
    3998    10274604 :         if (state.afn->distribution_simulated && state.afn->AirflowNetworkFanActivated && state.afn->VAVTerminalRatio > 0.0) {
    3999           0 :             MassFlow *= state.afn->VAVTerminalRatio;
    4000           0 :             if (MassFlow > state.dataLoopNodes->Node(this->InletNodeNum).MassFlowRate) {
    4001           0 :                 MassFlow = state.dataLoopNodes->Node(this->InletNodeNum).MassFlowRate;
    4002             :             }
    4003             :         }
    4004             : 
    4005             :         // now make any corrections to heating coil loads
    4006    10274604 :         if (this->MaxReheatTempSetByUser) {
    4007     1908370 :             state.dataSingleDuct->QZoneMaxRHTempLimitSDAT =
    4008     1908370 :                 MassFlow * CpAirAvg * (state.dataSingleDuct->MaxHeatTempSDAT - state.dataSingleDuct->ZoneTempSDAT);
    4009     1908370 :             state.dataSingleDuct->QZoneMax2SDAT = min(state.dataSingleDuct->QZoneMaxRHTempLimitSDAT, QToHeatSetPt);
    4010             :         }
    4011             : 
    4012    10274604 :         this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    4013             : 
    4014    10274604 :         this->UpdateSys(state);
    4015             : 
    4016             :         // Now do the heating coil calculation for each heating coil type
    4017    10274604 :         switch (this->ReheatComp_Num) { // Reverse damper option is working only for water coils for now.
    4018             :             // hot water heating coil
    4019     8990011 :         case HeatingCoilType::SimpleHeating: { // COIL:WATER:SIMPLEHEATING
    4020             :             // Determine the load required to pass to the Component controller
    4021             :             // Although this equation looks strange (using temp instead of deltaT), it is corrected later in ControlCompOutput
    4022             :             // and is working as-is, temperature setpoints are maintained as expected.
    4023     8990011 :             QZnReq = state.dataSingleDuct->QZoneMax2SDAT + MassFlow * CpAirAvg * state.dataSingleDuct->ZoneTempSDAT;
    4024             : 
    4025             :             // Initialize hot water flow rate to zero.
    4026     8990011 :             DummyMdot = 0.0;
    4027     8990011 :             SetActuatedBranchFlowRate(state, DummyMdot, this->ReheatControlNode, this->HWplantLoc, true);
    4028             :             // On the first HVAC iteration the system values are given to the controller, but after that
    4029             :             // the demand limits are in place and there needs to be feedback to the Zone Equipment
    4030     8990011 :             if (FirstHVACIteration) {
    4031     3639726 :                 MaxFlowWater = this->MaxReheatWaterFlow;
    4032     3639726 :                 MinFlowWater = this->MinReheatWaterFlow;
    4033             :             } else {
    4034     5350285 :                 WaterControlNode = this->ReheatControlNode;
    4035     5350285 :                 MaxFlowWater = state.dataLoopNodes->Node(WaterControlNode).MassFlowRateMaxAvail;
    4036     5350285 :                 MinFlowWater = state.dataLoopNodes->Node(WaterControlNode).MassFlowRateMinAvail;
    4037             :             }
    4038             : 
    4039             :             // Simulate the reheat coil at constant air flow. Control by varying the
    4040             :             // hot water flow rate.
    4041             :             // FB use QActualHeating, change ControlCompOutput to use new
    4042     8990011 :             ControlCompOutput(state,
    4043             :                               this->ReheatName,
    4044             :                               this->ReheatComp,
    4045             :                               this->ReheatComp_Index,
    4046             :                               FirstHVACIteration,
    4047             :                               QZnReq,
    4048             :                               this->ReheatControlNode,
    4049             :                               MaxFlowWater,
    4050             :                               MinFlowWater,
    4051             :                               this->ControllerOffset,
    4052             :                               this->ControlCompTypeNum,
    4053             :                               this->CompErrIndex,
    4054             :                               _,
    4055             :                               SysOutletNode,
    4056             :                               MassFlow,
    4057             :                               _,
    4058             :                               _,
    4059             :                               this->HWplantLoc);
    4060             : 
    4061             :             // If reverse action damper and the hot water flow is at maximum, simulate the
    4062             :             // hot water coil with fixed (maximum) hot water flow but allow the air flow to
    4063             :             // vary up to the maximum (air damper opens to try to meet zone load)
    4064     8990011 :             if (this->DamperHeatingAction == Action::Reverse || this->DamperHeatingAction == Action::ReverseWithLimits) {
    4065     4685564 :                 if (state.dataLoopNodes->Node(this->ReheatControlNode).MassFlowRate == MaxFlowWater) {
    4066             :                     // fill limits for air flow for controller
    4067     1401211 :                     state.dataSingleDuct->MinAirMassFlowRevActSVAV = this->AirMassFlowRateMax * this->ZoneMinAirFrac;
    4068     1401211 :                     state.dataSingleDuct->MinAirMassFlowRevActSVAV =
    4069     1401211 :                         min(state.dataSingleDuct->MinAirMassFlowRevActSVAV, this->sd_airterminalInlet.AirMassFlowRateMaxAvail);
    4070     1401211 :                     state.dataSingleDuct->MinAirMassFlowRevActSVAV =
    4071     1401211 :                         max(state.dataSingleDuct->MinAirMassFlowRevActSVAV, this->sd_airterminalInlet.AirMassFlowRateMinAvail);
    4072             : 
    4073     1401211 :                     state.dataSingleDuct->MaxAirMassFlowRevActSVAV = this->AirMassFlowRateMax;
    4074     1401211 :                     state.dataSingleDuct->MaxAirMassFlowRevActSVAV =
    4075     1401211 :                         min(state.dataSingleDuct->MaxAirMassFlowRevActSVAV, state.dataSingleDuct->MaxDeviceAirMassFlowReheatSDAT);
    4076     1401211 :                     state.dataSingleDuct->MaxAirMassFlowRevActSVAV =
    4077     1401211 :                         max(state.dataSingleDuct->MaxAirMassFlowRevActSVAV, state.dataSingleDuct->MinAirMassFlowRevActSVAV);
    4078     1401211 :                     state.dataSingleDuct->MaxAirMassFlowRevActSVAV =
    4079     1401211 :                         min(state.dataSingleDuct->MaxAirMassFlowRevActSVAV, this->sd_airterminalInlet.AirMassFlowRateMaxAvail);
    4080             : 
    4081     1401211 :                     state.dataLoopNodes->Node(this->OutletNodeNum).MassFlowRateMaxAvail =
    4082     1401211 :                         state.dataSingleDuct->MaxAirMassFlowRevActSVAV; // suspect, check how/if used in ControlCompOutput
    4083     5604844 :                     ControlCompOutput(state,
    4084             :                                       this->ReheatName,
    4085             :                                       this->ReheatComp,
    4086             :                                       this->ReheatComp_Index,
    4087             :                                       FirstHVACIteration,
    4088     1401211 :                                       state.dataSingleDuct->QZoneMax2SDAT,
    4089             :                                       this->OutletNodeNum,
    4090     1401211 :                                       state.dataSingleDuct->MaxAirMassFlowRevActSVAV,
    4091     1401211 :                                       state.dataSingleDuct->MinAirMassFlowRevActSVAV,
    4092             :                                       this->ControllerOffset,
    4093             :                                       this->ControlCompTypeNum,
    4094             :                                       this->CompErrIndex,
    4095             :                                       ZoneNodeNum,
    4096             :                                       SysOutletNode); // why not QZnReq  ?
    4097             :                     // air flow controller, not on plant, don't pass plant topology info
    4098             :                     // reset terminal unit inlet air mass flow to new value.
    4099     1401211 :                     state.dataLoopNodes->Node(this->OutletNodeNum).MassFlowRateMaxAvail = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    4100     1401211 :                     MassFlow = state.dataLoopNodes->Node(SysOutletNode).MassFlowRate;
    4101             : 
    4102             :                     //         ! look for bang-bang condition: flow rate oscillating between 2 values during the air loop / zone
    4103             :                     //         ! equipment iteration. If detected, set flow rate to previous value and recalc HW flow.
    4104     3919541 :                     if (((std::abs(MassFlow - this->MassFlow2) < this->MassFlowDiff) ||
    4105     1685491 :                          (std::abs(MassFlow - this->MassFlow3) < this->MassFlowDiff)) &&
    4106      284280 :                         (std::abs(MassFlow - this->MassFlow1) >= this->MassFlowDiff)) {
    4107         933 :                         if (MassFlow > 0.0) MassFlow = this->MassFlow1;
    4108         933 :                         this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    4109         933 :                         this->UpdateSys(state);
    4110             : 
    4111             :                         // Although this equation looks strange (using temp instead of deltaT), it is corrected later in ControlCompOutput
    4112             :                         // and is working as-is, temperature setpoints are maintained as expected.
    4113         933 :                         QZnReq = state.dataSingleDuct->QZoneMax2SDAT + MassFlow * CpAirAvg * state.dataSingleDuct->ZoneTempSDAT;
    4114         933 :                         ControlCompOutput(state,
    4115             :                                           this->ReheatName,
    4116             :                                           this->ReheatComp,
    4117             :                                           this->ReheatComp_Index,
    4118             :                                           FirstHVACIteration,
    4119             :                                           QZnReq,
    4120             :                                           this->ReheatControlNode,
    4121             :                                           MaxFlowWater,
    4122             :                                           MinFlowWater,
    4123             :                                           this->ControllerOffset,
    4124             :                                           this->ControlCompTypeNum,
    4125             :                                           this->CompErrIndex,
    4126             :                                           _,
    4127             :                                           SysOutletNode,
    4128             :                                           MassFlow,
    4129             :                                           _,
    4130             :                                           _,
    4131             :                                           this->HWplantLoc);
    4132             :                     }
    4133             : 
    4134     1401211 :                     this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    4135             :                     // reset OA report variable
    4136     1401211 :                     this->UpdateSys(state);
    4137             :                 } // IF (Node(sd_airterminal(SysNum)%ReheatControlNode)%MassFlowRate .EQ. MaxFlowWater) THEN
    4138             :             }     // IF (sd_airterminal(SysNum)%DamperHeatingAction .EQ. ReverseAction) THEN
    4139             : 
    4140             :             // Recalculate the Damper Position.
    4141     8990011 :             if (MassFlow == 0.0) {
    4142           0 :                 this->DamperPosition = 0.0;
    4143           0 :                 this->ZoneMinAirFracReport = 0.0;
    4144     8990011 :             } else if ((MassFlow > 0.0) && (MassFlow < this->AirMassFlowRateMax)) {
    4145     5446460 :                 this->DamperPosition = MassFlow / this->AirMassFlowRateMax;
    4146     5446460 :                 this->ZoneMinAirFracReport = this->ZoneMinAirFrac;
    4147     3543551 :             } else if (MassFlow == this->AirMassFlowRateMax) {
    4148     3543551 :                 this->DamperPosition = 1.0;
    4149     3543551 :                 this->ZoneMinAirFracReport = this->ZoneMinAirFrac;
    4150             :             }
    4151     8990011 :         } break;
    4152       10899 :         case HeatingCoilType::SteamAirHeating: { // ! COIL:STEAM:AIRHEATING
    4153             :             // Determine the load required to pass to the Component controller
    4154       10899 :             QZnReq =
    4155       10899 :                 state.dataSingleDuct->QZoneMax2SDAT - MassFlow * CpAirAvg * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSDAT);
    4156             : 
    4157             :             // Simulate reheat coil for the VAV system
    4158       10899 :             SimulateSteamCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index, QZnReq);
    4159       10899 :         } break;
    4160     1119492 :         case HeatingCoilType::Electric: { // COIL:ELECTRIC:HEATING
    4161             :             // Determine the load required to pass to the Component controller
    4162     1119492 :             QZnReq =
    4163     1119492 :                 state.dataSingleDuct->QZoneMax2SDAT - MassFlow * CpAirAvg * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSDAT);
    4164             : 
    4165             :             // Simulate reheat coil for the VAV system
    4166     1119492 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, QZnReq, this->ReheatComp_Index);
    4167     1119492 :         } break;
    4168       82471 :         case HeatingCoilType::Gas: { // COIL:GAS:HEATING
    4169             :             // Determine the load required to pass to the Component controller
    4170       82471 :             QZnReq =
    4171       82471 :                 state.dataSingleDuct->QZoneMax2SDAT - MassFlow * CpAirAvg * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSDAT);
    4172             : 
    4173             :             // Simulate reheat coil for the VAV system
    4174       82471 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, QZnReq, this->ReheatComp_Index, QHeatingDelivered);
    4175       82471 :         } break;
    4176       71731 :         case HeatingCoilType::None: { // blank
    4177             :                                       // I no reheat is defined then assume that the damper is the only component.
    4178             :             // If something else is there that is not a reheat coil or a blank then give the error message
    4179       71731 :         } break;
    4180           0 :         default: {
    4181           0 :             ShowFatalError(state, "Invalid Reheat Component=" + this->ReheatComp);
    4182           0 :         } break;
    4183             :         }
    4184             : 
    4185             :         // the COIL is OFF the properties are calculated for this special case.
    4186             :     } else {
    4187    13158124 :         switch (this->ReheatComp_Num) {
    4188    10328516 :         case HeatingCoilType::SimpleHeating: { // COIL:WATER:SIMPLEHEATING
    4189             :             // Simulate reheat coil for the Const Volume system
    4190    10328516 :             DummyMdot = 0.0;
    4191    10328516 :             SetActuatedBranchFlowRate(state, DummyMdot, this->ReheatControlNode, this->HWplantLoc, true);
    4192             :             // call the reheat coil with the NO FLOW condition to make sure that the Node values
    4193             :             // are passed through to the coil outlet correctly
    4194    10328516 :             SimulateWaterCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index);
    4195    10328516 :         } break;
    4196       18741 :         case HeatingCoilType::SteamAirHeating: { // COIL:STEAM:AIRHEATING
    4197             :             // Simulate reheat coil for the VAV system
    4198       18741 :             SimulateSteamCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index, 0.0);
    4199       18741 :         } break;
    4200     2119510 :         case HeatingCoilType::Electric: { // COIL:ELECTRIC:HEATING
    4201             :             // Simulate reheat coil for the VAV system
    4202     2119510 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, 0.0, this->ReheatComp_Index);
    4203     2119510 :         } break;
    4204      401084 :         case HeatingCoilType::Gas: { // COIL:GAS:HEATING
    4205             :             // Simulate reheat coil for the VAV system
    4206      401084 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, 0.0, this->ReheatComp_Index);
    4207      401084 :         } break;
    4208      290273 :         case HeatingCoilType::None: { // blank
    4209             :                                       // If no reheat is defined then assume that the damper is the only component.
    4210             :                                       // If something else is that is not a reheat coil or a blank then give the error message
    4211      290273 :         } break;
    4212           0 :         default: {
    4213           0 :             ShowFatalError(state, "Invalid Reheat Component=" + this->ReheatComp);
    4214           0 :         } break;
    4215             :         }
    4216             :     }
    4217             : 
    4218             :     // push the flow rate history
    4219    23432728 :     this->MassFlow3 = this->MassFlow2;
    4220    23432728 :     this->MassFlow2 = this->MassFlow1;
    4221    23432728 :     this->MassFlow1 = MassFlow;
    4222    23432728 : }
    4223             : 
    4224    20031221 : void SingleDuctAirTerminal::CalcOAMassFlow(EnergyPlusData &state,
    4225             :                                            Real64 &SAMassFlow,   // outside air based on optional user input
    4226             :                                            Real64 &AirLoopOAFrac // outside air based on optional user input
    4227             : ) const
    4228             : {
    4229             : 
    4230             :     // FUNCTION INFORMATION:
    4231             :     //       AUTHOR         R. Raustad (FSEC)
    4232             :     //       DATE WRITTEN   Jan 2010
    4233             :     //       MODIFIED       Mangesh Basarkar, 06/2011: Modifying outside air based on airloop DCV flag
    4234             :     //       RE-ENGINEERED  na
    4235             : 
    4236             :     // PURPOSE OF THIS FUNCTION:
    4237             :     // Calculates the amount of outside air required based on optional user input.
    4238             :     // Zone multipliers are included and are applied in GetInput.
    4239             : 
    4240             :     // METHODOLOGY EMPLOYED:
    4241             :     // User input defines method used to calculate OA.
    4242             : 
    4243             :     // REFERENCES:
    4244             : 
    4245             :     // Using/Aliasing
    4246             :     using Psychrometrics::PsyRhoAirFnPbTdbW;
    4247             : 
    4248             :     // Locals
    4249             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    4250             : 
    4251             :     // FUNCTION PARAMETER DEFINITIONS:
    4252    20031221 :     bool constexpr UseMinOASchFlag(true); // Always use min OA schedule in calculations.
    4253             : 
    4254             :     // FUNCTION PARAMETER DEFINITIONS:
    4255             :     // na
    4256             : 
    4257             :     // INTERFACE BLOCK SPECIFICATIONS
    4258             :     // na
    4259             : 
    4260             :     // DERIVED TYPE DEFINITIONS
    4261             :     // na
    4262             : 
    4263             :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    4264             :     Real64 OAVolumeFlowRate; // outside air volume flow rate (m3/s)
    4265             :     Real64 OAMassFlow;       // outside air mass flow rate (kg/s)
    4266             : 
    4267             :     // initialize OA flow rate and OA report variable
    4268    20031221 :     SAMassFlow = 0.0;
    4269    20031221 :     AirLoopOAFrac = 0.0;
    4270    20031221 :     int AirLoopNum = this->AirLoopNum;
    4271             : 
    4272             :     // Calculate the amount of OA based on optional user inputs
    4273    20031221 :     if (AirLoopNum > 0) {
    4274    20030933 :         AirLoopOAFrac = state.dataAirLoop->AirLoopFlow(AirLoopNum).OAFrac;
    4275             :         // If no additional input from user, RETURN from subroutine
    4276    20030933 :         if (this->NoOAFlowInputFromUser) return;
    4277             :         // Calculate outdoor air flow rate, zone multipliers are applied in GetInput
    4278     2433415 :         if (AirLoopOAFrac > 0.0) {
    4279     4866830 :             OAVolumeFlowRate = DataSizing::calcDesignSpecificationOutdoorAir(
    4280     4866830 :                 state, this->OARequirementsPtr, this->CtrlZoneNum, state.dataAirLoop->AirLoopControlInfo(AirLoopNum).AirLoopDCVFlag, UseMinOASchFlag);
    4281     2433415 :             OAMassFlow = OAVolumeFlowRate * state.dataEnvrn->StdRhoAir;
    4282             : 
    4283             :             // convert OA mass flow rate to supply air flow rate based on air loop OA fraction
    4284     2433415 :             SAMassFlow = OAMassFlow / AirLoopOAFrac;
    4285             :         }
    4286             :     }
    4287             : }
    4288             : 
    4289       68737 : void SingleDuctAirTerminal::SimCBVAV(EnergyPlusData &state, bool const FirstHVACIteration, int const ZoneNum, int const ZoneNodeNum)
    4290             : {
    4291             : 
    4292             :     // SUBROUTINE INFORMATION:
    4293             :     //       AUTHOR         Richard Raustad
    4294             :     //       DATE WRITTEN   August 2006
    4295             :     //       MODIFIED       KHL/TH 10/2010: added maximum supply air temperature leaving reheat coil
    4296             :     //       RE-ENGINEERED  na
    4297             : 
    4298             :     // PURPOSE OF THIS SUBROUTINE:
    4299             :     // This subroutine simulates the VAV box with varying airflow in heating and cooling.
    4300             :     // Modified version of SimVAV.
    4301             : 
    4302             :     // METHODOLOGY EMPLOYED:
    4303             :     // na
    4304             : 
    4305             :     // REFERENCES:
    4306             :     // na
    4307             : 
    4308             :     // Using/Aliasing
    4309             :     using namespace DataZoneEnergyDemands;
    4310             :     using DataHVACGlobals::SmallLoad;
    4311             :     // unused   USE DataHeatBalFanSys,    ONLY: Mat
    4312             :     using HeatingCoils::SimulateHeatingCoilComponents;
    4313             :     using SteamCoils::SimulateSteamCoilComponents;
    4314             :     using WaterCoils::SimulateWaterCoilComponents;
    4315             :     // unused   USE DataHeatBalFanSys,    ONLY: ZoneThermostatSetPointHi, ZoneThermostatSetPointLo
    4316             :     using PlantUtilities::SetActuatedBranchFlowRate;
    4317             : 
    4318             :     // Locals
    4319             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    4320             : 
    4321             :     // SUBROUTINE PARAMETER DEFINITIONS:
    4322             : 
    4323             :     // INTERFACE BLOCK SPECIFICATIONS
    4324             :     // na
    4325             : 
    4326             :     // DERIVED TYPE DEFINITIONS
    4327             :     // na
    4328             : 
    4329             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4330             :     Real64 MassFlow;      // Total Mass Flow Rate from Hot & Cold Inlets [kg/sec]
    4331             :     Real64 QTotLoad;      // Total load based on thermostat setpoint temperature [Watts]
    4332             :     Real64 QZnReq;        // Total load to be met by terminal heater [Watts]
    4333             :     Real64 QToHeatSetPt;  // Remaining load to heating setpoint [W]
    4334             :     Real64 QSupplyAir;    // Zone load met by VAVHeatandCool system
    4335             :     Real64 CpAirZn;       // Specific heat of zone air [J/kg-C]
    4336             :     Real64 CpAirSysIn;    // Specific heat of VAVHeatandCool box entering air [J/kg-C]
    4337             :     Real64 DeltaTemp;     // Temperature difference multiplied by specific heat [J/kg]
    4338             :     Real64 MaxFlowWater;  // This is the value passed to the Controller depending if FirstHVACIteration or not
    4339             :     Real64 MinFlowWater;  // This is the value passed to the Controller depending if FirstHVACIteration or not
    4340             :     Real64 LeakLoadMult;  // Load multiplier to adjust for downstream leaks
    4341             :     int SysOutletNode;    // The node number of the terminal unit outlet node
    4342             :     int SysInletNode;     // The node number of the terminal unit inlet node
    4343             :     int WaterControlNode; // This is the Actuated Reheat Control Node
    4344             :     Real64 DummyMdot;
    4345             :     Real64 QActualHeating;
    4346             :     Real64 MinFlowFrac; // minimum flow fraction (and minimum damper position)
    4347             : 
    4348             :     // sd_airterminal(SysNum)%InletNodeNum is the inlet node to the terminal unit and the damper
    4349             :     // sd_airterminal(SysNum)%OutletNodeNum is the outlet node of the damper and the inlet node of the heating coil
    4350             :     // sd_airterminal(SysNum)%ReheatAirOutletNode is the outlet node of the terminal unit and the heating coil
    4351             : 
    4352             :     // The calculated load from the Heat Balance
    4353       68737 :     LeakLoadMult = state.dataDefineEquipment->AirDistUnit(this->ADUNum).LeakLoadMult;
    4354       68737 :     QTotLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputRequired * LeakLoadMult;
    4355       68737 :     QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToHeatSP * LeakLoadMult;
    4356       68737 :     SysOutletNode = this->ReheatAirOutletNode;
    4357       68737 :     SysInletNode = this->InletNodeNum;
    4358       68737 :     CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNodeNum).HumRat);
    4359       68737 :     MinFlowFrac = this->ZoneMinAirFrac;
    4360       68737 :     state.dataSingleDuct->MinMassAirFlowSCBVAV = MinFlowFrac * state.dataEnvrn->StdRhoAir * this->MaxAirVolFlowRate;
    4361       68737 :     state.dataSingleDuct->ZoneTempSCBVAV = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
    4362             : 
    4363             :     // Then depending on if the Load is for heating or cooling it is handled differently.  First
    4364             :     // the massflow rate for cooling is determined to meet the entire load.  Then
    4365             :     // if the massflow is below the minimum or greater than the Max it is set to either the Min
    4366             :     // or the Max as specified for the VAV model.
    4367       68737 :     if (this->sd_airterminalInlet.AirMassFlowRateMaxAvail > 0.0) {
    4368             :         // Calculate the flow required for cooling
    4369       44059 :         CpAirSysIn = PsyCpAirFnW(this->sd_airterminalInlet.AirHumRat);
    4370       44059 :         DeltaTemp = CpAirSysIn * this->sd_airterminalInlet.AirTemp - CpAirZn * state.dataSingleDuct->ZoneTempSCBVAV;
    4371             : 
    4372             :         // Need to check DeltaTemp and ensure that it is not zero
    4373       44059 :         if (DeltaTemp != 0.0) {
    4374       44050 :             MassFlow = QTotLoad / DeltaTemp;
    4375             :         } else {
    4376           9 :             MassFlow = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    4377             :         }
    4378             : 
    4379             :         // Check to see if the flow is < the Min or > the Max air Fraction to the zone; then set to min or max
    4380       44059 :         MassFlow = max(MassFlow, this->sd_airterminalInlet.AirMassFlowRateMinAvail);
    4381       44059 :         MassFlow = min(MassFlow, this->sd_airterminalInlet.AirMassFlowRateMaxAvail);
    4382             :     } else {
    4383             :         // System is Off set massflow to 0.0
    4384       24678 :         MassFlow = 0.0;
    4385             :     }
    4386             :     // look for bang-bang condition: flow rate oscillating between 2 values during the air loop / zone
    4387             :     // equipment iteration. If detected, set flow rate to previous value.
    4388       94270 :     if (((std::abs(MassFlow - this->MassFlow2) < this->MassFlowDiff) || (std::abs(MassFlow - this->MassFlow3) < this->MassFlowDiff)) &&
    4389       25533 :         (std::abs(MassFlow - this->MassFlow1) >= this->MassFlowDiff)) {
    4390           0 :         MassFlow = this->MassFlow1;
    4391             :     }
    4392             : 
    4393             :     // Move data to the damper outlet node
    4394       68737 :     this->sd_airterminalOutlet.AirTemp = this->sd_airterminalInlet.AirTemp;
    4395       68737 :     this->sd_airterminalOutlet.AirHumRat = this->sd_airterminalInlet.AirHumRat;
    4396       68737 :     this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    4397       68737 :     this->sd_airterminalOutlet.AirMassFlowRateMaxAvail = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    4398       68737 :     this->sd_airterminalOutlet.AirMassFlowRateMinAvail = this->sd_airterminalInlet.AirMassFlowRateMinAvail;
    4399       68737 :     this->sd_airterminalOutlet.AirEnthalpy = this->sd_airterminalInlet.AirEnthalpy;
    4400             : 
    4401             :     // Calculate the Damper Position when there is a Max air flow specified.
    4402       68737 :     if (this->AirMassFlowRateMax == 0.0) {
    4403          13 :         this->DamperPosition = 0.0;
    4404             :     } else {
    4405       68724 :         this->DamperPosition = MassFlow / this->AirMassFlowRateMax;
    4406             :     }
    4407             : 
    4408             :     // Need to make sure that the damper outlets are passed to the coil inlet
    4409       68737 :     this->UpdateSys(state);
    4410             : 
    4411       68737 :     QActualHeating = QToHeatSetPt - MassFlow * CpAirZn * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSCBVAV);
    4412             : 
    4413       89114 :     if ((MassFlow > SmallMassFlow) && (QActualHeating > 0.0) &&
    4414       20377 :         (state.dataHeatBalFanSys->TempControlType(ZoneNum) != DataHVACGlobals::ThermostatType::SingleCooling)) {
    4415             :         //   VAVHeatandCool boxes operate at varying mass flow rates when reheating, VAV boxes operate at min flow
    4416             :         //      (MassFlow <= this->sd_airterminalInlet%AirMassFlowRateMinAvail) .AND. &
    4417             :         //   Per Fred Buhl, don't use DeadBandOrSetback to determine if heaters operate
    4418             :         //      (.NOT. DeadBandOrSetback(ZoneNum))) Then
    4419             : 
    4420             :         // At this point we know that there is a heating requirement: i.e., the heating coil needs to
    4421             :         // be activated (there's a zone heating load or there's a reheat requirement). There are 3 possible
    4422             :         // situations: 1) the coil load can be met by variable temperature air (below the max heat temp) at
    4423             :         // the minimum air mass flow rate; 2) the coil load can be met by variable air flow rate with the air
    4424             :         // temperature fixed at the max heat temp; 3) the load cannot be met (we will run at max air temp and
    4425             :         // max air flow rate). We check for condition 2 by assuming the air temperatute is at the max heat temp
    4426             :         // and solving for the air mass flow rate that will meet the load. If the flow rate is between the min and
    4427             :         // max we are in condition 2.
    4428             : 
    4429       20377 :         state.dataSingleDuct->QZoneMax2SCBVAV = QToHeatSetPt;
    4430             : 
    4431       20377 :         if (this->MaxReheatTempSetByUser) {
    4432             : 
    4433        5043 :             state.dataSingleDuct->MaxHeatTempSCBVAV = this->MaxReheatTemp;
    4434        5043 :             if (QToHeatSetPt > SmallLoad) { // zone has a positive load to heating setpoint
    4435        5043 :                 state.dataSingleDuct->MassFlowReqSCBVAV =
    4436        5043 :                     QToHeatSetPt / (CpAirZn * (state.dataSingleDuct->MaxHeatTempSCBVAV - state.dataSingleDuct->ZoneTempSCBVAV));
    4437             :             } else {
    4438           0 :                 state.dataSingleDuct->MassFlowReqSCBVAV = MassFlow;
    4439             :             }
    4440             : 
    4441        5043 :             state.dataSingleDuct->QZoneMax3SCBVAV =
    4442        5043 :                 CpAirZn * (state.dataSingleDuct->MaxHeatTempSCBVAV - state.dataSingleDuct->ZoneTempSCBVAV) * MassFlow;
    4443             : 
    4444        5043 :             state.dataSingleDuct->MassFlowActualSCBVAV = MassFlow;
    4445             : 
    4446        5043 :             if (state.dataSingleDuct->QZoneMax3SCBVAV < QToHeatSetPt) {
    4447        2419 :                 state.dataSingleDuct->MassFlowActualSCBVAV = state.dataSingleDuct->MassFlowReqSCBVAV;
    4448             :                 // QZoneMax3 = CpAirZn * (MaxHeatTemp - ZoneTemp) * MassFlowActual
    4449             :             }
    4450             : 
    4451        5043 :             if (state.dataSingleDuct->MassFlowActualSCBVAV <= state.dataSingleDuct->MinMassAirFlowSCBVAV) {
    4452           0 :                 state.dataSingleDuct->MassFlowActualSCBVAV = state.dataSingleDuct->MinMassAirFlowSCBVAV;
    4453        5043 :             } else if (state.dataSingleDuct->MassFlowActualSCBVAV >= this->AirMassFlowRateMax) {
    4454        3820 :                 state.dataSingleDuct->MassFlowActualSCBVAV = this->AirMassFlowRateMax;
    4455             :             }
    4456             : 
    4457       10086 :             state.dataSingleDuct->QZoneMaxSCBVAV = CpAirZn * state.dataSingleDuct->MassFlowActualSCBVAV *
    4458        5043 :                                                    (state.dataSingleDuct->MaxHeatTempSCBVAV - state.dataSingleDuct->ZoneTempSCBVAV);
    4459             : 
    4460             :             // temporary variable
    4461        5043 :             state.dataSingleDuct->QZoneMax2SCBVAV = min(state.dataSingleDuct->QZoneMaxSCBVAV, QToHeatSetPt);
    4462             : 
    4463        5043 :             MassFlow = state.dataSingleDuct->MassFlowActualSCBVAV;
    4464             : 
    4465             :         } // IF (sd_airterminal(SysNum)%MaxReheatTempSetByUser) THEN
    4466             : 
    4467       20377 :         this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    4468             : 
    4469       20377 :         this->UpdateSys(state);
    4470             : 
    4471       20377 :         switch (this->ReheatComp_Num) {        // hot water heating coil
    4472           0 :         case HeatingCoilType::SimpleHeating: { // COIL:WATER:SIMPLEHEATING
    4473             :             // Determine the load required to pass to the Component controller
    4474             :             // Although this equation looks strange (using temp instead of deltaT), it is corrected later in ControlCompOutput
    4475             :             // and is working as-is, temperature setpoints are maintained as expected.
    4476           0 :             QZnReq = state.dataSingleDuct->QZoneMax2SCBVAV + MassFlow * CpAirZn * state.dataLoopNodes->Node(ZoneNodeNum).Temp;
    4477           0 :             if (QZnReq < SmallLoad) QZnReq = 0.0;
    4478             : 
    4479             :             // Initialize hot water flow rate to zero.
    4480             :             // Node(sd_airterminal(SysNum)%ReheatControlNode)%MassFlowRate = 0.0D0
    4481           0 :             DummyMdot = 0.0;
    4482           0 :             SetActuatedBranchFlowRate(state, DummyMdot, this->ReheatControlNode, this->HWplantLoc, true);
    4483             :             // On the first HVAC iteration the system values are given to the controller, but after that
    4484             :             // the demand limits are in place and there needs to be feedback to the Zone Equipment
    4485           0 :             if (FirstHVACIteration) {
    4486           0 :                 MaxFlowWater = this->MaxReheatWaterFlow;
    4487           0 :                 MinFlowWater = this->MinReheatWaterFlow;
    4488             :             } else {
    4489           0 :                 WaterControlNode = this->ReheatControlNode;
    4490           0 :                 MaxFlowWater = state.dataLoopNodes->Node(WaterControlNode).MassFlowRateMaxAvail;
    4491           0 :                 MinFlowWater = state.dataLoopNodes->Node(WaterControlNode).MassFlowRateMinAvail;
    4492             :             }
    4493             : 
    4494             :             // Simulate the reheat coil at constant air flow. Control by varying the
    4495             :             // hot water flow rate.
    4496           0 :             ControlCompOutput(state,
    4497             :                               this->ReheatName,
    4498             :                               this->ReheatComp,
    4499             :                               this->ReheatComp_Index,
    4500             :                               FirstHVACIteration,
    4501             :                               QZnReq,
    4502             :                               this->ReheatControlNode,
    4503             :                               MaxFlowWater,
    4504             :                               MinFlowWater,
    4505             :                               this->ControllerOffset,
    4506             :                               this->ControlCompTypeNum,
    4507             :                               this->CompErrIndex,
    4508             :                               _,
    4509             :                               SysOutletNode,
    4510             :                               MassFlow,
    4511             :                               _,
    4512             :                               _,
    4513             :                               this->HWplantLoc);
    4514             : 
    4515             :             // If reverse action damper and the hot water flow is at maximum, simulate the
    4516             :             // hot water coil with fixed (maximum) hot water flow but allow the air flow to
    4517             :             // vary up to the maximum (air damper opens to try to meet zone load).
    4518           0 :             if (this->DamperHeatingAction == Action::Reverse) {
    4519           0 :                 if (state.dataLoopNodes->Node(this->ReheatControlNode).MassFlowRate == this->MaxReheatWaterFlow) {
    4520           0 :                     ControlCompOutput(state,
    4521             :                                       this->ReheatName,
    4522             :                                       this->ReheatComp,
    4523             :                                       this->ReheatComp_Index,
    4524             :                                       FirstHVACIteration,
    4525           0 :                                       state.dataSingleDuct->QZoneMax2SCBVAV,
    4526             :                                       this->OutletNodeNum,
    4527             :                                       this->sd_airterminalInlet.AirMassFlowRateMaxAvail,
    4528             :                                       this->sd_airterminalInlet.AirMassFlowRateMinAvail,
    4529             :                                       this->ControllerOffset,
    4530             :                                       this->ControlCompTypeNum,
    4531             :                                       this->CompErrIndex,
    4532             :                                       ZoneNodeNum,
    4533             :                                       SysOutletNode);
    4534             :                     //                                   ! air flow controller, not on plant, don't pass plant topology info
    4535             : 
    4536             :                     // reset terminal unit inlet air mass flow to new value.
    4537           0 :                     MassFlow = state.dataLoopNodes->Node(SysOutletNode).MassFlowRate;
    4538           0 :                     this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    4539           0 :                     this->UpdateSys(state);
    4540             :                 }
    4541             :                 // look for bang-bang condition: flow rate oscillating between 2 values during the air loop / zone
    4542             :                 // equipment iteration. If detected, set flow rate to previous value and recalc HW flow.
    4543           0 :                 if (((std::abs(MassFlow - this->MassFlow2) < this->MassFlowDiff) || (std::abs(MassFlow - this->MassFlow3) < this->MassFlowDiff)) &&
    4544           0 :                     (std::abs(MassFlow - this->MassFlow1) >= this->MassFlowDiff)) {
    4545           0 :                     MassFlow = this->MassFlow1;
    4546           0 :                     this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    4547           0 :                     this->UpdateSys(state);
    4548           0 :                     ControlCompOutput(state,
    4549             :                                       this->ReheatName,
    4550             :                                       this->ReheatComp,
    4551             :                                       this->ReheatComp_Index,
    4552             :                                       FirstHVACIteration,
    4553             :                                       QZnReq,
    4554             :                                       this->ReheatControlNode,
    4555             :                                       MaxFlowWater,
    4556             :                                       MinFlowWater,
    4557             :                                       this->ControllerOffset,
    4558             :                                       this->ControlCompTypeNum,
    4559             :                                       this->CompErrIndex,
    4560             :                                       _,
    4561             :                                       SysOutletNode,
    4562             :                                       MassFlow,
    4563             :                                       _,
    4564             :                                       _,
    4565             :                                       this->HWplantLoc);
    4566             :                 }
    4567             :                 // recalculate damper position
    4568           0 :                 if (this->AirMassFlowRateMax == 0.0) {
    4569           0 :                     this->DamperPosition = 0.0;
    4570             :                 } else {
    4571           0 :                     this->DamperPosition = MassFlow / this->AirMassFlowRateMax;
    4572             :                 }
    4573             :             }
    4574           0 :         } break;
    4575           0 :         case HeatingCoilType::SteamAirHeating: { // ! COIL:STEAM:AIRHEATING
    4576             :             // Determine the load required to pass to the Component controller
    4577           0 :             QZnReq = state.dataSingleDuct->QZoneMax2SCBVAV -
    4578           0 :                      MassFlow * CpAirZn * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSCBVAV);
    4579           0 :             if (QZnReq < SmallLoad) QZnReq = 0.0;
    4580             : 
    4581             :             // Simulate reheat coil for the VAV system
    4582           0 :             SimulateSteamCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index, QZnReq);
    4583           0 :         } break;
    4584       13167 :         case HeatingCoilType::Electric: { // COIL:ELECTRIC:HEATING
    4585             :             // Determine the load required to pass to the Component controller
    4586       13167 :             QSupplyAir = MassFlow * CpAirZn * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSCBVAV);
    4587       13167 :             QZnReq = state.dataSingleDuct->QZoneMax2SCBVAV - QSupplyAir;
    4588       13167 :             if (QZnReq < SmallLoad) QZnReq = 0.0;
    4589             : 
    4590             :             // Simulate reheat coil for the VAV system
    4591       13167 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, QZnReq, this->ReheatComp_Index);
    4592       13167 :         } break;
    4593           0 :         case HeatingCoilType::Gas: { // COIL:GAS:HEATING
    4594             :             // Determine the load required to pass to the Component controller
    4595           0 :             QZnReq = state.dataSingleDuct->QZoneMax2SCBVAV -
    4596           0 :                      MassFlow * CpAirZn * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSCBVAV);
    4597           0 :             if (QZnReq < SmallLoad) QZnReq = 0.0;
    4598             : 
    4599             :             // Simulate reheat coil for the VAV system
    4600           0 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, QZnReq, this->ReheatComp_Index);
    4601           0 :         } break;
    4602        7210 :         case HeatingCoilType::None: { // blank
    4603             :                                       // If no reheat is defined then assume that the damper is the only component.
    4604             :             // If something else is there that is not a reheat coil then give the error message below.
    4605        7210 :         } break;
    4606           0 :         default: {
    4607           0 :             ShowFatalError(state, "Invalid Reheat Component=" + this->ReheatComp);
    4608           0 :         } break;
    4609             :         }
    4610             : 
    4611             :         // the COIL is OFF the properties are calculated for this special case.
    4612             :     } else {
    4613       48360 :         switch (this->ReheatComp_Num) {
    4614           0 :         case HeatingCoilType::SimpleHeating: { // COIL:WATER:SIMPLEHEATING
    4615             :             // Simulate reheat coil for the Const Volume system
    4616             :             // Node(sd_airterminal(SysNum)%ReheatControlNode)%MassFlowRate = 0.0D0
    4617             :             // Initialize hot water flow rate to zero.
    4618           0 :             DummyMdot = 0.0;
    4619           0 :             SetActuatedBranchFlowRate(state, DummyMdot, this->ReheatControlNode, this->HWplantLoc, true);
    4620             : 
    4621             :             // call the reheat coil with the NO FLOW condition to make sure that the Node values
    4622             :             // are passed through to the coil outlet correctly
    4623           0 :             SimulateWaterCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index);
    4624           0 :         } break;
    4625           0 :         case HeatingCoilType::SteamAirHeating: { // COIL:STEAM:AIRHEATING
    4626             :             // Simulate reheat coil for the VAV system
    4627           0 :             SimulateSteamCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index, 0.0);
    4628           0 :         } break;
    4629       33900 :         case HeatingCoilType::Electric: { // COIL:ELECTRIC:HEATING
    4630             :             // Simulate reheat coil for the VAV system
    4631       33900 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, 0.0, this->ReheatComp_Index);
    4632       33900 :         } break;
    4633           0 :         case HeatingCoilType::Gas: { // COIL:GAS:HEATING
    4634             :             // Simulate reheat coil for the VAV system
    4635           0 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, 0.0, this->ReheatComp_Index);
    4636           0 :         } break;
    4637       14460 :         case HeatingCoilType::None: { // blank
    4638             :                                       // If no reheat is defined then assume that the damper is the only component.
    4639             :                                       // If something else is there that is not a reheat coil then give the error message
    4640       14460 :         } break;
    4641           0 :         default: {
    4642           0 :             ShowFatalError(state, "Invalid Reheat Component=" + this->ReheatComp);
    4643           0 :         } break;
    4644             :         }
    4645             :     }
    4646             :     // push the flow rate history
    4647       68737 :     this->MassFlow3 = this->MassFlow2;
    4648       68737 :     this->MassFlow2 = this->MassFlow1;
    4649       68737 :     this->MassFlow1 = MassFlow;
    4650       68737 : }
    4651             : 
    4652       31064 : void SingleDuctAirTerminal::SimVAVVS(EnergyPlusData &state, bool const FirstHVACIteration, int const ZoneNum, int const ZoneNodeNum)
    4653             : {
    4654             : 
    4655             :     // SUBROUTINE INFORMATION:
    4656             :     //       AUTHOR         Fred Buhl
    4657             :     //       DATE WRITTEN   July 2004
    4658             :     //       MODIFIED       na
    4659             :     //       RE-ENGINEERED  na
    4660             : 
    4661             :     // PURPOSE OF THIS SUBROUTINE:
    4662             :     // This subroutine simulates a single duct VAV terminal unit with a variable-speed fan upstream
    4663             :     // and a reheat coil on the downstream side.
    4664             : 
    4665             :     // METHODOLOGY EMPLOYED:
    4666             :     // Define a compound component in CalcVAVVS. Break the heating/cooling load into 4 regions based
    4667             :     // on equip on/off combinations. Assign the heating load to the appropriate region and iteratively
    4668             :     // solve for the appropriate control variable value using Regula-Falsi solver.
    4669             : 
    4670             :     // Using/Aliasing
    4671             :     using namespace DataZoneEnergyDemands;
    4672             :     using General::SolveRoot;
    4673             :     using SteamCoils::GetCoilCapacity;
    4674             : 
    4675             :     // SUBROUTINE PARAMETER DEFINITIONS:
    4676       31064 :     Real64 constexpr BigLoad(1.0e+20);
    4677             : 
    4678             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4679       31064 :     Real64 MassFlow = 0; // [kg/sec]   Total Mass Flow Rate from Hot & Cold Inlets
    4680             :     Real64 QTotLoad;     // [Watts]
    4681             :     // unused  REAL(r64) :: QZnReq      ! [Watts]
    4682             :     Real64 CpAirZn;
    4683             :     // unused  REAL(r64) :: CpAirSysIn
    4684             :     // unused  REAL(r64) :: DeltaTemp
    4685             :     int SysOutletNode;    // The node number of the terminal unit outlet node
    4686             :     int SysInletNode;     // the node number of the terminal unit inlet node
    4687             :     int WaterControlNode; // This is the Actuated Reheat Control Node
    4688             :     int SteamControlNode;
    4689             :     Real64 MaxFlowWater;    // This is the value passed to the Controller depending if FirstHVACIteration or not
    4690             :     Real64 MinFlowWater;    // This is the value passed to the Controller depending if FirstHVACIteration or not
    4691             :     Real64 MaxFlowSteam;    // This is the value passed to the Controller depending if FirstHVACIteration or not
    4692             :     Real64 MinFlowSteam;    // This is the value passed to the Controller depending if FirstHVACIteration or not
    4693             :     Real64 HWFlow;          // the hot water flow rate [kg/s]
    4694             :     Real64 QCoolFanOnMax;   // max cooling - fan at max flow; note that cooling is always < 0. [W]
    4695             :     Real64 QCoolFanOnMin;   // min active cooling with fan on - fan at lowest speed. [W]
    4696             :     Real64 QHeatFanOnMax;   // max heating - fan at heat flow max, hot water flow at max [W]
    4697             :     Real64 QHeatFanOnMin;   // min heating - fan at min flow, hot water at max flow [W]
    4698             :     Real64 QHeatFanOffMax;  // max heating - fan off, hot water flow at max [W]
    4699             :     Real64 QNoHeatFanOff;   // min heating - fan off, hot water at min flow [W]
    4700             :     HeatingCoilType HCType; // heating coil type
    4701             :     int FanType;            // fan type (as a number)
    4702             :     Real64 HCLoad;          // load passed to a gas or electric heating coil [W]
    4703             :     int FanOp;              // 1 if fan is on; 0 if off.
    4704             :     Real64 MaxCoolMassFlow; // air flow at max cooling [kg/s]
    4705             :     Real64 MaxHeatMassFlow; // air flow at max heating [kg/s]
    4706             :     Real64 MinMassFlow;     // minimum air flow rate [kg/s]
    4707             :     Real64 UnitFlowToler;   // flow rate tolerance
    4708             :     Real64 QDelivered;
    4709             :     Real64 FracDelivered;
    4710             :     int SolFlag;
    4711             :     Real64 ErrTolerance;
    4712             :     Real64 MaxSteamCap; // steam coil capacity at full load
    4713             :     bool ErrorsFound;   // returned from mining function call
    4714             : 
    4715             :     // The calculated load from the Heat Balance
    4716       31064 :     QTotLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputRequired;
    4717       31064 :     SysOutletNode = this->ReheatAirOutletNode;
    4718       31064 :     SysInletNode = this->InletNodeNum;
    4719       31064 :     CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNodeNum).HumRat);
    4720       31064 :     HCType = this->ReheatComp_Num;
    4721       31064 :     FanType = this->Fan_Num;
    4722       31064 :     MaxCoolMassFlow = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    4723       31064 :     MaxHeatMassFlow = min(this->HeatAirMassFlowRateMax, this->sd_airterminalInlet.AirMassFlowRateMaxAvail);
    4724       31064 :     MinMassFlow = MaxCoolMassFlow * this->ZoneMinAirFrac;
    4725       31064 :     UnitFlowToler = 0.001 * DataConvergParams::HVACFlowRateToler;
    4726       31064 :     QDelivered = 0.0;
    4727       31064 :     HWFlow = 0.0;
    4728       31064 :     if (this->sd_airterminalInlet.AirMassFlowRateMaxAvail <= 0.0 || state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
    4729        7914 :         MassFlow = 0.0;
    4730        7914 :         FanOp = 0;
    4731        7914 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, 0.0, 0.0, FanType, MassFlow, FanOp, QDelivered);
    4732        7914 :         return;
    4733             :     }
    4734             : 
    4735       23150 :     if (HCType == HeatingCoilType::SimpleHeating) {
    4736       23150 :         WaterControlNode = this->ReheatControlNode;
    4737       23150 :         HCLoad = 0.0;
    4738       23150 :         if (FirstHVACIteration) {
    4739       11572 :             MaxFlowWater = this->MaxReheatWaterFlow;
    4740       11572 :             MinFlowWater = this->MinReheatWaterFlow;
    4741             :         } else {
    4742       11578 :             WaterControlNode = this->ReheatControlNode;
    4743       11578 :             MaxFlowWater = state.dataLoopNodes->Node(WaterControlNode).MassFlowRateMaxAvail;
    4744       11578 :             MinFlowWater = state.dataLoopNodes->Node(WaterControlNode).MassFlowRateMinAvail;
    4745             :         }
    4746             :     } else {
    4747           0 :         WaterControlNode = 0;
    4748           0 :         HCLoad = BigLoad;
    4749           0 :         MaxFlowWater = 0.0;
    4750           0 :         MinFlowWater = 0.0;
    4751             :     }
    4752             : 
    4753       23150 :     if (HCType == HeatingCoilType::SteamAirHeating) {
    4754           0 :         SteamControlNode = this->ReheatControlNode;
    4755           0 :         HCLoad = 0.0;
    4756           0 :         if (FirstHVACIteration) {
    4757           0 :             MaxFlowSteam = this->MaxReheatSteamFlow;
    4758           0 :             MinFlowSteam = this->MinReheatSteamFlow;
    4759             :         } else {
    4760           0 :             MaxFlowSteam = state.dataLoopNodes->Node(SteamControlNode).MassFlowRateMaxAvail;
    4761           0 :             MinFlowSteam = state.dataLoopNodes->Node(SteamControlNode).MassFlowRateMinAvail;
    4762             :         }
    4763             :     } else {
    4764       23150 :         SteamControlNode = 0;
    4765       23150 :         HCLoad = BigLoad;
    4766       23150 :         MaxFlowSteam = 0.0;
    4767       23150 :         MinFlowSteam = 0.0;
    4768             :     }
    4769             : 
    4770             :     // define 3 load regions and assign the current load to the correct region.
    4771             :     // region 1: active cooling with fan on
    4772       23150 :     FanOp = 1;
    4773       23150 :     if (HCType == HeatingCoilType::SteamAirHeating) {
    4774           0 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowSteam, 0.0, FanType, MaxCoolMassFlow, FanOp, QCoolFanOnMax);
    4775           0 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowSteam, 0.0, FanType, MinMassFlow, FanOp, QCoolFanOnMin);
    4776             :         // region 2: active heating with fan on
    4777           0 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowSteam, BigLoad, FanType, MaxHeatMassFlow, FanOp, QHeatFanOnMax);
    4778           0 :         MaxSteamCap = GetCoilCapacity(state, this->ReheatComp, this->ReheatName, ErrorsFound);
    4779           0 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowSteam, 0.0, FanType, MinMassFlow, FanOp, QHeatFanOnMin);
    4780             :         // region 3: active heating with fan off
    4781           0 :         FanOp = 0;
    4782           0 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowSteam, BigLoad, FanType, MinMassFlow, FanOp, QHeatFanOffMax);
    4783           0 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowSteam, 0.0, FanType, MinMassFlow, FanOp, QNoHeatFanOff);
    4784             :     } else {
    4785       23150 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowWater, 0.0, FanType, MaxCoolMassFlow, FanOp, QCoolFanOnMax);
    4786       23150 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowWater, 0.0, FanType, MinMassFlow, FanOp, QCoolFanOnMin);
    4787             :         // region 2: active heating with fan on
    4788       23150 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowWater, BigLoad, FanType, MaxHeatMassFlow, FanOp, QHeatFanOnMax);
    4789       23150 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowWater, 0.0, FanType, MinMassFlow, FanOp, QHeatFanOnMin);
    4790             :         // region 3: active heating with fan off
    4791       23150 :         FanOp = 0;
    4792       23150 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowWater, BigLoad, FanType, MinMassFlow, FanOp, QHeatFanOffMax);
    4793       23150 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowWater, 0.0, FanType, MinMassFlow, FanOp, QNoHeatFanOff);
    4794             :     }
    4795             : 
    4796             :     // Active cooling with fix for issue #5592
    4797       32314 :     if (QTotLoad < (-1.0 * SmallLoad) && QTotLoad < (QCoolFanOnMin - SmallLoad) && this->sd_airterminalInlet.AirMassFlowRateMaxAvail > 0.0 &&
    4798        9164 :         !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
    4799             :         // check that it can meet the load
    4800        9164 :         FanOp = 1;
    4801        9164 :         if (QCoolFanOnMax < QTotLoad - SmallLoad) {
    4802        9164 :             Real64 MinHWFlow = (HCType == HeatingCoilType::SteamAirHeating) ? MinFlowSteam : MinFlowWater;
    4803             : 
    4804      318178 :             auto f = [&state, this, FirstHVACIteration, ZoneNodeNum, MinHWFlow, FanType, FanOp, QTotLoad](Real64 const SupplyAirMassFlow) {
    4805       45454 :                 Real64 UnitOutput = 0.0; // cooling output [W] (cooling is negative)
    4806             : 
    4807       90908 :                 state.dataSingleDuct->sd_airterminal(this->SysNum)
    4808       90908 :                     .CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinHWFlow, 0.0, FanType, SupplyAirMassFlow, FanOp, UnitOutput);
    4809       90908 :                 return (QTotLoad - UnitOutput) / QTotLoad;
    4810        9164 :             };
    4811             : 
    4812        9164 :             SolveRoot(state, UnitFlowToler, 50, SolFlag, MassFlow, f, MinMassFlow, MaxCoolMassFlow);
    4813        9164 :             if (SolFlag == -1) {
    4814           0 :                 if (this->IterationLimit == 0) {
    4815           0 :                     ShowWarningError(state, "Supply air flow control failed in VS VAV terminal unit " + this->SysName);
    4816           0 :                     ShowContinueError(state, "  Iteration limit exceeded in calculating air flow rate");
    4817             :                 }
    4818           0 :                 ShowRecurringWarningErrorAtEnd(
    4819           0 :                     state, "Supply air flow Iteration limit exceeded in VS VAV terminal unit " + this->SysName, this->IterationLimit);
    4820        9164 :             } else if (SolFlag == -2) {
    4821           0 :                 if (this->IterationFailed == 0) {
    4822           0 :                     ShowWarningError(state, "Supply air flow control failed in VS VAV terminal unit " + this->SysName);
    4823           0 :                     ShowContinueError(state, "  Bad air flow limits");
    4824             :                 }
    4825           0 :                 ShowRecurringWarningErrorAtEnd(
    4826           0 :                     state, "Supply air flow control failed in VS VAV terminal unit " + this->SysName, this->IterationFailed);
    4827             :             }
    4828             : 
    4829             :         } else {
    4830             : 
    4831           0 :             MassFlow = MaxCoolMassFlow;
    4832             : 
    4833           0 :             if (HCType == HeatingCoilType::SteamAirHeating) {
    4834           0 :                 this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowSteam, 0.0, FanType, MassFlow, FanOp, QDelivered);
    4835             :             } else {
    4836           0 :                 this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowWater, 0.0, FanType, MassFlow, FanOp, QDelivered);
    4837             :             }
    4838             :         }
    4839             : 
    4840             :         // no active heating or cooling
    4841       41972 :     } else if ((QTotLoad >= QCoolFanOnMin - SmallLoad && QTotLoad <= QNoHeatFanOff + SmallLoad &&
    4842       27986 :                 this->sd_airterminalInlet.AirMassFlowRateMaxAvail > 0.0) ||
    4843       27944 :                (this->sd_airterminalInlet.AirMassFlowRateMaxAvail > 0.0 && state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum))) {
    4844          14 :         MassFlow = MinMassFlow;
    4845          14 :         FanOp = 0;
    4846          14 :         if (HCType == HeatingCoilType::SteamAirHeating) {
    4847           0 :             this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowSteam, QTotLoad, FanType, MassFlow, FanOp, QNoHeatFanOff);
    4848             :         } else {
    4849          14 :             this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MinFlowWater, 0.0, FanType, MassFlow, FanOp, QNoHeatFanOff);
    4850             :         }
    4851             : 
    4852             :         // active heating
    4853       27944 :     } else if (QTotLoad > QNoHeatFanOff + SmallLoad && this->sd_airterminalInlet.AirMassFlowRateMaxAvail > 0.0 &&
    4854       13972 :                !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum)) {
    4855             :         // hot water coil
    4856       13972 :         if (HCType == HeatingCoilType::SimpleHeating) {
    4857       13972 :             if (QTotLoad < QHeatFanOffMax - SmallLoad) {
    4858             :                 // vary HW flow, leave air flow at minimum
    4859        7595 :                 ErrTolerance = this->ControllerOffset;
    4860        7595 :                 MassFlow = MinMassFlow;
    4861        7595 :                 FanOp = 0;
    4862             : 
    4863      846685 :                 auto f = [&state, this, FirstHVACIteration, ZoneNodeNum, MassFlow, FanType, FanOp, QTotLoad](Real64 const HWMassFlow) {
    4864      120955 :                     Real64 UnitOutput = 0.0; // heating output [W]
    4865      120955 :                     Real64 QSteamLoad = 0.0; // proportional load to calculate steam flow [W]
    4866             : 
    4867      241910 :                     state.dataSingleDuct->sd_airterminal(this->SysNum)
    4868      241910 :                         .CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, HWMassFlow, QSteamLoad, FanType, MassFlow, FanOp, UnitOutput);
    4869             : 
    4870      241910 :                     return (QTotLoad - UnitOutput) / QTotLoad;
    4871        7595 :                 };
    4872             : 
    4873        7595 :                 SolveRoot(state, ErrTolerance, 500, SolFlag, HWFlow, f, MinFlowWater, MaxFlowWater);
    4874        7595 :                 if (SolFlag == -1) {
    4875           0 :                     ShowRecurringWarningErrorAtEnd(state, "Hot Water flow control failed in VS VAV terminal unit " + this->SysName, this->ErrCount1);
    4876           0 :                     ShowRecurringContinueErrorAtEnd(
    4877             :                         state, "...Iteration limit (500) exceeded in calculating the hot water flow rate", this->ErrCount1c);
    4878           0 :                     this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, HWFlow, 0.0, FanType, MassFlow, FanOp, QDelivered);
    4879        7595 :                 } else if (SolFlag == -2) {
    4880           0 :                     ShowRecurringWarningErrorAtEnd(
    4881           0 :                         state, "Hot Water flow control failed (bad air flow limits) in VS VAV terminal unit " + this->SysName, this->ErrCount2);
    4882             :                 }
    4883        6377 :             } else if (QTotLoad >= QHeatFanOffMax - SmallLoad && QTotLoad <= QHeatFanOnMin + SmallLoad) {
    4884          14 :                 MassFlow = MinMassFlow;
    4885          14 :                 FanOp = 0;
    4886          14 :                 this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowWater, 0.0, FanType, MassFlow, FanOp, QDelivered);
    4887        6363 :             } else if (QTotLoad > QHeatFanOnMin + SmallLoad && QTotLoad < QHeatFanOnMax - SmallLoad) {
    4888             :                 // set hot water flow to max and vary the supply air flow rate
    4889        6345 :                 FanOp = 1;
    4890      332038 :                 auto f = [&state, this, FirstHVACIteration, ZoneNodeNum, MaxFlowWater, FanType, FanOp, QTotLoad](Real64 const SupplyAirMassFlow) {
    4891       47434 :                     Real64 UnitOutput = 0.0; // heating output [W]
    4892       94868 :                     state.dataSingleDuct->sd_airterminal(this->SysNum)
    4893       94868 :                         .CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowWater, QTotLoad, FanType, SupplyAirMassFlow, FanOp, UnitOutput);
    4894             : 
    4895       94868 :                     return (QTotLoad - UnitOutput) / QTotLoad;
    4896        6345 :                 };
    4897        6345 :                 SolveRoot(state, UnitFlowToler, 50, SolFlag, MassFlow, f, MinMassFlow, MaxHeatMassFlow);
    4898        6345 :                 if (SolFlag == -1) {
    4899           0 :                     if (this->IterationLimit == 0) {
    4900           0 :                         ShowWarningError(state, "Supply air flow control failed in VS VAV terminal unit " + this->SysName);
    4901           0 :                         ShowContinueError(state, "  Iteration limit exceeded in calculating air flow rate");
    4902             :                     }
    4903           0 :                     ShowRecurringWarningErrorAtEnd(
    4904           0 :                         state, "Supply air flow Iteration limit exceeded in VS VAV terminal unit " + this->SysName, this->IterationLimit);
    4905        6345 :                 } else if (SolFlag == -2) {
    4906           0 :                     if (this->IterationFailed == 0) {
    4907           0 :                         ShowWarningError(state, "Supply air flow control failed in VS VAV terminal unit " + this->SysName);
    4908           0 :                         ShowContinueError(state, "  Bad air flow limits");
    4909             :                     }
    4910           0 :                     ShowRecurringWarningErrorAtEnd(
    4911           0 :                         state, "Supply air flow control failed in VS VAV terminal unit " + this->SysName, this->IterationFailed);
    4912        6345 :                 }
    4913             :             } else {
    4914          18 :                 MassFlow = MaxHeatMassFlow;
    4915          18 :                 FanOp = 1;
    4916          18 :                 this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowWater, 0.0, FanType, MassFlow, FanOp, QDelivered);
    4917             :             }
    4918           0 :         } else if (HCType == HeatingCoilType::SteamAirHeating) {
    4919             :             //      IF (QTotLoad > QNoHeatFanOff + SmallLoad .AND. QTotLoad < QHeatFanOffMax - SmallLoad) THEN
    4920           0 :             if (QTotLoad < QHeatFanOffMax - SmallLoad) {
    4921           0 :                 ErrTolerance = this->ControllerOffset;
    4922           0 :                 MassFlow = MinMassFlow;
    4923           0 :                 FanOp = 0;
    4924             :                 auto f = [&state, this, FirstHVACIteration, ZoneNodeNum, MassFlow, FanType, FanOp, QTotLoad, MinFlowSteam, MaxFlowSteam, MaxSteamCap](
    4925           0 :                              Real64 const HWMassFlow) {
    4926           0 :                     Real64 UnitOutput = 0.0; // heating output [W]
    4927           0 :                     Real64 QSteamLoad = 0.0; // proportional load to calculate steam flow [W]
    4928             : 
    4929             :                     // vary the load to be met by the steam coil to converge on a steam flow rate to meet the load
    4930             :                     //   backwards way of varying steam flow rate. Steam coil calculates a flow rate to meet a load.
    4931           0 :                     if ((MaxFlowSteam - MinFlowSteam) == 0.0) {
    4932           0 :                         QSteamLoad = QTotLoad; // Use QTotLoad, bad starting value error for RegulaFalsi will occur
    4933             :                     } else {
    4934           0 :                         QSteamLoad = MaxSteamCap * HWMassFlow / (MaxFlowSteam - MinFlowSteam);
    4935             :                     }
    4936           0 :                     state.dataSingleDuct->sd_airterminal(this->SysNum)
    4937           0 :                         .CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, HWMassFlow, QSteamLoad, FanType, MassFlow, FanOp, UnitOutput);
    4938             : 
    4939           0 :                     return (QTotLoad - UnitOutput) / QTotLoad;
    4940           0 :                 };
    4941           0 :                 SolveRoot(state, ErrTolerance, 500, SolFlag, HWFlow, f, MinFlowSteam, MaxFlowSteam);
    4942           0 :                 if (SolFlag == -1) {
    4943           0 :                     ShowRecurringWarningErrorAtEnd(state, "Steam flow control failed in VS VAV terminal unit " + this->SysName, this->ErrCount1);
    4944           0 :                     ShowRecurringContinueErrorAtEnd(
    4945             :                         state, "...Iteration limit (500) exceeded in calculating the hot water flow rate", this->ErrCount1c);
    4946           0 :                     this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, HWFlow, 0.0, FanType, MassFlow, FanOp, QDelivered);
    4947           0 :                 } else if (SolFlag == -2) {
    4948           0 :                     ShowRecurringWarningErrorAtEnd(
    4949           0 :                         state, "Steam flow control failed (bad air flow limits) in VS VAV terminal unit " + this->SysName, this->ErrCount2);
    4950             :                 }
    4951           0 :             } else if (QTotLoad >= QHeatFanOffMax - SmallLoad && QTotLoad <= QHeatFanOnMin + SmallLoad) {
    4952           0 :                 MassFlow = MinMassFlow;
    4953           0 :                 FanOp = 0;
    4954           0 :                 this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowWater, 0.0, FanType, MassFlow, FanOp, QDelivered);
    4955           0 :             } else if (QTotLoad > QHeatFanOnMin + SmallLoad && QTotLoad < QHeatFanOnMax - SmallLoad) {
    4956           0 :                 FanOp = 1;
    4957             : 
    4958           0 :                 auto f = [&state, this, FirstHVACIteration, ZoneNodeNum, MaxFlowSteam, FanType, FanOp, QTotLoad](Real64 const SupplyAirMassFlow) {
    4959           0 :                     Real64 UnitOutput = 0.0; // heating output [W]
    4960             : 
    4961           0 :                     state.dataSingleDuct->sd_airterminal(this->SysNum)
    4962           0 :                         .CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, MaxFlowSteam, QTotLoad, FanType, SupplyAirMassFlow, FanOp, UnitOutput);
    4963             : 
    4964           0 :                     return (QTotLoad - UnitOutput) / QTotLoad;
    4965           0 :                 };
    4966             : 
    4967           0 :                 SolveRoot(state, UnitFlowToler, 50, SolFlag, MassFlow, f, MinMassFlow, MaxHeatMassFlow);
    4968           0 :                 if (SolFlag == -1) {
    4969           0 :                     if (this->IterationLimit == 0) {
    4970           0 :                         ShowWarningError(state, "Steam heating coil control failed in VS VAV terminal unit " + this->SysName);
    4971           0 :                         ShowContinueError(state, "  Iteration limit exceeded in calculating air flow rate");
    4972             :                     }
    4973           0 :                     ShowRecurringWarningErrorAtEnd(
    4974           0 :                         state, "Steam heating coil iteration limit exceeded in VS VAV terminal unit " + this->SysName, this->IterationLimit);
    4975           0 :                 } else if (SolFlag == -2) {
    4976           0 :                     if (this->IterationFailed == 0) {
    4977           0 :                         ShowWarningError(state, "Steam heating coil control failed in VS VAV terminal unit " + this->SysName);
    4978           0 :                         ShowContinueError(state, "  Bad air flow limits");
    4979             :                     }
    4980           0 :                     ShowRecurringWarningErrorAtEnd(
    4981           0 :                         state, "Steam heating coil control failed in VS VAV terminal unit " + this->SysName, this->IterationFailed);
    4982           0 :                 }
    4983             :             } else {
    4984           0 :                 MassFlow = MaxHeatMassFlow;
    4985           0 :                 FanOp = 1;
    4986           0 :                 this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, QTotLoad, QTotLoad, FanType, MassFlow, FanOp, QDelivered);
    4987             :             }
    4988           0 :         } else if (HCType == HeatingCoilType::Gas || HCType == HeatingCoilType::Electric) {
    4989           0 :             if (QTotLoad <= QHeatFanOnMin + SmallLoad) {
    4990             :                 // vary heating coil power, leave mass flow at minimum
    4991           0 :                 MassFlow = MinMassFlow;
    4992           0 :                 FanOp = 0;
    4993           0 :                 this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, 0.0, QTotLoad, FanType, MassFlow, FanOp, QDelivered);
    4994           0 :             } else if (QTotLoad > QHeatFanOnMin + SmallLoad && QTotLoad < QHeatFanOnMax - SmallLoad) {
    4995           0 :                 FanOp = 1;
    4996             : 
    4997           0 :                 auto f = [&state, this, FirstHVACIteration, ZoneNodeNum, FanType, FanOp, QTotLoad](Real64 const HeatingFrac) {
    4998           0 :                     Real64 MaxHeatOut{this->ReheatCoilMaxCapacity}; // maximum heating output [W]
    4999             :                     Real64 UnitOutput;                              // heating output [W]
    5000             :                     Real64 AirMassFlowRate;                         // [kg/s]
    5001             :                     Real64 HeatOut;                                 // heating coil output [W]
    5002             : 
    5003           0 :                     HeatOut = HeatingFrac * MaxHeatOut;
    5004           0 :                     AirMassFlowRate = max(HeatingFrac * state.dataSingleDuct->sd_airterminal(this->SysNum).HeatAirMassFlowRateMax,
    5005           0 :                                           state.dataSingleDuct->sd_airterminal(this->SysNum).sd_airterminalInlet.AirMassFlowRateMaxAvail *
    5006           0 :                                               state.dataSingleDuct->sd_airterminal(this->SysNum).ZoneMinAirFrac);
    5007             : 
    5008           0 :                     state.dataSingleDuct->sd_airterminal(this->SysNum)
    5009           0 :                         .CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, 0.0, HeatOut, FanType, AirMassFlowRate, FanOp, UnitOutput);
    5010             : 
    5011           0 :                     return (QTotLoad - UnitOutput) / QTotLoad;
    5012           0 :                 };
    5013             : 
    5014           0 :                 SolveRoot(state, UnitFlowToler, 50, SolFlag, FracDelivered, f, 0.0, 1.0);
    5015           0 :                 MassFlow = state.dataLoopNodes->Node(SysInletNode).MassFlowRate;
    5016           0 :                 if (SolFlag == -1) {
    5017           0 :                     if (this->IterationLimit == 0) {
    5018           0 :                         ShowWarningError(state, "Heating coil control failed in VS VAV terminal unit " + this->SysName);
    5019           0 :                         ShowContinueError(state, "  Iteration limit exceeded in calculating air flow rate");
    5020             :                     }
    5021           0 :                     ShowRecurringWarningErrorAtEnd(
    5022           0 :                         state, "Heating coil control iteration limit exceeded in VS VAV terminal unit " + this->SysName, this->IterationLimit);
    5023           0 :                 } else if (SolFlag == -2) {
    5024           0 :                     if (this->IterationFailed == 0) {
    5025           0 :                         ShowWarningError(state, "Heating coil control failed in VS VAV terminal unit " + this->SysName);
    5026           0 :                         ShowContinueError(state, "  Bad air flow limits");
    5027             :                     }
    5028           0 :                     ShowRecurringWarningErrorAtEnd(
    5029           0 :                         state, "Heating coil control failed in VS VAV terminal unit " + this->SysName, this->IterationFailed);
    5030           0 :                 }
    5031             :             } else {
    5032           0 :                 MassFlow = MaxHeatMassFlow;
    5033           0 :                 FanOp = 1;
    5034           0 :                 this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, 0.0, QTotLoad, FanType, MassFlow, FanOp, QDelivered);
    5035           0 :             }
    5036             :         } else {
    5037           0 :             ShowFatalError(state, "Invalid Reheat Component=" + this->ReheatComp);
    5038             :         }
    5039             : 
    5040             :     } else {
    5041             : 
    5042           0 :         MassFlow = 0.0;
    5043           0 :         FanOp = 0;
    5044           0 :         this->CalcVAVVS(state, FirstHVACIteration, ZoneNodeNum, 0.0, 0.0, FanType, MassFlow, FanOp, QDelivered);
    5045             :     }
    5046             : 
    5047             :     // Move mass flow rates to the damper outlet node
    5048       23150 :     this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    5049       23150 :     this->sd_airterminalOutlet.AirMassFlowRateMaxAvail = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    5050       23150 :     this->sd_airterminalOutlet.AirMassFlowRateMinAvail = this->sd_airterminalInlet.AirMassFlowRateMinAvail;
    5051             : 
    5052             :     // calculate VAV damper Position.
    5053       23150 :     if (this->AirMassFlowRateMax == 0.0) {
    5054           0 :         this->DamperPosition = 0.0;
    5055             :     } else {
    5056       23150 :         this->DamperPosition = MassFlow / this->AirMassFlowRateMax;
    5057             :     }
    5058             :     // update the air terminal outlet node data
    5059       23150 :     this->UpdateSys(state);
    5060             : }
    5061             : 
    5062     1679042 : void SingleDuctAirTerminal::SimConstVol(EnergyPlusData &state, bool const FirstHVACIteration, int const ZoneNum, int const ZoneNodeNum)
    5063             : {
    5064             : 
    5065             :     // SUBROUTINE INFORMATION:
    5066             :     //       AUTHOR         Richard J. Liesen
    5067             :     //       DATE WRITTEN   February 2000
    5068             :     //       MODIFIED       FB/KHL/TH 2/2011: added maximum supply air temperature leaving reheat coil
    5069             :     //       RE-ENGINEERED  na
    5070             : 
    5071             :     // PURPOSE OF THIS SUBROUTINE:
    5072             :     // This subroutine simulates the simple single duct constant volume systems.
    5073             : 
    5074             :     // METHODOLOGY EMPLOYED:
    5075             :     // There is method to this madness.
    5076             : 
    5077             :     // REFERENCES:
    5078             :     // na
    5079             : 
    5080             :     // Using/Aliasing
    5081             :     using namespace DataZoneEnergyDemands;
    5082             :     // unused   USE DataHeatBalFanSys, ONLY: Mat
    5083             :     using HeatingCoils::SimulateHeatingCoilComponents;
    5084             :     using PlantUtilities::SetActuatedBranchFlowRate;
    5085             :     using SteamCoils::SimulateSteamCoilComponents;
    5086             :     using WaterCoils::SimulateWaterCoilComponents;
    5087             : 
    5088             :     // Locals
    5089             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5090             : 
    5091             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5092             : 
    5093             :     // INTERFACE BLOCK SPECIFICATIONS
    5094             :     // na
    5095             : 
    5096             :     // DERIVED TYPE DEFINITIONS
    5097             :     // na
    5098             : 
    5099             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5100             :     Real64 MassFlow;     // [kg/sec]   Total Mass Flow Rate from Hot & Cold Inlets
    5101             :     Real64 QZnReq;       // [Watts]
    5102             :     Real64 QToHeatSetPt; // [W]  remaining load to heating setpoint
    5103             :     Real64 CpAir;
    5104             :     int WaterControlNode;  // This is the Actuated Reheat Control Node
    5105             :     Real64 MaxFlowWater;   // This is the value passed to the Controller depending if FirstHVACIteration or not
    5106             :     Real64 MinFlowWater;   // This is the value passed to the Controller depending if FirstHVACIteration or not
    5107             :     Real64 QActualHeating; // the heating load seen by the reheat coil
    5108             :     Real64 DummyMdot;      // local fluid mass flow rate
    5109             : 
    5110     1679042 :     QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToHeatSP; // The calculated load from the Heat Balance
    5111     1679042 :     MassFlow = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;                                       // System massflow is set to the Available
    5112     1679042 :     state.dataSingleDuct->QMax2SCV = QToHeatSetPt;
    5113     1679042 :     state.dataSingleDuct->ZoneTempSCV = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
    5114     1679042 :     CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNodeNum).HumRat); // zone air specific heat
    5115     1679042 :     if (this->MaxReheatTempSetByUser) {
    5116       10665 :         state.dataSingleDuct->TAirMaxSCV = this->MaxReheatTemp;
    5117       10665 :         state.dataSingleDuct->QMaxSCV = CpAir * MassFlow * (state.dataSingleDuct->TAirMaxSCV - state.dataSingleDuct->ZoneTempSCV);
    5118       10665 :         state.dataSingleDuct->QMax2SCV = min(QToHeatSetPt, state.dataSingleDuct->QMaxSCV);
    5119             :     } // if (this->MaxReheatTempSetByUser) {
    5120             : 
    5121     2680060 :     if (((this->sd_airterminalInlet.AirMassFlowRateMaxAvail == 0.0) && (this->sd_airterminalInlet.AirMassFlowRateMinAvail == 0.0)) ||
    5122     1001018 :         (this->sd_airterminalInlet.AirMassFlowRate == 0.0)) {
    5123             :         // System is Off set massflow to 0.0
    5124      678024 :         MassFlow = 0.0;
    5125             :     }
    5126             : 
    5127             :     // Calculate the Damper Position when there is a Max air flow specified.
    5128     1679042 :     if (this->AirMassFlowRateMax == 0.0) {
    5129          43 :         this->DamperPosition = 0.0;
    5130             :     } else {
    5131     1678999 :         this->DamperPosition = MassFlow / this->AirMassFlowRateMax;
    5132             :     }
    5133             : 
    5134             :     // make sure the inlet node flow rate is updated if the mass flow has been limited
    5135     1679042 :     this->sd_airterminalOutlet.AirMassFlowRate = MassFlow;
    5136     1679042 :     this->sd_airterminalOutlet.AirMassFlowRateMaxAvail = this->sd_airterminalInlet.AirMassFlowRateMaxAvail;
    5137     1679042 :     this->sd_airterminalOutlet.AirMassFlowRateMinAvail = this->sd_airterminalInlet.AirMassFlowRateMinAvail;
    5138     1679042 :     this->UpdateSys(state);
    5139             : 
    5140     1679042 :     QActualHeating = QToHeatSetPt - MassFlow * CpAir * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSCV); // reheat needed
    5141             :     // Now the massflow for reheating has been determined. If it is zero, or in SetBack, or the
    5142             :     // system scheduled OFF then not operational and shut the system down.
    5143     2442511 :     if ((MassFlow > SmallMassFlow) && (QActualHeating > 0.0) &&
    5144      763469 :         (state.dataHeatBalFanSys->TempControlType(ZoneNum) != DataHVACGlobals::ThermostatType::SingleCooling)) {
    5145             : 
    5146      486019 :         switch (this->ReheatComp_Num) {
    5147      434210 :         case HeatingCoilType::SimpleHeating: { // COIL:WATER:SIMPLEHEATING
    5148             :             // Determine the load required to pass to the Component controller
    5149      434210 :             QZnReq = state.dataSingleDuct->QMax2SCV + MassFlow * CpAir * state.dataSingleDuct->ZoneTempSCV;
    5150             : 
    5151             :             // Before Iterating through the Reheat Coil and Controller set the flags for the
    5152             :             // Do Loop to initialized conditions.
    5153             :             // Node(sd_airterminal(SysNum)%ReheatControlNode)%MassFlowRate = 0.0D0
    5154             :             // Initialize hot water flow rate to zero.
    5155      434210 :             DummyMdot = 0.0;
    5156      434210 :             SetActuatedBranchFlowRate(state, DummyMdot, this->ReheatControlNode, this->HWplantLoc, true);
    5157             : 
    5158             :             // On the first HVAC iteration the system values are given to the controller, but after that
    5159             :             // the demand limits are in place and there needs to be feedback to the Zone Equipment
    5160      434210 :             if (FirstHVACIteration) {
    5161      218673 :                 MaxFlowWater = this->MaxReheatWaterFlow;
    5162      218673 :                 MinFlowWater = this->MinReheatWaterFlow;
    5163             :             } else {
    5164      215537 :                 WaterControlNode = this->ReheatControlNode;
    5165      215537 :                 MaxFlowWater = state.dataLoopNodes->Node(WaterControlNode).MassFlowRateMaxAvail;
    5166      215537 :                 MinFlowWater = state.dataLoopNodes->Node(WaterControlNode).MassFlowRateMinAvail;
    5167             :             }
    5168             : 
    5169             :             // Simulate reheat coil for the Const Volume system
    5170             :             // Set Converged to True & when controller is not converged it will set to False.
    5171      434210 :             ControlCompOutput(state,
    5172             :                               this->ReheatName,
    5173             :                               this->ReheatComp,
    5174             :                               this->ReheatComp_Index,
    5175             :                               FirstHVACIteration,
    5176             :                               QZnReq,
    5177             :                               this->ReheatControlNode,
    5178             :                               MaxFlowWater,
    5179             :                               MinFlowWater,
    5180             :                               this->ControllerOffset,
    5181             :                               this->ControlCompTypeNum,
    5182             :                               this->CompErrIndex,
    5183             :                               _,
    5184             :                               this->ReheatAirOutletNode,
    5185             :                               MassFlow,
    5186             :                               _,
    5187             :                               _,
    5188             :                               this->HWplantLoc);
    5189             : 
    5190      434210 :         } break;
    5191           0 :         case HeatingCoilType::SteamAirHeating: { // COIL:STEAM:STEAMAIRHEATING
    5192             :             // Determine the load required to pass to the Component controller
    5193           0 :             QZnReq = state.dataSingleDuct->QMax2SCV - MassFlow * CpAir * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSCV);
    5194             : 
    5195             :             // Simulate reheat coil for the VAV system
    5196           0 :             SimulateSteamCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index, QZnReq);
    5197           0 :         } break;
    5198        4581 :         case HeatingCoilType::Electric: { // COIL:ELECTRIC:HEATING
    5199             :             // Determine the load required to pass to the Component controller
    5200        4581 :             QZnReq = state.dataSingleDuct->QMax2SCV - MassFlow * CpAir * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSCV);
    5201             : 
    5202             :             // Simulate reheat coil for the VAV system
    5203        4581 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, QZnReq, this->ReheatComp_Index);
    5204             : 
    5205        4581 :         } break;
    5206       47228 :         case HeatingCoilType::Gas: { // COIL:GAS:HEATING
    5207             :             // Determine the load required to pass to the Component controller
    5208       47228 :             QZnReq = state.dataSingleDuct->QMax2SCV - MassFlow * CpAir * (this->sd_airterminalInlet.AirTemp - state.dataSingleDuct->ZoneTempSCV);
    5209             : 
    5210             :             // Simulate reheat coil for the VAV system
    5211       47228 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, QZnReq, this->ReheatComp_Index);
    5212       47228 :         } break;
    5213           0 :         default: {
    5214           0 :             ShowFatalError(state, "Invalid Reheat Component=" + this->ReheatComp);
    5215           0 :         } break;
    5216             :         }
    5217             : 
    5218             :         // the COIL is OFF the properties are calculated for this special case.
    5219             :     } else {
    5220     1193023 :         switch (this->ReheatComp_Num) {
    5221      964587 :         case HeatingCoilType::SimpleHeating: { // COIL:WATER:SIMPLEHEATING
    5222             :             // Simulate reheat coil for the Const Volume system
    5223             :             // Node(sd_airterminal(SysNum)%ReheatControlNode)%MassFlowRate = 0.0D0
    5224             :             // Initialize hot water flow rate to zero.
    5225      964587 :             DummyMdot = 0.0;
    5226      964587 :             SetActuatedBranchFlowRate(state, DummyMdot, this->ReheatControlNode, this->HWplantLoc, true);
    5227             : 
    5228             :             // call the reheat coil with the NO FLOW condition to make sure that the Node values
    5229             :             // are passed through to the coil outlet correctly
    5230      964587 :             SimulateWaterCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index);
    5231      964587 :         } break;
    5232           0 :         case HeatingCoilType::SteamAirHeating: { // COIL:STEAM:AIRHEATING
    5233             :             // Simulate reheat coil for the Const Volume system
    5234           0 :             SimulateSteamCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index, 0.0);
    5235           0 :         } break;
    5236       20559 :         case HeatingCoilType::Electric: { // COIL:ELECTRIC:HEATING
    5237             :             // Simulate reheat coil for the Const Volume system
    5238       20559 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, 0.0, this->ReheatComp_Index);
    5239       20559 :         } break;
    5240      207877 :         case HeatingCoilType::Gas: { // COIL:GAS:HEATING
    5241             :             // Simulate reheat coil for the Const Volume system
    5242      207877 :             SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, 0.0, this->ReheatComp_Index);
    5243      207877 :         } break;
    5244           0 :         default: {
    5245           0 :             ShowFatalError(state, "Invalid Reheat Component=" + this->ReheatComp);
    5246           0 :         } break;
    5247             :         }
    5248             :     }
    5249     1679042 : }
    5250             : 
    5251     7471141 : void SingleDuctAirTerminal::SimConstVolNoReheat(EnergyPlusData &state)
    5252             : {
    5253             : 
    5254             :     // PURPOSE OF THIS SUBROUTINE:
    5255             :     // Sets outlet flow rate and conditions for singleduct constantvolume with no reheat air terminal.
    5256             : 
    5257     7471141 :     this->sd_airterminalOutlet = this->sd_airterminalInlet;
    5258             : 
    5259             :     // update the air terminal outlet node data
    5260     7471141 :     this->UpdateSys(state);
    5261     7471141 : }
    5262             : 
    5263      360703 : void SingleDuctAirTerminal::CalcVAVVS(EnergyPlusData &state,
    5264             :                                       bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
    5265             :                                       int const ZoneNode,            // zone node number
    5266             :                                       Real64 const HWFlow,           // hot water flow (kg/s)
    5267             :                                       Real64 const HCoilReq,         // gas or elec coil demand requested
    5268             :                                       int const FanType,             // type of fan
    5269             :                                       Real64 const AirFlow,          // air flow rate (kg/s)
    5270             :                                       int const FanOn,               // 1 means fan is on
    5271             :                                       Real64 &LoadMet                // load met by unit (watts)
    5272             : )
    5273             : {
    5274             : 
    5275             :     // SUBROUTINE INFORMATION:
    5276             :     //       AUTHOR         Fred Buhl
    5277             :     //       DATE WRITTEN   July 2004
    5278             :     //       MODIFIED       na
    5279             :     //       RE-ENGINEERED  na
    5280             : 
    5281             :     // PURPOSE OF THIS SUBROUTINE:
    5282             :     // Simulate the components making up the VAV terminal unit with variable speed fan.
    5283             : 
    5284             :     // METHODOLOGY EMPLOYED:
    5285             :     // Simulates the unit components sequentially in the air flow direction.
    5286             : 
    5287             :     // REFERENCES:
    5288             :     // na
    5289             : 
    5290             :     // Using/Aliasing
    5291             :     using HeatingCoils::SimulateHeatingCoilComponents;
    5292             :     using PlantUtilities::SetComponentFlowRate;
    5293             :     using SteamCoils::SimulateSteamCoilComponents;
    5294             :     using WaterCoils::SimulateWaterCoilComponents;
    5295             : 
    5296             :     // Locals
    5297             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5298             : 
    5299             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5300             :     // na
    5301             : 
    5302             :     // INTERFACE BLOCK SPECIFICATIONS
    5303             :     // na
    5304             : 
    5305             :     // DERIVED TYPE DEFINITIONS
    5306             :     // na
    5307             : 
    5308             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5309             :     int FanInNode;       // unit air inlet node (fan inlet)
    5310             :     int FanOutNode;      // fan outlet node (heating coil inlet node)
    5311             :     int HCOutNode;       // unit air outlet node (heating coil air outlet node)
    5312             :     int HotControlNode;  // the hot water inlet node
    5313             :     Real64 AirMassFlow;  // total air mass flow rate [kg/s]
    5314             :     Real64 CpAirZn;      // zone air specific heat [J/kg-C]
    5315             :     bool TurnFansOffSav; // save the fan off flag
    5316             :     Real64 mdot;
    5317             : 
    5318      360703 :     TurnFansOffSav = state.dataHVACGlobal->TurnFansOff;
    5319      360703 :     FanInNode = this->InletNodeNum;
    5320      360703 :     FanOutNode = this->OutletNodeNum;
    5321      360703 :     HCOutNode = this->ReheatAirOutletNode;
    5322      360703 :     HotControlNode = this->ReheatControlNode;
    5323      360703 :     AirMassFlow = AirFlow;
    5324      360703 :     state.dataLoopNodes->Node(FanInNode).MassFlowRate = AirMassFlow;
    5325      360703 :     CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNode).HumRat);
    5326      360703 :     if (FanType == DataHVACGlobals::FanType_SimpleVAV && FanOn == 1) {
    5327       99203 :         Fans::SimulateFanComponents(state, this->FanName, FirstHVACIteration, this->Fan_Index);
    5328      261500 :     } else if (FanType == DataHVACGlobals::FanType_SystemModelObject && FanOn == 1) {
    5329       86303 :         state.dataHVACFan->fanObjs[this->Fan_Index]->simulate(state, _, _, _, _);
    5330             : 
    5331             :     } else { // pass through conditions
    5332      175197 :         state.dataHVACGlobal->TurnFansOff = true;
    5333      175197 :         if (FanType == DataHVACGlobals::FanType_SimpleVAV) {
    5334      102954 :             Fans::SimulateFanComponents(state, this->FanName, FirstHVACIteration, this->Fan_Index);
    5335       72243 :         } else if (FanType == DataHVACGlobals::FanType_SystemModelObject) {
    5336       72243 :             state.dataHVACFan->fanObjs[this->Fan_Index]->simulate(state, _, _, state.dataHVACGlobal->TurnFansOff, _);
    5337             :         }
    5338      175197 :         state.dataHVACGlobal->TurnFansOff = TurnFansOffSav;
    5339      175197 :         state.dataLoopNodes->Node(FanOutNode).MassFlowRate = state.dataLoopNodes->Node(FanInNode).MassFlowRate;
    5340      175197 :         state.dataLoopNodes->Node(FanOutNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(FanInNode).MassFlowRateMaxAvail;
    5341      175197 :         state.dataLoopNodes->Node(FanOutNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(FanInNode).MassFlowRateMinAvail;
    5342             :     }
    5343      360703 :     switch (this->ReheatComp_Num) {
    5344      360703 :     case HeatingCoilType::SimpleHeating: { // COIL:WATER:SIMPLEHEATING
    5345      360703 :         mdot = HWFlow;
    5346      360703 :         if (this->HWplantLoc.loopNum > 0) {
    5347      360703 :             SetComponentFlowRate(state, mdot, this->ReheatControlNode, this->ReheatCoilOutletNode, this->HWplantLoc);
    5348             :         }
    5349             : 
    5350      360703 :         SimulateWaterCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index);
    5351      360703 :     } break;
    5352           0 :     case HeatingCoilType::SteamAirHeating: { // HW Flow is steam mass flow here
    5353           0 :         mdot = HWFlow;
    5354           0 :         if (this->HWplantLoc.loopNum > 0) {
    5355           0 :             SetComponentFlowRate(state, mdot, this->ReheatControlNode, this->ReheatCoilOutletNode, this->HWplantLoc);
    5356             :         }
    5357           0 :         SimulateSteamCoilComponents(state, this->ReheatName, FirstHVACIteration, this->ReheatComp_Index, HCoilReq);
    5358           0 :     } break;
    5359           0 :     case HeatingCoilType::Electric: { // COIL:ELECTRIC:HEATING
    5360           0 :         SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, HCoilReq, this->ReheatComp_Index);
    5361           0 :     } break;
    5362           0 :     case HeatingCoilType::Gas: { // COIL:GAS:HEATING
    5363           0 :         SimulateHeatingCoilComponents(state, this->ReheatName, FirstHVACIteration, HCoilReq, this->ReheatComp_Index);
    5364           0 :     } break;
    5365           0 :     default: {
    5366           0 :         ShowFatalError(state, "Invalid Reheat Component=" + this->ReheatComp);
    5367           0 :     } break;
    5368             :     }
    5369             : 
    5370      360703 :     LoadMet = AirMassFlow * CpAirZn * (state.dataLoopNodes->Node(HCOutNode).Temp - state.dataLoopNodes->Node(ZoneNode).Temp);
    5371      360703 : }
    5372             : 
    5373             : // End Algorithm Section of the Module
    5374             : // *****************************************************************************
    5375             : 
    5376             : // Beginning of Update subroutines for the Sys Module
    5377             : // *****************************************************************************
    5378             : 
    5379    44371923 : void SingleDuctAirTerminal::UpdateSys(EnergyPlusData &state) const
    5380             : {
    5381             : 
    5382             :     // SUBROUTINE INFORMATION:
    5383             :     //       AUTHOR         Richard J. Liesen
    5384             :     //       DATE WRITTEN   january 2000
    5385             :     //       MODIFIED       na
    5386             :     //       RE-ENGINEERED  na
    5387             : 
    5388             :     // PURPOSE OF THIS SUBROUTINE:
    5389             :     // This subroutine updates the Syss.
    5390             : 
    5391             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5392             :     int OutletNode;
    5393             :     int InletNode;
    5394             : 
    5395    44371923 :     OutletNode = this->OutletNodeNum;
    5396    44371923 :     InletNode = this->InletNodeNum;
    5397             : 
    5398    54007871 :     if (this->SysType_Num == SysType::SingleDuctVAVReheat || this->SysType_Num == SysType::SingleDuctCBVAVReheat ||
    5399    28416349 :         this->SysType_Num == SysType::SingleDuctCBVAVNoReheat || this->SysType_Num == SysType::SingleDuctVAVNoReheat ||
    5400     9173333 :         this->SysType_Num == SysType::SingleDuctConstVolNoReheat) {
    5401             :         // Set the outlet air nodes of the Sys
    5402    42669731 :         state.dataLoopNodes->Node(OutletNode).MassFlowRate = this->sd_airterminalOutlet.AirMassFlowRate;
    5403    42669731 :         state.dataLoopNodes->Node(OutletNode).Temp = this->sd_airterminalOutlet.AirTemp;
    5404    42669731 :         state.dataLoopNodes->Node(OutletNode).HumRat = this->sd_airterminalOutlet.AirHumRat;
    5405    42669731 :         state.dataLoopNodes->Node(OutletNode).Enthalpy = this->sd_airterminalOutlet.AirEnthalpy;
    5406             :         // Set the outlet nodes for properties that just pass through & not used
    5407    42669731 :         state.dataLoopNodes->Node(OutletNode).Quality = state.dataLoopNodes->Node(InletNode).Quality;
    5408    42669731 :         state.dataLoopNodes->Node(OutletNode).Press = state.dataLoopNodes->Node(InletNode).Press;
    5409             :     }
    5410             : 
    5411             :     // After all of the Outlets are updated the mass flow information needs to be
    5412             :     // passed back to the system inlet.
    5413    44371923 :     state.dataLoopNodes->Node(InletNode).MassFlowRate = this->sd_airterminalOutlet.AirMassFlowRate;
    5414    44371923 :     state.dataLoopNodes->Node(OutletNode).MassFlowRateMaxAvail =
    5415    44371923 :         min(this->sd_airterminalOutlet.AirMassFlowRateMaxAvail, state.dataLoopNodes->Node(OutletNode).MassFlowRateMax);
    5416    44371923 :     state.dataLoopNodes->Node(OutletNode).MassFlowRateMinAvail = this->sd_airterminalOutlet.AirMassFlowRateMinAvail;
    5417             : 
    5418    44371923 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    5419       84486 :         state.dataLoopNodes->Node(OutletNode).CO2 = state.dataLoopNodes->Node(InletNode).CO2;
    5420             :     }
    5421             : 
    5422    44371923 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    5423       34971 :         state.dataLoopNodes->Node(OutletNode).GenContam = state.dataLoopNodes->Node(InletNode).GenContam;
    5424             :     }
    5425    44371923 : }
    5426             : 
    5427             : //        End of Update subroutines for the Sys Module
    5428             : // *****************************************************************************
    5429             : 
    5430             : // Beginning of Reporting subroutines for the Sys Module
    5431             : // *****************************************************************************
    5432             : 
    5433    32682712 : void SingleDuctAirTerminal::ReportSys(EnergyPlusData &state) // unused1208
    5434             : {
    5435             : 
    5436             :     // SUBROUTINE INFORMATION:
    5437             :     //       AUTHOR         Unknown
    5438             :     //       DATE WRITTEN   Unknown
    5439             :     //       MODIFIED       na
    5440             :     //       RE-ENGINEERED  na
    5441             : 
    5442             :     // PURPOSE OF THIS SUBROUTINE:
    5443             :     // This subroutine updates the Sys report variables.
    5444             : 
    5445             :     // METHODOLOGY EMPLOYED:
    5446             :     // There is method to this madness.
    5447             : 
    5448             :     // REFERENCES:
    5449             :     // na
    5450             : 
    5451             :     // USE STATEMENTS:
    5452             :     // na
    5453             : 
    5454             :     // Locals
    5455             :     // SUBROUTINE ARGUMENT DEFINITIONS:
    5456             : 
    5457             :     // SUBROUTINE PARAMETER DEFINITIONS:
    5458             :     // na
    5459             : 
    5460             :     // INTERFACE BLOCK SPECIFICATIONS
    5461             :     // na
    5462             : 
    5463             :     // DERIVED TYPE DEFINITIONS
    5464             :     // na
    5465             : 
    5466             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5467             : 
    5468             :     // Still needs to report the Sys power from this component
    5469             : 
    5470             :     // set zone OA volume flow rate
    5471    32682712 :     this->CalcOutdoorAirVolumeFlowRate(state);
    5472    32682712 : }
    5473             : 
    5474         111 : void GetHVACSingleDuctSysIndex(EnergyPlusData &state,
    5475             :                                std::string const &SDSName,
    5476             :                                int &SDSIndex,
    5477             :                                bool &ErrorsFound,
    5478             :                                std::string_view const ThisObjectType,
    5479             :                                Optional_int DamperInletNode, // Damper inlet node number
    5480             :                                Optional_int DamperOutletNode // Damper outlet node number
    5481             : )
    5482             : {
    5483             : 
    5484             :     // SUBROUTINE INFORMATION:
    5485             :     //       AUTHOR         Lixing Gu
    5486             :     //       DATE WRITTEN   February 2006
    5487             :     //       MODIFIED       na
    5488             :     //       RE-ENGINEERED  na
    5489             : 
    5490             :     // PURPOSE OF THIS SUBROUTINE:
    5491             :     // This subroutine sets an index for a given single duct system -- issues error message if that system
    5492             :     // is not a legal system.
    5493             : 
    5494         111 :     if (state.dataSingleDuct->GetInputFlag) { // First time subroutine has been entered
    5495           0 :         GetSysInput(state);
    5496           0 :         state.dataSingleDuct->GetInputFlag = false;
    5497             :     }
    5498             : 
    5499         111 :     SDSIndex = UtilityRoutines::FindItemInList(SDSName, state.dataSingleDuct->sd_airterminal, &SingleDuctAirTerminal::SysName);
    5500         111 :     if (SDSIndex == 0) {
    5501           0 :         if (!ThisObjectType.empty()) {
    5502           0 :             ShowSevereError(state, fmt::format("{}, GetHVACSingleDuctSysIndex: Single duct system not found={}", ThisObjectType, SDSName));
    5503             :         } else {
    5504           0 :             ShowSevereError(state, "GetHVACSingleDuctSysIndex: Single duct system not found=" + SDSName);
    5505             :         }
    5506           0 :         ErrorsFound = true;
    5507             :     } else {
    5508         201 :         if ((state.dataSingleDuct->sd_airterminal(SDSIndex).SysType_Num != SysType::SingleDuctConstVolReheat) &&
    5509          90 :             (state.dataSingleDuct->sd_airterminal(SDSIndex).SysType_Num != SysType::SingleDuctVAVReheat)) {
    5510           0 :             if (!ThisObjectType.empty()) {
    5511           0 :                 ShowSevereError(state, fmt::format("{}, GetHVACSingleDuctSysIndex: Could not find allowed types={}", ThisObjectType, SDSName));
    5512             :             } else {
    5513           0 :                 ShowSevereError(state, "GetHVACSingleDuctSysIndex: Could not find allowed types=" + SDSName);
    5514             :             }
    5515           0 :             ShowContinueError(state, "The allowed types are: AirTerminal:SingleDuct:ConstantVolume:Reheat and AirTerminal:SingleDuct:VAV:Reheat");
    5516           0 :             ErrorsFound = true;
    5517             :         }
    5518         111 :         if (state.dataSingleDuct->sd_airterminal(SDSIndex).SysType_Num == SysType::SingleDuctVAVReheat) {
    5519          90 :             if (present(DamperInletNode)) DamperInletNode = state.dataSingleDuct->sd_airterminal(SDSIndex).InletNodeNum;
    5520          90 :             if (present(DamperOutletNode)) DamperOutletNode = state.dataSingleDuct->sd_airterminal(SDSIndex).OutletNodeNum;
    5521             :         }
    5522             :     }
    5523         111 : }
    5524             : 
    5525     1478855 : void SimATMixer(EnergyPlusData &state, std::string const &SysName, bool const FirstHVACIteration, int &SysIndex)
    5526             : {
    5527             : 
    5528             :     // SUBROUTINE INFORMATION:
    5529             :     //       AUTHOR
    5530             :     //       DATE WRITTEN   March 2012
    5531             :     //       MODIFIED       na
    5532             :     //       RE-ENGINEERED  na
    5533             : 
    5534             :     // PURPOSE OF THIS SUBROUTINE
    5535             :     // Simulate an Air Terminal Mixer component
    5536             : 
    5537             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5538             : 
    5539     1478855 :     if (state.dataSingleDuct->GetATMixerFlag) {
    5540           0 :         state.dataSingleDuct->GetATMixerFlag = false;
    5541             :     }
    5542             : 
    5543     1478855 :     if (SysIndex == 0) {
    5544           0 :         state.dataSingleDuct->SysNumSATM = UtilityRoutines::FindItemInList(SysName, state.dataSingleDuct->SysATMixer);
    5545           0 :         SysIndex = state.dataSingleDuct->SysNumSATM;
    5546           0 :         if (state.dataSingleDuct->SysNumSATM == 0) {
    5547           0 :             ShowFatalError(state, "Object " + SysName + " not found");
    5548             :         }
    5549             :     } else {
    5550     1478855 :         state.dataSingleDuct->SysNumSATM = SysIndex;
    5551             :     }
    5552             : 
    5553     1478855 :     state.dataSingleDuct->SysATMixer(state.dataSingleDuct->SysNumSATM).InitATMixer(state, FirstHVACIteration);
    5554             : 
    5555     1478855 :     CalcATMixer(state, state.dataSingleDuct->SysNumSATM);
    5556             : 
    5557     1478855 :     UpdateATMixer(state, state.dataSingleDuct->SysNumSATM);
    5558     1478855 : }
    5559             : 
    5560      202454 : void GetATMixers(EnergyPlusData &state)
    5561             : {
    5562             : 
    5563             :     // SUBROUTINE INFORMATION:
    5564             :     //       AUTHOR
    5565             :     //       DATE WRITTEN   March 2012
    5566             :     //       MODIFIED       na
    5567             :     //       RE-ENGINEERED  na
    5568             : 
    5569             :     // PURPOSE OF THIS SUBROUTINE
    5570             :     // Get input for inlet side air terminal mixers and store it in the inlet side air terminal mixer array
    5571             : 
    5572             :     // METHODOLOGY EMPLOYED:
    5573             :     // Use the Get routines from the InputProcessor module.
    5574             : 
    5575             :     // Using/Aliasing
    5576             :     using DataZoneEquipment::EquipmentData;
    5577             :     using DataZoneEquipment::SubEquipmentData;
    5578             :     using NodeInputManager::GetOnlySingleNode;
    5579             :     using namespace DataLoopNode;
    5580             :     using BranchNodeConnections::TestCompSet;
    5581             :     using DataHVACGlobals::ATMixer_InletSide;
    5582             :     using DataHVACGlobals::ATMixer_SupplySide;
    5583             : 
    5584             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    5585             :     int NumNums;    // Number of REAL(r64) numbers returned by GetObjectItem
    5586             :     int NumAlphas;  // Number of alphanumerics returned by GetObjectItem
    5587             :     int ATMixerNum; // Index of inlet side mixer air terminal unit
    5588             :     int IOStat;
    5589             :     static constexpr std::string_view RoutineName("GetATMixers: "); // include trailing blank space
    5590      202454 :     bool ErrorsFound(false);                                        // Error flag
    5591             :     int NodeNum;                                                    // Index to node number
    5592             :     int CtrlZone;                                                   // Index to control zone
    5593             :     bool ZoneNodeNotFound;                                          // Flag for error checking
    5594             :     bool errFlag;                                                   // error flag from component validation
    5595             : 
    5596      202454 :     if (!state.dataSingleDuct->GetATMixerFlag) {
    5597      202262 :         return;
    5598             :     }
    5599         192 :     state.dataSingleDuct->GetATMixerFlag = false;
    5600         192 :     auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
    5601         192 :     cCurrentModuleObject = "AirTerminal:SingleDuct:Mixer";
    5602         192 :     state.dataSingleDuct->NumATMixers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
    5603         192 :     state.dataSingleDuct->SysATMixer.allocate(state.dataSingleDuct->NumATMixers);
    5604             : 
    5605             :     // make sure the input data is read in only once
    5606         192 :     if (state.dataZoneAirLoopEquipmentManager->GetAirDistUnitsFlag) {
    5607             :         // Need air distribution units first
    5608          41 :         ZoneAirLoopEquipmentManager::GetZoneAirLoopEquipment(state);
    5609          41 :         state.dataZoneAirLoopEquipmentManager->GetAirDistUnitsFlag = false;
    5610             :     }
    5611             : 
    5612         241 :     for (ATMixerNum = 1; ATMixerNum <= state.dataSingleDuct->NumATMixers; ++ATMixerNum) {
    5613         343 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
    5614             :                                                                  cCurrentModuleObject,
    5615             :                                                                  ATMixerNum,
    5616          49 :                                                                  state.dataIPShortCut->cAlphaArgs,
    5617             :                                                                  NumAlphas,
    5618          49 :                                                                  state.dataIPShortCut->rNumericArgs,
    5619             :                                                                  NumNums,
    5620             :                                                                  IOStat,
    5621          49 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
    5622          49 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
    5623          49 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
    5624          49 :                                                                  state.dataIPShortCut->cNumericFieldNames);
    5625          49 :         UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
    5626          49 :         state.dataSingleDuct->SysATMixer(ATMixerNum).Name = state.dataIPShortCut->cAlphaArgs(1);
    5627          49 :         if (state.dataIPShortCut->cAlphaArgs(7) == "INLETSIDE") {
    5628          27 :             state.dataSingleDuct->SysATMixer(ATMixerNum).MixerType = ATMixer_InletSide; // inlet side mixer
    5629          22 :         } else if (state.dataIPShortCut->cAlphaArgs(7) == "SUPPLYSIDE") {
    5630          22 :             state.dataSingleDuct->SysATMixer(ATMixerNum).MixerType = ATMixer_SupplySide; // supply side mixer
    5631             :         }
    5632          49 :         if (state.dataIPShortCut->cAlphaArgs(2) == "ZONEHVAC:WATERTOAIRHEATPUMP") {
    5633          10 :             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitType = 1;
    5634          39 :         } else if (state.dataIPShortCut->cAlphaArgs(2) == "ZONEHVAC:FOURPIPEFANCOIL") {
    5635          10 :             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitType = 2;
    5636          29 :         } else if (state.dataIPShortCut->cAlphaArgs(2) == "ZONEHVAC:PACKAGEDTERMINALAIRCONDITIONER") {
    5637           9 :             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitType = 3;
    5638          20 :         } else if (state.dataIPShortCut->cAlphaArgs(2) == "ZONEHVAC:PACKAGEDTERMINALHEATPUMP") {
    5639           5 :             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitType = 4;
    5640          15 :         } else if (state.dataIPShortCut->cAlphaArgs(2) == "ZONEHVAC:VARIABLEREFRIGERANTFLOW") {
    5641           0 :             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitType = 5;
    5642          15 :         } else if (state.dataIPShortCut->cAlphaArgs(2) == "AIRLOOPHVAC:UNITARYSYSTEM") {
    5643           5 :             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitType = 6;
    5644          10 :         } else if (state.dataIPShortCut->cAlphaArgs(2) == "ZONEHVAC:UNITVENTILATOR") {
    5645           5 :             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitType = 7;
    5646             :         }
    5647             : 
    5648          49 :         state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitName = state.dataIPShortCut->cAlphaArgs(3);
    5649             : 
    5650          98 :         ValidateComponent(
    5651          98 :             state, state.dataIPShortCut->cAlphaArgs(2), state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneHVACUnitName, errFlag, cCurrentModuleObject);
    5652             : 
    5653          49 :         state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode =
    5654          98 :             GetOnlySingleNode(state,
    5655          49 :                               state.dataIPShortCut->cAlphaArgs(4),
    5656             :                               ErrorsFound,
    5657             :                               DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctMixer,
    5658          49 :                               state.dataIPShortCut->cAlphaArgs(1),
    5659             :                               DataLoopNode::NodeFluidType::Air,
    5660             :                               DataLoopNode::ConnectionType::Outlet,
    5661             :                               NodeInputManager::CompFluidStream::Primary,
    5662             :                               ObjectIsNotParent,
    5663          49 :                               state.dataIPShortCut->cAlphaFieldNames(4));
    5664             : 
    5665          98 :         state.dataSingleDuct->SysATMixer(ATMixerNum).PriInNode = GetOnlySingleNode(state,
    5666          49 :                                                                                    state.dataIPShortCut->cAlphaArgs(5),
    5667             :                                                                                    ErrorsFound,
    5668             :                                                                                    DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctMixer,
    5669          49 :                                                                                    state.dataIPShortCut->cAlphaArgs(1),
    5670             :                                                                                    DataLoopNode::NodeFluidType::Air,
    5671             :                                                                                    DataLoopNode::ConnectionType::Inlet,
    5672             :                                                                                    NodeInputManager::CompFluidStream::Primary,
    5673             :                                                                                    ObjectIsNotParent,
    5674          49 :                                                                                    state.dataIPShortCut->cAlphaFieldNames(5));
    5675          98 :         state.dataSingleDuct->SysATMixer(ATMixerNum).SecInNode = GetOnlySingleNode(state,
    5676          49 :                                                                                    state.dataIPShortCut->cAlphaArgs(6),
    5677             :                                                                                    ErrorsFound,
    5678             :                                                                                    DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctMixer,
    5679          49 :                                                                                    state.dataIPShortCut->cAlphaArgs(1),
    5680             :                                                                                    DataLoopNode::NodeFluidType::Air,
    5681             :                                                                                    DataLoopNode::ConnectionType::Inlet,
    5682             :                                                                                    NodeInputManager::CompFluidStream::Primary,
    5683             :                                                                                    ObjectIsNotParent,
    5684          49 :                                                                                    state.dataIPShortCut->cAlphaFieldNames(6));
    5685             : 
    5686          49 :         if (state.dataIPShortCut->lAlphaFieldBlanks(8)) {
    5687          30 :             state.dataSingleDuct->SysATMixer(ATMixerNum).NoOAFlowInputFromUser = true;
    5688             :         } else {
    5689          19 :             state.dataSingleDuct->SysATMixer(ATMixerNum).OARequirementsPtr =
    5690          19 :                 UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(8), state.dataSize->OARequirements);
    5691          19 :             if (state.dataSingleDuct->SysATMixer(ATMixerNum).OARequirementsPtr == 0) {
    5692           0 :                 ShowSevereError(state,
    5693           0 :                                 std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid data.");
    5694           0 :                 ShowContinueError(state,
    5695           0 :                                   "..invalid " + state.dataIPShortCut->cAlphaFieldNames(8) + "=\"" + state.dataIPShortCut->cAlphaArgs(8) + "\".");
    5696           0 :                 ErrorsFound = true;
    5697             :             } else {
    5698          19 :                 state.dataSingleDuct->SysATMixer(ATMixerNum).NoOAFlowInputFromUser = false;
    5699             :             }
    5700             :         }
    5701             : 
    5702          49 :         if (state.dataIPShortCut->lAlphaFieldBlanks(9)) {
    5703          40 :             state.dataSingleDuct->SysATMixer(ATMixerNum).OAPerPersonMode = DataZoneEquipment::PerPersonVentRateMode::DCVByCurrentLevel;
    5704             :         } else {
    5705           9 :             if (state.dataIPShortCut->cAlphaArgs(9) == "CURRENTOCCUPANCY") {
    5706           9 :                 state.dataSingleDuct->SysATMixer(ATMixerNum).OAPerPersonMode = DataZoneEquipment::PerPersonVentRateMode::DCVByCurrentLevel;
    5707           0 :             } else if (state.dataIPShortCut->cAlphaArgs(9) == "DESIGNOCCUPANCY") {
    5708           0 :                 state.dataSingleDuct->SysATMixer(ATMixerNum).OAPerPersonMode = DataZoneEquipment::PerPersonVentRateMode::ByDesignLevel;
    5709             :             } else {
    5710           0 :                 state.dataSingleDuct->SysATMixer(ATMixerNum).OAPerPersonMode = DataZoneEquipment::PerPersonVentRateMode::DCVByCurrentLevel;
    5711           0 :                 ShowWarningError(state,
    5712           0 :                                  std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + "\", invalid data.");
    5713           0 :                 ShowContinueError(state,
    5714           0 :                                   "..invalid " + state.dataIPShortCut->cAlphaFieldNames(9) + "=\"" + state.dataIPShortCut->cAlphaArgs(9) +
    5715             :                                       "\". The default input of CurrentOccupancy is assigned");
    5716             :             }
    5717             :         }
    5718             : 
    5719             :         // Check for dupes in the three nodes.
    5720          49 :         if (state.dataSingleDuct->SysATMixer(ATMixerNum).SecInNode == state.dataSingleDuct->SysATMixer(ATMixerNum).PriInNode) {
    5721           0 :             ShowSevereError(state,
    5722           0 :                             cCurrentModuleObject + " = " + state.dataSingleDuct->SysATMixer(ATMixerNum).Name + ' ' +
    5723           0 :                                 state.dataIPShortCut->cAlphaArgs(5) + " = " +
    5724           0 :                                 state.dataLoopNodes->NodeID(state.dataSingleDuct->SysATMixer(ATMixerNum).PriInNode) + " duplicates the " +
    5725           0 :                                 state.dataIPShortCut->cAlphaArgs(4) + '.');
    5726           0 :             ErrorsFound = true;
    5727          49 :         } else if (state.dataSingleDuct->SysATMixer(ATMixerNum).SecInNode == state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode) {
    5728           0 :             ShowSevereError(state,
    5729           0 :                             cCurrentModuleObject + " = " + state.dataSingleDuct->SysATMixer(ATMixerNum).Name + ' ' +
    5730           0 :                                 state.dataIPShortCut->cAlphaArgs(6) + " = " +
    5731           0 :                                 state.dataLoopNodes->NodeID(state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode) + " duplicates the " +
    5732           0 :                                 state.dataIPShortCut->cAlphaArgs(4) + '.');
    5733           0 :             ErrorsFound = true;
    5734             :         }
    5735             : 
    5736          49 :         if (state.dataSingleDuct->SysATMixer(ATMixerNum).PriInNode == state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode) {
    5737           0 :             ShowSevereError(state,
    5738           0 :                             cCurrentModuleObject + " = " + state.dataSingleDuct->SysATMixer(ATMixerNum).Name + ' ' +
    5739           0 :                                 state.dataIPShortCut->cAlphaArgs(6) + " = " +
    5740           0 :                                 state.dataLoopNodes->NodeID(state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode) + " duplicates the " +
    5741           0 :                                 state.dataIPShortCut->cAlphaArgs(5) + '.');
    5742           0 :             ErrorsFound = true;
    5743             :         }
    5744             : 
    5745         148 :         for (int ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
    5746         148 :             if (state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode == state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
    5747          49 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum = state.dataSingleDuct->SysATMixer(ATMixerNum).PriInNode;
    5748          49 :                 state.dataSingleDuct->SysATMixer(ATMixerNum).ADUNum = ADUNum;
    5749          49 :                 break;
    5750             :             }
    5751             :         }
    5752             :         // one assumes if there isn't one assigned, it's an error?
    5753          49 :         if (state.dataSingleDuct->SysATMixer(ATMixerNum).ADUNum == 0) {
    5754           0 :             ShowSevereError(state,
    5755           0 :                             std::string{RoutineName} + "No matching Air Distribution Unit, for System = [" + cCurrentModuleObject + ',' +
    5756           0 :                                 state.dataSingleDuct->SysATMixer(ATMixerNum).Name + "].");
    5757           0 :             ShowContinueError(
    5758           0 :                 state, "...should have outlet node = " + state.dataLoopNodes->NodeID(state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode));
    5759           0 :             ErrorsFound = true;
    5760             :         } else {
    5761             : 
    5762          49 :             if (state.dataSingleDuct->SysATMixer(ATMixerNum).MixerType == ATMixer_InletSide) {
    5763             :                 // Air Terminal inlet node must be the same as a zone exhaust node
    5764          27 :                 ZoneNodeNotFound = true;
    5765          94 :                 for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    5766          93 :                     if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
    5767         103 :                     for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumExhaustNodes; ++NodeNum) {
    5768         126 :                         if (state.dataSingleDuct->SysATMixer(ATMixerNum).SecInNode ==
    5769          63 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).ExhaustNode(NodeNum)) {
    5770          26 :                             ZoneNodeNotFound = false;
    5771          26 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->SysATMixer(ATMixerNum).ADUNum).ZoneEqNum = CtrlZone;
    5772          26 :                             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneNum = CtrlZone;
    5773             :                             // Must wait until InitATMixer to fill other zone equip config data because ultimate zone inlet node is not known yet
    5774             :                             // for inlet side mixers
    5775          26 :                             if (!state.dataSingleDuct->SysATMixer(ATMixerNum).NoOAFlowInputFromUser) {
    5776          10 :                                 bool UseOccSchFlag = false;
    5777          10 :                                 bool UseMinOASchFlag = false;
    5778          10 :                                 state.dataSingleDuct->SysATMixer(ATMixerNum).DesignPrimaryAirVolRate =
    5779          30 :                                     DataSizing::calcDesignSpecificationOutdoorAir(state,
    5780          10 :                                                                                   state.dataSingleDuct->SysATMixer(ATMixerNum).OARequirementsPtr,
    5781          10 :                                                                                   state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneNum,
    5782             :                                                                                   UseOccSchFlag,
    5783             :                                                                                   UseMinOASchFlag);
    5784             :                             }
    5785          26 :                             goto ControlledZoneLoop_exit;
    5786             :                         }
    5787             :                     }
    5788             :                 }
    5789           1 :             ControlledZoneLoop_exit:;
    5790          27 :                 if (ZoneNodeNotFound) {
    5791           1 :                     bool ZoneNodeFoundAgain = false;
    5792           4 :                     for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    5793           9 :                         for (int Num = 1; Num <= state.dataZoneEquip->ZoneEquipList(CtrlZone).NumOfEquipTypes; ++Num) {
    5794          12 :                             if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(3),
    5795          13 :                                                             state.dataZoneEquip->ZoneEquipList(CtrlZone).EquipName(Num)) &&
    5796           1 :                                 UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(2),
    5797           1 :                                                             state.dataZoneEquip->ZoneEquipList(CtrlZone).EquipType(Num))) {
    5798           1 :                                 state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->SysATMixer(ATMixerNum).ADUNum).ZoneEqNum = CtrlZone;
    5799           1 :                                 state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneNum = CtrlZone;
    5800             :                                 // Must wait until InitATMixer to fill other zone equip config data because ultimate zone inlet node is not known yet
    5801             :                                 // for inlet side mixers
    5802           1 :                                 if (!state.dataSingleDuct->SysATMixer(ATMixerNum).NoOAFlowInputFromUser) {
    5803           1 :                                     bool UseOccSchFlag = false;
    5804           1 :                                     bool UseMinOASchFlag = false;
    5805           1 :                                     state.dataSingleDuct->SysATMixer(ATMixerNum).DesignPrimaryAirVolRate =
    5806           3 :                                         DataSizing::calcDesignSpecificationOutdoorAir(state,
    5807           1 :                                                                                       state.dataSingleDuct->SysATMixer(ATMixerNum).OARequirementsPtr,
    5808           1 :                                                                                       state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneNum,
    5809             :                                                                                       UseOccSchFlag,
    5810             :                                                                                       UseMinOASchFlag);
    5811             :                                 }
    5812           1 :                                 ZoneNodeFoundAgain = true;
    5813           1 :                                 break;
    5814             :                             }
    5815             :                         }
    5816           4 :                         if (ZoneNodeFoundAgain) break;
    5817             :                     }
    5818           1 :                     if (!ZoneNodeFoundAgain) {
    5819           0 :                         ShowSevereError(state,
    5820           0 :                                         cCurrentModuleObject + " = \"" + state.dataSingleDuct->SysATMixer(ATMixerNum).Name +
    5821             :                                             "\". Inlet Side Air Terminal Mixer air inlet node name must be the same as either a zone exhaust node "
    5822             :                                             "name or an induced "
    5823             :                                             "air node in ZonePlenum.");
    5824           0 :                         ShowContinueError(state, "..Zone exhaust node name is specified in ZoneHVAC:EquipmentConnections object.");
    5825           0 :                         ShowContinueError(state, "..Induced Air Outlet Node name is specified in AirLoopHVAC:ReturnPlenum object.");
    5826           0 :                         ShowContinueError(state,
    5827           0 :                                           "..Inlet Side CONNECTED Air Terminal Mixer inlet node name = " +
    5828           0 :                                               state.dataLoopNodes->NodeID(state.dataSingleDuct->SysATMixer(ATMixerNum).SecInNode));
    5829           0 :                         ErrorsFound = true;
    5830             :                     }
    5831             :                 }
    5832             :             }
    5833             : 
    5834          49 :             if (state.dataSingleDuct->SysATMixer(ATMixerNum).MixerType == ATMixer_SupplySide) {
    5835          22 :                 ZoneNodeNotFound = true;
    5836         106 :                 for (CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    5837         106 :                     if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) continue;
    5838         148 :                     for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(CtrlZone).NumInletNodes; ++NodeNum) {
    5839         172 :                         if (state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode ==
    5840          86 :                             state.dataZoneEquip->ZoneEquipConfig(CtrlZone).InletNode(NodeNum)) {
    5841          22 :                             ZoneNodeNotFound = false;
    5842          22 :                             state.dataDefineEquipment->AirDistUnit(state.dataSingleDuct->SysATMixer(ATMixerNum).ADUNum).ZoneEqNum = CtrlZone;
    5843          22 :                             state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneNum = CtrlZone;
    5844             :                             // Wait until InitATMixer to fill other zone equip config data
    5845             : 
    5846          22 :                             if (!state.dataSingleDuct->SysATMixer(ATMixerNum).NoOAFlowInputFromUser) {
    5847           8 :                                 bool UseOccSchFlag = false;
    5848           8 :                                 bool UseMinOASchFlag = false;
    5849           8 :                                 state.dataSingleDuct->SysATMixer(ATMixerNum).DesignPrimaryAirVolRate =
    5850          24 :                                     DataSizing::calcDesignSpecificationOutdoorAir(state,
    5851           8 :                                                                                   state.dataSingleDuct->SysATMixer(ATMixerNum).OARequirementsPtr,
    5852           8 :                                                                                   state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneNum,
    5853             :                                                                                   UseOccSchFlag,
    5854             :                                                                                   UseMinOASchFlag);
    5855             :                             }
    5856          22 :                             goto ControlZoneLoop_exit;
    5857             :                         }
    5858             :                     }
    5859             :                 }
    5860           0 :             ControlZoneLoop_exit:;
    5861          22 :                 if (ZoneNodeNotFound) {
    5862           0 :                     ShowSevereError(state,
    5863           0 :                                     cCurrentModuleObject + " = \"" + state.dataSingleDuct->SysATMixer(ATMixerNum).Name +
    5864             :                                         "\". Supply Side Air Terminal Mixer air outlet node name must be the same as a zone inlet node name.");
    5865           0 :                     ShowContinueError(state, "..Zone inlet node name is specified in ZoneHVAC:EquipmentConnections object.");
    5866           0 :                     ShowContinueError(state,
    5867           0 :                                       "..Supply Side connected Air Terminal Mixer outlet node name = " +
    5868           0 :                                           state.dataLoopNodes->NodeID(state.dataSingleDuct->SysATMixer(ATMixerNum).MixedAirOutNode));
    5869           0 :                     ErrorsFound = true;
    5870             :                 }
    5871             :             }
    5872             :         }
    5873          98 :         TestCompSet(state,
    5874             :                     cCurrentModuleObject,
    5875          49 :                     state.dataSingleDuct->SysATMixer(ATMixerNum).Name,
    5876          49 :                     state.dataIPShortCut->cAlphaArgs(5),
    5877          49 :                     state.dataIPShortCut->cAlphaArgs(4),
    5878             :                     "Air Nodes");
    5879             : 
    5880          49 :         if (state.dataSingleDuct->SysATMixer(ATMixerNum).OARequirementsPtr == 0) {
    5881          30 :             if (state.dataSize->ZoneSizingInput.allocated()) {
    5882         180 :                 for (int SizingInputNum = 1; SizingInputNum <= state.dataSize->NumZoneSizingInput; ++SizingInputNum) {
    5883         150 :                     if (state.dataSize->ZoneSizingInput(SizingInputNum).ZoneNum == state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneNum) {
    5884          30 :                         if (state.dataSize->ZoneSizingInput(SizingInputNum).ZoneDesignSpecOAIndex == 0) {
    5885           0 :                             ShowWarningError(state,
    5886           0 :                                              std::string{RoutineName} + cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
    5887             :                                                  "\", invalid data.");
    5888           0 :                             ShowContinueError(state,
    5889           0 :                                               state.dataIPShortCut->cAlphaFieldNames(8) +
    5890             :                                                   " is blank in both the mixer and the Sizing:Zone object for the same zone.");
    5891           0 :                             ShowContinueError(state, "The mixer outdoor airflow rate is set to zero.");
    5892           0 :                             state.dataSingleDuct->SysATMixer(ATMixerNum).DesignPrimaryAirVolRate = 0.0;
    5893             :                         } else {
    5894          30 :                             state.dataSingleDuct->SysATMixer(ATMixerNum).OARequirementsPtr =
    5895          30 :                                 state.dataSize->ZoneSizingInput(SizingInputNum).ZoneDesignSpecOAIndex;
    5896          30 :                             state.dataSingleDuct->SysATMixer(ATMixerNum).DesignPrimaryAirVolRate =
    5897          60 :                                 DataSizing::calcDesignSpecificationOutdoorAir(state,
    5898          30 :                                                                               state.dataSingleDuct->SysATMixer(ATMixerNum).OARequirementsPtr,
    5899          30 :                                                                               state.dataSingleDuct->SysATMixer(ATMixerNum).ZoneNum,
    5900             :                                                                               false,
    5901             :                                                                               false);
    5902          30 :                             state.dataSingleDuct->SysATMixer(ATMixerNum).NoOAFlowInputFromUser = false;
    5903             :                         }
    5904             :                     }
    5905             :                 }
    5906             :             } else {
    5907           0 :                 ShowWarningError(state,
    5908           0 :                                  state.dataIPShortCut->cAlphaFieldNames(8) +
    5909             :                                      "is blank and there is no Sizing:Zone for the same zone. The mixer outdoor airflow rate is set to zero.");
    5910           0 :                 state.dataSingleDuct->SysATMixer(ATMixerNum).DesignPrimaryAirVolRate = 0.0;
    5911             :             }
    5912             :         }
    5913          49 :         state.dataSingleDuct->SysATMixer(ATMixerNum).MassFlowRateMaxAvail =
    5914          49 :             state.dataSingleDuct->SysATMixer(ATMixerNum).DesignPrimaryAirVolRate * state.dataEnvrn->StdRhoAir;
    5915             :     }
    5916             : 
    5917         192 :     if (ErrorsFound) {
    5918           0 :         ShowFatalError(state, std::string{RoutineName} + "Errors found in input.  Program terminates.");
    5919             :     }
    5920             : }
    5921             : 
    5922     1478904 : void AirTerminalMixerData::InitATMixer(EnergyPlusData &state, bool const FirstHVACIteration)
    5923             : {
    5924             :     // Purpose: Initialize the AirTerminalMixers data structure with node data
    5925     1478904 :     if (this->OneTimeInitFlag) {
    5926             :         {
    5927          49 :             auto &thisADU(state.dataDefineEquipment->AirDistUnit(this->ADUNum));
    5928             :             {
    5929          49 :                 auto &thisZoneEqConfig(state.dataZoneEquip->ZoneEquipConfig(thisADU.ZoneEqNum));
    5930          98 :                 for (int SupAirIn = 1; SupAirIn <= thisZoneEqConfig.NumInletNodes; ++SupAirIn) {
    5931          49 :                     if (this->ZoneInletNode == thisZoneEqConfig.InletNode(SupAirIn)) {
    5932          49 :                         thisZoneEqConfig.AirDistUnitCool(SupAirIn).InNode = this->PriInNode;
    5933          49 :                         thisZoneEqConfig.AirDistUnitCool(SupAirIn).OutNode = this->MixedAirOutNode;
    5934          49 :                         thisZoneEqConfig.AirDistUnitHeat(SupAirIn).InNode = this->PriInNode;
    5935          49 :                         thisZoneEqConfig.AirDistUnitHeat(SupAirIn).OutNode = this->MixedAirOutNode;
    5936          49 :                         thisADU.TermUnitSizingNum = thisZoneEqConfig.AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
    5937          49 :                         this->CtrlZoneInNodeIndex = SupAirIn;
    5938             :                         {
    5939          49 :                             auto &thisTermUnitSizingData(state.dataSize->TermUnitSizing(thisADU.TermUnitSizingNum));
    5940          49 :                             thisTermUnitSizingData.ADUName = thisADU.Name;
    5941             :                             // Fill TermUnitSizing with specs from DesignSpecification:AirTerminal:Sizing if there is one attached to this
    5942             :                             // terminal unit
    5943          49 :                             if (thisADU.AirTerminalSizingSpecIndex > 0) {
    5944             :                                 {
    5945           0 :                                     auto const &thisAirTermSizingSpec(state.dataSize->AirTerminalSizingSpec(thisADU.AirTerminalSizingSpecIndex));
    5946           0 :                                     thisTermUnitSizingData.SpecDesCoolSATRatio = thisAirTermSizingSpec.DesCoolSATRatio;
    5947           0 :                                     thisTermUnitSizingData.SpecDesHeatSATRatio = thisAirTermSizingSpec.DesHeatSATRatio;
    5948           0 :                                     thisTermUnitSizingData.SpecDesSensCoolingFrac = thisAirTermSizingSpec.DesSensCoolingFrac;
    5949           0 :                                     thisTermUnitSizingData.SpecDesSensHeatingFrac = thisAirTermSizingSpec.DesSensHeatingFrac;
    5950           0 :                                     thisTermUnitSizingData.SpecMinOAFrac = thisAirTermSizingSpec.MinOAFrac;
    5951             :                                 }
    5952             :                             }
    5953             :                         }
    5954             :                     }
    5955             :                 }
    5956             :             }
    5957             :         }
    5958          49 :         this->OneTimeInitFlag = false;
    5959             :     }
    5960             : 
    5961             :     // Keep trying until we find it, the airloopnum, that is
    5962     1478904 :     if (this->OneTimeInitFlag2) {
    5963         448 :         this->AirLoopNum = state.dataZoneEquip->ZoneEquipConfig(state.dataDefineEquipment->AirDistUnit(this->ADUNum).ZoneEqNum)
    5964         224 :                                .InletNodeAirLoopNum(this->CtrlZoneInNodeIndex);
    5965         224 :         state.dataDefineEquipment->AirDistUnit(this->ADUNum).AirLoopNum = this->AirLoopNum;
    5966         224 :         if (this->AirLoopNum > 0) {
    5967          49 :             this->OneTimeInitFlag2 = false;
    5968             :         }
    5969             :     }
    5970             : 
    5971             :     // Every iteration
    5972     1478904 :     Real64 mDotFromOARequirement(0.0);
    5973     1478904 :     Real64 vDotOAReq(0.0);
    5974     1478904 :     if (!this->NoOAFlowInputFromUser) {
    5975     1478904 :         Real64 airLoopOAFrac(0.0);
    5976     1478904 :         bool UseOccSchFlag = false;
    5977     1478904 :         if (this->OAPerPersonMode == DataZoneEquipment::PerPersonVentRateMode::DCVByCurrentLevel) UseOccSchFlag = true;
    5978     1478904 :         if (this->AirLoopNum > 0) {
    5979     1478729 :             airLoopOAFrac = state.dataAirLoop->AirLoopFlow(this->AirLoopNum).OAFrac;
    5980     1478729 :             if (airLoopOAFrac > 0.0) {
    5981     1265223 :                 vDotOAReq = DataSizing::calcDesignSpecificationOutdoorAir(state, this->OARequirementsPtr, this->ZoneNum, UseOccSchFlag, true);
    5982     1265223 :                 mDotFromOARequirement = vDotOAReq * state.dataEnvrn->StdRhoAir / airLoopOAFrac;
    5983             :             } else {
    5984      213506 :                 mDotFromOARequirement = state.dataLoopNodes->Node(this->PriInNode).MassFlowRate;
    5985             :             }
    5986             :         }
    5987     1478904 :         if (FirstHVACIteration) {
    5988      713955 :             state.dataLoopNodes->Node(this->PriInNode).MassFlowRate = mDotFromOARequirement;
    5989      713955 :             state.dataLoopNodes->Node(this->PriInNode).MassFlowRateMaxAvail = this->MassFlowRateMaxAvail;
    5990      713955 :             state.dataLoopNodes->Node(this->PriInNode).MassFlowRateMinAvail = 0.0;
    5991             :         } else {
    5992      764949 :             state.dataLoopNodes->Node(this->PriInNode).MassFlowRate = mDotFromOARequirement;
    5993             : 
    5994      764949 :             state.dataLoopNodes->Node(this->PriInNode).MassFlowRate =
    5995      764949 :                 min(state.dataLoopNodes->Node(this->PriInNode).MassFlowRate, state.dataLoopNodes->Node(this->PriInNode).MassFlowRateMaxAvail);
    5996      764949 :             state.dataLoopNodes->Node(this->PriInNode).MassFlowRate =
    5997      764949 :                 max(state.dataLoopNodes->Node(this->PriInNode).MassFlowRate, state.dataLoopNodes->Node(this->PriInNode).MassFlowRateMinAvail);
    5998      764949 :             state.dataLoopNodes->Node(this->PriInNode).MassFlowRate =
    5999      764949 :                 max(state.dataLoopNodes->Node(this->PriInNode).MassFlowRate, state.dataLoopNodes->Node(this->PriInNode).MassFlowRateMin);
    6000             :         }
    6001             :     }
    6002     1478904 :     if (this->MixerType == ATMixer_InletSide) {
    6003      877173 :         state.dataLoopNodes->Node(this->PriInNode).MassFlowRate =
    6004      877173 :             min(state.dataLoopNodes->Node(this->PriInNode).MassFlowRate, state.dataLoopNodes->Node(this->MixedAirOutNode).MassFlowRate);
    6005             :     }
    6006     1478904 : }
    6007             : 
    6008     1478855 : void CalcATMixer(EnergyPlusData &state, int const SysNum)
    6009             : {
    6010             : 
    6011             :     // SUBROUTINE INFORMATION:
    6012             :     //       AUTHOR
    6013             :     //       DATE WRITTEN   March 2012
    6014             :     //       MODIFIED       na
    6015             :     //       RE-ENGINEERED  na
    6016             : 
    6017             :     // PURPOSE OF THIS SUBROUTINE
    6018             :     // Calculate the mixed air flow and conditions in the air terminal mixer
    6019             : 
    6020             :     // METHODOLOGY EMPLOYED:
    6021             : 
    6022             :     // REFERENCES:
    6023             : 
    6024             :     // Using/Aliasing
    6025             :     using Psychrometrics::PsyTdbFnHW;
    6026             : 
    6027             :     // Locals
    6028             :     // SUBROUTINE ARGUMENT DEFINITIONS
    6029             : 
    6030             :     // SUBROUTINE PARAMETER DEFINITIONS:
    6031             : 
    6032             :     // INTERFACE BLOCK SPECIFICATIONS
    6033             :     // na
    6034             : 
    6035             :     // DERIVED TYPE DEFINITIONS
    6036             :     // na
    6037             : 
    6038             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6039             : 
    6040     1478855 :     state.dataSingleDuct->PriEnthalpyCATM = state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).PriInNode).Enthalpy;
    6041     1478855 :     state.dataSingleDuct->PriHumRatCATM = state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).PriInNode).HumRat;
    6042     1478855 :     state.dataSingleDuct->PriTempCATM = state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).PriInNode).Temp;
    6043     1478855 :     state.dataSingleDuct->PriMassFlowRateCATM = state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).PriInNode).MassFlowRate;
    6044             : 
    6045     1478855 :     state.dataSingleDuct->SecAirMassFlowRateCATM = state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).SecInNode).MassFlowRate;
    6046     1478855 :     state.dataSingleDuct->SecAirEnthalpyCATM = state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).SecInNode).Enthalpy;
    6047     1478855 :     state.dataSingleDuct->SecAirHumRatCATM = state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).SecInNode).HumRat;
    6048     1478855 :     state.dataSingleDuct->SecAirTempCATM = state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).SecInNode).Temp;
    6049             : 
    6050     1478855 :     if (state.dataSingleDuct->SysATMixer(SysNum).MixerType == ATMixer_SupplySide) {
    6051      601709 :         state.dataSingleDuct->MixedAirMassFlowRateCATM = state.dataSingleDuct->SecAirMassFlowRateCATM + state.dataSingleDuct->PriMassFlowRateCATM;
    6052             :     } else {
    6053             :         // for inlet side mixer, the mixed air flow has been set, but we don't know the secondary flow
    6054      877146 :         state.dataSingleDuct->MixedAirMassFlowRateCATM =
    6055      877146 :             state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).MixedAirOutNode).MassFlowRate;
    6056      877146 :         state.dataSingleDuct->SecAirMassFlowRateCATM =
    6057      877146 :             max(state.dataSingleDuct->MixedAirMassFlowRateCATM - state.dataSingleDuct->PriMassFlowRateCATM, 0.0);
    6058      877146 :         state.dataLoopNodes->Node(state.dataSingleDuct->SysATMixer(SysNum).SecInNode).MassFlowRate = state.dataSingleDuct->SecAirMassFlowRateCATM;
    6059     2631438 :         if (std::abs(state.dataSingleDuct->PriMassFlowRateCATM + state.dataSingleDuct->SecAirMassFlowRateCATM -
    6060     1754292 :                      state.dataSingleDuct->MixedAirMassFlowRateCATM) > SmallMassFlow) {
    6061           0 :             ShowSevereError(state,
    6062           0 :                             "CalcATMixer: Invalid mass flow rates in AirTerminal:SingleDuct:Mixer=" + state.dataSingleDuct->SysATMixer(SysNum).Name);
    6063           0 :             ShowContinueErrorTimeStamp(state,
    6064           0 :                                        format("Primary mass flow rate={:.6R}Secondary mass flow rate={:.6R}Mixed mass flow rate={:.6R}",
    6065           0 :                                               state.dataSingleDuct->PriMassFlowRateCATM,
    6066           0 :                                               state.dataSingleDuct->SecAirMassFlowRateCATM,
    6067           0 :                                               state.dataSingleDuct->MixedAirMassFlowRateCATM));
    6068           0 :             ShowFatalError(state, "Simulation terminates.");
    6069             :         }
    6070             :     }
    6071             :     // now calculate the mixed (outlet) conditions
    6072     1478855 :     if (state.dataSingleDuct->MixedAirMassFlowRateCATM > 0.0) {
    6073     4173669 :         state.dataSingleDuct->MixedAirEnthalpyCATM = (state.dataSingleDuct->SecAirMassFlowRateCATM * state.dataSingleDuct->SecAirEnthalpyCATM +
    6074     2782446 :                                                       state.dataSingleDuct->PriMassFlowRateCATM * state.dataSingleDuct->PriEnthalpyCATM) /
    6075     1391223 :                                                      state.dataSingleDuct->MixedAirMassFlowRateCATM;
    6076     4173669 :         state.dataSingleDuct->MixedAirHumRatCATM = (state.dataSingleDuct->SecAirMassFlowRateCATM * state.dataSingleDuct->SecAirHumRatCATM +
    6077     2782446 :                                                     state.dataSingleDuct->PriMassFlowRateCATM * state.dataSingleDuct->PriHumRatCATM) /
    6078     1391223 :                                                    state.dataSingleDuct->MixedAirMassFlowRateCATM;
    6079             :         // Mixed air temperature is calculated from the mixed air enthalpy and humidity ratio.
    6080     1391223 :         state.dataSingleDuct->MixedAirTempCATM = PsyTdbFnHW(state.dataSingleDuct->MixedAirEnthalpyCATM, state.dataSingleDuct->MixedAirHumRatCATM);
    6081             :     }
    6082             : 
    6083     1478855 :     state.dataSingleDuct->SysATMixer(SysNum).MixedAirMassFlowRate = state.dataSingleDuct->MixedAirMassFlowRateCATM;
    6084     1478855 :     state.dataSingleDuct->SysATMixer(SysNum).MixedAirEnthalpy = state.dataSingleDuct->MixedAirEnthalpyCATM;
    6085     1478855 :     state.dataSingleDuct->SysATMixer(SysNum).MixedAirHumRat = state.dataSingleDuct->MixedAirHumRatCATM;
    6086     1478855 :     state.dataSingleDuct->SysATMixer(SysNum).MixedAirTemp = state.dataSingleDuct->MixedAirTempCATM;
    6087     1478855 : }
    6088             : 
    6089     1478855 : void UpdateATMixer(EnergyPlusData &state, int const SysNum)
    6090             : {
    6091             : 
    6092             :     // SUBROUTINE INFORMATION:
    6093             :     //       AUTHOR
    6094             :     //       DATE WRITTEN   March 2012
    6095             :     //       MODIFIED       na
    6096             :     //       RE-ENGINEERED  na
    6097             : 
    6098             :     // PURPOSE OF THIS SUBROUTINE
    6099             :     // Move the results of CalcATMixer to the affected nodes
    6100             : 
    6101             :     // METHODOLOGY EMPLOYED:
    6102             : 
    6103             :     // REFERENCES:
    6104             : 
    6105             :     // Using/Aliasing
    6106             :     using namespace DataLoopNode;
    6107             : 
    6108             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6109     1478855 :     int PriInNode = state.dataSingleDuct->SysATMixer(SysNum).PriInNode;
    6110     1478855 :     int SecInNode = state.dataSingleDuct->SysATMixer(SysNum).SecInNode;
    6111     1478855 :     int MixedAirOutNode = state.dataSingleDuct->SysATMixer(SysNum).MixedAirOutNode;
    6112             : 
    6113             :     // mixed air data
    6114     1478855 :     state.dataLoopNodes->Node(MixedAirOutNode).Temp = state.dataSingleDuct->SysATMixer(SysNum).MixedAirTemp;
    6115     1478855 :     state.dataLoopNodes->Node(MixedAirOutNode).HumRat = state.dataSingleDuct->SysATMixer(SysNum).MixedAirHumRat;
    6116     1478855 :     state.dataLoopNodes->Node(MixedAirOutNode).Enthalpy = state.dataSingleDuct->SysATMixer(SysNum).MixedAirEnthalpy;
    6117     1478855 :     state.dataLoopNodes->Node(MixedAirOutNode).Press = state.dataSingleDuct->SysATMixer(SysNum).MixedAirPressure;
    6118     1478855 :     state.dataLoopNodes->Node(MixedAirOutNode).MassFlowRate = state.dataSingleDuct->SysATMixer(SysNum).MixedAirMassFlowRate;
    6119             : 
    6120     1478855 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    6121      320474 :         if (state.dataSingleDuct->SysATMixer(SysNum).MixedAirMassFlowRate <= DataHVACGlobals::VerySmallMassFlow) {
    6122        9292 :             state.dataLoopNodes->Node(MixedAirOutNode).CO2 = state.dataLoopNodes->Node(PriInNode).CO2;
    6123             :         } else {
    6124      311182 :             state.dataLoopNodes->Node(MixedAirOutNode).CO2 =
    6125      622364 :                 (state.dataLoopNodes->Node(SecInNode).MassFlowRate * state.dataLoopNodes->Node(SecInNode).CO2 +
    6126      622364 :                  state.dataLoopNodes->Node(PriInNode).MassFlowRate * state.dataLoopNodes->Node(PriInNode).CO2) /
    6127      311182 :                 state.dataLoopNodes->Node(MixedAirOutNode).MassFlowRate;
    6128             :         }
    6129             :     }
    6130             : 
    6131     1478855 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    6132           0 :         if (state.dataSingleDuct->SysATMixer(SysNum).MixedAirMassFlowRate <= DataHVACGlobals::VerySmallMassFlow) {
    6133           0 :             state.dataLoopNodes->Node(MixedAirOutNode).GenContam = state.dataLoopNodes->Node(PriInNode).GenContam;
    6134             :         } else {
    6135           0 :             state.dataLoopNodes->Node(MixedAirOutNode).GenContam =
    6136           0 :                 (state.dataLoopNodes->Node(SecInNode).MassFlowRate * state.dataLoopNodes->Node(SecInNode).GenContam +
    6137           0 :                  state.dataLoopNodes->Node(PriInNode).MassFlowRate * state.dataLoopNodes->Node(PriInNode).GenContam) /
    6138           0 :                 state.dataLoopNodes->Node(MixedAirOutNode).MassFlowRate;
    6139             :         }
    6140             :     }
    6141             : 
    6142             :     // update ADU flow data - because SimATMixer is called from the various zone equipment so the updates in SimZoneAirLoopEquipment won't work
    6143     1478855 :     int aduNum = state.dataSingleDuct->SysATMixer(SysNum).ADUNum;
    6144     1478855 :     state.dataDefineEquipment->AirDistUnit(aduNum).MassFlowRateTU = state.dataLoopNodes->Node(PriInNode).MassFlowRate;
    6145     1478855 :     state.dataDefineEquipment->AirDistUnit(aduNum).MassFlowRateZSup = state.dataLoopNodes->Node(PriInNode).MassFlowRate;
    6146     1478855 :     state.dataDefineEquipment->AirDistUnit(aduNum).MassFlowRateSup = state.dataLoopNodes->Node(PriInNode).MassFlowRate;
    6147     1478855 : }
    6148             : 
    6149         754 : void GetATMixer(EnergyPlusData &state,
    6150             :                 std::string const &ZoneEquipName, // zone unit name name
    6151             :                 std::string &ATMixerName,         // air terminal mixer name
    6152             :                 int &ATMixerNum,                  // air terminal mixer index
    6153             :                 int &ATMixerType,                 // air teminal mixer type
    6154             :                 int &ATMixerPriNode,              // air terminal mixer primary air node number
    6155             :                 int &ATMixerSecNode,              // air terminal mixer secondary air node number
    6156             :                 int &ATMixerOutNode,              // air terminal mixer outlet air node number
    6157             :                 int const ZoneEquipOutletNode     // zone equipment outlet node (used with inlet side mixers)
    6158             : )
    6159             : {
    6160             : 
    6161             :     // SUBROUTINE INFORMATION:
    6162             :     //       AUTHOR         Fred Buhl
    6163             :     //       DATE WRITTEN   April 2012
    6164             :     //       MODIFIED       na
    6165             :     //       RE-ENGINEERED  na
    6166             : 
    6167             :     // PURPOSE OF THIS SUBROUTINE:
    6168             :     // This subroutine gets: 1) the index of the named AT Mixer in the SysATMixer data array
    6169             :     //                       2) the node number of the primary air inlet node of the AT Mixer
    6170             :     //                       3) set the AT Mixer ultimate zone inlet node
    6171             : 
    6172             :     int ATMixerIndex; // local air terminal mixer index
    6173             : 
    6174         754 :     if (state.dataSingleDuct->GetATMixerFlag) {
    6175         184 :         GetATMixers(state);
    6176         184 :         state.dataSingleDuct->GetATMixerFlag = false;
    6177             :     }
    6178             : 
    6179         754 :     if (state.dataSingleDuct->NumATMixers <= 0) {
    6180         704 :         ATMixerNum = 0;
    6181         704 :         ATMixerName = "";
    6182         704 :         ATMixerPriNode = 0;
    6183         704 :         ATMixerSecNode = 0;
    6184         704 :         ATMixerOutNode = 0;
    6185         704 :         ATMixerType = 0;
    6186         704 :         return;
    6187             :     }
    6188             : 
    6189          50 :     ATMixerIndex = UtilityRoutines::FindItemInList(ZoneEquipName, state.dataSingleDuct->SysATMixer, &AirTerminalMixerData::ZoneHVACUnitName);
    6190          50 :     if (ATMixerIndex > 0) {
    6191          49 :         ATMixerNum = ATMixerIndex;
    6192          49 :         ATMixerName = state.dataSingleDuct->SysATMixer(ATMixerIndex).Name;
    6193          49 :         ATMixerPriNode = state.dataSingleDuct->SysATMixer(ATMixerIndex).PriInNode;
    6194          49 :         ATMixerSecNode = state.dataSingleDuct->SysATMixer(ATMixerIndex).SecInNode;
    6195          49 :         ATMixerOutNode = state.dataSingleDuct->SysATMixer(ATMixerIndex).MixedAirOutNode;
    6196          49 :         ATMixerType = state.dataSingleDuct->SysATMixer(ATMixerIndex).MixerType;
    6197          49 :         if (ATMixerType == ATMixer_InletSide) {
    6198          27 :             state.dataSingleDuct->SysATMixer(ATMixerIndex).ZoneInletNode = ZoneEquipOutletNode;
    6199             :         } else {
    6200          22 :             state.dataSingleDuct->SysATMixer(ATMixerIndex).ZoneInletNode = ATMixerOutNode;
    6201             :         }
    6202          49 :         state.dataSingleDuct->SysATMixer(ATMixerNum).InitATMixer(state, false);
    6203             :     } else {
    6204           1 :         ATMixerNum = 0;
    6205           1 :         ATMixerName = "";
    6206           1 :         ATMixerPriNode = 0;
    6207           1 :         ATMixerSecNode = 0;
    6208           1 :         ATMixerOutNode = 0;
    6209           1 :         ATMixerType = 0;
    6210             :     }
    6211             : }
    6212             : 
    6213           0 : void SetATMixerPriFlow(EnergyPlusData &state,
    6214             :                        int const ATMixerNum,                     // Air terminal mixer index
    6215             :                        Optional<Real64 const> PriAirMassFlowRate // Air terminal mixer primary air mass flow rate [kg/s]
    6216             : )
    6217             : {
    6218             : 
    6219             :     // SUBROUTINE INFORMATION:
    6220             :     //       AUTHOR         Fred Buhl
    6221             :     //       DATE WRITTEN   April 2012
    6222             :     //       MODIFIED       na
    6223             :     //       RE-ENGINEERED  na
    6224             : 
    6225             :     // PURPOSE OF THIS SUBROUTINE:
    6226             :     // This Subroutine sets the primary air mass flow rate on the primary air inlet
    6227             :     // node of a terminal unit mixer component.
    6228             : 
    6229             :     // METHODOLOGY EMPLOYED:
    6230             :     // The flow is set to either the input PriAirMassFlowRate if this optional input
    6231             :     // parameter is present, or to the maximum available mass flow rate of the primary
    6232             :     // air inlet node.
    6233             : 
    6234             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    6235             :     int PriAirNode; // air terminal mixer primary air inlet node number
    6236             : 
    6237           0 :     if (ATMixerNum <= 0) return;
    6238           0 :     PriAirNode = state.dataSingleDuct->SysATMixer(ATMixerNum).PriInNode;
    6239           0 :     if (present(PriAirMassFlowRate)) {
    6240           0 :         state.dataLoopNodes->Node(PriAirNode).MassFlowRate = PriAirMassFlowRate;
    6241             :     } else {
    6242           0 :         state.dataLoopNodes->Node(PriAirNode).MassFlowRate = state.dataLoopNodes->Node(PriAirNode).MassFlowRateMaxAvail;
    6243             :     }
    6244             : }
    6245             : 
    6246          78 : void setATMixerSizingProperties(EnergyPlusData &state,
    6247             :                                 int const inletATMixerIndex, // index to ATMixer at inlet of zone equipment
    6248             :                                 int const controlledZoneNum, // controlled zone number
    6249             :                                 int const curZoneEqNum       // current zone equipment being simulated
    6250             : )
    6251             : {
    6252          78 :     auto &ZoneEqSizing(state.dataSize->ZoneEqSizing);
    6253          78 :     auto &FinalSysSizing(state.dataSize->FinalSysSizing);
    6254          78 :     auto &FinalZoneSizing(state.dataSize->FinalZoneSizing);
    6255             : 
    6256         113 :     if (inletATMixerIndex == 0) return; // protect this function from bad inputs
    6257          78 :     if (controlledZoneNum == 0) return;
    6258          78 :     if (curZoneEqNum == 0) return;
    6259          78 :     if (state.dataSingleDuct->SysATMixer(inletATMixerIndex).MixerType == DataHVACGlobals::No_ATMixer) return;
    6260             : 
    6261             :     // ATMixer properties only affect coil sizing when the mixer is on the inlet side of zone equipment
    6262          78 :     if (state.dataSingleDuct->SysATMixer(inletATMixerIndex).MixerType == DataHVACGlobals::ATMixer_SupplySide) {
    6263             :         // check if user has selected No to account for DOAS system
    6264          35 :         if (FinalZoneSizing.allocated() && state.dataSingleDuct->SysATMixer(inletATMixerIndex).printWarning) {
    6265          22 :             if (!FinalZoneSizing(curZoneEqNum).AccountForDOAS && FinalZoneSizing(curZoneEqNum).DOASControlStrategy != DOANeutralSup) {
    6266           2 :                 ShowWarningError(state, "AirTerminal:SingleDuct:Mixer: " + state.dataSingleDuct->SysATMixer(inletATMixerIndex).Name);
    6267           2 :                 ShowContinueError(
    6268             :                     state,
    6269             :                     " Supply side Air Terminal Mixer does not adjust zone equipment coil sizing and may result in inappropriately sized coils.");
    6270           6 :                 ShowContinueError(state,
    6271           4 :                                   " Set Account for Dedicated Outdoor Air System = Yes in Sizing:Zone object for zone = " +
    6272           2 :                                       FinalZoneSizing(curZoneEqNum).ZoneName);
    6273             :             }
    6274          22 :             state.dataSingleDuct->SysATMixer(inletATMixerIndex).printWarning = false;
    6275             :         }
    6276          35 :         return; // do nothing else if this is a supply side ATMixer
    6277             :     }
    6278             :     // check if user has selected Yes to account for DOAS system
    6279          43 :     if (FinalZoneSizing.allocated() && state.dataSingleDuct->SysATMixer(inletATMixerIndex).printWarning) {
    6280          43 :         if (FinalZoneSizing(curZoneEqNum).AccountForDOAS && FinalZoneSizing(curZoneEqNum).DOASControlStrategy != DOANeutralSup) {
    6281           0 :             ShowWarningError(state, "AirTerminal:SingleDuct:Mixer: " + state.dataSingleDuct->SysATMixer(inletATMixerIndex).Name);
    6282           0 :             ShowContinueError(state, " Inlet side Air Terminal Mixer automatically adjusts zone equipment coil sizing.");
    6283           0 :             ShowContinueError(state,
    6284           0 :                               " Set Account for Dedicated Outdoor Air System = No in Sizing:Zone object for zone = " +
    6285           0 :                                   FinalZoneSizing(curZoneEqNum).ZoneName);
    6286           0 :             state.dataSingleDuct->SysATMixer(inletATMixerIndex).printWarning = false;
    6287             :         }
    6288             :     }
    6289             : 
    6290             :     // proceed to set ATMixer properties used for sizing coils
    6291             : 
    6292             :     int airLoopIndex = // find air loop associated with ATMixer
    6293          43 :         state.dataZoneEquip->ZoneEquipConfig(controlledZoneNum)
    6294          43 :             .InletNodeAirLoopNum(state.dataSingleDuct->SysATMixer(inletATMixerIndex).CtrlZoneInNodeIndex);
    6295             : 
    6296             :     // must be a system sizing run or calculations are not possible
    6297          43 :     bool SizingDesRunThisAirSys = false;                                      // Sizing:System object found flag
    6298          43 :     CheckThisAirSystemForSizing(state, airLoopIndex, SizingDesRunThisAirSys); // check for Sizing:System object
    6299             : 
    6300          43 :     if (SizingDesRunThisAirSys) {
    6301             : 
    6302             :         // set ATMixer outlet air flow rate in ZoneEqSizing array for ATMixer. If this value > 0, then the Sizer will know an ATMixer exists
    6303          43 :         ZoneEqSizing(curZoneEqNum).ATMixerVolFlow = state.dataSingleDuct->SysATMixer(inletATMixerIndex).DesignPrimaryAirVolRate;
    6304             : 
    6305             :         // If air loop has heating coil use SA conditions, else if OA sys has coils then use precool conditions, else use OA conditions
    6306          43 :         if (state.dataAirSystemsData->PrimaryAirSystems(airLoopIndex).CentralHeatCoilExists) {
    6307             :             // if central heating coil exists, ATMixer outlet is assumed to be at supply air conditions described in sizing input
    6308           5 :             ZoneEqSizing(curZoneEqNum).ATMixerHeatPriDryBulb = FinalSysSizing(airLoopIndex).HeatSupTemp;
    6309           5 :             ZoneEqSizing(curZoneEqNum).ATMixerHeatPriHumRat = FinalSysSizing(airLoopIndex).HeatSupHumRat;
    6310          38 :         } else if (state.dataAirSystemsData->PrimaryAirSystems(airLoopIndex).NumOAHeatCoils > 0) {
    6311             :             // if no central heating coil exists and an outdoor air coil does exist, then ATMixer outlet is mixture of preheat and return
    6312           0 :             if (FinalSysSizing(airLoopIndex).DesMainVolFlow == 0.0) { // protect divide by 0
    6313             :                 // doesn't matter, just pick a condition
    6314           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerHeatPriDryBulb = FinalSysSizing(airLoopIndex).PreheatTemp;
    6315           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerHeatPriHumRat = FinalSysSizing(airLoopIndex).PreheatHumRat;
    6316             :             } else {
    6317             :                 // mix preheat condition with return air condition based on OA frac. OA frac should nearly always be 1.
    6318             :                 // OA frac is based on air loop fraction, not ATMixer flow fraction since air loop can serve multiple ATMixers
    6319           0 :                 Real64 OutAirFrac = FinalSysSizing(airLoopIndex).DesOutAirVolFlow / FinalSysSizing(airLoopIndex).DesMainVolFlow;
    6320           0 :                 OutAirFrac = min(1.0, max(0.0, OutAirFrac));
    6321             : 
    6322             :                 // calculate humrat based on simple mixing
    6323             :                 Real64 CoilInHumRatForSizing =
    6324           0 :                     OutAirFrac * FinalSysSizing(airLoopIndex).PreheatHumRat + (1 - OutAirFrac) * FinalSysSizing(airLoopIndex).HeatRetHumRat;
    6325             : 
    6326             :                 // calculate enthalpy based on simple mixing
    6327             :                 Real64 CoilInEnthalpyForSizing =
    6328           0 :                     OutAirFrac * Psychrometrics::PsyHFnTdbW(FinalSysSizing(airLoopIndex).PreheatTemp, FinalSysSizing(airLoopIndex).PreheatHumRat) +
    6329           0 :                     (1 - OutAirFrac) *
    6330           0 :                         Psychrometrics::PsyHFnTdbW(FinalSysSizing(airLoopIndex).HeatRetTemp, FinalSysSizing(airLoopIndex).HeatRetHumRat);
    6331             : 
    6332             :                 // back calculate temperature based on humrat and enthalpy state points
    6333           0 :                 Real64 CoilInTempForSizing = Psychrometrics::PsyTdbFnHW(CoilInEnthalpyForSizing, CoilInHumRatForSizing);
    6334             : 
    6335           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerHeatPriDryBulb = CoilInTempForSizing;
    6336           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerHeatPriHumRat = CoilInHumRatForSizing;
    6337             :             }
    6338             :         } else {
    6339             :             // else no coils exist in air loop so mix OA condition with return air condition
    6340          38 :             if (FinalSysSizing(airLoopIndex).DesMainVolFlow == 0.0) { // protect divide by 0
    6341             :                 // doesn't matter, just pick a condition
    6342           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerHeatPriDryBulb = FinalSysSizing(airLoopIndex).HeatOutTemp;
    6343           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerHeatPriHumRat = FinalSysSizing(airLoopIndex).HeatOutHumRat;
    6344             :             } else {
    6345             :                 // OA frac is based on air loop fraction, not ATMixer flow fraction since air loop can serve multiple ATMixers
    6346          38 :                 Real64 OutAirFrac = FinalSysSizing(airLoopIndex).DesOutAirVolFlow / FinalSysSizing(airLoopIndex).DesMainVolFlow;
    6347          38 :                 OutAirFrac = min(1.0, max(0.0, OutAirFrac));
    6348             : 
    6349             :                 // calculate humrat based on simple mixing
    6350             :                 Real64 CoilInHumRatForSizing =
    6351          38 :                     OutAirFrac * FinalSysSizing(airLoopIndex).HeatOutHumRat + (1 - OutAirFrac) * FinalSysSizing(airLoopIndex).HeatRetHumRat;
    6352             : 
    6353             :                 // calculate enthalpy based on simple mixing
    6354             :                 Real64 CoilInEnthalpyForSizing =
    6355          38 :                     OutAirFrac * Psychrometrics::PsyHFnTdbW(FinalSysSizing(airLoopIndex).HeatOutTemp, FinalSysSizing(airLoopIndex).HeatOutHumRat) +
    6356          76 :                     (1 - OutAirFrac) *
    6357          76 :                         Psychrometrics::PsyHFnTdbW(FinalSysSizing(airLoopIndex).HeatRetTemp, FinalSysSizing(airLoopIndex).HeatRetHumRat);
    6358             : 
    6359             :                 // back calculate temperature based on humrat and enthalpy state points
    6360          38 :                 Real64 CoilInTempForSizing = Psychrometrics::PsyTdbFnHW(CoilInEnthalpyForSizing, CoilInHumRatForSizing);
    6361             : 
    6362          38 :                 ZoneEqSizing(curZoneEqNum).ATMixerHeatPriDryBulb = CoilInTempForSizing;
    6363          38 :                 ZoneEqSizing(curZoneEqNum).ATMixerHeatPriHumRat = CoilInHumRatForSizing;
    6364             :             }
    6365             :         }
    6366             : 
    6367             :         // If air loop has cooling coil use SA conditions, else if OA sys has coils then use precool conditions, else use OA conditions
    6368          43 :         if (state.dataAirSystemsData->PrimaryAirSystems(airLoopIndex).CentralCoolCoilExists) {
    6369             :             // if central cooling coil exists, ATMixer outlet is assumed to be at supply air conditions described in sizing input
    6370           5 :             ZoneEqSizing(curZoneEqNum).ATMixerCoolPriDryBulb = FinalSysSizing(airLoopIndex).CoolSupTemp;
    6371           5 :             ZoneEqSizing(curZoneEqNum).ATMixerCoolPriHumRat = FinalSysSizing(airLoopIndex).CoolSupHumRat;
    6372          38 :         } else if (state.dataAirSystemsData->PrimaryAirSystems(airLoopIndex).NumOACoolCoils > 0) {
    6373             :             // if no central cooling coil exists and an outdoor air coil does exist, then ATMixer outlet is mixture of precool and return
    6374           0 :             if (FinalSysSizing(airLoopIndex).DesMainVolFlow == 0.0) { // protect divide by 0
    6375             :                 // doesn't matter, just pick a condition
    6376           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerCoolPriDryBulb = FinalSysSizing(airLoopIndex).PrecoolTemp;
    6377           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerCoolPriHumRat = FinalSysSizing(airLoopIndex).PrecoolHumRat;
    6378             :             } else {
    6379             :                 // mix precool condition with return air condition based on OA frac. OA frac should nearly always be 1.
    6380             :                 // OA frac is based on air loop fraction, not ATMixer flow fraction since air loop can serve multiple ATMixers
    6381           0 :                 Real64 OutAirFrac = FinalSysSizing(airLoopIndex).DesOutAirVolFlow / FinalSysSizing(airLoopIndex).DesMainVolFlow;
    6382           0 :                 OutAirFrac = min(1.0, max(0.0, OutAirFrac));
    6383             : 
    6384             :                 // calculate humrat based on simple mixing
    6385             :                 Real64 CoilInHumRatForSizing =
    6386           0 :                     OutAirFrac * FinalSysSizing(airLoopIndex).PrecoolHumRat + (1 - OutAirFrac) * FinalSysSizing(airLoopIndex).RetHumRatAtCoolPeak;
    6387             : 
    6388             :                 // calculate enthalpy based on simple mixing
    6389             :                 Real64 CoilInEnthalpyForSizing =
    6390           0 :                     OutAirFrac * Psychrometrics::PsyHFnTdbW(FinalSysSizing(airLoopIndex).PrecoolTemp, FinalSysSizing(airLoopIndex).PrecoolHumRat) +
    6391           0 :                     (1 - OutAirFrac) *
    6392           0 :                         Psychrometrics::PsyHFnTdbW(FinalSysSizing(airLoopIndex).RetTempAtCoolPeak, FinalSysSizing(airLoopIndex).RetHumRatAtCoolPeak);
    6393             : 
    6394             :                 // back calculate temperature based on humrat and enthalpy state points
    6395           0 :                 Real64 CoilInTempForSizing = Psychrometrics::PsyTdbFnHW(CoilInEnthalpyForSizing, CoilInHumRatForSizing);
    6396             : 
    6397           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerCoolPriDryBulb = CoilInTempForSizing;
    6398           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerCoolPriHumRat = CoilInHumRatForSizing;
    6399             :             }
    6400             :         } else {
    6401             :             // else no coils exist in air loop so mix OA condition with return air condition
    6402          38 :             if (FinalSysSizing(airLoopIndex).DesMainVolFlow == 0.0) { // protect divide by 0
    6403             :                 // doesn't matter, just pick a condition
    6404           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerCoolPriDryBulb = FinalSysSizing(airLoopIndex).OutTempAtCoolPeak;
    6405           0 :                 ZoneEqSizing(curZoneEqNum).ATMixerCoolPriHumRat = FinalSysSizing(airLoopIndex).OutHumRatAtCoolPeak;
    6406             :             } else {
    6407             :                 // OA frac is based on air loop fraction, not ATMixer flow fraction since air loop can serve multiple ATMixers
    6408          38 :                 Real64 OutAirFrac = FinalSysSizing(airLoopIndex).DesOutAirVolFlow / FinalSysSizing(airLoopIndex).DesMainVolFlow;
    6409          38 :                 OutAirFrac = min(1.0, max(0.0, OutAirFrac));
    6410             : 
    6411             :                 // calculate humrat based on simple mixing
    6412          38 :                 Real64 CoilInHumRatForSizing = OutAirFrac * FinalSysSizing(airLoopIndex).OutHumRatAtCoolPeak +
    6413          38 :                                                (1 - OutAirFrac) * FinalSysSizing(airLoopIndex).RetHumRatAtCoolPeak;
    6414             : 
    6415             :                 // calculate enthalpy based on simple mixing
    6416          38 :                 Real64 CoilInEnthalpyForSizing = OutAirFrac * Psychrometrics::PsyHFnTdbW(FinalSysSizing(airLoopIndex).OutTempAtCoolPeak,
    6417          38 :                                                                                          FinalSysSizing(airLoopIndex).OutHumRatAtCoolPeak) +
    6418          76 :                                                  (1 - OutAirFrac) * Psychrometrics::PsyHFnTdbW(FinalSysSizing(airLoopIndex).RetTempAtCoolPeak,
    6419          76 :                                                                                                FinalSysSizing(airLoopIndex).RetHumRatAtCoolPeak);
    6420             : 
    6421             :                 // back calculate temperature based on humrat and enthalpy state points
    6422          38 :                 Real64 CoilInTempForSizing = Psychrometrics::PsyTdbFnHW(CoilInEnthalpyForSizing, CoilInHumRatForSizing);
    6423             : 
    6424          38 :                 ZoneEqSizing(curZoneEqNum).ATMixerCoolPriDryBulb = CoilInTempForSizing;
    6425          38 :                 ZoneEqSizing(curZoneEqNum).ATMixerCoolPriHumRat = CoilInHumRatForSizing;
    6426             :             }
    6427             :         }
    6428             : 
    6429             :     } else {
    6430             :         // warn user that system sizing is needed to size coils when AT Mixer is used ?
    6431             :         // if there were a message here then this function should only be called when SizingDesRunThisZone is true
    6432             :     }
    6433             : }
    6434             : 
    6435    32682712 : void SingleDuctAirTerminal::CalcOutdoorAirVolumeFlowRate(EnergyPlusData &state)
    6436             : {
    6437             :     // calculates zone outdoor air volume flow rate using the supply air flow rate and OA fraction
    6438    32682712 :     if (this->AirLoopNum > 0) {
    6439    32673825 :         this->OutdoorAirFlowRate =
    6440    32673825 :             (this->sd_airterminalOutlet.AirMassFlowRate / state.dataEnvrn->StdRhoAir) * state.dataAirLoop->AirLoopFlow(this->AirLoopNum).OAFrac;
    6441             :     } else {
    6442        8887 :         this->OutdoorAirFlowRate = 0.0;
    6443             :     }
    6444    32682712 : }
    6445             : 
    6446             : //        End of Reporting subroutines for the Sys Module
    6447             : // *****************************************************************************
    6448             : 
    6449        2313 : } // namespace EnergyPlus::SingleDuct

Generated by: LCOV version 1.13