LCOV - code coverage report
Current view: top level - EnergyPlus - DataZoneEquipment.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 73.8 % 1384 1021
Test Date: 2025-06-02 07:23:51 Functions: 100.0 % 31 31

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // ObjexxFCL Headers
      49              : #include <ObjexxFCL/Array.functions.hh>
      50              : #include <ObjexxFCL/Fmath.hh>
      51              : 
      52              : // EnergyPlus Headers
      53              : #include <EnergyPlus/Autosizing/Base.hh>
      54              : #include <EnergyPlus/BranchNodeConnections.hh>
      55              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      56              : #include <EnergyPlus/DataContaminantBalance.hh>
      57              : #include <EnergyPlus/DataDefineEquip.hh>
      58              : #include <EnergyPlus/DataEnvironment.hh>
      59              : #include <EnergyPlus/DataHVACGlobals.hh>
      60              : #include <EnergyPlus/DataHeatBalance.hh>
      61              : #include <EnergyPlus/DataLoopNode.hh>
      62              : #include <EnergyPlus/DataSizing.hh>
      63              : #include <EnergyPlus/DataZoneEquipment.hh>
      64              : #include <EnergyPlus/General.hh>
      65              : #include <EnergyPlus/GeneralRoutines.hh>
      66              : #include <EnergyPlus/GlobalNames.hh>
      67              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      68              : #include <EnergyPlus/NodeInputManager.hh>
      69              : #include <EnergyPlus/Psychrometrics.hh>
      70              : #include <EnergyPlus/ScheduleManager.hh>
      71              : #include <EnergyPlus/UnitarySystem.hh>
      72              : #include <EnergyPlus/UtilityRoutines.hh>
      73              : #include <EnergyPlus/ZoneEquipmentManager.hh>
      74              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      75              : 
      76              : namespace EnergyPlus::DataZoneEquipment {
      77              : 
      78              : // MODULE INFORMATION
      79              : //             AUTHOR:  Russ Taylor
      80              : //       DATE WRITTEN:  June 1998
      81              : 
      82              : // PURPOSE OF THIS MODULE:
      83              : // This module contains variable declarations for zone equipment configuration data
      84              : 
      85              : Array1D_string const cValidSysAvailManagerCompTypes(NumValidSysAvailZoneComponents,
      86              :                                                     {"ZoneHVAC:FourPipeFanCoil",
      87              :                                                      "ZoneHVAC:PackagedTerminalHeatPump",
      88              :                                                      "ZoneHVAC:PackagedTerminalAirConditioner",
      89              :                                                      "ZoneHVAC:WaterToAirHeatPump",
      90              :                                                      "ZoneHVAC:WindowAirConditioner",
      91              :                                                      "ZoneHVAC:UnitHeater",
      92              :                                                      "ZoneHVAC:UnitVentilator",
      93              :                                                      "ZoneHVAC:EnergyRecoveryVentilator",
      94              :                                                      "ZoneHVAC:VentilatedSlab",
      95              :                                                      "ZoneHVAC:OutdoorAirUnit",
      96              :                                                      "ZoneHVAC:TerminalUnit:VariableRefrigerantFlow",
      97              :                                                      "ZoneHVAC:IdealLoadsAirSystem",
      98              :                                                      "ZoneHVAC:EvaporativeCoolerUnit",
      99              :                                                      "ZoneHVAC:HybridUnitaryHVAC"});
     100              : 
     101              : constexpr std::array<std::string_view, static_cast<int>(ZoneEquipType::Num)> zoneEquipTypeNamesUC = {
     102              :     "DUMMY", // DUMMY,
     103              : 
     104              :     "ZONEHVAC:FOURPIPEFANCOIL",                      // FanCoilFourPipe
     105              :     "ZONEHVAC:PACKAGEDTERMINALHEATPUMP",             //   PackagedTerminalHeatPump
     106              :     "ZONEHVAC:PACKAGEDTERMINALAIRCONDITIONER",       //  PackagedTerminalAirConditioner
     107              :     "ZONEHVAC:WATERTOAIRHEATPUMP",                   //   PackagedTerminalHeatPumpWaterToAir
     108              :     "ZONEHVAC:WINDOWAIRCONDITIONER",                 //  WindowAirConditioner
     109              :     "ZONEHVAC:UNITHEATER",                           //  UnitHeater
     110              :     "ZONEHVAC:UNITVENTILATOR",                       //  UnitVentilator
     111              :     "ZONEHVAC:ENERGYRECOVERYVENTILATOR",             // EnergyRecoveryVentilator
     112              :     "ZONEHVAC:VENTILATEDSLAB",                       // VentilatedSlab
     113              :     "ZONEHVAC:OUTDOORAIRUNIT",                       // OutdoorAirUnit
     114              :     "ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW", //  VariableRefrigerantFlowTerminal
     115              :     "ZONEHVAC:IDEALLOADSAIRSYSTEM",                  // IdealLoadsAirSystem
     116              :     "ZONEHVAC:EVAPORATIVECOOLERUNIT",                // EvaporativeCooler
     117              :     "ZONEHVAC:HYBRIDUNITARYHVAC",                    // HybridEvaporativeCooler,
     118              : 
     119              :     // last zone equipment type to use zone availability manager. The above list must not change or
     120              :     // NumValidSysAvailZoneComponents must also change.
     121              : 
     122              :     "ZONEHVAC:AIRDISTRIBUTIONUNIT",                            // AirDistributionUnit
     123              :     "ZONEHVAC:BASEBOARD:CONVECTIVE:WATER",                     // BaseboardWaterConvective
     124              :     "ZONEHVAC:BASEBOARD:CONVECTIVE:ELECTRIC",                  // BaseboardElectricConvective
     125              :     "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:STEAM",              // BaseboardSteam
     126              :     "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:WATER",              // BaseboardWater
     127              :     "ZONEHVAC:BASEBOARD:RADIANTCONVECTIVE:ELECTRIC",           // BaseboardElectric
     128              :     "ZONEHVAC:HIGHTEMPERATURERADIANT",                         // HighTempRadiant
     129              :     "ZONEHVAC:LOWTEMPERATURERADIANT:CONSTANTFLOW",             //  LowTempRadiantConstFlow
     130              :     "ZONEHVAC:LOWTEMPERATURERADIANT:VARIABLEFLOW",             //  LowTempRadiantVarFlow
     131              :     "ZONEHVAC:LOWTEMPERATURERADIANT:ELECTRIC",                 //  LowTempRadiantElectric
     132              :     "FAN:ZONEEXHAUST",                                         // ExhaustFan
     133              :     "HEATEXCHANGER:AIRTOAIR:FLATPLATE",                        // HeatExchanger
     134              :     "WATERHEATER:HEATPUMP:PUMPEDCONDENSER",                    //  HeatPumpWaterHeaterPumpedCondenser
     135              :     "WATERHEATER:HEATPUMP:WRAPPEDCONDENSER",                   //  HeatPumpWaterHeaterWrappedCondenser
     136              :     "ZONEHVAC:DEHUMIDIFIER:DX",                                //  DXDehumidifier
     137              :     "ZONEHVAC:REFRIGERATIONCHILLERSET",                        // RefrigerationAirChillerSet
     138              :     "ZONEHVAC:FORCEDAIR:USERDEFINED",                          // UserDefinedVACForcedAir
     139              :     "ZONEHVAC:COOLINGPANEL:RADIANTCONVECTIVE:WATER",           // CoolingPanel
     140              :     "AIRLOOPHVAC:UNITARYSYSTEM",                               // UnitarySystem
     141              :     "AIRTERMINAL:DUALDUCT:CONSTANTVOLUME",                     // AirTerminalDualDuctConstantVolume
     142              :     "AIRTERMINAL:DUALDUCT:VAV",                                // AirTerminalDualDuctVAV
     143              :     "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:REHEAT",            // AirTerminalSingleDuctConstantVolumeReheat
     144              :     "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:NOREHEAT",          // AirTerminalSingleDuctConstantVolumeNoReheat
     145              :     "AIRTERMINAL:SINGLEDUCT:VAV:REHEAT",                       // AirTerminalSingleDuctVAVReheat
     146              :     "AIRTERMINAL:SINGLEDUCT:VAV:NOREHEAT",                     // AirTerminalSingleDuctVAVNoReheat
     147              :     "AIRTERMINAL:SINGLEDUCT:SERIESPIU:REHEAT",                 // AirTerminalSingleDuctSeriesPIUReheat
     148              :     "AIRTERMINAL:SINGLEDUCT:PARALLELPIU:REHEAT",               // AirTerminalSingleDuctParallelPIUReheat
     149              :     "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:FOURPIPEINDUCTION", // AirTerminalSingleDuctCAVFourPipeInduction
     150              :     "AIRTERMINAL:SINGLEDUCT:VAV:REHEAT:VARIABLESPEEDFAN",      // AirTerminalSingleDuctVAVReheatVariableSpeedFan
     151              :     "AIRTERMINAL:SINGLEDUCT:VAV:HEATANDCOOL:REHEAT",           // AirTerminalSingleDuctVAVHeatAndCoolReheat
     152              :     "AIRTERMINAL:SINGLEDUCT:VAV:HEATANDCOOL:NOREHEAT",         // AirTerminalSingleDuctVAVHeatAndCoolNoReheat
     153              :     "AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:COOLEDBEAM",        // AirTerminalSingleDuctConstantVolumeCooledBeam
     154              :     "AIRTERMINAL:DUALDUCT:VAV:OUTDOORAIR",                     // AirTerminalDualDuctVAVOutdoorAir
     155              :     "AIRLOOPHVACRETURNAIR"                                     // AirLoopHVACReturnAir
     156              : };
     157              : 
     158              : static constexpr std::array<std::string_view, static_cast<int>(LoadDist::Num)> LoadDistNamesUC = {
     159              :     "SEQUENTIALLOAD", "UNIFORMLOAD", "UNIFORMPLR", "SEQUENTIALUNIFORMPLR"};
     160              : 
     161              : static constexpr std::array<std::string_view, static_cast<int>(ZoneEquipTstatControl::Num)> zoneEquipTstatControlNamesUC = {
     162              :     "SINGLESPACE", "MAXIMUM", "IDEAL"};
     163              : 
     164              : static constexpr std::array<std::string_view, static_cast<int>(SpaceEquipSizingBasis::Num)> spaceEquipSizingBasisNamesUC = {
     165              :     "DESIGNCOOLINGLOAD", "DESIGNHEATINGLOAD", "FLOORAREA", "VOLUME", "PERIMETERLENGTH"};
     166              : 
     167          801 : void GetZoneEquipmentData(EnergyPlusData &state)
     168              : {
     169              : 
     170              :     // SUBROUTINE INFORMATION:
     171              :     //       AUTHOR         Russ Taylor
     172              :     //       DATE WRITTEN   June 1997
     173              :     //       MODIFIED       Aug 2003, FCW: set ZoneEquipConfig number for each zone
     174              : 
     175              :     // PURPOSE OF THIS SUBROUTINE:
     176              :     // Get all the system related equipment which may be attached to
     177              :     // a zone
     178              : 
     179              :     // Using/Aliasing
     180              :     using NodeInputManager::CheckUniqueNodeNames;
     181              :     using NodeInputManager::CheckUniqueNodeNumbers;
     182              :     using NodeInputManager::EndUniqueNodeCheck;
     183              :     using NodeInputManager::GetNodeNums;
     184              :     using NodeInputManager::GetOnlySingleNode;
     185              :     using NodeInputManager::InitUniqueNodeCheck;
     186              :     using namespace DataLoopNode;
     187              : 
     188              :     // SUBROUTINE PARAMETER DEFINITIONS:
     189              :     static constexpr std::string_view RoutineName("GetZoneEquipmentData: "); // include trailing blank space
     190              : 
     191              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     192              :     int NumAlphas;
     193              :     int NumNums;
     194              :     int IOStat;
     195          801 :     Array1D_string AlphArray;
     196          801 :     Array1D<Real64> NumArray;
     197              :     int MaxAlphas;
     198              :     int MaxNums;
     199              :     int NumParams;
     200          801 :     Array1D_int NodeNums;
     201              :     bool IsNotOK;                    // Flag to verify nam
     202          801 :     std::string CurrentModuleObject; // Object type for getting and error messages
     203          801 :     Array1D_string cAlphaFields;     // Alpha field names
     204          801 :     Array1D_string cNumericFields;   // Numeric field names
     205          801 :     Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     206          801 :     Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     207              : 
     208              :     struct EquipListAudit
     209              :     {
     210              :         // Members
     211              :         std::string ObjectType;
     212              :         std::string ObjectName;
     213              :         int OnListNum;
     214              : 
     215              :         // Default Constructor
     216         5191 :         EquipListAudit() : OnListNum(0)
     217              :         {
     218         5191 :         }
     219              :     };
     220              :     // Object Data
     221          801 :     Array1D<EquipListAudit> ZoneEquipListAcct;
     222              : 
     223              :     // Look in the input file for zones with air loop and zone equipment attached
     224              : 
     225          801 :     int numControlledZones = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneHVAC:EquipmentConnections");
     226          801 :     int numControlledSpaces = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "SpaceHVAC:EquipmentConnections");
     227          801 :     state.dataZoneEquip->NumOfZoneEquipLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(
     228              :         state, "ZoneHVAC:EquipmentList"); // Look for lists of equipment data - there should
     229              :     // be as many of these as there are controlled zones
     230          801 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumParams, NumAlphas, NumNums);
     231          801 :     NodeNums.dimension(NumParams, 0);
     232          801 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "ZoneHVAC:EquipmentList", NumParams, NumAlphas, NumNums);
     233          801 :     MaxAlphas = NumAlphas;
     234          801 :     MaxNums = NumNums;
     235          801 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "ZoneHVAC:EquipmentConnections", NumParams, NumAlphas, NumNums);
     236          801 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     237          801 :     MaxNums = max(MaxNums, NumNums);
     238          801 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "SpaceHVAC:EquipmentConnections", NumParams, NumAlphas, NumNums);
     239          801 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     240          801 :     MaxNums = max(MaxNums, NumNums);
     241          801 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:SupplyPath", NumParams, NumAlphas, NumNums);
     242          801 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     243          801 :     MaxNums = max(MaxNums, NumNums);
     244          801 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:ReturnPath", NumParams, NumAlphas, NumNums);
     245          801 :     MaxAlphas = max(MaxAlphas, NumAlphas);
     246          801 :     MaxNums = max(MaxNums, NumNums);
     247          801 :     AlphArray.allocate(MaxAlphas);
     248          801 :     NumArray.dimension(MaxNums, 0.0);
     249          801 :     cAlphaFields.allocate(MaxAlphas);
     250          801 :     cNumericFields.allocate(MaxNums);
     251          801 :     lAlphaBlanks.dimension(MaxAlphas, true);
     252          801 :     lNumericBlanks.dimension(MaxNums, true);
     253              : 
     254          801 :     if (!allocated(state.dataZoneEquip->SupplyAirPath)) {
     255              :         // Look for and read in the air supply path
     256              :         // component (splitters) information for each zone
     257          801 :         state.dataZoneEquip->NumSupplyAirPaths = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:SupplyPath");
     258          801 :         state.dataZoneEquip->SupplyAirPath.allocate(state.dataZoneEquip->NumSupplyAirPaths);
     259              :     }
     260              : 
     261          801 :     if (!allocated(state.dataZoneEquip->ReturnAirPath)) {
     262              :         // Look for and read in the air return path
     263              :         // component (mixers & plenums) information for each zone
     264          801 :         state.dataZoneEquip->NumReturnAirPaths = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:ReturnPath");
     265          801 :         state.dataZoneEquip->ReturnAirPath.allocate(state.dataZoneEquip->NumReturnAirPaths);
     266              :     }
     267              : 
     268          801 :     state.dataZoneEquip->ZoneEquipConfig.allocate(state.dataGlobal->NumOfZones); // Allocate the array containing the configuration data for each zone
     269          801 :     if (state.dataHeatBal->doSpaceHeatBalanceSizing || state.dataHeatBal->doSpaceHeatBalanceSimulation) {
     270            4 :         state.dataZoneEquip->spaceEquipConfig.allocate(
     271            2 :             state.dataGlobal->numSpaces); // Allocate the array containing the configuration data for each space
     272              :     }
     273          801 :     state.dataZoneEquip->ZoneEquipList.allocate(state.dataGlobal->NumOfZones);
     274          801 :     state.dataZoneEquip->ZoneEquipAvail.dimension(state.dataGlobal->NumOfZones, Avail::Status::NoAction);
     275          801 :     state.dataZoneEquip->UniqueZoneEquipListNames.reserve(state.dataGlobal->NumOfZones);
     276              : 
     277          801 :     if (state.dataZoneEquip->NumOfZoneEquipLists != numControlledZones) {
     278            0 :         ShowSevereError(state,
     279            0 :                         format("{}Number of Zone Equipment lists [{}] not equal Number of Controlled Zones [{}]",
     280              :                                RoutineName,
     281            0 :                                state.dataZoneEquip->NumOfZoneEquipLists,
     282              :                                numControlledZones));
     283            0 :         ShowContinueError(state, "..Each Controlled Zone [ZoneHVAC:EquipmentConnections] must have a corresponding (unique) ZoneHVAC:EquipmentList");
     284            0 :         ShowFatalError(state, "GetZoneEquipment: Incorrect number of zone equipment lists");
     285              :     }
     286              : 
     287          801 :     if (numControlledZones > state.dataGlobal->NumOfZones) {
     288            0 :         ShowSevereError(state,
     289            0 :                         format("{}Number of Controlled Zone objects [{}] greater than Number of Zones [{}]",
     290              :                                RoutineName,
     291              :                                numControlledZones,
     292            0 :                                state.dataGlobal->NumOfZones));
     293            0 :         ShowFatalError(state, format("{}Too many ZoneHVAC:EquipmentConnections objects.", RoutineName));
     294              :     }
     295              : 
     296          801 :     InitUniqueNodeCheck(state, "ZoneHVAC:EquipmentConnections");
     297              : 
     298          801 :     int overallEquipCount = 0;
     299          801 :     int locTermUnitSizingCounter = 0; // will increment for every zone inlet node
     300              : 
     301              :     // auto &Zone(state.dataHeatBal->Zone);
     302              : 
     303         5262 :     for (int controlledZoneLoop = 1; controlledZoneLoop <= numControlledZones; ++controlledZoneLoop) {
     304         4461 :         CurrentModuleObject = "ZoneHVAC:EquipmentConnections";
     305         4461 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     306              :                                                                  CurrentModuleObject,
     307              :                                                                  controlledZoneLoop,
     308              :                                                                  AlphArray,
     309              :                                                                  NumAlphas,
     310              :                                                                  NumArray,
     311              :                                                                  NumNums,
     312              :                                                                  IOStat,
     313              :                                                                  lNumericBlanks,
     314              :                                                                  lAlphaBlanks,
     315              :                                                                  cAlphaFields,
     316              :                                                                  cNumericFields); // Get Equipment | data for one zone
     317              : 
     318         4461 :         int zoneNum = Util::FindItemInList(AlphArray(1), state.dataHeatBal->Zone);
     319         4461 :         std::string_view zsString = "Zone";
     320              : 
     321         4461 :         if (zoneNum == 0) {
     322            0 :             ShowSevereError(state, format("{}{}: {}=\"{}\"", RoutineName, CurrentModuleObject, cAlphaFields(1), AlphArray(1)));
     323            0 :             ShowContinueError(state,
     324            0 :                               format("..Requested Controlled {} not among {}s, remaining items for this object not processed.", zsString, zsString));
     325            0 :             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     326            0 :             continue;
     327              :         }
     328         4461 :         auto &thisZone = state.dataHeatBal->Zone(zoneNum);
     329              :         // Is this a duplicate for the same zone?
     330         4461 :         if (thisZone.IsControlled) {
     331            0 :             ShowSevereError(state, format("{}{}: {}=\"{}\"", RoutineName, CurrentModuleObject, cAlphaFields(1), AlphArray(1)));
     332            0 :             ShowContinueError(state,
     333            0 :                               format("..Duplicate Controlled {} entered, only one {} per {} is allowed.", zsString, CurrentModuleObject, zsString));
     334            0 :             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     335            0 :             continue;
     336              :         }
     337         4461 :         thisZone.IsControlled = true;
     338         4461 :         bool isSpace = false;
     339         4461 :         auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum);
     340         4461 :         processZoneEquipmentInput(state,
     341              :                                   CurrentModuleObject,
     342              :                                   zoneNum,
     343              :                                   isSpace,
     344              :                                   locTermUnitSizingCounter,
     345              :                                   overallEquipCount,
     346              :                                   thisZoneEquipConfig,
     347              :                                   AlphArray,
     348              :                                   cAlphaFields,
     349              :                                   lAlphaBlanks,
     350              :                                   NodeNums);
     351         4461 :         thisZone.SystemZoneNodeNumber = thisZoneEquipConfig.ZoneNode;
     352              :     } // end loop over controlled zones
     353          804 :     for (int controlledSpaceLoop = 1; controlledSpaceLoop <= numControlledSpaces; ++controlledSpaceLoop) {
     354            3 :         CurrentModuleObject = "SpaceHVAC:EquipmentConnections";
     355            3 :         if (!state.dataHeatBal->doSpaceHeatBalanceSimulation) {
     356            0 :             ShowWarningError(
     357              :                 state,
     358            0 :                 format("{} requires \"Do Space Heat Balance for Simulation = Yes\" in ZoneAirHeatBalanceAlgorithm. {} objects will be ignored.",
     359              :                        CurrentModuleObject,
     360              :                        CurrentModuleObject));
     361            0 :             break;
     362              :         }
     363            3 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     364              :                                                                  CurrentModuleObject,
     365              :                                                                  controlledSpaceLoop,
     366              :                                                                  AlphArray,
     367              :                                                                  NumAlphas,
     368              :                                                                  NumArray,
     369              :                                                                  NumNums,
     370              :                                                                  IOStat,
     371              :                                                                  lNumericBlanks,
     372              :                                                                  lAlphaBlanks,
     373              :                                                                  cAlphaFields,
     374              :                                                                  cNumericFields); // Get Equipment | data for one zone
     375              : 
     376            3 :         int spaceNum = Util::FindItemInList(AlphArray(1), state.dataHeatBal->space);
     377            3 :         std::string_view zsString = "Space";
     378              : 
     379            3 :         if (spaceNum == 0) {
     380            0 :             ShowSevereError(state, format("{}{}: {}=\"{}\"", RoutineName, CurrentModuleObject, cAlphaFields(1), AlphArray(1)));
     381            0 :             ShowContinueError(state,
     382            0 :                               format("..Requested Controlled {} not among {}s, remaining items for this object not processed.", zsString, zsString));
     383            0 :             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     384            0 :             continue;
     385              :         }
     386            3 :         auto &thisSpace = state.dataHeatBal->space(spaceNum);
     387            3 :         int zoneNum = thisSpace.zoneNum;
     388            3 :         if (!state.dataHeatBal->Zone(zoneNum).IsControlled) {
     389            0 :             ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisSpace.Name));
     390            0 :             ShowContinueError(state,
     391            0 :                               format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConnections object is required for this zone.",
     392            0 :                                      state.dataHeatBal->Zone(zoneNum).Name));
     393            0 :             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     394            0 :             continue;
     395              :         }
     396              :         // Is this a duplicate for the same space?
     397            3 :         if (thisSpace.IsControlled) {
     398            0 :             ShowSevereError(state, format("{}{}: {}=\"{}\"", RoutineName, CurrentModuleObject, cAlphaFields(1), AlphArray(1)));
     399            0 :             ShowContinueError(state,
     400            0 :                               format("..Duplicate Controlled {} entered, only one {} per {} is allowed.", zsString, CurrentModuleObject, zsString));
     401            0 :             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     402            0 :             continue;
     403              :         }
     404            3 :         thisSpace.IsControlled = true;
     405            3 :         bool isSpace = true;
     406            3 :         auto &thisSpaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(spaceNum);
     407            3 :         processZoneEquipmentInput(state,
     408              :                                   CurrentModuleObject,
     409              :                                   spaceNum,
     410              :                                   isSpace,
     411              :                                   locTermUnitSizingCounter,
     412              :                                   overallEquipCount,
     413              :                                   thisSpaceEquipConfig,
     414              :                                   AlphArray,
     415              :                                   cAlphaFields,
     416              :                                   lAlphaBlanks,
     417              :                                   NodeNums);
     418            3 :         thisSpace.SystemZoneNodeNumber = thisSpaceEquipConfig.ZoneNode;
     419              :     } // end loop over controlled spaces
     420              : 
     421          801 :     if (state.dataHeatBal->doSpaceHeatBalanceSizing || state.dataHeatBal->doSpaceHeatBalanceSimulation) {
     422              :         // Auto-assign the system node name for spaces in controlled zones that do not have a SpaceHVAC:EquipmentConnections input
     423           14 :         for (auto &thisZone : state.dataHeatBal->Zone) {
     424           12 :             if (!thisZone.IsControlled) {
     425            2 :                 continue;
     426              :             }
     427           10 :             int spaceCount = 0;
     428           24 :             for (int spaceNum : thisZone.spaceIndexes) {
     429           14 :                 ++spaceCount;
     430           14 :                 if (state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber == 0) {
     431           11 :                     std::string spaceNodeName = format("{}-Space {}", state.dataLoopNodes->NodeID(thisZone.SystemZoneNodeNumber), spaceCount);
     432           11 :                     int spaceNodeNum = GetOnlySingleNode(state,
     433              :                                                          spaceNodeName,
     434           11 :                                                          state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
     435              :                                                          DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections,
     436           11 :                                                          AlphArray(1),
     437              :                                                          DataLoopNode::NodeFluidType::Air,
     438              :                                                          DataLoopNode::ConnectionType::ZoneNode,
     439              :                                                          NodeInputManager::CompFluidStream::Primary,
     440              :                                                          DataLoopNode::ObjectIsNotParent);
     441           11 :                     state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = spaceNodeNum;
     442           11 :                 }
     443           10 :             }
     444            2 :         }
     445              :     }
     446              :     // Allocate TermUnitSizing array and set zone number
     447          801 :     if (locTermUnitSizingCounter > 0) {
     448          677 :         state.dataSize->NumAirTerminalUnits = locTermUnitSizingCounter;
     449          677 :         state.dataSize->TermUnitSizing.allocate(state.dataSize->NumAirTerminalUnits);
     450         5626 :         for (int loopZoneNum = 1; loopZoneNum <= state.dataGlobal->NumOfZones; ++loopZoneNum) {
     451              :             {
     452         4949 :                 auto &thisZoneEqConfig = state.dataZoneEquip->ZoneEquipConfig(loopZoneNum);
     453         9697 :                 for (int loopNodeNum = 1; loopNodeNum <= thisZoneEqConfig.NumInletNodes; ++loopNodeNum) {
     454         4748 :                     state.dataSize->TermUnitSizing(thisZoneEqConfig.AirDistUnitCool(loopNodeNum).TermUnitSizingIndex).CtrlZoneNum = loopZoneNum;
     455              :                 }
     456              :             }
     457              :         }
     458              :     }
     459          801 :     if (state.dataZoneEquip->GetZoneEquipmentDataErrorsFound) {
     460            0 :         ShowWarningError(state, format("{}{}, duplicate items NOT CHECKED due to previous errors.", RoutineName, CurrentModuleObject));
     461            0 :         overallEquipCount = 0;
     462              :     }
     463          801 :     if (overallEquipCount > 0) {
     464          703 :         ZoneEquipListAcct.allocate(overallEquipCount);
     465          703 :         overallEquipCount = 0;
     466         5164 :         for (int Loop1 = 1; Loop1 <= numControlledZones; ++Loop1) {
     467         9247 :             for (int Loop2 = 1; Loop2 <= state.dataZoneEquip->ZoneEquipList(Loop1).NumOfEquipTypes; ++Loop2) {
     468         4786 :                 ++overallEquipCount;
     469         4786 :                 ZoneEquipListAcct(overallEquipCount).ObjectType = state.dataZoneEquip->ZoneEquipList(Loop1).EquipType(Loop2);
     470         4786 :                 ZoneEquipListAcct(overallEquipCount).ObjectName = state.dataZoneEquip->ZoneEquipList(Loop1).EquipName(Loop2);
     471         4786 :                 ZoneEquipListAcct(overallEquipCount).OnListNum = Loop1;
     472              :             }
     473              :         }
     474              :         // Now check for uniqueness
     475         5489 :         for (int Loop1 = 1; Loop1 <= overallEquipCount; ++Loop1) {
     476       114426 :             for (int Loop2 = Loop1 + 1; Loop2 <= overallEquipCount; ++Loop2) {
     477       179203 :                 if (ZoneEquipListAcct(Loop1).ObjectType != ZoneEquipListAcct(Loop2).ObjectType ||
     478        69563 :                     ZoneEquipListAcct(Loop1).ObjectName != ZoneEquipListAcct(Loop2).ObjectName) {
     479       109640 :                     continue;
     480              :                 }
     481              :                 // Duplicated -- not allowed
     482            0 :                 ShowSevereError(state, format("{}{}, duplicate items in ZoneHVAC:EquipmentList.", RoutineName, CurrentModuleObject));
     483            0 :                 ShowContinueError(state,
     484            0 :                                   format("Equipment: Type={}, Name={}", ZoneEquipListAcct(Loop1).ObjectType, ZoneEquipListAcct(Loop1).ObjectName));
     485            0 :                 ShowContinueError(state,
     486            0 :                                   format("Found on List=\"{}\".", state.dataZoneEquip->ZoneEquipList(ZoneEquipListAcct(Loop1).OnListNum).Name));
     487            0 :                 ShowContinueError(
     488              :                     state,
     489            0 :                     format("Equipment Duplicated on List=\"{}\".", state.dataZoneEquip->ZoneEquipList(ZoneEquipListAcct(Loop2).OnListNum).Name));
     490            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     491              :             }
     492              :         }
     493          703 :         ZoneEquipListAcct.deallocate();
     494              :     }
     495              : 
     496              :     // map ZoneEquipConfig%EquipListIndex to ZoneEquipList%Name
     497              : 
     498         6002 :     for (int ControlledZoneLoop = 1; ControlledZoneLoop <= state.dataGlobal->NumOfZones; ++ControlledZoneLoop) {
     499         5201 :         state.dataZoneEquip->GetZoneEquipmentDataFound = Util::FindItemInList(
     500         5201 :             state.dataZoneEquip->ZoneEquipList(ControlledZoneLoop).Name, state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::EquipListName);
     501         5201 :         if (state.dataZoneEquip->GetZoneEquipmentDataFound > 0) {
     502         5201 :             state.dataZoneEquip->ZoneEquipConfig(state.dataZoneEquip->GetZoneEquipmentDataFound).EquipListIndex = ControlledZoneLoop;
     503              :         }
     504              :     } // end loop over controlled zones
     505              : 
     506          801 :     EndUniqueNodeCheck(state, "ZoneHVAC:EquipmentConnections");
     507              : 
     508          801 :     auto &ip = state.dataInputProcessing->inputProcessor;
     509              : 
     510          801 :     CurrentModuleObject = "SpaceHVAC:ZoneEquipmentSplitter";
     511          801 :     auto instances = ip->epJSON.find(CurrentModuleObject);
     512          801 :     if (instances != ip->epJSON.end()) {
     513            1 :         if (!state.dataHeatBal->doSpaceHeatBalanceSimulation) {
     514            0 :             ShowWarningError(
     515              :                 state,
     516            0 :                 format("{} requires \"Do Space Heat Balance for Simulation = Yes\" in ZoneAirHeatBalanceAlgorithm. {} objects will be ignored.",
     517              :                        CurrentModuleObject,
     518              :                        CurrentModuleObject));
     519              :         } else {
     520            1 :             auto const &objectSchemaProps = ip->getObjectSchemaProps(state, CurrentModuleObject);
     521            1 :             auto &instancesValue = instances.value();
     522            1 :             int numZoneEqSplitters = instancesValue.size();
     523            1 :             state.dataZoneEquip->zoneEquipSplitter.resize(numZoneEqSplitters);
     524            1 :             int zeqSplitterNum = -1;
     525            2 :             for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
     526            1 :                 ++zeqSplitterNum;
     527            1 :                 auto const &objectFields = instance.value();
     528            1 :                 auto &thisZeqSplitter = state.dataZoneEquip->zoneEquipSplitter[zeqSplitterNum];
     529            1 :                 thisZeqSplitter.Name = Util::makeUPPER(instance.key());
     530            1 :                 thisZeqSplitter.spaceEquipType = DataLoopNode::ConnectionObjectType::SpaceHVACZoneEquipmentSplitter;
     531            1 :                 ip->markObjectAsUsed(CurrentModuleObject, instance.key());
     532              : 
     533            2 :                 std::string zoneName = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_name");
     534            1 :                 int zoneNum = Util::FindItemInList(zoneName, state.dataHeatBal->Zone);
     535            1 :                 if (zoneNum == 0) {
     536            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZeqSplitter.Name));
     537            0 :                     ShowContinueError(state, format("..Zone Name={} not found, remaining items for this object not processed.", zoneName));
     538            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     539            0 :                     continue;
     540              :                 }
     541            1 :                 if (!state.dataHeatBal->Zone(zoneNum).IsControlled) {
     542            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZeqSplitter.Name));
     543            0 :                     ShowContinueError(
     544              :                         state,
     545            0 :                         format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConnections object is required for this zone.",
     546              :                                zoneName));
     547            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     548            0 :                     continue;
     549              :                 }
     550              : 
     551            1 :                 processZoneEquipSplitterInput(state, CurrentModuleObject, zeqSplitterNum, zoneNum, objectSchemaProps, objectFields, thisZeqSplitter);
     552            2 :             } // end loop over zone equipment splitters
     553              :         }
     554              :     }
     555              : 
     556          801 :     CurrentModuleObject = "SpaceHVAC:ZoneEquipmentMixer";
     557          801 :     instances = ip->epJSON.find(CurrentModuleObject);
     558          801 :     if (instances != ip->epJSON.end()) {
     559            1 :         if (!state.dataHeatBal->doSpaceHeatBalanceSimulation) {
     560            0 :             ShowWarningError(
     561              :                 state,
     562            0 :                 format("{} requires \"Do Space Heat Balance for Simulation = Yes\" in ZoneAirHeatBalanceAlgorithm. {} objects will be ignored.",
     563              :                        CurrentModuleObject,
     564              :                        CurrentModuleObject));
     565              :         } else {
     566            1 :             auto const &objectSchemaProps = ip->getObjectSchemaProps(state, CurrentModuleObject);
     567            1 :             auto &instancesValue = instances.value();
     568            1 :             int numZoneEqMixers = instancesValue.size();
     569            1 :             state.dataZoneEquip->zoneEquipMixer.resize(numZoneEqMixers);
     570            1 :             int zeqMixerNum = -1;
     571            2 :             for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
     572            1 :                 ++zeqMixerNum;
     573            1 :                 auto const &objectFields = instance.value();
     574            1 :                 auto &thisZeqMixer = state.dataZoneEquip->zoneEquipMixer[zeqMixerNum];
     575            1 :                 thisZeqMixer.Name = Util::makeUPPER(instance.key());
     576            1 :                 thisZeqMixer.spaceEquipType = DataLoopNode::ConnectionObjectType::SpaceHVACZoneEquipmentMixer;
     577            1 :                 ip->markObjectAsUsed(CurrentModuleObject, instance.key());
     578              : 
     579            2 :                 std::string zoneName = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_name");
     580            1 :                 int zoneNum = Util::FindItemInList(zoneName, state.dataHeatBal->Zone);
     581            1 :                 if (zoneNum == 0) {
     582            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZeqMixer.Name));
     583            0 :                     ShowContinueError(state, format("..Zone Name={} not found, remaining items for this object not processed.", zoneName));
     584            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     585            0 :                     continue;
     586              :                 }
     587            1 :                 if (!state.dataHeatBal->Zone(zoneNum).IsControlled) {
     588            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZeqMixer.Name));
     589            0 :                     ShowContinueError(
     590              :                         state,
     591            0 :                         format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConnections object is required for this zone.",
     592              :                                zoneName));
     593            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     594            0 :                     continue;
     595              :                 }
     596              : 
     597            1 :                 processZoneEquipMixerInput(state, CurrentModuleObject, zoneNum, objectSchemaProps, objectFields, thisZeqMixer);
     598            2 :             } // end loop over zone equipment mixers
     599              :         }
     600              :     }
     601              : 
     602          801 :     CurrentModuleObject = "SpaceHVAC:ZoneReturnMixer";
     603          801 :     instances = ip->epJSON.find(CurrentModuleObject);
     604          801 :     if (instances != ip->epJSON.end()) {
     605            1 :         if (!state.dataHeatBal->doSpaceHeatBalanceSimulation) {
     606            0 :             ShowWarningError(
     607              :                 state,
     608            0 :                 format("{} requires \"Do Space Heat Balance for Simulation = Yes\" in ZoneAirHeatBalanceAlgorithm. {} objects will be ignored.",
     609              :                        CurrentModuleObject,
     610              :                        CurrentModuleObject));
     611              :         } else {
     612            1 :             auto const &objectSchemaProps = ip->getObjectSchemaProps(state, CurrentModuleObject);
     613            1 :             auto &instancesValue = instances.value();
     614            1 :             int numZoneRetMixers = instancesValue.size();
     615            1 :             state.dataZoneEquip->zoneReturnMixer.resize(numZoneRetMixers);
     616            1 :             int zeqRetNum = -1;
     617            2 :             for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
     618            1 :                 ++zeqRetNum;
     619            1 :                 auto const &objectFields = instance.value();
     620            1 :                 auto &thisZretMixer = state.dataZoneEquip->zoneReturnMixer[zeqRetNum];
     621            1 :                 thisZretMixer.Name = Util::makeUPPER(instance.key());
     622            1 :                 thisZretMixer.spaceEquipType = DataLoopNode::ConnectionObjectType::SpaceHVACZoneReturnMixer;
     623            1 :                 ip->markObjectAsUsed(CurrentModuleObject, instance.key());
     624              : 
     625            2 :                 std::string zoneName = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_name");
     626            1 :                 int zoneNum = Util::FindItemInList(zoneName, state.dataHeatBal->Zone);
     627            1 :                 if (zoneNum == 0) {
     628            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZretMixer.Name));
     629            0 :                     ShowContinueError(state, format("..Zone Name={} not found, remaining items for this object not processed.", zoneName));
     630            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     631            0 :                     continue;
     632              :                 }
     633            1 :                 if (!state.dataHeatBal->Zone(zoneNum).IsControlled) {
     634            0 :                     ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, CurrentModuleObject, thisZretMixer.Name));
     635            0 :                     ShowContinueError(
     636              :                         state,
     637            0 :                         format("..Zone Name={} is not a controlled zone. A ZoneHVAC:EquipmentConnections object is required for this zone.",
     638              :                                zoneName));
     639            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     640            0 :                     continue;
     641              :                 }
     642              : 
     643            1 :                 processZoneReturnMixerInput(state, CurrentModuleObject, zoneNum, objectSchemaProps, objectFields, zeqRetNum);
     644            2 :             } // end loop over zone return mixers
     645              :         }
     646              :     }
     647              : 
     648          801 :     CurrentModuleObject = "AirLoopHVAC:SupplyPath";
     649         2031 :     for (int PathNum = 1; PathNum <= state.dataZoneEquip->NumSupplyAirPaths; ++PathNum) {
     650              : 
     651         1230 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     652              :                                                                  CurrentModuleObject,
     653              :                                                                  PathNum,
     654              :                                                                  AlphArray,
     655              :                                                                  NumAlphas,
     656              :                                                                  NumArray,
     657              :                                                                  NumNums,
     658              :                                                                  IOStat,
     659              :                                                                  lNumericBlanks,
     660              :                                                                  lAlphaBlanks,
     661              :                                                                  cAlphaFields,
     662              :                                                                  cNumericFields); //  data for one zone
     663         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).Name = AlphArray(1);
     664         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents = nint((double(NumAlphas) - 2.0) / 2.0);
     665              : 
     666         2460 :         state.dataZoneEquip->SupplyAirPath(PathNum).InletNodeNum = GetOnlySingleNode(state,
     667         1230 :                                                                                      AlphArray(2),
     668         1230 :                                                                                      state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
     669              :                                                                                      DataLoopNode::ConnectionObjectType::AirLoopHVACSupplyPath,
     670         1230 :                                                                                      AlphArray(1),
     671              :                                                                                      DataLoopNode::NodeFluidType::Air,
     672              :                                                                                      DataLoopNode::ConnectionType::Inlet,
     673              :                                                                                      NodeInputManager::CompFluidStream::Primary,
     674              :                                                                                      ObjectIsParent);
     675              : 
     676         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).ComponentType.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
     677         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).ComponentTypeEnum.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
     678         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).ComponentTypeEnum = DataZoneEquipment::AirLoopHVACZone::Invalid;
     679         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).ComponentName.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
     680         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).ComponentIndex.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
     681         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).SplitterIndex.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
     682         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).PlenumIndex.allocate(state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents);
     683              : 
     684         1230 :         int Counter = 3;
     685              : 
     686         2467 :         for (int CompNum = 1; CompNum <= state.dataZoneEquip->SupplyAirPath(PathNum).NumOfComponents; ++CompNum) {
     687              : 
     688         1237 :             if ((AlphArray(Counter) == "AIRLOOPHVAC:ZONESPLITTER") || (AlphArray(Counter) == "AIRLOOPHVAC:SUPPLYPLENUM")) {
     689              : 
     690         1237 :                 state.dataZoneEquip->SupplyAirPath(PathNum).ComponentType(CompNum) = AlphArray(Counter);
     691         1237 :                 state.dataZoneEquip->SupplyAirPath(PathNum).ComponentName(CompNum) = AlphArray(Counter + 1);
     692         2474 :                 ValidateComponent(state,
     693         1237 :                                   state.dataZoneEquip->SupplyAirPath(PathNum).ComponentType(CompNum),
     694         1237 :                                   state.dataZoneEquip->SupplyAirPath(PathNum).ComponentName(CompNum),
     695              :                                   IsNotOK,
     696              :                                   CurrentModuleObject);
     697         1237 :                 state.dataZoneEquip->SupplyAirPath(PathNum).ComponentIndex(CompNum) = 0;
     698         1237 :                 state.dataZoneEquip->SupplyAirPath(PathNum).SplitterIndex(CompNum) = 0;
     699         1237 :                 state.dataZoneEquip->SupplyAirPath(PathNum).PlenumIndex(CompNum) = 0;
     700         1237 :                 state.dataZoneEquip->SupplyAirPath(PathNum).ComponentTypeEnum(CompNum) =
     701         2474 :                     (AirLoopHVACZone)getEnumValue(AirLoopHVACTypeNamesUC, AlphArray(Counter));
     702              :             } else {
     703            0 :                 ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cAlphaFields(1), state.dataZoneEquip->SupplyAirPath(PathNum).Name));
     704            0 :                 ShowContinueError(state, format("Unhandled component type =\"{}\".", AlphArray(Counter)));
     705            0 :                 ShowContinueError(state, R"(Must be "AirLoopHVAC:ZoneSplitter" or "AirLoopHVAC:SupplyPlenum")");
     706            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     707              :             }
     708              : 
     709         1237 :             Counter += 2;
     710              :         }
     711              : 
     712         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).NumOutletNodes = 0;
     713         1230 :         state.dataZoneEquip->SupplyAirPath(PathNum).NumNodes = 0;
     714              : 
     715              :     } // end loop over supply air paths
     716              : 
     717          801 :     CurrentModuleObject = "AirLoopHVAC:ReturnPath";
     718         2014 :     for (int PathNum = 1; PathNum <= state.dataZoneEquip->NumReturnAirPaths; ++PathNum) {
     719              : 
     720         1213 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     721              :                                                                  CurrentModuleObject,
     722              :                                                                  PathNum,
     723              :                                                                  AlphArray,
     724              :                                                                  NumAlphas,
     725              :                                                                  NumArray,
     726              :                                                                  NumNums,
     727              :                                                                  IOStat,
     728              :                                                                  lNumericBlanks,
     729              :                                                                  lAlphaBlanks,
     730              :                                                                  cAlphaFields,
     731              :                                                                  cNumericFields); //  data for one zone
     732         1213 :         state.dataZoneEquip->ReturnAirPath(PathNum).Name = AlphArray(1);
     733         1213 :         state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents = nint((double(NumAlphas) - 2.0) / 2.0);
     734              : 
     735         2426 :         state.dataZoneEquip->ReturnAirPath(PathNum).OutletNodeNum = GetOnlySingleNode(state,
     736         1213 :                                                                                       AlphArray(2),
     737         1213 :                                                                                       state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
     738              :                                                                                       DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPath,
     739         1213 :                                                                                       AlphArray(1),
     740              :                                                                                       DataLoopNode::NodeFluidType::Air,
     741              :                                                                                       DataLoopNode::ConnectionType::Outlet,
     742              :                                                                                       NodeInputManager::CompFluidStream::Primary,
     743              :                                                                                       ObjectIsParent);
     744              : 
     745         1213 :         state.dataZoneEquip->ReturnAirPath(PathNum).ComponentType.allocate(state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents);
     746         1213 :         state.dataZoneEquip->ReturnAirPath(PathNum).ComponentTypeEnum.allocate(state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents);
     747         1213 :         state.dataZoneEquip->ReturnAirPath(PathNum).ComponentTypeEnum = DataZoneEquipment::AirLoopHVACZone::Invalid;
     748         1213 :         state.dataZoneEquip->ReturnAirPath(PathNum).ComponentName.allocate(state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents);
     749         1213 :         state.dataZoneEquip->ReturnAirPath(PathNum).ComponentIndex.allocate(state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents);
     750              : 
     751         1213 :         int Counter = 3;
     752              : 
     753         2542 :         for (int CompNum = 1; CompNum <= state.dataZoneEquip->ReturnAirPath(PathNum).NumOfComponents; ++CompNum) {
     754              : 
     755         1329 :             if ((AlphArray(Counter) == "AIRLOOPHVAC:ZONEMIXER") || (AlphArray(Counter) == "AIRLOOPHVAC:RETURNPLENUM")) {
     756              : 
     757         1329 :                 state.dataZoneEquip->ReturnAirPath(PathNum).ComponentType(CompNum) = AlphArray(Counter);
     758         1329 :                 state.dataZoneEquip->ReturnAirPath(PathNum).ComponentName(CompNum) = AlphArray(Counter + 1);
     759         1329 :                 state.dataZoneEquip->ReturnAirPath(PathNum).ComponentIndex(CompNum) = 0;
     760         2658 :                 ValidateComponent(state,
     761         1329 :                                   state.dataZoneEquip->ReturnAirPath(PathNum).ComponentType(CompNum),
     762         1329 :                                   state.dataZoneEquip->ReturnAirPath(PathNum).ComponentName(CompNum),
     763              :                                   IsNotOK,
     764              :                                   CurrentModuleObject);
     765         1329 :                 if (IsNotOK) {
     766            0 :                     ShowContinueError(state, format("In {} = {}", CurrentModuleObject, state.dataZoneEquip->ReturnAirPath(PathNum).Name));
     767            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     768              :                 }
     769         1329 :                 state.dataZoneEquip->ReturnAirPath(PathNum).ComponentTypeEnum(CompNum) =
     770         2658 :                     static_cast<AirLoopHVACZone>(getEnumValue(AirLoopHVACTypeNamesUC, AlphArray(Counter)));
     771              :             } else {
     772            0 :                 ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cAlphaFields(1), state.dataZoneEquip->ReturnAirPath(PathNum).Name));
     773            0 :                 ShowContinueError(state, format("Unhandled component type =\"{}\".", AlphArray(Counter)));
     774            0 :                 ShowContinueError(state, R"(Must be "AirLoopHVAC:ZoneMixer" or "AirLoopHVAC:ReturnPlenum")");
     775            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     776              :             }
     777              : 
     778         1329 :             Counter += 2;
     779              :         }
     780              : 
     781              :     } // end loop over return air paths
     782              : 
     783          801 :     AlphArray.deallocate();
     784          801 :     NumArray.deallocate();
     785          801 :     cAlphaFields.deallocate();
     786          801 :     cNumericFields.deallocate();
     787          801 :     lAlphaBlanks.deallocate();
     788          801 :     lNumericBlanks.deallocate();
     789              : 
     790          801 :     if (state.dataZoneEquip->GetZoneEquipmentDataErrorsFound) {
     791            0 :         ShowFatalError(state, format("{}Errors found in getting Zone Equipment input.", RoutineName));
     792              :     }
     793          801 : }
     794              : 
     795         4464 : void processZoneEquipmentInput(EnergyPlusData &state,
     796              :                                std::string_view zoneEqModuleObject,
     797              :                                int const zoneOrSpaceNum,
     798              :                                bool const isSpace,
     799              :                                int &locTermUnitSizingCounter,
     800              :                                int &overallEquipCount,
     801              :                                DataZoneEquipment::EquipConfiguration &thisEquipConfig,
     802              :                                Array1D_string &AlphArray,
     803              :                                Array1D_string &cAlphaFields, // Alpha field names
     804              :                                Array1D_bool &lAlphaBlanks,   // Logical array, alpha field input BLANK = .TRUE.
     805              :                                Array1D_int &NodeNums)
     806              : {
     807              :     static constexpr std::string_view RoutineName("processZoneEquipmentInput: "); // include trailing blank space
     808              :     static constexpr std::string_view routineName = "processZoneEquipmentInput";
     809              : 
     810         4464 :     int spaceFieldShift = 0;
     811         4464 :     if (isSpace) {
     812            3 :         spaceFieldShift = -1;
     813              :     }
     814              : 
     815         4464 :     ErrorObjectHeader eoh{routineName, zoneEqModuleObject, AlphArray(1)};
     816              : 
     817         4464 :     thisEquipConfig.IsControlled = true;
     818         4464 :     thisEquipConfig.ZoneName = AlphArray(1); // for x-referencing with the geometry data
     819              : 
     820         4464 :     bool IsNotOK = false;
     821         8928 :     GlobalNames::IntraObjUniquenessCheck(
     822         4464 :         state, AlphArray(2), zoneEqModuleObject, cAlphaFields(2), state.dataZoneEquip->UniqueZoneEquipListNames, IsNotOK);
     823         4464 :     if (IsNotOK) {
     824            0 :         ShowContinueError(state, format("..another Controlled Zone has been assigned that {}.", cAlphaFields(2)));
     825            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     826              :     }
     827         4464 :     thisEquipConfig.EquipListName = AlphArray(2); // the name of the list containing all the zone eq.
     828         4464 :     std::string const InletNodeListName = AlphArray(3 + spaceFieldShift);
     829         4464 :     std::string const ExhaustNodeListName = AlphArray(4 + spaceFieldShift);
     830         4464 :     thisEquipConfig.ZoneNode = GetOnlySingleNode(state,
     831         4464 :                                                  AlphArray(5 + spaceFieldShift),
     832         4464 :                                                  state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
     833              :                                                  DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections,
     834         4464 :                                                  AlphArray(1),
     835              :                                                  DataLoopNode::NodeFluidType::Air,
     836              :                                                  DataLoopNode::ConnectionType::ZoneNode,
     837              :                                                  NodeInputManager::CompFluidStream::Primary,
     838              :                                                  DataLoopNode::ObjectIsNotParent); // all zone air state variables are
     839         4464 :     if (thisEquipConfig.ZoneNode == 0) {
     840            0 :         ShowSevereError(state, format("{}{}: {}=\"{}\", invalid", RoutineName, zoneEqModuleObject, cAlphaFields(1), AlphArray(1)));
     841            0 :         ShowContinueError(state, format("{} must be present.", cAlphaFields(5 + spaceFieldShift)));
     842            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     843              :     } else {
     844         4464 :         bool UniqueNodeError = false;
     845         4464 :         NodeInputManager::CheckUniqueNodeNames(
     846         4464 :             state, cAlphaFields(5 + spaceFieldShift), UniqueNodeError, AlphArray(5 + spaceFieldShift), AlphArray(1));
     847         4464 :         if (UniqueNodeError) {
     848              :             // ShowContinueError(state, format("Occurs for {} = {}", trim( cAlphaFields( 1 ) ), trim( AlphArray( 1 ) )));
     849            0 :             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     850              :         }
     851              :     }
     852              : 
     853         4464 :     std::string ReturnNodeListName = AlphArray(6 + spaceFieldShift);
     854         4464 :     if (lAlphaBlanks(7)) {
     855         4459 :         thisEquipConfig.returnFlowFracSched = Sched::GetScheduleAlwaysOn(state); // Not an availability sched, but defaults to constant-1.0
     856            5 :     } else if ((thisEquipConfig.returnFlowFracSched = Sched::GetSchedule(state, AlphArray(7 + spaceFieldShift))) == nullptr) {
     857            0 :         ShowSevereItemNotFound(state, eoh, cAlphaFields(7), AlphArray(7));
     858            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     859              :     }
     860         4464 :     std::string ReturnFlowBasisNodeListName = AlphArray(8 + spaceFieldShift);
     861              : 
     862              :     // Read in the equipment type, name and sequence information
     863              :     // for each equipment list
     864              : 
     865         4464 :     if (!isSpace) {
     866         4461 :         std::string CurrentModuleObject = "ZoneHVAC:EquipmentList";
     867         4461 :         auto &ip = state.dataInputProcessing->inputProcessor;
     868              : 
     869         4461 :         int ZoneEquipListNum = ip->getObjectItemNum(state, CurrentModuleObject, thisEquipConfig.EquipListName);
     870              : 
     871         4461 :         if (ZoneEquipListNum <= 0) {
     872            0 :             ShowSevereError(state, format("{}{} not found = {}", RoutineName, CurrentModuleObject, thisEquipConfig.EquipListName));
     873            0 :             ShowContinueError(state, format("In ZoneHVAC:EquipmentConnections object, for Zone = {}", thisEquipConfig.ZoneName));
     874            0 :             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     875              :         } else {
     876         4461 :             auto const &epListFields = ip->getJSONObjectItem(state, CurrentModuleObject, thisEquipConfig.EquipListName);
     877              : 
     878         4461 :             auto const &objectSchemaProps = ip->getObjectSchemaProps(state, CurrentModuleObject);
     879              : 
     880         4461 :             EquipList &thisZoneEquipList = state.dataZoneEquip->ZoneEquipList(zoneOrSpaceNum);
     881              : 
     882         4461 :             thisZoneEquipList.Name = thisEquipConfig.EquipListName;
     883              : 
     884         8922 :             std::string loadDistName = ip->getAlphaFieldValue(epListFields, objectSchemaProps, "load_distribution_scheme");
     885         4461 :             thisZoneEquipList.LoadDistScheme =
     886         4461 :                 static_cast<DataZoneEquipment::LoadDist>(getEnumValue(DataZoneEquipment::LoadDistNamesUC, Util::makeUPPER(loadDistName)));
     887         4461 :             if (thisZoneEquipList.LoadDistScheme == DataZoneEquipment::LoadDist::Invalid) {
     888            0 :                 ShowSevereError(state, format("{}{} = \"{}, Invalid choice\".", RoutineName, CurrentModuleObject, thisZoneEquipList.Name));
     889            0 :                 ShowContinueError(state, format("...load_distribution_scheme=\"{}\".", loadDistName));
     890            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     891              :             }
     892              : 
     893         4461 :             auto extensibles = epListFields.find("equipment");
     894         4461 :             if (extensibles != epListFields.end()) {
     895         4461 :                 auto &extensiblesArray = extensibles.value();
     896         4461 :                 thisZoneEquipList.NumOfEquipTypes = static_cast<int>(extensiblesArray.size());
     897              : 
     898              :                 // Increment overall count of equipment
     899         4461 :                 overallEquipCount += thisZoneEquipList.NumOfEquipTypes;
     900              : 
     901         4461 :                 thisZoneEquipList.EquipTypeName.allocate(thisZoneEquipList.NumOfEquipTypes);
     902         4461 :                 thisZoneEquipList.EquipType.allocate(thisZoneEquipList.NumOfEquipTypes);
     903         4461 :                 thisZoneEquipList.compPointer.resize(thisZoneEquipList.NumOfEquipTypes + 1);
     904         4461 :                 thisZoneEquipList.EquipName.allocate(thisZoneEquipList.NumOfEquipTypes);
     905         4461 :                 thisZoneEquipList.EquipIndex.allocate(thisZoneEquipList.NumOfEquipTypes);
     906         4461 :                 thisZoneEquipList.zoneEquipSplitterIndex.allocate(thisZoneEquipList.NumOfEquipTypes);
     907         4461 :                 thisZoneEquipList.EquipData.allocate(thisZoneEquipList.NumOfEquipTypes);
     908         4461 :                 thisZoneEquipList.CoolingPriority.allocate(thisZoneEquipList.NumOfEquipTypes);
     909         4461 :                 thisZoneEquipList.HeatingPriority.allocate(thisZoneEquipList.NumOfEquipTypes);
     910         4461 :                 thisZoneEquipList.CoolingCapacity.allocate(thisZoneEquipList.NumOfEquipTypes);
     911         4461 :                 thisZoneEquipList.HeatingCapacity.allocate(thisZoneEquipList.NumOfEquipTypes);
     912         4461 :                 thisZoneEquipList.sequentialCoolingFractionScheds.allocate(thisZoneEquipList.NumOfEquipTypes);
     913         4461 :                 thisZoneEquipList.sequentialHeatingFractionScheds.allocate(thisZoneEquipList.NumOfEquipTypes);
     914         9652 :                 for (int eqNum = 1; eqNum <= thisZoneEquipList.NumOfEquipTypes; ++eqNum) {
     915         5191 :                     thisZoneEquipList.EquipTypeName(eqNum) = "";
     916         5191 :                     thisZoneEquipList.EquipType(eqNum) = DataZoneEquipment::ZoneEquipType::Invalid;
     917         5191 :                     thisZoneEquipList.EquipName(eqNum) = "";
     918         5191 :                     thisZoneEquipList.EquipIndex(eqNum) = 0;
     919         5191 :                     thisZoneEquipList.zoneEquipSplitterIndex(eqNum) = -1;
     920         5191 :                     thisZoneEquipList.compPointer[eqNum] = nullptr;
     921         5191 :                     thisZoneEquipList.CoolingPriority(eqNum) = 0;
     922         5191 :                     thisZoneEquipList.HeatingPriority(eqNum) = 0;
     923         5191 :                     thisZoneEquipList.CoolingCapacity(eqNum) = 0;
     924         5191 :                     thisZoneEquipList.HeatingCapacity(eqNum) = 0;
     925         5191 :                     thisZoneEquipList.sequentialCoolingFractionScheds(eqNum) = nullptr;
     926         5191 :                     thisZoneEquipList.sequentialHeatingFractionScheds(eqNum) = nullptr;
     927              :                 }
     928              : 
     929         4461 :                 auto const &extensionSchemaProps = objectSchemaProps["equipment"]["items"]["properties"];
     930              : 
     931         4461 :                 int ZoneEquipTypeNum = 0;
     932         9652 :                 for (auto &extensibleInstance : extensiblesArray) {
     933         5191 :                     ++ZoneEquipTypeNum;
     934              : 
     935         5191 :                     thisZoneEquipList.EquipTypeName(ZoneEquipTypeNum) =
     936        15573 :                         ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "zone_equipment_object_type");
     937         5191 :                     thisZoneEquipList.EquipName(ZoneEquipTypeNum) =
     938        15573 :                         ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "zone_equipment_name");
     939              : 
     940        10382 :                     ValidateComponent(state,
     941         5191 :                                       thisZoneEquipList.EquipTypeName(ZoneEquipTypeNum),
     942         5191 :                                       thisZoneEquipList.EquipName(ZoneEquipTypeNum),
     943              :                                       IsNotOK,
     944              :                                       CurrentModuleObject);
     945         5191 :                     if (IsNotOK) {
     946            0 :                         ShowContinueError(state, format("In {}={}", CurrentModuleObject, thisZoneEquipList.Name));
     947            0 :                         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     948              :                     }
     949              : 
     950              :                     // If not present, this return 0
     951        10382 :                     thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) =
     952        10382 :                         ip->getIntFieldValue(extensibleInstance, extensionSchemaProps, "zone_equipment_cooling_sequence");
     953              : 
     954        10382 :                     if ((thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) < 0) ||
     955         5191 :                         (thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) > thisZoneEquipList.NumOfEquipTypes)) {
     956            0 :                         ShowSevereError(state, format("{}{} = \"{}\".", RoutineName, CurrentModuleObject, thisZoneEquipList.Name));
     957            0 :                         ShowContinueError(
     958            0 :                             state, format("invalid zone_equipment_cooling_sequence=[{}].", thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum)));
     959            0 :                         ShowContinueError(state, "equipment sequence must be > 0 and <= number of equipments in the list.");
     960            0 :                         if (thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) > 0) {
     961            0 :                             ShowContinueError(state, format("only {} in the list.", thisZoneEquipList.NumOfEquipTypes));
     962              :                         }
     963            0 :                         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     964              :                     }
     965              : 
     966        10382 :                     thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) =
     967        10382 :                         ip->getIntFieldValue(extensibleInstance, extensionSchemaProps, "zone_equipment_heating_or_no_load_sequence");
     968        10382 :                     if ((thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) < 0) ||
     969         5191 :                         (thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) > thisZoneEquipList.NumOfEquipTypes)) {
     970            0 :                         ShowSevereError(state, format("{}{} = \"{}\".", RoutineName, CurrentModuleObject, thisZoneEquipList.Name));
     971            0 :                         ShowContinueError(
     972            0 :                             state, format("invalid zone_equipment_heating_sequence=[{}].", thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum)));
     973            0 :                         ShowContinueError(state, "equipment sequence must be > 0 and <= number of equipments in the list.");
     974            0 :                         if (thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) > 0) {
     975            0 :                             ShowContinueError(state, format("only {} in the list.", thisZoneEquipList.NumOfEquipTypes));
     976              :                         }
     977            0 :                         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     978              :                     }
     979              : 
     980              :                     std::string coolingSchName =
     981        10382 :                         ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "zone_equipment_sequential_cooling_fraction_schedule_name");
     982         5191 :                     if (coolingSchName.empty()) {
     983         5169 :                         thisZoneEquipList.sequentialCoolingFractionScheds(ZoneEquipTypeNum) =
     984         5169 :                             Sched::GetScheduleAlwaysOn(state); // Not an availability schedule, but defaults to constant-1.0
     985              :                     } else {
     986           22 :                         thisZoneEquipList.sequentialCoolingFractionScheds(ZoneEquipTypeNum) = Sched::GetSchedule(state, coolingSchName);
     987           22 :                         if (thisZoneEquipList.sequentialCoolingFractionScheds(ZoneEquipTypeNum) == nullptr) {
     988            0 :                             ShowSevereItemNotFound(state, eoh, "zone_equipment_sequential_cooling_fraction_schedule_name", coolingSchName);
     989            0 :                             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
     990              :                         }
     991              :                     }
     992              : 
     993              :                     std::string heatingSchName =
     994        10382 :                         ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "zone_equipment_sequential_heating_fraction_schedule_name");
     995         5191 :                     if (heatingSchName.empty()) {
     996         5169 :                         thisZoneEquipList.sequentialHeatingFractionScheds(ZoneEquipTypeNum) =
     997         5169 :                             Sched::GetScheduleAlwaysOn(state); // Not an availability schedule, but defaults to constant-1.0
     998              :                     } else {
     999           22 :                         thisZoneEquipList.sequentialHeatingFractionScheds(ZoneEquipTypeNum) = Sched::GetSchedule(state, heatingSchName);
    1000           22 :                         if (thisZoneEquipList.sequentialHeatingFractionScheds(ZoneEquipTypeNum) == nullptr) {
    1001            0 :                             ShowSevereItemNotFound(state, eoh, "zone_equipment_sequential_heating_fraction_schedule_name", coolingSchName);
    1002            0 :                             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1003              :                         }
    1004              :                     }
    1005              : 
    1006              :                     // do this here for initial prototype, but later will call all the equipment in a separate function to see who is on - maybe
    1007         5191 :                     if (thisZoneEquipList.HeatingPriority(ZoneEquipTypeNum) > 0) {
    1008         5191 :                         ++thisZoneEquipList.NumAvailHeatEquip;
    1009              :                     }
    1010         5191 :                     if (thisZoneEquipList.CoolingPriority(ZoneEquipTypeNum) > 0) {
    1011         5191 :                         ++thisZoneEquipList.NumAvailCoolEquip;
    1012              :                     }
    1013              : 
    1014        10382 :                     thisZoneEquipList.EquipType(ZoneEquipTypeNum) = static_cast<ZoneEquipType>(
    1015         5191 :                         getEnumValue(zoneEquipTypeNamesUC, Util::makeUPPER(thisZoneEquipList.EquipTypeName(ZoneEquipTypeNum))));
    1016              : 
    1017         5191 :                     if (thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::UnitarySystem ||
    1018         5170 :                         thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::PackagedTerminalAirConditioner ||
    1019        15356 :                         thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::PackagedTerminalHeatPump ||
    1020         4995 :                         thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::PackagedTerminalHeatPumpWaterToAir) {
    1021              :                         // loop index accesses correct pointer to equipment on this equipment list
    1022              :                         // EquipIndex is used to access specific equipment for a single class of equipment (e.g., PTAC 1, 2 and 3)
    1023          351 :                         thisZoneEquipList.compPointer[ZoneEquipTypeNum] = UnitarySystems::UnitarySys::factory(
    1024          351 :                             state, HVAC::UnitarySysType::Unitary_AnyCoilType, thisZoneEquipList.EquipName(ZoneEquipTypeNum), true, 0);
    1025          351 :                         thisZoneEquipList.EquipIndex(ZoneEquipTypeNum) = thisZoneEquipList.compPointer[ZoneEquipTypeNum]->getEquipIndex();
    1026              :                     }
    1027              : 
    1028         5191 :                     if (thisZoneEquipList.EquipType(ZoneEquipTypeNum) == ZoneEquipType::Invalid) {
    1029            0 :                         ShowSevereError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, thisZoneEquipList.Name));
    1030            0 :                         ShowContinueError(state, format("..Invalid Equipment Type = {}", thisZoneEquipList.EquipType(ZoneEquipTypeNum)));
    1031            0 :                         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1032              :                     }
    1033         9652 :                 }
    1034              :             } // End parsing all extensible Zone Equipment info
    1035              : 
    1036              :             // Check for multiple assignments
    1037         9652 :             for (int ZoneEquipTypeNum = 1; ZoneEquipTypeNum <= thisZoneEquipList.NumOfEquipTypes; ++ZoneEquipTypeNum) {
    1038         5191 :                 if (count_eq(thisZoneEquipList.CoolingPriority, ZoneEquipTypeNum) > 1) {
    1039            0 :                     ShowSevereError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, thisZoneEquipList.Name));
    1040            0 :                     ShowContinueError(state,
    1041            0 :                                       format("...multiple assignments for Zone Equipment Cooling Sequence={}, must be 1-1 correspondence between "
    1042              :                                              "sequence assignments and number of equipments.",
    1043              :                                              ZoneEquipTypeNum));
    1044            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1045         5191 :                 } else if (count_eq(thisZoneEquipList.CoolingPriority, ZoneEquipTypeNum) == 0) {
    1046            0 :                     ShowWarningError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, thisZoneEquipList.Name));
    1047            0 :                     ShowContinueError(state,
    1048            0 :                                       format("...zero assigned to Zone Equipment Cooling Sequence={}, apparent gap in sequence assignments in "
    1049              :                                              "this equipment list.",
    1050              :                                              ZoneEquipTypeNum));
    1051              :                 }
    1052         5191 :                 if (count_eq(thisZoneEquipList.HeatingPriority, ZoneEquipTypeNum) > 1) {
    1053            0 :                     ShowSevereError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, thisZoneEquipList.Name));
    1054            0 :                     ShowContinueError(state,
    1055            0 :                                       format("...multiple assignments for Zone Equipment Heating or No-Load Sequence={}, must be 1-1 "
    1056              :                                              "correspondence between sequence assignments and number of equipments.",
    1057              :                                              ZoneEquipTypeNum));
    1058            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1059         5191 :                 } else if (count_eq(thisZoneEquipList.HeatingPriority, ZoneEquipTypeNum) == 0) {
    1060            0 :                     ShowWarningError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, thisZoneEquipList.Name));
    1061            0 :                     ShowContinueError(state,
    1062            0 :                                       format("...zero assigned to Zone Equipment Heating or No-Load Sequence={}, apparent gap in sequence "
    1063              :                                              "assignments in this equipment list.",
    1064              :                                              ZoneEquipTypeNum));
    1065              :                 }
    1066              :             }
    1067         4461 :         } // End ZoneHVAC:EquipmentList
    1068         4461 :     }
    1069         4464 :     bool NodeListError = false;
    1070         4464 :     int NumNodes = 0;
    1071         8928 :     GetNodeNums(state,
    1072              :                 InletNodeListName,
    1073              :                 NumNodes,
    1074              :                 NodeNums,
    1075              :                 NodeListError,
    1076              :                 DataLoopNode::NodeFluidType::Air,
    1077              :                 (isSpace ? DataLoopNode::ConnectionObjectType::SpaceHVACEquipmentConnections
    1078              :                          : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections),
    1079         4464 :                 thisEquipConfig.ZoneName,
    1080              :                 DataLoopNode::ConnectionType::ZoneInlet,
    1081              :                 NodeInputManager::CompFluidStream::Primary,
    1082              :                 DataLoopNode::ObjectIsNotParent);
    1083              : 
    1084         4464 :     if (!NodeListError) {
    1085         4464 :         thisEquipConfig.NumInletNodes = NumNodes;
    1086              : 
    1087         4464 :         thisEquipConfig.InletNode.allocate(NumNodes);
    1088         4464 :         thisEquipConfig.InletNodeAirLoopNum.allocate(NumNodes);
    1089         4464 :         thisEquipConfig.InletNodeADUNum.allocate(NumNodes);
    1090         4464 :         thisEquipConfig.AirDistUnitCool.allocate(NumNodes);
    1091         4464 :         thisEquipConfig.AirDistUnitHeat.allocate(NumNodes);
    1092              : 
    1093         9215 :         for (int NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
    1094         4751 :             thisEquipConfig.InletNode(NodeNum) = NodeNums(NodeNum);
    1095         4751 :             bool UniqueNodeError = false;
    1096         9502 :             NodeInputManager::CheckUniqueNodeNumbers(state, "Zone Air Inlet Nodes", UniqueNodeError, NodeNums(NodeNum), thisEquipConfig.ZoneName);
    1097         4751 :             if (UniqueNodeError) {
    1098            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1099              :             }
    1100         4751 :             thisEquipConfig.InletNodeAirLoopNum(NodeNum) = 0;
    1101         4751 :             thisEquipConfig.InletNodeADUNum(NodeNum) = 0;
    1102         4751 :             thisEquipConfig.AirDistUnitCool(NodeNum).InNode = 0;
    1103         4751 :             thisEquipConfig.AirDistUnitHeat(NodeNum).InNode = 0;
    1104         4751 :             thisEquipConfig.AirDistUnitCool(NodeNum).OutNode = 0;
    1105         4751 :             thisEquipConfig.AirDistUnitHeat(NodeNum).OutNode = 0;
    1106         4751 :             if (!isSpace) {
    1107         4748 :                 ++locTermUnitSizingCounter;
    1108         4748 :                 thisEquipConfig.AirDistUnitCool(NodeNum).TermUnitSizingIndex = locTermUnitSizingCounter;
    1109         4748 :                 thisEquipConfig.AirDistUnitHeat(NodeNum).TermUnitSizingIndex = locTermUnitSizingCounter;
    1110              :             }
    1111              :         }
    1112              :     } else {
    1113            0 :         ShowContinueError(
    1114              :             state,
    1115            0 :             format("Invalid Zone Air Inlet Node or NodeList Name in ZoneHVAC:EquipmentConnections object, for Zone = {}", thisEquipConfig.ZoneName));
    1116            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1117              :     }
    1118              : 
    1119         4464 :     NodeListError = false;
    1120         8928 :     GetNodeNums(state,
    1121              :                 ExhaustNodeListName,
    1122              :                 NumNodes,
    1123              :                 NodeNums,
    1124              :                 NodeListError,
    1125              :                 DataLoopNode::NodeFluidType::Air,
    1126              :                 (isSpace ? DataLoopNode::ConnectionObjectType::SpaceHVACEquipmentConnections
    1127              :                          : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections),
    1128         4464 :                 thisEquipConfig.ZoneName,
    1129              :                 DataLoopNode::ConnectionType::ZoneExhaust,
    1130              :                 NodeInputManager::CompFluidStream::Primary,
    1131              :                 DataLoopNode::ObjectIsNotParent);
    1132              : 
    1133         4464 :     if (!NodeListError) {
    1134         4464 :         thisEquipConfig.NumExhaustNodes = NumNodes;
    1135              : 
    1136         4464 :         thisEquipConfig.ExhaustNode.allocate(NumNodes);
    1137              : 
    1138         5462 :         for (int NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
    1139          998 :             thisEquipConfig.ExhaustNode(NodeNum) = NodeNums(NodeNum);
    1140          998 :             bool UniqueNodeError = false;
    1141         1996 :             NodeInputManager::CheckUniqueNodeNumbers(state, "Zone Air Exhaust Nodes", UniqueNodeError, NodeNums(NodeNum), thisEquipConfig.ZoneName);
    1142          998 :             if (UniqueNodeError) {
    1143              :                 // ShowContinueError(state, format("Occurs for Zone = {}", trim( AlphArray( 1 ) )));
    1144            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1145              :             }
    1146              :         }
    1147              :     } else {
    1148            0 :         ShowContinueError(
    1149              :             state,
    1150            0 :             format("Invalid Zone Air Exhaust Node or NodeList Name in ZoneHVAC:EquipmentConnections object, for Zone={}", thisEquipConfig.ZoneName));
    1151            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1152              :     }
    1153              : 
    1154         4464 :     NodeListError = false;
    1155         8928 :     GetNodeNums(state,
    1156              :                 ReturnNodeListName,
    1157              :                 NumNodes,
    1158              :                 NodeNums,
    1159              :                 NodeListError,
    1160              :                 DataLoopNode::NodeFluidType::Air,
    1161              :                 (isSpace ? DataLoopNode::ConnectionObjectType::SpaceHVACEquipmentConnections
    1162              :                          : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections),
    1163         4464 :                 thisEquipConfig.ZoneName,
    1164              :                 DataLoopNode::ConnectionType::ZoneReturn,
    1165              :                 NodeInputManager::CompFluidStream::Primary,
    1166              :                 DataLoopNode::ObjectIsNotParent);
    1167              : 
    1168         4464 :     if (!NodeListError) {
    1169         4464 :         thisEquipConfig.NumReturnNodes = NumNodes;
    1170              : 
    1171         4464 :         thisEquipConfig.ReturnNode.allocate(NumNodes);
    1172         4464 :         thisEquipConfig.returnNodeSpaceMixerIndex.allocate(NumNodes);
    1173         8932 :         for (int &mixIndex : thisEquipConfig.returnNodeSpaceMixerIndex) {
    1174         4468 :             mixIndex = -1;
    1175              :         }
    1176         4464 :         thisEquipConfig.ReturnNodeAirLoopNum.allocate(NumNodes);
    1177         4464 :         thisEquipConfig.ReturnNodeRetPathNum.allocate(NumNodes);
    1178         4464 :         thisEquipConfig.ReturnNodeRetPathCompNum.allocate(NumNodes);
    1179         4464 :         thisEquipConfig.ReturnNodeInletNum.allocate(NumNodes);
    1180         4464 :         thisEquipConfig.FixedReturnFlow.allocate(NumNodes);
    1181         4464 :         thisEquipConfig.ReturnNodePlenumNum.allocate(NumNodes);
    1182         4464 :         thisEquipConfig.ReturnNodeExhaustNodeNum.allocate(NumNodes);
    1183         4464 :         thisEquipConfig.SharedExhaustNode.allocate(NumNodes);
    1184         4464 :         thisEquipConfig.ReturnNode = 0;           // initialize to zero here
    1185         4464 :         thisEquipConfig.ReturnNodeAirLoopNum = 0; // initialize to zero here
    1186         4464 :         thisEquipConfig.ReturnNodeInletNum = 0;   // initialize to zero here
    1187         4464 :         thisEquipConfig.ReturnNodeRetPathNum = 0;
    1188         4464 :         thisEquipConfig.ReturnNodeRetPathCompNum = 0;
    1189         4464 :         thisEquipConfig.FixedReturnFlow = false;                                // initialize to false here
    1190         4464 :         thisEquipConfig.ReturnNodePlenumNum = 0;                                // initialize to zero here
    1191         4464 :         thisEquipConfig.ReturnNodeExhaustNodeNum = 0;                           // initialize to zero here
    1192         4464 :         thisEquipConfig.SharedExhaustNode = LightReturnExhaustConfig::NoExhast; // initialize to zero here
    1193              : 
    1194         8932 :         for (int NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
    1195         4468 :             thisEquipConfig.ReturnNode(NodeNum) = NodeNums(NodeNum);
    1196         4468 :             bool UniqueNodeError = false;
    1197         8936 :             NodeInputManager::CheckUniqueNodeNumbers(state, "Zone Return Air Nodes", UniqueNodeError, NodeNums(NodeNum), thisEquipConfig.ZoneName);
    1198         4468 :             if (UniqueNodeError) {
    1199              :                 // ShowContinueError(state, format("Occurs for Zone = {}", trim( AlphArray( 1 ) )));
    1200            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1201              :             }
    1202              :         }
    1203              :     } else {
    1204            0 :         ShowContinueError(
    1205              :             state,
    1206            0 :             format("Invalid Zone Return Air Node or NodeList Name in ZoneHVAC:EquipmentConnections object, for Zone={}", thisEquipConfig.ZoneName));
    1207            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1208              :     }
    1209              : 
    1210         4464 :     NodeListError = false;
    1211         8928 :     GetNodeNums(state,
    1212              :                 ReturnFlowBasisNodeListName,
    1213              :                 NumNodes,
    1214              :                 NodeNums,
    1215              :                 NodeListError,
    1216              :                 DataLoopNode::NodeFluidType::Air,
    1217              :                 (isSpace ? DataLoopNode::ConnectionObjectType::SpaceHVACEquipmentConnections
    1218              :                          : DataLoopNode::ConnectionObjectType::ZoneHVACEquipmentConnections),
    1219         4464 :                 thisEquipConfig.ZoneName,
    1220              :                 DataLoopNode::ConnectionType::Sensor,
    1221              :                 NodeInputManager::CompFluidStream::Primary,
    1222              :                 DataLoopNode::ObjectIsNotParent);
    1223              : 
    1224         4464 :     if (!NodeListError) {
    1225         4464 :         thisEquipConfig.NumReturnFlowBasisNodes = NumNodes;
    1226              : 
    1227         4464 :         thisEquipConfig.ReturnFlowBasisNode.allocate(NumNodes);
    1228              : 
    1229         4464 :         for (int NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
    1230            0 :             thisEquipConfig.ReturnFlowBasisNode(NodeNum) = NodeNums(NodeNum);
    1231              :         }
    1232              :     } else {
    1233            0 :         ShowContinueError(
    1234              :             state,
    1235            0 :             format("Invalid Zone Return Air Node 1 Flow Rate Basis Node or NodeList Name in ZoneHVAC:EquipmentConnections object, for Zone={}",
    1236            0 :                    thisEquipConfig.ZoneName));
    1237            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1238              :     }
    1239         4464 : }
    1240              : 
    1241            1 : void processZoneEquipSplitterInput(EnergyPlusData &state,
    1242              :                                    std::string_view zeqSplitterModuleObject,
    1243              :                                    int const zeqSplitterNum,
    1244              :                                    int const zoneNum,
    1245              :                                    InputProcessor::json const objectSchemaProps,
    1246              :                                    InputProcessor::json const objectFields,
    1247              :                                    DataZoneEquipment::ZoneEquipmentSplitter &thisZeqSplitter)
    1248              : 
    1249              : {
    1250              :     static constexpr std::string_view RoutineName("processZoneEquipSplitterInput: "); // include trailing blank space
    1251            1 :     auto &ip = state.dataInputProcessing->inputProcessor;
    1252            2 :     std::string const zeqTypeName = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_equipment_object_type");
    1253            1 :     thisZeqSplitter.zoneEquipType = DataZoneEquipment::ZoneEquipType(getEnumValue(zoneEquipTypeNamesUC, zeqTypeName));
    1254            1 :     if (thisZeqSplitter.zoneEquipType == ZoneEquipType::Invalid) {
    1255            0 :         ShowSevereError(state, format("{}{} = {}", RoutineName, zeqSplitterModuleObject, thisZeqSplitter.Name));
    1256            0 :         ShowContinueError(state, format("..Invalid Equipment Type = {}", zeqTypeName));
    1257            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1258              :     }
    1259              : 
    1260            2 :     thisZeqSplitter.zoneEquipName = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_equipment_name");
    1261              : 
    1262              :     // Search zone equipment list for matching equip type and name
    1263            1 :     bool found = false;
    1264            1 :     auto &thisZoneEqList = state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex);
    1265            1 :     for (int eqCount = 1; eqCount <= thisZoneEqList.NumOfEquipTypes; ++eqCount) {
    1266            1 :         if (thisZeqSplitter.zoneEquipType == thisZoneEqList.EquipType(eqCount)) {
    1267            1 :             if (thisZeqSplitter.zoneEquipName == thisZoneEqList.EquipName(eqCount)) {
    1268            1 :                 found = true;
    1269              :                 // Set index in zone equipment list pointing to this SpaceHVAC:ZoneEquipmentSplitter
    1270            1 :                 thisZoneEqList.zoneEquipSplitterIndex = zeqSplitterNum;
    1271              :                 // SpaceHVAC TODO: Outletnodes aren't know yet - need to set this in a later init
    1272              :                 // thisZeqSplitter.zoneEquipOutletNodeNum = thisZoneEqList.EquipData(eqCount).OutletNodeNums(1);
    1273            1 :                 break;
    1274              :             }
    1275              :         }
    1276              :     }
    1277            1 :     if (!found) {
    1278            0 :         ShowSevereError(state, format("{}{} = {}", RoutineName, zeqSplitterModuleObject, thisZeqSplitter.Name));
    1279            0 :         ShowContinueError(
    1280            0 :             state, format(".. Zone Equipment Object Type={} and Zone Equipment Name={} not found", zeqTypeName, thisZeqSplitter.zoneEquipName));
    1281            0 :         ShowContinueError(state, format(".. in ZoneHVAC:EquipmentList={}", thisZoneEqList.Name));
    1282            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1283            0 :         return;
    1284              :     }
    1285              : 
    1286            1 :     bool objectIsParent = true;
    1287            1 :     thisZeqSplitter.zoneEquipOutletNodeNum =
    1288            2 :         GetOnlySingleNode(state,
    1289            2 :                           ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_equipment_outlet_node_name"),
    1290            1 :                           state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
    1291              :                           thisZeqSplitter.spaceEquipType,
    1292            1 :                           thisZeqSplitter.Name,
    1293              :                           DataLoopNode::NodeFluidType::Air,
    1294              :                           DataLoopNode::ConnectionType::Inlet,
    1295              :                           NodeInputManager::CompFluidStream::Primary,
    1296              :                           objectIsParent);
    1297              : 
    1298            1 :     thisZeqSplitter.tstatControl = DataZoneEquipment::ZoneEquipTstatControl(
    1299            2 :         getEnumValue(zoneEquipTstatControlNamesUC, ip->getAlphaFieldValue(objectFields, objectSchemaProps, "thermostat_control_method")));
    1300            1 :     if (thisZeqSplitter.tstatControl == DataZoneEquipment::ZoneEquipTstatControl::SingleSpace) {
    1301            2 :         std::string spaceName = ip->getAlphaFieldValue(objectFields, objectSchemaProps, "control_space_name");
    1302            1 :         thisZeqSplitter.controlSpaceIndex = Util::FindItemInList(spaceName, state.dataHeatBal->space);
    1303            1 :         if (thisZeqSplitter.controlSpaceIndex == 0) {
    1304            0 :             ShowSevereError(state, format("{}{}={}", RoutineName, zeqSplitterModuleObject, thisZeqSplitter.Name));
    1305            0 :             ShowContinueError(state, format("Space Name={} not found.", spaceName));
    1306            0 :             state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1307              :         }
    1308            1 :     }
    1309            1 :     thisZeqSplitter.spaceSizingBasis = DataZoneEquipment::SpaceEquipSizingBasis(
    1310            3 :         getEnumValue(spaceEquipSizingBasisNamesUC, ip->getAlphaFieldValue(objectFields, objectSchemaProps, "space_fraction_method")));
    1311              : 
    1312            1 :     auto extensibles = objectFields.find("spaces");
    1313            1 :     auto const &extensionSchemaProps = objectSchemaProps["spaces"]["items"]["properties"];
    1314            1 :     if (extensibles != objectFields.end()) {
    1315            1 :         auto &extensiblesArray = extensibles.value();
    1316            1 :         int const numSpaces = extensiblesArray.size();
    1317            1 :         thisZeqSplitter.spaces.resize(numSpaces);
    1318            1 :         int spaceCount = -1;
    1319            4 :         for (auto &extensibleInstance : extensiblesArray) {
    1320            3 :             ++spaceCount;
    1321            3 :             auto &thisZeqSpace = thisZeqSplitter.spaces[spaceCount];
    1322            6 :             std::string const spaceName = ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_name");
    1323            3 :             thisZeqSpace.spaceIndex = Util::FindItemInList(spaceName, state.dataHeatBal->space);
    1324            3 :             if (thisZeqSpace.spaceIndex == 0) {
    1325            0 :                 ShowSevereError(state, format("{}{}={}", RoutineName, zeqSplitterModuleObject, thisZeqSplitter.Name));
    1326            0 :                 ShowContinueError(state, format("Space Name={} not found.", spaceName));
    1327            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1328              :             } else {
    1329            6 :                 thisZeqSpace.fraction = ip->getRealFieldValue(extensibleInstance, extensionSchemaProps, "space_fraction");
    1330            3 :                 thisZeqSpace.spaceNodeNum =
    1331            6 :                     GetOnlySingleNode(state,
    1332            6 :                                       ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_supply_node_name"),
    1333            3 :                                       state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
    1334              :                                       thisZeqSplitter.spaceEquipType,
    1335            3 :                                       thisZeqSplitter.Name,
    1336              :                                       DataLoopNode::NodeFluidType::Air,
    1337              :                                       DataLoopNode::ConnectionType::Outlet,
    1338              :                                       NodeInputManager::CompFluidStream::Primary,
    1339              :                                       objectIsParent);
    1340            3 :                 if (thisZeqSplitter.controlSpaceIndex == thisZeqSpace.spaceIndex) {
    1341            1 :                     thisZeqSplitter.controlSpaceNumber = spaceCount;
    1342              :                 }
    1343              :             }
    1344            4 :         }
    1345              :     }
    1346            1 : }
    1347              : 
    1348            1 : void processZoneEquipMixerInput(EnergyPlusData &state,
    1349              :                                 std::string_view zeqMixerModuleObject,
    1350              :                                 int const zoneNum,
    1351              :                                 InputProcessor::json const objectSchemaProps,
    1352              :                                 InputProcessor::json const objectFields,
    1353              :                                 DataZoneEquipment::ZoneEquipmentMixer &thisZeqMixer)
    1354              : 
    1355              : {
    1356              :     static constexpr std::string_view RoutineName("processZoneEquipMixerInput: "); // include trailing blank space
    1357            1 :     auto &ip = state.dataInputProcessing->inputProcessor;
    1358            1 :     bool objectIsParent = true;
    1359            2 :     thisZeqMixer.outletNodeNum = GetOnlySingleNode(state,
    1360            2 :                                                    ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_equipment_inlet_node_name"),
    1361            1 :                                                    state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
    1362              :                                                    thisZeqMixer.spaceEquipType,
    1363            1 :                                                    thisZeqMixer.Name,
    1364              :                                                    DataLoopNode::NodeFluidType::Air,
    1365              :                                                    DataLoopNode::ConnectionType::Outlet,
    1366              :                                                    NodeInputManager::CompFluidStream::Primary,
    1367              :                                                    objectIsParent);
    1368              :     // Check zone exhaust nodes
    1369            1 :     bool found = false;
    1370            1 :     auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum);
    1371            1 :     for (int exhNodeNum : thisZoneEquipConfig.ExhaustNode) {
    1372            1 :         if (thisZeqMixer.outletNodeNum == exhNodeNum) {
    1373            1 :             found = true;
    1374            1 :             break;
    1375              :         }
    1376              :     }
    1377            1 :     if (!found) {
    1378            0 :         ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZeqMixer.Name));
    1379            0 :         ShowContinueError(state,
    1380            0 :                           format("Zone Equipment Inlet Node Name={} is not an exhaust node for ZoneHVAC:EquipmentConnections={}.",
    1381            0 :                                  state.dataLoopNodes->NodeID(thisZeqMixer.outletNodeNum),
    1382            0 :                                  thisZoneEquipConfig.ZoneName));
    1383            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1384              :     }
    1385              : 
    1386            1 :     thisZeqMixer.spaceSizingBasis = DataZoneEquipment::SpaceEquipSizingBasis(
    1387            3 :         getEnumValue(spaceEquipSizingBasisNamesUC, ip->getAlphaFieldValue(objectFields, objectSchemaProps, "space_fraction_method")));
    1388              : 
    1389            1 :     auto extensibles = objectFields.find("spaces");
    1390            1 :     auto const &extensionSchemaProps = objectSchemaProps["spaces"]["items"]["properties"];
    1391            1 :     if (extensibles != objectFields.end()) {
    1392            1 :         auto &extensiblesArray = extensibles.value();
    1393            1 :         int const numSpaces = extensiblesArray.size();
    1394            1 :         thisZeqMixer.spaces.resize(numSpaces);
    1395            1 :         int spaceCount = -1;
    1396            2 :         for (auto &extensibleInstance : extensiblesArray) {
    1397            1 :             ++spaceCount;
    1398            1 :             auto &thisZeqSpace = thisZeqMixer.spaces[spaceCount];
    1399            2 :             std::string const spaceName = ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_name");
    1400            1 :             thisZeqSpace.spaceIndex = Util::FindItemInList(spaceName, state.dataHeatBal->space);
    1401            1 :             if (thisZeqSpace.spaceIndex == 0) {
    1402            0 :                 ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZeqMixer.Name));
    1403            0 :                 ShowContinueError(state, format("Space Name={} not found.", spaceName));
    1404            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1405              :             } else {
    1406            2 :                 thisZeqSpace.fraction = ip->getRealFieldValue(extensibleInstance, extensionSchemaProps, "space_fraction");
    1407            2 :                 thisZeqSpace.spaceNodeNum = GetOnlySingleNode(state,
    1408            2 :                                                               ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_node_name"),
    1409            1 :                                                               state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
    1410              :                                                               thisZeqMixer.spaceEquipType,
    1411            1 :                                                               thisZeqMixer.Name,
    1412              :                                                               DataLoopNode::NodeFluidType::Air,
    1413              :                                                               DataLoopNode::ConnectionType::Inlet,
    1414              :                                                               NodeInputManager::CompFluidStream::Primary,
    1415              :                                                               objectIsParent);
    1416              :                 // Check space exhaust nodes
    1417            1 :                 found = false;
    1418            1 :                 auto &thisSpaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(thisZeqSpace.spaceIndex);
    1419            1 :                 for (int exhNodeNum : thisSpaceEquipConfig.ExhaustNode) {
    1420            1 :                     if (thisZeqSpace.spaceNodeNum == exhNodeNum) {
    1421            1 :                         found = true;
    1422            1 :                         break;
    1423              :                     }
    1424              :                 }
    1425            1 :                 if (!found) {
    1426            0 :                     ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZeqMixer.Name));
    1427            0 :                     ShowContinueError(state,
    1428            0 :                                       format("Space Node Name={} is not an exhaust node for SpaceHVAC:EquipmentConnections={}.",
    1429            0 :                                              state.dataLoopNodes->NodeID(thisZeqSpace.spaceNodeNum),
    1430            0 :                                              thisSpaceEquipConfig.ZoneName));
    1431            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1432              :                 }
    1433              :             }
    1434            2 :         }
    1435              :     }
    1436            1 : }
    1437              : 
    1438            1 : void processZoneReturnMixerInput(EnergyPlusData &state,
    1439              :                                  std::string_view zeqMixerModuleObject,
    1440              :                                  int const zoneNum,
    1441              :                                  InputProcessor::json const objectSchemaProps,
    1442              :                                  InputProcessor::json const objectFields,
    1443              :                                  int mixerIndex)
    1444              : 
    1445              : {
    1446              :     static constexpr std::string_view RoutineName("processZoneReturnMixerInput: "); // include trailing blank space
    1447            1 :     auto &ip = state.dataInputProcessing->inputProcessor;
    1448            1 :     bool objectIsParent = true;
    1449            1 :     auto &thisZretMixer = state.dataZoneEquip->zoneReturnMixer[mixerIndex];
    1450            2 :     thisZretMixer.outletNodeNum = GetOnlySingleNode(state,
    1451            2 :                                                     ip->getAlphaFieldValue(objectFields, objectSchemaProps, "zone_return_air_node_name"),
    1452            1 :                                                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
    1453              :                                                     thisZretMixer.spaceEquipType,
    1454            1 :                                                     thisZretMixer.Name,
    1455              :                                                     DataLoopNode::NodeFluidType::Air,
    1456              :                                                     DataLoopNode::ConnectionType::Outlet,
    1457              :                                                     NodeInputManager::CompFluidStream::Primary,
    1458              :                                                     objectIsParent);
    1459              :     // Check zone return nodes
    1460            1 :     bool found = false;
    1461            1 :     auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(zoneNum);
    1462            1 :     int nodeCounter = 0;
    1463            1 :     for (int retNodeNum : thisZoneEquipConfig.ReturnNode) {
    1464            1 :         ++nodeCounter;
    1465            1 :         if (thisZretMixer.outletNodeNum == retNodeNum) {
    1466            1 :             found = true;
    1467              :             // Zone return node is fed by a space return mixer
    1468            1 :             thisZoneEquipConfig.returnNodeSpaceMixerIndex(nodeCounter) = mixerIndex;
    1469            1 :             break;
    1470              :         }
    1471              :     }
    1472            1 :     if (!found) {
    1473            0 :         ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZretMixer.Name));
    1474            0 :         ShowContinueError(state,
    1475            0 :                           format("Zone Equipment Return Air Node Name={} is not a return air node for ZoneHVAC:EquipmentConnections={}.",
    1476            0 :                                  state.dataLoopNodes->NodeID(thisZretMixer.outletNodeNum),
    1477            0 :                                  thisZoneEquipConfig.ZoneName));
    1478            0 :         state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1479              :     }
    1480              : 
    1481            1 :     auto extensibles = objectFields.find("spaces");
    1482            1 :     auto const &extensionSchemaProps = objectSchemaProps["spaces"]["items"]["properties"];
    1483            1 :     if (extensibles != objectFields.end()) {
    1484            1 :         auto &extensiblesArray = extensibles.value();
    1485            1 :         int const numSpaces = extensiblesArray.size();
    1486            1 :         thisZretMixer.spaces.resize(numSpaces);
    1487            1 :         int spaceCount = -1;
    1488            4 :         for (auto &extensibleInstance : extensiblesArray) {
    1489            3 :             ++spaceCount;
    1490            3 :             auto &thisZeqSpace = thisZretMixer.spaces[spaceCount];
    1491            6 :             std::string const spaceName = ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_name");
    1492            3 :             thisZeqSpace.spaceIndex = Util::FindItemInList(spaceName, state.dataHeatBal->space);
    1493            3 :             if (thisZeqSpace.spaceIndex == 0) {
    1494            0 :                 ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZretMixer.Name));
    1495            0 :                 ShowContinueError(state, format("Space Name={} not found.", spaceName));
    1496            0 :                 state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1497              :             } else {
    1498            3 :                 thisZeqSpace.spaceNodeNum =
    1499            6 :                     GetOnlySingleNode(state,
    1500            6 :                                       ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "space_return_air_node_name"),
    1501            3 :                                       state.dataZoneEquip->GetZoneEquipmentDataErrorsFound,
    1502              :                                       thisZretMixer.spaceEquipType,
    1503            3 :                                       thisZretMixer.Name,
    1504              :                                       DataLoopNode::NodeFluidType::Air,
    1505              :                                       DataLoopNode::ConnectionType::Inlet,
    1506              :                                       NodeInputManager::CompFluidStream::Primary,
    1507              :                                       objectIsParent);
    1508              :                 // Check space return nodes
    1509            3 :                 found = false;
    1510            3 :                 auto &thisSpaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(thisZeqSpace.spaceIndex);
    1511            3 :                 for (int retNodeNum : thisSpaceEquipConfig.ReturnNode) {
    1512            3 :                     if (thisZeqSpace.spaceNodeNum == retNodeNum) {
    1513            3 :                         found = true;
    1514            3 :                         break;
    1515              :                     }
    1516              :                 }
    1517            3 :                 if (!found) {
    1518            0 :                     ShowSevereError(state, format("{}{}={}", RoutineName, zeqMixerModuleObject, thisZretMixer.Name));
    1519            0 :                     ShowContinueError(state,
    1520            0 :                                       format("Space Return Air Node Name={} is not a return air node for SpaceHVAC:EquipmentConnections={}.",
    1521            0 :                                              state.dataLoopNodes->NodeID(thisZeqSpace.spaceNodeNum),
    1522            0 :                                              thisSpaceEquipConfig.ZoneName));
    1523            0 :                     state.dataZoneEquip->GetZoneEquipmentDataErrorsFound = true;
    1524              :                 }
    1525              :             }
    1526            4 :         }
    1527              :     }
    1528            1 : }
    1529              : 
    1530         4574 : bool CheckZoneEquipmentList(EnergyPlusData &state,
    1531              :                             std::string_view const ComponentType, // Type of component
    1532              :                             std::string_view const ComponentName, // Name of component
    1533              :                             ObjexxFCL::Optional_int CtrlZoneNum)
    1534              : {
    1535              : 
    1536              :     // FUNCTION INFORMATION:
    1537              :     //       AUTHOR         Linda Lawrie
    1538              :     //       DATE WRITTEN   May 2007
    1539              :     //       MODIFIED       na
    1540              :     //       RE-ENGINEERED  na
    1541              : 
    1542              :     // PURPOSE OF THIS FUNCTION:
    1543              :     // Provides a way to check if a component name is listed on a zone equipment list.
    1544              : 
    1545              :     // Return value
    1546              :     bool IsOnList; // True if item is on a list, false if not.
    1547              : 
    1548              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
    1549              :     int Loop;
    1550              :     int ListLoop;
    1551              :     int CtrlZoneNumLocal;
    1552              : 
    1553         4574 :     CtrlZoneNumLocal = 0;
    1554         4574 :     IsOnList = false;
    1555        78010 :     for (Loop = 1; Loop <= state.dataGlobal->NumOfZones; ++Loop) { // NumOfZoneEquipLists
    1556        78010 :         if (state.dataZoneEquip->ZoneEquipList(Loop).Name.empty()) {
    1557         3755 :             continue; // dimensioned by NumOfZones.  Only valid ones have names.
    1558              :         }
    1559       167942 :         for (ListLoop = 1; ListLoop <= state.dataZoneEquip->ZoneEquipList(Loop).NumOfEquipTypes; ++ListLoop) {
    1560              : 
    1561        98261 :             if (!Util::SameString(state.dataZoneEquip->ZoneEquipList(Loop).EquipTypeName(ListLoop), ComponentType)) {
    1562        30108 :                 continue;
    1563              :             }
    1564        68153 :             if (ComponentName == "*") {
    1565            0 :                 IsOnList = true;
    1566            0 :                 CtrlZoneNumLocal = Loop;
    1567            0 :                 goto EquipList_exit;
    1568              :             }
    1569        68153 :             if (!Util::SameString(state.dataZoneEquip->ZoneEquipList(Loop).EquipName(ListLoop), ComponentName)) {
    1570        63579 :                 continue;
    1571              :             }
    1572         4574 :             IsOnList = true;
    1573         4574 :             CtrlZoneNumLocal = Loop;
    1574         4574 :             goto EquipList_exit;
    1575              :         }
    1576              :     }
    1577            0 : EquipList_exit:;
    1578         4574 :     if (present(CtrlZoneNum)) {
    1579            0 :         CtrlZoneNum = CtrlZoneNumLocal;
    1580              :     }
    1581         4574 :     return IsOnList;
    1582              : }
    1583              : 
    1584            7 : int GetControlledZoneIndex(EnergyPlusData &state, std::string const &ZoneName) // Zone name to match into Controlled Zone structure
    1585              : {
    1586              : 
    1587              :     // FUNCTION INFORMATION:
    1588              :     //       AUTHOR         Linda Lawrie
    1589              :     //       DATE WRITTEN   March 2008
    1590              : 
    1591              :     // PURPOSE OF THIS FUNCTION:
    1592              :     // This function returns the index into the Controlled Zone Equipment structure
    1593              :     // of the indicated zone.
    1594              : 
    1595            7 :     return Util::FindItemInList(ZoneName, state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::ZoneName);
    1596              : }
    1597              : 
    1598            4 : int FindControlledZoneIndexFromSystemNodeNumberForZone(EnergyPlusData &state,
    1599              :                                                        int const TrialZoneNodeNum) // Node number to match into Controlled Zone structure
    1600              : {
    1601              : 
    1602              :     // FUNCTION INFORMATION:
    1603              :     //       AUTHOR         Brent Griffith
    1604              :     //       DATE WRITTEN   August 2013
    1605              : 
    1606              :     // PURPOSE OF THIS FUNCTION:
    1607              :     // This function returns the zone number for the indicated
    1608              :     // zone node num.  Returns 0 if did not find zone node in any Zone
    1609              : 
    1610            4 :     int ControlledZoneIndex = 0; // Index into Controlled Zone structure
    1611              : 
    1612           19 :     for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    1613           16 :         if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).IsControlled) {
    1614           16 :             if (TrialZoneNodeNum == state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ZoneNode) {
    1615              :                 // found it.
    1616            1 :                 ControlledZoneIndex = ZoneNum;
    1617            1 :                 break;
    1618              :             }
    1619              :         }
    1620              :     }
    1621              : 
    1622            4 :     return ControlledZoneIndex;
    1623              : }
    1624              : 
    1625          233 : int GetSystemNodeNumberForZone(EnergyPlusData &state, int const zoneNum)
    1626              : {
    1627              : 
    1628              :     // FUNCTION INFORMATION:
    1629              :     //       AUTHOR         Linda Lawrie
    1630              :     //       DATE WRITTEN   March 2008
    1631              : 
    1632              :     // PURPOSE OF THIS FUNCTION:
    1633              :     // This function returns the system node number for the indicated
    1634              :     // zone.  Returns 0 if the Zone is not a controlled zone.
    1635              : 
    1636          233 :     int SystemZoneNodeNumber = 0; // System node number for controlled zone
    1637              : 
    1638          233 :     if (zoneNum > 0) {
    1639          233 :         if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) {
    1640          233 :             SystemZoneNodeNumber = state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneNode;
    1641              :         }
    1642              :     }
    1643              : 
    1644          233 :     return SystemZoneNodeNumber;
    1645              : }
    1646              : 
    1647          122 : int GetReturnAirNodeForZone(EnergyPlusData &state,
    1648              :                             int const zoneNum,
    1649              :                             std::string const &NodeName,             // Return air node name to match (may be blank)
    1650              :                             std::string const &calledFromDescription // String identifying the calling function and object
    1651              : )
    1652              : {
    1653              : 
    1654              :     // FUNCTION INFORMATION:
    1655              :     //       AUTHOR         Linda Lawrie
    1656              :     //       DATE WRITTEN   March 2008
    1657              :     //       MODIFIED       Feb 2017 expanded for multiple return nodes in a zone
    1658              : 
    1659              :     // PURPOSE OF THIS FUNCTION:
    1660              :     // This function returns the return air node number for the indicated
    1661              :     // zone and node name.  If NodeName is blank, return the first return node number,
    1662              :     // otherwise return the node number of the matching return node name.
    1663              :     // Returns 0 if the Zone is not a controlled zone or the node name does not match.
    1664              : 
    1665              :     // Return value
    1666          122 :     int ReturnAirNodeNumber = 0; // Return Air node number for controlled zone
    1667              : 
    1668          122 :     ReturnAirNodeNumber = 0; // default is not found
    1669          122 :     if (zoneNum > 0) {
    1670              :         {
    1671          122 :             auto const &thisZoneEquip(state.dataZoneEquip->ZoneEquipConfig(zoneNum));
    1672          122 :             if (thisZoneEquip.IsControlled) {
    1673          122 :                 if (NodeName.empty()) {
    1674              :                     // If NodeName is blank, return first return node number, but warn if there are multiple return nodes for this zone
    1675          122 :                     ReturnAirNodeNumber = thisZoneEquip.ReturnNode(1);
    1676          122 :                     if (thisZoneEquip.NumReturnNodes > 1) {
    1677            0 :                         ShowWarningError(state,
    1678            0 :                                          format("GetReturnAirNodeForZone: {}, request for zone return node is ambiguous.", calledFromDescription));
    1679            0 :                         ShowContinueError(state,
    1680            0 :                                           format("Zone={} has {} return nodes. First return node will be used.",
    1681            0 :                                                  thisZoneEquip.ZoneName,
    1682            0 :                                                  thisZoneEquip.NumReturnNodes));
    1683              :                     }
    1684              :                 } else {
    1685            0 :                     for (int nodeCount = 1; nodeCount <= thisZoneEquip.NumReturnNodes; ++nodeCount) {
    1686            0 :                         int curNodeNum = thisZoneEquip.ReturnNode(nodeCount);
    1687            0 :                         if (NodeName == state.dataLoopNodes->NodeID(curNodeNum)) {
    1688            0 :                             ReturnAirNodeNumber = curNodeNum;
    1689              :                         }
    1690              :                     }
    1691              :                 }
    1692              :             }
    1693              :         }
    1694              :     }
    1695              : 
    1696          122 :     return ReturnAirNodeNumber;
    1697              : }
    1698              : 
    1699         4471 : int GetReturnNumForZone(EnergyPlusData &state,
    1700              :                         int const zoneNum,
    1701              :                         std::string const &NodeName // Return air node name to match (may be blank)
    1702              : )
    1703              : {
    1704              : 
    1705              :     // PURPOSE OF THIS FUNCTION:
    1706              :     // This function returns the zone return number (not the node number) for the indicated
    1707              :     // zone and node name.  If NodeName is blank, return 1 (the first return node)
    1708              :     // otherwise return the index of the matching return node name.
    1709              :     // Returns 0 if the Zone is not a controlled zone or the node name does not match.
    1710              : 
    1711              :     // Return value
    1712         4471 :     int ReturnIndex = 0; // Return number for the given zone (not the node number)
    1713              : 
    1714         4471 :     if (zoneNum > 0) {
    1715         4471 :         if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).IsControlled) {
    1716         4337 :             if (NodeName.empty()) {
    1717              :                 // If NodeName is blank, return first return node number
    1718         4336 :                 ReturnIndex = 1;
    1719              :             } else {
    1720            2 :                 for (int nodeCount = 1; nodeCount <= state.dataZoneEquip->ZoneEquipConfig(zoneNum).NumReturnNodes; ++nodeCount) {
    1721            1 :                     int curNodeNum = state.dataZoneEquip->ZoneEquipConfig(zoneNum).ReturnNode(nodeCount);
    1722            1 :                     if (NodeName == state.dataLoopNodes->NodeID(curNodeNum)) {
    1723            1 :                         ReturnIndex = nodeCount;
    1724              :                     }
    1725              :                 }
    1726              :             }
    1727              :         }
    1728              :     }
    1729              : 
    1730         4471 :     return ReturnIndex;
    1731              : }
    1732              : 
    1733            1 : bool VerifyLightsExhaustNodeForZone(EnergyPlusData &state, int const ZoneNum, int const ZoneExhaustNodeNum)
    1734              : {
    1735            1 :     bool exhaustNodeError = true;
    1736              : 
    1737            1 :     for (int ExhaustNum = 1; ExhaustNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumExhaustNodes; ++ExhaustNum) {
    1738            1 :         if (ZoneExhaustNodeNum == state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ExhaustNode(ExhaustNum)) {
    1739            1 :             exhaustNodeError = false;
    1740            1 :             break;
    1741              :         }
    1742              :     }
    1743              : 
    1744            1 :     return exhaustNodeError;
    1745              : }
    1746              : 
    1747          485 : void EquipList::getPrioritiesForInletNode(EnergyPlusData &state,
    1748              :                                           int const inletNodeNum, // Zone inlet node number to match
    1749              :                                           int &coolingPriority,   // Cooling priority num for matching equipment
    1750              :                                           int &heatingPriority    // Heating priority num for matching equipment
    1751              : )
    1752              : {
    1753          485 :     bool equipFound = false;
    1754          601 :     for (int equipNum = 1; equipNum <= this->NumOfEquipTypes; ++equipNum) {
    1755          601 :         if (this->EquipType(equipNum) == DataZoneEquipment::ZoneEquipType::AirDistributionUnit) {
    1756          490 :             if (inletNodeNum == state.dataDefineEquipment->AirDistUnit(this->EquipIndex(equipNum)).OutletNodeNum) {
    1757          485 :                 equipFound = true;
    1758              :             }
    1759              :         }
    1760          601 :         if (equipFound) {
    1761          485 :             coolingPriority = this->CoolingPriority(equipNum);
    1762          485 :             heatingPriority = this->HeatingPriority(equipNum);
    1763          485 :             break;
    1764              :         }
    1765              :     }
    1766              :     // Set MinAirLoopIterationsAfterFirst for equipment that uses sequenced loads, based on zone equip load distribution scheme
    1767          485 :     int minIterations = state.dataHVACGlobal->MinAirLoopIterationsAfterFirst;
    1768          485 :     if (this->LoadDistScheme == DataZoneEquipment::LoadDist::Sequential) {
    1769              :         // Sequential needs one extra iterations up to the highest airterminal unit equipment number
    1770          479 :         minIterations = max(coolingPriority, heatingPriority, minIterations);
    1771            6 :     } else if (this->LoadDistScheme == DataZoneEquipment::LoadDist::Uniform) {
    1772              :         // Uniform needs one extra iteration which is the default
    1773            4 :     } else if (this->LoadDistScheme == DataZoneEquipment::LoadDist::UniformPLR) {
    1774              :         // UniformPLR needs two extra iterations, regardless of unit equipment number
    1775            2 :         minIterations = max(2, minIterations);
    1776            2 :     } else if (this->LoadDistScheme == DataZoneEquipment::LoadDist::SequentialUniformPLR) {
    1777              :         // SequentialUniformPLR needs one extra iterations up to the highest airterminal unit equipment number plus one more
    1778            2 :         minIterations = max((coolingPriority + 1), (heatingPriority + 1), minIterations);
    1779              :     }
    1780          485 :     state.dataHVACGlobal->MinAirLoopIterationsAfterFirst = minIterations;
    1781          485 : }
    1782              : 
    1783     91645495 : Real64 EquipList::SequentialHeatingFraction([[maybe_unused]] EnergyPlusData &state, const int equipNum)
    1784              : {
    1785     91645495 :     return sequentialHeatingFractionScheds(equipNum)->getCurrentVal();
    1786              : }
    1787              : 
    1788     91144417 : Real64 EquipList::SequentialCoolingFraction([[maybe_unused]] EnergyPlusData &state, const int equipNum)
    1789              : {
    1790     91144417 :     return sequentialCoolingFractionScheds(equipNum)->getCurrentVal();
    1791              : }
    1792              : 
    1793          217 : int GetZoneEquipControlledZoneNum(EnergyPlusData &state, DataZoneEquipment::ZoneEquipType const zoneEquipType, std::string const &EquipmentName)
    1794              : {
    1795              :     static constexpr std::string_view RoutineName("GetZoneEquipControlledZoneNum: ");
    1796          217 :     int ControlZoneNum = 0;
    1797              : 
    1798         1046 :     for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
    1799         1046 :         if (!state.dataZoneEquip->ZoneEquipConfig(CtrlZone).IsControlled) {
    1800           89 :             continue;
    1801              :         }
    1802         2397 :         for (int Num = 1; Num <= state.dataZoneEquip->ZoneEquipList(CtrlZone).NumOfEquipTypes; ++Num) {
    1803         2380 :             if (zoneEquipType == state.dataZoneEquip->ZoneEquipList(CtrlZone).EquipType(Num) &&
    1804          723 :                 Util::SameString(EquipmentName, state.dataZoneEquip->ZoneEquipList(CtrlZone).EquipName(Num))) {
    1805          217 :                 return ControlZoneNum = CtrlZone;
    1806              :             }
    1807              :         }
    1808              :     }
    1809            0 :     ShowSevereError(state,
    1810            0 :                     fmt::format("{}{}=\"{}\" is not on any ZoneHVAC:Equipmentlist. It will not be simulated.",
    1811              :                                 RoutineName,
    1812            0 :                                 zoneEquipTypeNamesUC[(int)zoneEquipType],
    1813              :                                 EquipmentName));
    1814            0 :     return ControlZoneNum;
    1815              : }
    1816              : 
    1817            1 : void CheckSharedExhaust(EnergyPlusData &state)
    1818              : {
    1819            1 :     int ExhastNodeNum = 0;
    1820            7 :     for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    1821            6 :         if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes < 2) {
    1822            6 :             continue;
    1823              :         }
    1824            0 :         for (int nodeCount = 1; nodeCount <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes; ++nodeCount) {
    1825            0 :             if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount) == LightReturnExhaustConfig::Shared) {
    1826            0 :                 continue;
    1827              :             }
    1828            0 :             ExhastNodeNum = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNodeExhaustNodeNum(nodeCount);
    1829            0 :             if (ExhastNodeNum > 0) {
    1830            0 :                 state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount) = LightReturnExhaustConfig::Single;
    1831            0 :                 for (int nodeCount1 = nodeCount + 1; nodeCount1 <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes; ++nodeCount1) {
    1832            0 :                     if (ExhastNodeNum == state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNodeExhaustNodeNum(nodeCount1)) {
    1833            0 :                         state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount) = LightReturnExhaustConfig::Multi;
    1834            0 :                         state.dataZoneEquip->ZoneEquipConfig(ZoneNum).SharedExhaustNode(nodeCount1) = LightReturnExhaustConfig::Shared;
    1835              :                     }
    1836              :                 }
    1837              :             }
    1838              :         }
    1839              :     }
    1840            1 : }
    1841              : 
    1842     54137511 : void EquipConfiguration::setTotalInletFlows(EnergyPlusData &state)
    1843              : {
    1844     54137511 :     this->TotInletAirMassFlowRate = 0.0;
    1845     54137511 :     Real64 TotInletAirMassFlowRateMax = 0.0;
    1846     54137511 :     Real64 TotInletAirMassFlowRateMaxAvail = 0.0;
    1847     54137511 :     Real64 TotInletAirMassFlowRateMin = 0.0;
    1848     54137511 :     Real64 TotInletAirMassFlowRateMinAvail = 0.0;
    1849    111669417 :     for (int NodeNum = 1; NodeNum <= this->NumInletNodes; ++NodeNum) {
    1850              :         {
    1851     57531906 :             auto const &thisNode(state.dataLoopNodes->Node(this->InletNode(NodeNum)));
    1852     57531906 :             this->TotInletAirMassFlowRate += thisNode.MassFlowRate;
    1853     57531906 :             TotInletAirMassFlowRateMax += thisNode.MassFlowRateMax;
    1854     57531906 :             TotInletAirMassFlowRateMaxAvail += thisNode.MassFlowRateMaxAvail;
    1855     57531906 :             TotInletAirMassFlowRateMin += thisNode.MassFlowRateMin;
    1856     57531906 :             TotInletAirMassFlowRateMinAvail += thisNode.MassFlowRateMinAvail;
    1857              :         }
    1858              :     }
    1859     54137511 :     auto &zoneSpaceNode = state.dataLoopNodes->Node(this->ZoneNode);
    1860     54137511 :     zoneSpaceNode.MassFlowRate = this->TotInletAirMassFlowRate;
    1861     54137511 :     zoneSpaceNode.MassFlowRateMax = TotInletAirMassFlowRateMax;
    1862     54137511 :     zoneSpaceNode.MassFlowRateMaxAvail = TotInletAirMassFlowRateMaxAvail;
    1863     54137511 :     zoneSpaceNode.MassFlowRateMin = TotInletAirMassFlowRateMin;
    1864     54137511 :     zoneSpaceNode.MassFlowRateMinAvail = TotInletAirMassFlowRateMinAvail;
    1865     54137511 : }
    1866              : 
    1867        83763 : void scaleInletFlows(EnergyPlusData &state, int const zoneNodeNum, int const spaceNodeNum, Real64 const frac)
    1868              : {
    1869        83763 :     assert(zoneNodeNum > 0);
    1870        83763 :     assert(spaceNodeNum > 0);
    1871        83763 :     auto const &zoneNode = state.dataLoopNodes->Node(zoneNodeNum);
    1872        83763 :     auto &spaceNode = state.dataLoopNodes->Node(spaceNodeNum);
    1873        83763 :     spaceNode.MassFlowRate = zoneNode.MassFlowRate * frac;
    1874        83763 :     spaceNode.MassFlowRateMax = zoneNode.MassFlowRateMax * frac;
    1875        83763 :     spaceNode.MassFlowRateMaxAvail = zoneNode.MassFlowRateMaxAvail * frac;
    1876        83763 :     spaceNode.MassFlowRateMin = zoneNode.MassFlowRateMin * frac;
    1877        83763 :     spaceNode.MassFlowRateMinAvail = zoneNode.MassFlowRateMinAvail * frac;
    1878        83763 : }
    1879              : 
    1880            2 : void ZoneEquipmentSplitterMixer::size(EnergyPlusData &state)
    1881              : {
    1882              :     bool anyAutoSize =
    1883            4 :         std::any_of(spaces.begin(), spaces.end(), [](ZoneEquipSplitterMixerSpace const &s) { return s.fraction == DataSizing::AutoSize; });
    1884            2 :     if (!anyAutoSize) {
    1885            0 :         return;
    1886              :     }
    1887              : 
    1888            2 :     if (!state.dataHeatBal->doSpaceHeatBalanceSizing && (this->spaceSizingBasis == DataZoneEquipment::SpaceEquipSizingBasis::DesignCoolingLoad ||
    1889            0 :                                                          (this->spaceSizingBasis == DataZoneEquipment::SpaceEquipSizingBasis::DesignHeatingLoad))) {
    1890            0 :         ShowSevereError(state,
    1891            0 :                         format("ZoneEquipmentSplitterMixer::size: {} is unknown for {}={}. Unable to autosize Space Fractions.",
    1892            0 :                                DataZoneEquipment::spaceEquipSizingBasisNamesUC[(int)this->spaceSizingBasis],
    1893            0 :                                BranchNodeConnections::ConnectionObjectTypeNames[(int)this->spaceEquipType],
    1894            0 :                                this->Name));
    1895            0 :         ShowFatalError(state,
    1896              :                        "Set \"Do Space Heat Balance for Sizing\" to Yes in ZoneAirHeatBalanceAlgorithm or choose a different Space Fraction Method.");
    1897            0 :         return;
    1898              :     }
    1899              : 
    1900              :     // Calculate total of space fraction basis value across all spaces for this splitter or mixer
    1901              :     // including spaces which are not autosized here.
    1902            2 :     Real64 spacesTotal = 0.0;
    1903            2 :     switch (this->spaceSizingBasis) {
    1904            2 :     case DataZoneEquipment::SpaceEquipSizingBasis::DesignCoolingLoad:
    1905            6 :         for (auto &thisSpace : this->spaces) {
    1906            4 :             spacesTotal += state.dataSize->FinalSpaceSizing(thisSpace.spaceIndex).DesCoolLoad;
    1907            2 :         }
    1908            2 :         break;
    1909            0 :     case DataZoneEquipment::SpaceEquipSizingBasis::DesignHeatingLoad:
    1910            0 :         for (auto &thisSpace : this->spaces) {
    1911            0 :             spacesTotal += state.dataSize->FinalSpaceSizing(thisSpace.spaceIndex).DesHeatLoad;
    1912            0 :         }
    1913            0 :         break;
    1914            0 :     case DataZoneEquipment::SpaceEquipSizingBasis::FloorArea:
    1915            0 :         for (auto &thisSpace : this->spaces) {
    1916            0 :             spacesTotal += state.dataHeatBal->space(thisSpace.spaceIndex).FloorArea;
    1917            0 :         }
    1918            0 :         break;
    1919            0 :     case DataZoneEquipment::SpaceEquipSizingBasis::Volume:
    1920            0 :         for (auto &thisSpace : this->spaces) {
    1921            0 :             spacesTotal += state.dataHeatBal->space(thisSpace.spaceIndex).Volume;
    1922            0 :         }
    1923            0 :         break;
    1924            0 :     case DataZoneEquipment::SpaceEquipSizingBasis::PerimeterLength:
    1925            0 :         for (auto &thisSpace : this->spaces) {
    1926            0 :             spacesTotal += state.dataHeatBal->space(thisSpace.spaceIndex).extPerimeter;
    1927            0 :         }
    1928            0 :         break;
    1929            0 :     default:
    1930              :         // If method is not set, then return
    1931            0 :         return;
    1932              :         break;
    1933              :     }
    1934              : 
    1935            2 :     if (spacesTotal < 0.00001) {
    1936            0 :         ShowSevereError(state,
    1937            0 :                         format("ZoneEquipmentSplitterMixer::size: Total {} is zero for {}={}. Unable to autosize Space Fractions.",
    1938            0 :                                DataZoneEquipment::spaceEquipSizingBasisNamesUC[(int)this->spaceSizingBasis],
    1939            0 :                                BranchNodeConnections::ConnectionObjectTypeNames[(int)this->spaceEquipType],
    1940            0 :                                this->Name));
    1941            0 :         Real64 spaceFrac = 1.0 / (int)this->spaces.size();
    1942            0 :         ShowContinueError(state, format("Setting space fractions to 1/number of spaces = {}.", spaceFrac));
    1943            0 :         for (auto &thisSpace : this->spaces) {
    1944            0 :             thisSpace.fraction = spaceFrac;
    1945            0 :         }
    1946              :     } else {
    1947              :         // Calculate space fractions
    1948            6 :         for (auto &thisSpace : this->spaces) {
    1949            4 :             if (thisSpace.fraction == DataSizing::AutoSize) {
    1950            4 :                 switch (this->spaceSizingBasis) {
    1951            4 :                 case DataZoneEquipment::SpaceEquipSizingBasis::DesignCoolingLoad:
    1952            4 :                     thisSpace.fraction = state.dataSize->FinalSpaceSizing(thisSpace.spaceIndex).DesCoolLoad / spacesTotal;
    1953            4 :                     break;
    1954            0 :                 case DataZoneEquipment::SpaceEquipSizingBasis::DesignHeatingLoad:
    1955            0 :                     thisSpace.fraction = state.dataSize->FinalSpaceSizing(thisSpace.spaceIndex).DesHeatLoad / spacesTotal;
    1956            0 :                     break;
    1957            0 :                 case DataZoneEquipment::SpaceEquipSizingBasis::FloorArea:
    1958            0 :                     thisSpace.fraction = state.dataHeatBal->space(thisSpace.spaceIndex).FloorArea / spacesTotal;
    1959            0 :                     break;
    1960            0 :                 case DataZoneEquipment::SpaceEquipSizingBasis::Volume:
    1961            0 :                     thisSpace.fraction = state.dataHeatBal->space(thisSpace.spaceIndex).Volume / spacesTotal;
    1962            0 :                     break;
    1963            0 :                 case DataZoneEquipment::SpaceEquipSizingBasis::PerimeterLength:
    1964            0 :                     thisSpace.fraction = state.dataHeatBal->space(thisSpace.spaceIndex).extPerimeter / spacesTotal;
    1965            0 :                     break;
    1966            0 :                 default:
    1967            0 :                     break;
    1968              :                 }
    1969              :             }
    1970            2 :         }
    1971              :     }
    1972              :     // Report sizing results
    1973            2 :     int spaceCounter = 0;
    1974            6 :     for (auto &thisSpace : this->spaces) {
    1975            4 :         ++spaceCounter;
    1976           16 :         BaseSizer::reportSizerOutput(state,
    1977            4 :                                      BranchNodeConnections::ConnectionObjectTypeNames[(int)this->spaceEquipType],
    1978              :                                      this->Name,
    1979            8 :                                      format("Space {} Fraction", spaceCounter),
    1980              :                                      thisSpace.fraction);
    1981            2 :     }
    1982              : }
    1983              : 
    1984         8928 : void ZoneMixer::setOutletConditions(EnergyPlusData &state)
    1985              : {
    1986         8928 :     if (this->outletNodeNum == 0) {
    1987            0 :         return;
    1988              :     }
    1989              : 
    1990         8928 :     Real64 sumEnthalpy = 0.0;
    1991         8928 :     Real64 sumHumRat = 0.0;
    1992         8928 :     Real64 sumCO2 = 0.0;
    1993         8928 :     Real64 sumGenContam = 0.0;
    1994         8928 :     Real64 sumPressure = 0.0;
    1995         8928 :     Real64 sumFractions = 0.0;
    1996         8928 :     auto &outletNode = state.dataLoopNodes->Node(this->outletNodeNum);
    1997        26784 :     for (auto &mixerSpace : this->spaces) {
    1998        17856 :         auto const &spaceOutletNode = state.dataLoopNodes->Node(mixerSpace.spaceNodeNum);
    1999        17856 :         sumEnthalpy += spaceOutletNode.Enthalpy * mixerSpace.fraction;
    2000        17856 :         sumHumRat += spaceOutletNode.HumRat * mixerSpace.fraction;
    2001        17856 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2002            0 :             sumCO2 += spaceOutletNode.CO2 * mixerSpace.fraction;
    2003              :         }
    2004        17856 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2005            0 :             sumGenContam += spaceOutletNode.GenContam * mixerSpace.fraction;
    2006              :         }
    2007        17856 :         sumPressure += spaceOutletNode.Press * mixerSpace.fraction;
    2008        17856 :         sumFractions += mixerSpace.fraction;
    2009         8928 :     }
    2010              : 
    2011              :     // For SpaceHVAC:ZoneReturnMixer, the fractions are dynamic and could be zero if there is no flow
    2012         8928 :     if (sumFractions > 0) {
    2013         8917 :         outletNode.Enthalpy = sumEnthalpy / sumFractions;
    2014         8917 :         outletNode.HumRat = sumHumRat / sumFractions;
    2015         8917 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2016            0 :             outletNode.CO2 = sumCO2 / sumFractions;
    2017              :         }
    2018         8917 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2019            0 :             outletNode.GenContam = sumGenContam / sumFractions;
    2020              :         }
    2021         8917 :         outletNode.Press = sumPressure / sumFractions;
    2022              : 
    2023              :         // Use Enthalpy and humidity ratio to get outlet temperature from psych chart
    2024         8917 :         outletNode.Temp = Psychrometrics::PsyTdbFnHW(outletNode.Enthalpy, outletNode.HumRat);
    2025              :     }
    2026              : }
    2027              : 
    2028         4464 : void ZoneReturnMixer::setInletConditions(EnergyPlusData &state)
    2029              : {
    2030        17856 :     for (auto &mixerSpace : this->spaces) {
    2031        13392 :         auto &spaceOutletNode = state.dataLoopNodes->Node(mixerSpace.spaceNodeNum);
    2032        13392 :         int spaceZoneNodeNum = state.dataZoneEquip->spaceEquipConfig(mixerSpace.spaceIndex).ZoneNode;
    2033        13392 :         auto const &spaceNode = state.dataLoopNodes->Node(spaceZoneNodeNum);
    2034        13392 :         spaceOutletNode.Temp = spaceNode.Temp;
    2035        13392 :         spaceOutletNode.HumRat = spaceNode.HumRat;
    2036        13392 :         spaceOutletNode.Enthalpy = spaceNode.Enthalpy;
    2037        13392 :         spaceOutletNode.Press = spaceNode.Press;
    2038        13392 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2039            0 :             spaceOutletNode.CO2 = spaceNode.CO2;
    2040              :         }
    2041        13392 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2042            0 :             spaceOutletNode.GenContam = spaceNode.GenContam;
    2043              :         }
    2044         4464 :     }
    2045         4464 : }
    2046         4464 : void ZoneEquipmentMixer::setInletFlows(EnergyPlusData &state)
    2047              : {
    2048         4464 :     if (this->outletNodeNum == 0) {
    2049            0 :         return;
    2050              :     }
    2051              : 
    2052         4464 :     auto &equipInletNode = state.dataLoopNodes->Node(this->outletNodeNum);
    2053         8928 :     for (auto &mixerSpace : this->spaces) {
    2054         4464 :         auto &spaceOutletNode = state.dataLoopNodes->Node(mixerSpace.spaceNodeNum);
    2055         4464 :         spaceOutletNode.MassFlowRate = equipInletNode.MassFlowRate * mixerSpace.fraction;
    2056         4464 :         spaceOutletNode.MassFlowRateMaxAvail = equipInletNode.MassFlowRateMaxAvail * mixerSpace.fraction;
    2057         4464 :         spaceOutletNode.MassFlowRateMinAvail = equipInletNode.MassFlowRateMinAvail * mixerSpace.fraction;
    2058         4464 :     }
    2059              : }
    2060              : 
    2061         4464 : void ZoneReturnMixer::setInletFlows(EnergyPlusData &state)
    2062              : {
    2063         4464 :     if (this->outletNodeNum == 0) {
    2064            0 :         return;
    2065              :     }
    2066         4464 :     auto &outletNode = state.dataLoopNodes->Node(this->outletNodeNum);
    2067              : 
    2068         4464 :     Real64 sumMixerInletMassFlow = 0;
    2069        17856 :     for (auto const &mixerSpace : this->spaces) {
    2070              :         // calc return flows for spaces feeding this mixer
    2071        13392 :         auto &spaceEquipConfig = state.dataZoneEquip->spaceEquipConfig(mixerSpace.spaceIndex);
    2072        13392 :         Real64 outletMassFlowRate = outletNode.MassFlowRate; // calcReturnFlows might adjust this parameter value, so make a copy here
    2073        13392 :         Real64 spaceReturnFlow = 0.0;
    2074        13392 :         spaceEquipConfig.calcReturnFlows(state, outletMassFlowRate, spaceReturnFlow);
    2075        13392 :         sumMixerInletMassFlow += spaceReturnFlow;
    2076         4464 :     }
    2077              : 
    2078        17856 :     for (auto &mixerSpace : this->spaces) {
    2079        13392 :         auto &spaceOutletNode = state.dataLoopNodes->Node(mixerSpace.spaceNodeNum);
    2080              :         // For return mixer, fraction is calculated every time step, not a user input
    2081        13392 :         if (sumMixerInletMassFlow > 0.0) {
    2082        13359 :             mixerSpace.fraction = spaceOutletNode.MassFlowRate / sumMixerInletMassFlow;
    2083              :         } else {
    2084           33 :             mixerSpace.fraction = 0.0;
    2085              :         }
    2086        13392 :         spaceOutletNode.MassFlowRate = outletNode.MassFlowRate * mixerSpace.fraction;
    2087        13392 :         spaceOutletNode.MassFlowRateMaxAvail = outletNode.MassFlowRateMaxAvail * mixerSpace.fraction;
    2088        13392 :         spaceOutletNode.MassFlowRateMinAvail = outletNode.MassFlowRateMinAvail * mixerSpace.fraction;
    2089         4464 :     }
    2090              : }
    2091              : 
    2092         8928 : void ZoneEquipmentSplitter::adjustLoads(EnergyPlusData &state, int zoneNum, int equipTypeNum)
    2093              : {
    2094         8928 :     auto &thisZoneEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum);
    2095         8928 :     auto &thisZoneMoistureDemand = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(zoneNum);
    2096              : 
    2097         8928 :     auto &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(zoneNum);
    2098              : 
    2099         8928 :     Real64 sensibleRatio = 1.0;
    2100         8928 :     Real64 latentRatio = 1.0;
    2101         8928 :     switch (this->tstatControl) {
    2102            0 :     case DataZoneEquipment::ZoneEquipTstatControl::Ideal: {
    2103            0 :         return;
    2104              :     } break; // Do nothing
    2105              : 
    2106         8928 :     case DataZoneEquipment::ZoneEquipTstatControl::SingleSpace: {
    2107         8928 :         Real64 controlSpaceFrac = this->spaces[this->controlSpaceNumber].fraction;
    2108         8928 :         if (controlSpaceFrac > 0.0) {
    2109         8928 :             if (thisZoneEnergyDemand.RemainingOutputRequired != 0.0) {
    2110         8900 :                 sensibleRatio = (state.dataZoneEnergyDemand->spaceSysEnergyDemand(this->controlSpaceIndex).RemainingOutputRequired /
    2111         8900 :                                  thisZoneEnergyDemand.RemainingOutputRequired) /
    2112              :                                 controlSpaceFrac;
    2113              :             }
    2114         8928 :             if (thisZoneMoistureDemand.RemainingOutputRequired != 0.0) {
    2115            0 :                 latentRatio = (state.dataZoneEnergyDemand->spaceSysMoistureDemand(this->controlSpaceIndex).RemainingOutputRequired /
    2116            0 :                                thisZoneMoistureDemand.RemainingOutputRequired) /
    2117              :                               controlSpaceFrac;
    2118              :             }
    2119              :         }
    2120         8928 :     } break;
    2121              : 
    2122            0 :     case DataZoneEquipment::ZoneEquipTstatControl::Maximum: {
    2123            0 :         int maxSpaceIndex = 0;
    2124            0 :         Real64 maxDeltaTemp = 0.0; // Only positive deltaTemps are relevant
    2125            0 :         Real64 maxSpaceFrac = 1.0;
    2126            0 :         for (auto &splitterSpace : this->spaces) {
    2127              :             Real64 spaceTemp =
    2128            0 :                 state.dataZoneTempPredictorCorrector->spaceHeatBalance(splitterSpace.spaceIndex).T1; // Based on calcPredictedSystemLoad usage
    2129            0 :             Real64 spaceDeltaTemp = max((zoneTstatSetpt.setptLo - spaceTemp), (spaceTemp - zoneTstatSetpt.setptHi));
    2130            0 :             if (spaceDeltaTemp > maxDeltaTemp) {
    2131            0 :                 maxSpaceIndex = splitterSpace.spaceIndex;
    2132            0 :                 maxSpaceFrac = splitterSpace.fraction;
    2133            0 :                 maxDeltaTemp = spaceDeltaTemp;
    2134              :             }
    2135            0 :         }
    2136            0 :         if ((maxSpaceIndex > 0) && (maxSpaceFrac > 0.0)) {
    2137            0 :             if (thisZoneEnergyDemand.RemainingOutputRequired != 0.0) {
    2138            0 :                 sensibleRatio = (state.dataZoneEnergyDemand->spaceSysEnergyDemand(maxSpaceIndex).RemainingOutputRequired /
    2139            0 :                                  thisZoneEnergyDemand.RemainingOutputRequired) /
    2140              :                                 maxSpaceFrac;
    2141              :             }
    2142            0 :             if (thisZoneMoistureDemand.RemainingOutputRequired != 0.0) {
    2143            0 :                 latentRatio = (state.dataZoneEnergyDemand->spaceSysMoistureDemand(maxSpaceIndex).RemainingOutputRequired /
    2144            0 :                                thisZoneMoistureDemand.RemainingOutputRequired) /
    2145              :                               maxSpaceFrac;
    2146              :             }
    2147              :         }
    2148            0 :     } break;
    2149            0 :     default:
    2150            0 :         break;
    2151              :     }
    2152              :     // Save unadjusted zone loads to restore later
    2153         8928 :     this->saveZoneSysSensibleDemand = thisZoneEnergyDemand;
    2154         8928 :     this->saveZoneSysMoistureDemand = thisZoneMoistureDemand;
    2155              :     // Apply zone load adjustment
    2156        17856 :     ZoneEquipmentManager::adjustSystemOutputRequired(sensibleRatio,
    2157              :                                                      latentRatio,
    2158         8928 :                                                      state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum),
    2159         8928 :                                                      state.dataZoneEnergyDemand->ZoneSysMoistureDemand(zoneNum),
    2160              :                                                      equipTypeNum);
    2161              : }
    2162              : 
    2163         8928 : void ZoneEquipmentSplitter::distributeOutput(EnergyPlusData &state,
    2164              :                                              int const zoneNum,
    2165              :                                              Real64 const sysOutputProvided,
    2166              :                                              Real64 const latOutputProvided,
    2167              :                                              Real64 const nonAirSysOutput,
    2168              :                                              int const equipTypeNum)
    2169              : {
    2170        35712 :     for (auto &splitterSpace : this->spaces) {
    2171        26784 :         if (this->tstatControl != DataZoneEquipment::ZoneEquipTstatControl::Ideal) {
    2172              :             // Restore zone loads to unadjusted values (for all ZoneEquipTstatControl types except Ideal)
    2173        26784 :             state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum) = this->saveZoneSysSensibleDemand;
    2174        26784 :             state.dataZoneEnergyDemand->ZoneSysMoistureDemand(zoneNum) = this->saveZoneSysMoistureDemand;
    2175              :         }
    2176              : 
    2177        26784 :         Real64 spaceFraction = splitterSpace.fraction;
    2178        26784 :         if (this->tstatControl == DataZoneEquipment::ZoneEquipTstatControl::Ideal) {
    2179              :             // Proportion output by sensible space load / zone load (varies every timestep, overrides outputFraction)
    2180            0 :             auto const &thisZoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum);
    2181            0 :             if (thisZoneSysEnergyDemand.RemainingOutputRequired != 0.0) {
    2182            0 :                 spaceFraction = state.dataZoneEnergyDemand->spaceSysEnergyDemand(splitterSpace.spaceIndex).RemainingOutputRequired /
    2183            0 :                                 thisZoneSysEnergyDemand.RemainingOutputRequired;
    2184              :             }
    2185              :         }
    2186              : 
    2187        26784 :         Real64 spaceSysOutputProvided = sysOutputProvided * spaceFraction;
    2188        26784 :         Real64 spaceLatOutputProvided = latOutputProvided * spaceFraction;
    2189        26784 :         state.dataZoneTempPredictorCorrector->spaceHeatBalance(splitterSpace.spaceIndex).NonAirSystemResponse += nonAirSysOutput * spaceFraction;
    2190        26784 :         if (this->zoneEquipOutletNodeNum > 0 && splitterSpace.spaceNodeNum > 0) {
    2191        26784 :             auto const &equipOutletNode = state.dataLoopNodes->Node(this->zoneEquipOutletNodeNum);
    2192        26784 :             auto &spaceInletNode = state.dataLoopNodes->Node(splitterSpace.spaceNodeNum);
    2193        26784 :             spaceInletNode.MassFlowRate = equipOutletNode.MassFlowRate * spaceFraction;
    2194        26784 :             spaceInletNode.MassFlowRateMaxAvail = equipOutletNode.MassFlowRateMaxAvail * spaceFraction;
    2195        26784 :             spaceInletNode.MassFlowRateMinAvail = equipOutletNode.MassFlowRateMinAvail * spaceFraction;
    2196        26784 :             spaceInletNode.Temp = equipOutletNode.Temp;
    2197        26784 :             spaceInletNode.HumRat = equipOutletNode.HumRat;
    2198        26784 :             spaceInletNode.CO2 = equipOutletNode.CO2;
    2199              :         }
    2200        26784 :         ZoneEquipmentManager::updateSystemOutputRequired(state,
    2201              :                                                          zoneNum,
    2202              :                                                          spaceSysOutputProvided,
    2203              :                                                          spaceLatOutputProvided,
    2204        26784 :                                                          state.dataZoneEnergyDemand->spaceSysEnergyDemand(splitterSpace.spaceIndex),
    2205        26784 :                                                          state.dataZoneEnergyDemand->spaceSysMoistureDemand(splitterSpace.spaceIndex),
    2206              :                                                          equipTypeNum);
    2207         8928 :     }
    2208         8928 : }
    2209              : 
    2210        44056 : void EquipConfiguration::beginEnvirnInit(EnergyPlusData &state)
    2211              : {
    2212        44056 :     auto &zoneNode = state.dataLoopNodes->Node(this->ZoneNode);
    2213        44056 :     zoneNode.Temp = 20.0;
    2214        44056 :     zoneNode.MassFlowRate = 0.0;
    2215        44056 :     zoneNode.Quality = 1.0;
    2216        44056 :     zoneNode.Press = state.dataEnvrn->OutBaroPress;
    2217        44056 :     zoneNode.HumRat = state.dataEnvrn->OutHumRat;
    2218        44056 :     zoneNode.Enthalpy = Psychrometrics::PsyHFnTdbW(zoneNode.Temp, zoneNode.HumRat);
    2219        44056 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2220          317 :         zoneNode.CO2 = state.dataContaminantBalance->OutdoorCO2;
    2221              :     }
    2222        44056 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2223          117 :         zoneNode.GenContam = state.dataContaminantBalance->OutdoorGC;
    2224              :     }
    2225              : 
    2226        91632 :     for (int const nodeNum : this->InletNode) {
    2227        47576 :         auto &inNode = state.dataLoopNodes->Node(nodeNum);
    2228        47576 :         inNode.Temp = 20.0;
    2229        47576 :         inNode.MassFlowRate = 0.0;
    2230        47576 :         inNode.Quality = 1.0;
    2231        47576 :         inNode.Press = state.dataEnvrn->OutBaroPress;
    2232        47576 :         inNode.HumRat = state.dataEnvrn->OutHumRat;
    2233        47576 :         inNode.Enthalpy = Psychrometrics::PsyHFnTdbW(inNode.Temp, inNode.HumRat);
    2234        47576 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2235          281 :             inNode.CO2 = state.dataContaminantBalance->OutdoorCO2;
    2236              :         }
    2237        47576 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2238           81 :             inNode.GenContam = state.dataContaminantBalance->OutdoorGC;
    2239              :         }
    2240              :     }
    2241              : 
    2242        54477 :     for (int const nodeNum : this->ExhaustNode) {
    2243        10421 :         auto &exhNode = state.dataLoopNodes->Node(nodeNum);
    2244        10421 :         exhNode.Temp = 20.0;
    2245        10421 :         exhNode.MassFlowRate = 0.0;
    2246        10421 :         exhNode.Quality = 1.0;
    2247        10421 :         exhNode.Press = state.dataEnvrn->OutBaroPress;
    2248        10421 :         exhNode.HumRat = state.dataEnvrn->OutHumRat;
    2249        10421 :         exhNode.Enthalpy = Psychrometrics::PsyHFnTdbW(exhNode.Temp, exhNode.HumRat);
    2250        10421 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2251          130 :             exhNode.CO2 = state.dataContaminantBalance->OutdoorCO2;
    2252              :         }
    2253        10421 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2254           30 :             exhNode.GenContam = state.dataContaminantBalance->OutdoorGC;
    2255              :         }
    2256              :     }
    2257              : 
    2258              :     // BG CR 7122 following resets return air node.
    2259        44056 :     int NumRetNodes = this->NumReturnNodes;
    2260        44056 :     if (NumRetNodes > 0) {
    2261        88149 :         for (int const nodeNum : this->ReturnNode) {
    2262        44102 :             auto &returnNode = state.dataLoopNodes->Node(nodeNum);
    2263        44102 :             returnNode.Temp = 20.0;
    2264        44102 :             returnNode.MassFlowRate = 0.0;
    2265        44102 :             returnNode.Quality = 1.0;
    2266        44102 :             returnNode.Press = state.dataEnvrn->OutBaroPress;
    2267        44102 :             returnNode.HumRat = state.dataEnvrn->OutHumRat;
    2268        44102 :             returnNode.Enthalpy = Psychrometrics::PsyHFnTdbW(returnNode.Temp, returnNode.HumRat);
    2269        44102 :             if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2270          317 :                 returnNode.CO2 = state.dataContaminantBalance->OutdoorCO2;
    2271              :             }
    2272        44102 :             if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2273          117 :                 returnNode.GenContam = state.dataContaminantBalance->OutdoorGC;
    2274              :             }
    2275              :         }
    2276              :     }
    2277        44056 : }
    2278              : 
    2279     53608986 : void EquipConfiguration::hvacTimeStepInit(EnergyPlusData &state, bool FirstHVACIteration)
    2280              : {
    2281     53608986 :     auto &zoneNode = state.dataLoopNodes->Node(this->ZoneNode);
    2282     53608986 :     this->ExcessZoneExh = 0.0;
    2283              : 
    2284     53608986 :     if (FirstHVACIteration) {
    2285     33142316 :         for (int const nodeNum : this->ExhaustNode) {
    2286      5979405 :             auto &exhNode = state.dataLoopNodes->Node(nodeNum);
    2287      5979405 :             exhNode.Temp = zoneNode.Temp;
    2288      5979405 :             exhNode.HumRat = zoneNode.HumRat;
    2289      5979405 :             exhNode.Enthalpy = zoneNode.Enthalpy;
    2290      5979405 :             exhNode.Press = zoneNode.Press;
    2291      5979405 :             exhNode.Quality = zoneNode.Quality;
    2292      5979405 :             exhNode.MassFlowRate = 0.0;
    2293      5979405 :             exhNode.MassFlowRateMaxAvail = 0.0;
    2294      5979405 :             exhNode.MassFlowRateMinAvail = 0.0;
    2295      5979405 :             if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    2296       113007 :                 exhNode.CO2 = zoneNode.CO2;
    2297              :             }
    2298      5979405 :             if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    2299        74282 :                 exhNode.GenContam = zoneNode.GenContam;
    2300              :             }
    2301              :         }
    2302              :     }
    2303     53608986 : }
    2304              : 
    2305     54126144 : void EquipConfiguration::calcReturnFlows(EnergyPlusData &state,
    2306              :                                          Real64 &ExpTotalReturnMassFlow,  // Expected total return air mass flow rate
    2307              :                                          Real64 &FinalTotalReturnMassFlow // Final total return air mass flow rate
    2308              : )
    2309              : {
    2310     54126144 :     int numRetNodes = this->NumReturnNodes;
    2311     54126144 :     Real64 totReturnFlow = 0.0; // Total flow to all return nodes in the zone (kg/s)
    2312     54126144 :     Real64 totVarReturnFlow =
    2313              :         0.0; // Total variable return flow, for return nodes connected to an airloop with an OA system or not with specified flow (kg/s)
    2314     54126144 :     Real64 returnSchedFrac = this->returnFlowFracSched->getCurrentVal();
    2315     54126144 :     this->FixedReturnFlow = false;
    2316     54126144 :     FinalTotalReturnMassFlow = 0.0;
    2317     54126144 :     this->TotAvailAirLoopOA = 0.0;
    2318              : 
    2319              :     // Set initial flow rate for each return node
    2320    108340035 :     for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) {
    2321     54213891 :         int retNode = this->ReturnNode(returnNum);
    2322              : 
    2323     54213891 :         if (retNode > 0) {
    2324     54213891 :             Real64 returnNodeMassFlow = 0.0;
    2325     54213891 :             auto &retNodeData(state.dataLoopNodes->Node(retNode));
    2326              : 
    2327     54213891 :             int inletNum = this->ReturnNodeInletNum(returnNum); // which inlet node matches this return node (same airloop)
    2328     54213891 :             int ADUNum = 0;
    2329     54213891 :             if (inletNum > 0) {
    2330     38905121 :                 ADUNum = this->InletNodeADUNum(inletNum);
    2331              :             }
    2332     54213891 :             int airLoop = this->ReturnNodeAirLoopNum(returnNum);
    2333     54213891 :             Real64 airLoopReturnFrac = 1.0;
    2334     54213891 :             if (airLoop > 0) {
    2335              :                 // Establish corresponding airloop inlet(s) mass flow rate and set return node max/min/maxavail
    2336     38905121 :                 Real64 inletMassFlow = 0.0;
    2337     38905121 :                 int maxMinNodeNum = 0;
    2338     38905121 :                 auto const &thisAirLoopFlow(state.dataAirLoop->AirLoopFlow(airLoop));
    2339     38905121 :                 if (ADUNum > 0) {
    2340              :                     // Zone return node could carry supply flow to zone without leaks plus any induced flow from plenum (but don't include other
    2341              :                     // secondary flows from exhaust nodes)
    2342     38765144 :                     inletMassFlow = state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateZSup +
    2343     38765144 :                                     state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRatePlenInd;
    2344     38765144 :                     maxMinNodeNum = state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum;
    2345       139977 :                 } else if (inletNum > 0) {
    2346              :                     // If not connected to an ADU, then use the inlet node flow
    2347       139977 :                     inletMassFlow = state.dataLoopNodes->Node(this->InletNode(inletNum)).MassFlowRate;
    2348       139977 :                     maxMinNodeNum = this->InletNode(inletNum);
    2349              :                 }
    2350     38905121 :                 if (maxMinNodeNum > 0) {
    2351     38905121 :                     auto const &maxMinNodeData(state.dataLoopNodes->Node(maxMinNodeNum));
    2352     38905121 :                     retNodeData.MassFlowRateMax = maxMinNodeData.MassFlowRateMax;
    2353     38905121 :                     retNodeData.MassFlowRateMin = maxMinNodeData.MassFlowRateMin;
    2354     38905121 :                     retNodeData.MassFlowRateMaxAvail = maxMinNodeData.MassFlowRateMaxAvail;
    2355              :                 } else {
    2356            0 :                     auto const &zoneNodeData(state.dataLoopNodes->Node(this->ZoneNode));
    2357            0 :                     retNodeData.MassFlowRateMax = zoneNodeData.MassFlowRateMax;
    2358            0 :                     retNodeData.MassFlowRateMin = zoneNodeData.MassFlowRateMin;
    2359            0 :                     retNodeData.MassFlowRateMaxAvail = zoneNodeData.MassFlowRateMaxAvail;
    2360              :                 }
    2361              : 
    2362     38905121 :                 airLoopReturnFrac = thisAirLoopFlow.DesReturnFrac;
    2363     38905121 :                 if (state.dataAirSystemsData->PrimaryAirSystems(airLoop).OASysExists && (thisAirLoopFlow.MaxOutAir > 0.0)) {
    2364              :                     // Set return flow as fraction of matching inlet node flow if there is an OA system and available OA flow > 0.0
    2365     36462391 :                     returnNodeMassFlow = airLoopReturnFrac * inletMassFlow;
    2366     36462391 :                     this->TotAvailAirLoopOA += thisAirLoopFlow.MaxOutAir;
    2367              :                 } else {
    2368              :                     // Set return flow to matching inlet node flow
    2369      2442730 :                     returnNodeMassFlow = inletMassFlow;
    2370      2442730 :                     this->FixedReturnFlow(returnNum) = true;
    2371              :                 }
    2372              :             } else {
    2373     15308770 :                 returnNodeMassFlow = 0.0;
    2374              :             }
    2375              : 
    2376              :             // Return node 1 is special
    2377     54213891 :             if (returnNum == 1) {
    2378              :                 // Make no return air flow adjustments during sizing
    2379     54122496 :                 if ((state.dataGlobal->DoingSizing) && numRetNodes == 1) {
    2380      9752883 :                     returnNodeMassFlow = ExpTotalReturnMassFlow;
    2381      9752883 :                     if (airLoop > 0) {
    2382            0 :                         if (!state.dataAirSystemsData->PrimaryAirSystems(airLoop).OASysExists ||
    2383            0 :                             (state.dataAirLoop->AirLoopFlow(airLoop).MaxOutAir == 0.0)) {
    2384            0 :                             ExpTotalReturnMassFlow = max(0.0, ExpTotalReturnMassFlow - this->ZoneExhBalanced + this->ZoneExh);
    2385            0 :                             returnNodeMassFlow = ExpTotalReturnMassFlow;
    2386              :                         }
    2387              :                     }
    2388     44369613 :                 } else if (!state.dataGlobal->DoingSizing) {
    2389     44350043 :                     if (this->NumReturnFlowBasisNodes > 0) {
    2390              :                         // Set base return air flow rate for node 1 using basis node flow rates
    2391            0 :                         Real64 basisNodesMassFlow = 0.0;
    2392            0 :                         for (int nodeNum = 1; nodeNum <= this->NumReturnFlowBasisNodes; ++nodeNum) {
    2393            0 :                             basisNodesMassFlow += state.dataLoopNodes->Node(this->ReturnFlowBasisNode(nodeNum)).MassFlowRate;
    2394              :                         }
    2395            0 :                         returnNodeMassFlow = max(0.0, (basisNodesMassFlow * returnSchedFrac));
    2396            0 :                         this->FixedReturnFlow(returnNum) = true;
    2397              :                     } else {
    2398              :                         // If only 1 return node, use the standard return mass flow
    2399     44350043 :                         if ((numRetNodes == 1) && !this->FixedReturnFlow(returnNum)) {
    2400     41979138 :                             returnNodeMassFlow = max(0.0, (ExpTotalReturnMassFlow * returnSchedFrac * airLoopReturnFrac));
    2401              :                         }
    2402              :                     }
    2403              :                 }
    2404              :             }
    2405     54213891 :             totReturnFlow += returnNodeMassFlow;
    2406     54213891 :             retNodeData.MassFlowRate = returnNodeMassFlow;
    2407     54213891 :             retNodeData.MassFlowRateMinAvail = 0.0;
    2408     54213891 :             if (!this->FixedReturnFlow(returnNum)) {
    2409     51771161 :                 totVarReturnFlow += returnNodeMassFlow;
    2410              :             }
    2411              :         }
    2412              :     }
    2413              : 
    2414              :     // if zone mass balance true, set to expected return flow
    2415     54126144 :     if (state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment != DataHeatBalance::AdjustmentType::NoAdjustReturnAndMixing) {
    2416              :         // applies zone return flow schedule multiplier
    2417       597505 :         ExpTotalReturnMassFlow = returnSchedFrac * ExpTotalReturnMassFlow;
    2418              :         // set air flow rate for each return node
    2419       597505 :         Real64 zoneTotReturnFlow = 0.0;
    2420       597505 :         Real64 returnNodeMassFlow = 0.0;
    2421      1195010 :         for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) {
    2422       597505 :             int retNode = this->ReturnNode(returnNum);
    2423       597505 :             if (retNode > 0) {
    2424       597505 :                 if (numRetNodes == 1) {
    2425       597505 :                     returnNodeMassFlow = ExpTotalReturnMassFlow;
    2426              :                 } else { // multiple return nodes
    2427            0 :                     if (ExpTotalReturnMassFlow > 0.0) {
    2428            0 :                         Real64 returnAdjFactor = state.dataLoopNodes->Node(retNode).MassFlowRate / ExpTotalReturnMassFlow;
    2429            0 :                         returnNodeMassFlow = returnAdjFactor * ExpTotalReturnMassFlow;
    2430              :                     } else {
    2431            0 :                         returnNodeMassFlow = 0.0;
    2432              :                     }
    2433              :                 }
    2434              :             }
    2435       597505 :             zoneTotReturnFlow += returnNodeMassFlow;
    2436              :         }
    2437              :         // Adjust return node flows if zone total return flow is > 0
    2438       597505 :         if (zoneTotReturnFlow > 0.0) {
    2439       986042 :             for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) {
    2440       493021 :                 int retNode = this->ReturnNode(returnNum);
    2441       493021 :                 if (retNode > 0) {
    2442       493021 :                     if (numRetNodes == 1) {
    2443              :                         // set it to expected return flows
    2444       493021 :                         state.dataLoopNodes->Node(retNode).MassFlowRate = ExpTotalReturnMassFlow;
    2445       493021 :                         FinalTotalReturnMassFlow = ExpTotalReturnMassFlow;
    2446              :                     } else { // multiple return nodes, adjust nodes flow
    2447            0 :                         Real64 newReturnFlow = 0.0;
    2448            0 :                         Real64 returnAdjFactor = ExpTotalReturnMassFlow / zoneTotReturnFlow;
    2449            0 :                         Real64 curReturnFlow = state.dataLoopNodes->Node(retNode).MassFlowRate;
    2450            0 :                         newReturnFlow = curReturnFlow * returnAdjFactor;
    2451            0 :                         state.dataLoopNodes->Node(retNode).MassFlowRate = newReturnFlow;
    2452            0 :                         FinalTotalReturnMassFlow += newReturnFlow;
    2453              :                     }
    2454              :                 }
    2455              :             }
    2456              :         } else {
    2457       104484 :             FinalTotalReturnMassFlow = ExpTotalReturnMassFlow;
    2458              :         }
    2459              :     } else {
    2460              :         // Adjust return flows if greater than expected (i.e. there is exhaust or mixing flow reducing the total available for return)
    2461     53528639 :         if ((totReturnFlow > ExpTotalReturnMassFlow) && (totVarReturnFlow > 0.0)) {
    2462            0 :             Real64 newReturnFlow = 0.0;
    2463            0 :             Real64 returnAdjFactor = (1 - ((totReturnFlow - ExpTotalReturnMassFlow) / totVarReturnFlow)); // Return flow adjustment factor
    2464            0 :             for (int returnNum = 1; returnNum <= numRetNodes; ++returnNum) {
    2465            0 :                 int retNode = this->ReturnNode(returnNum);
    2466            0 :                 Real64 curReturnFlow = state.dataLoopNodes->Node(retNode).MassFlowRate;
    2467            0 :                 if (retNode > 0) {
    2468            0 :                     if (!this->FixedReturnFlow(returnNum)) {
    2469            0 :                         newReturnFlow = curReturnFlow * returnAdjFactor;
    2470            0 :                         FinalTotalReturnMassFlow += newReturnFlow;
    2471            0 :                         state.dataLoopNodes->Node(retNode).MassFlowRate = newReturnFlow;
    2472              :                     } else {
    2473            0 :                         FinalTotalReturnMassFlow += curReturnFlow;
    2474              :                     }
    2475              :                 }
    2476              :             }
    2477            0 :         } else {
    2478     53528639 :             FinalTotalReturnMassFlow = totReturnFlow;
    2479              :         }
    2480              :     }
    2481     54126144 : }
    2482              : 
    2483              : } // namespace EnergyPlus::DataZoneEquipment
        

Generated by: LCOV version 2.0-1