LCOV - code coverage report
Current view: top level - EnergyPlus - SingleDuct.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 2384 3584 66.5 %
Date: 2024-08-24 18:31:18 Functions: 26 30 86.7 %

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

Generated by: LCOV version 1.14