LCOV - code coverage report
Current view: top level - EnergyPlus - ZonePlenum.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 85.7 % 657 563
Test Date: 2025-06-02 07:23:51 Functions: 100.0 % 13 13

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <algorithm>
      50              : #include <cmath>
      51              : 
      52              : // EnergyPlus Headers
      53              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      54              : #include <EnergyPlus/DataContaminantBalance.hh>
      55              : #include <EnergyPlus/DataEnvironment.hh>
      56              : #include <EnergyPlus/DataHeatBalance.hh>
      57              : #include <EnergyPlus/DataLoopNode.hh>
      58              : #include <EnergyPlus/DataZoneEquipment.hh>
      59              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      60              : #include <EnergyPlus/NodeInputManager.hh>
      61              : #include <EnergyPlus/PoweredInductionUnits.hh>
      62              : #include <EnergyPlus/Psychrometrics.hh>
      63              : #include <EnergyPlus/PurchasedAirManager.hh>
      64              : #include <EnergyPlus/UtilityRoutines.hh>
      65              : #include <EnergyPlus/ZonePlenum.hh>
      66              : 
      67              : namespace EnergyPlus::ZonePlenum {
      68              : // Module containing simulation routines for both zone return and zone supply plenums
      69              : 
      70              : // MODULE INFORMATION:
      71              : //       AUTHOR         Peter Graham Ellis
      72              : //       DATE WRITTEN   November 2000
      73              : //       MODIFIED       na
      74              : //       RE-ENGINEERED  na
      75              : 
      76              : // PURPOSE OF THIS MODULE:
      77              : // To encapsulate the data and algorithms required to
      78              : // manage Air Path Zone Return Plenum Components
      79              : 
      80              : // METHODOLOGY EMPLOYED:
      81              : // The Zone Plenum
      82              : 
      83              : // Using/Aliasing
      84              : using namespace DataLoopNode;
      85              : using Psychrometrics::PsyHFnTdbW;
      86              : using Psychrometrics::PsyTdbFnHW;
      87              : 
      88              : // Functions
      89              : 
      90      2691763 : void SimAirZonePlenum(EnergyPlusData &state,
      91              :                       std::string_view CompName,
      92              :                       DataZoneEquipment::AirLoopHVACZone const iCompType,
      93              :                       int &CompIndex,
      94              :                       ObjexxFCL::Optional_bool_const FirstHVACIteration, // Autodesk:OPTIONAL Used without PRESENT check
      95              :                       ObjexxFCL::Optional_bool_const FirstCall,          // Autodesk:OPTIONAL Used without PRESENT check
      96              :                       ObjexxFCL::Optional_bool PlenumInletChanged        // Autodesk:OPTIONAL Used without PRESENT check
      97              : )
      98              : {
      99              : 
     100              :     // SUBROUTINE INFORMATION:
     101              :     //       AUTHOR         Peter Graham Ellis
     102              :     //       DATE WRITTEN   November 2000
     103              :     //       MODIFIED       March 2000
     104              :     //       RE-ENGINEERED  na
     105              : 
     106              :     // PURPOSE OF THIS SUBROUTINE:
     107              :     // This subroutine manages the ZonePlenum component simulation for both
     108              :     // return and supply plenums.
     109              :     // It is called from the SimAirLoopComponent at the system time step.
     110              : 
     111              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     112              :     int ZonePlenumNum; // The ZonePlenum that you are currently loading input into
     113              : 
     114              :     // Obtains and Allocates ZonePlenum related parameters from input file
     115      2691763 :     if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
     116          193 :         GetZonePlenumInput(state);
     117          193 :         state.dataZonePlenum->GetInputFlag = false;
     118              :     }
     119              : 
     120      2691763 :     if (iCompType == DataZoneEquipment::AirLoopHVACZone::ReturnPlenum) { // 'AirLoopHVAC:ReturnPlenum'
     121              :         // Find the correct ZonePlenumNumber
     122      2613527 :         if (CompIndex == 0) {
     123          284 :             ZonePlenumNum = Util::FindItemInList(CompName, state.dataZonePlenum->ZoneRetPlenCond, &ZoneReturnPlenumConditions::ZonePlenumName);
     124          284 :             if (ZonePlenumNum == 0) {
     125            0 :                 ShowFatalError(state, format("SimAirZonePlenum: AirLoopHVAC:ReturnPlenum not found={}", CompName));
     126              :             }
     127          284 :             CompIndex = ZonePlenumNum;
     128              :         } else {
     129      2613243 :             ZonePlenumNum = CompIndex;
     130      2613243 :             if (ZonePlenumNum > state.dataZonePlenum->NumZoneReturnPlenums || ZonePlenumNum < 1) {
     131            0 :                 ShowFatalError(
     132              :                     state,
     133            0 :                     format("SimAirZonePlenum: Invalid CompIndex passed={}, Number of AirLoopHVAC:ReturnPlenum={}, AirLoopHVAC:ReturnPlenum name={}",
     134              :                            ZonePlenumNum,
     135            0 :                            state.dataZonePlenum->NumZoneReturnPlenums,
     136              :                            CompName));
     137              :             }
     138      2613243 :             if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).checkEquipName) {
     139          285 :                 if (CompName != state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZonePlenumName) {
     140            0 :                     ShowFatalError(state,
     141            0 :                                    format("SimAirZonePlenum: Invalid CompIndex passed={}, AirLoopHVAC:ReturnPlenum name={}, stored "
     142              :                                           "AirLoopHVAC:ReturnPlenum Name for that index={}",
     143              :                                           ZonePlenumNum,
     144              :                                           CompName,
     145            0 :                                           state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZonePlenumName));
     146              :                 }
     147          285 :                 state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).checkEquipName = false;
     148              :             }
     149              :         }
     150              : 
     151      2613527 :         InitAirZoneReturnPlenum(state, ZonePlenumNum); // Initialize all ZonePlenum related parameters
     152              : 
     153      2613527 :         CalcAirZoneReturnPlenum(state, ZonePlenumNum);
     154              : 
     155      2613527 :         UpdateAirZoneReturnPlenum(state, ZonePlenumNum); // Update the current ZonePlenum to the outlet nodes
     156              : 
     157        78236 :     } else if (iCompType == DataZoneEquipment::AirLoopHVACZone::SupplyPlenum) { // 'AirLoopHVAC:SupplyPlenum'
     158              :         // Find the correct ZonePlenumNumber
     159        78236 :         if (CompIndex == 0) {
     160            8 :             ZonePlenumNum = Util::FindItemInList(CompName, state.dataZonePlenum->ZoneSupPlenCond, &ZoneSupplyPlenumConditions::ZonePlenumName);
     161            8 :             if (ZonePlenumNum == 0) {
     162            0 :                 ShowFatalError(state, format("SimAirZonePlenum: AirLoopHVAC:SupplyPlenum not found={}", CompName));
     163              :             }
     164            8 :             CompIndex = ZonePlenumNum;
     165              :         } else {
     166        78228 :             ZonePlenumNum = CompIndex;
     167        78228 :             if (ZonePlenumNum > state.dataZonePlenum->NumZoneSupplyPlenums || ZonePlenumNum < 1) {
     168            0 :                 ShowFatalError(
     169              :                     state,
     170            0 :                     format("SimAirZonePlenum: Invalid CompIndex passed={}, Number of AirLoopHVAC:SupplyPlenum={}, AirLoopHVAC:SupplyPlenum name={}",
     171              :                            ZonePlenumNum,
     172            0 :                            state.dataZonePlenum->NumZoneReturnPlenums,
     173              :                            CompName));
     174              :             }
     175        78228 :             if (state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).checkEquipName) {
     176            8 :                 if (CompName != state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZonePlenumName) {
     177            0 :                     ShowFatalError(state,
     178            0 :                                    format("SimAirZonePlenum: Invalid CompIndex passed={}, AirLoopHVAC:SupplyPlenum name={}, stored "
     179              :                                           "AirLoopHVAC:SupplyPlenum Name for that index={}",
     180              :                                           ZonePlenumNum,
     181              :                                           CompName,
     182            0 :                                           state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZonePlenumName));
     183              :                 }
     184            8 :                 state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).checkEquipName = false;
     185              :             }
     186              :         }
     187              : 
     188        78236 :         InitAirZoneSupplyPlenum(state, ZonePlenumNum, FirstHVACIteration, FirstCall); // Initialize all ZonePlenum related parameters
     189              : 
     190        78236 :         CalcAirZoneSupplyPlenum(state, ZonePlenumNum, FirstCall);
     191              :         // Update the current ZonePlenum to the outlet nodes
     192        78236 :         UpdateAirZoneSupplyPlenum(state, ZonePlenumNum, PlenumInletChanged, FirstCall);
     193              : 
     194              :     } else {
     195            0 :         ShowSevereError(state, format("SimAirZonePlenum: Errors in Plenum={}", CompName));
     196            0 :         ShowContinueError(state, format("ZonePlenum: Unhandled plenum type found:{}", iCompType));
     197            0 :         ShowFatalError(state, "Preceding conditions cause termination.");
     198              :     }
     199      2691763 : }
     200              : 
     201          199 : void GetZonePlenumInput(EnergyPlusData &state)
     202              : {
     203              : 
     204              :     // SUBROUTINE INFORMATION:
     205              :     //       AUTHOR         Peter Graham Ellis
     206              :     //       DATE WRITTEN   November 2000
     207              :     //       MODIFIED       August 2003, FCW: For each zone with a return air plenum put the ZoneRetPlenCond
     208              :     //                       number for the return air plenum in the ZoneEquipConfig array for the zone
     209              :     //                       for later access to the zone's return air plenum conditions.
     210              :     //       RE-ENGINEERED  na
     211              : 
     212              :     // PURPOSE OF THIS SUBROUTINE:
     213              :     // This subroutine is the main routine to call other input routines and Get routines
     214              : 
     215              :     // METHODOLOGY EMPLOYED:
     216              :     // Uses the status flags to trigger events.
     217              : 
     218              :     // Using/Aliasing
     219              :     using DataZoneEquipment::EquipConfiguration;
     220              :     using NodeInputManager::CheckUniqueNodeNumbers;
     221              :     using NodeInputManager::EndUniqueNodeCheck;
     222              :     using NodeInputManager::GetNodeNums;
     223              :     using NodeInputManager::GetOnlySingleNode;
     224              :     using NodeInputManager::InitUniqueNodeCheck;
     225              :     using PoweredInductionUnits::PIUInducesPlenumAir;
     226              :     using PurchasedAirManager::CheckPurchasedAirForReturnPlenum;
     227              : 
     228              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     229              :     int ZoneEquipConfigLoop;
     230              :     int NumAlphas;
     231              :     int NumNums;
     232              :     int NumArgs;
     233              :     int NumNodes;
     234          199 :     Array1D_int NodeNums;
     235              :     int MaxNums;
     236              :     int MaxAlphas;
     237              :     int NodeNum;
     238              :     int IOStat;
     239          199 :     Array1D<Real64> NumArray;        // Numeric input items for object
     240          199 :     std::string CurrentModuleObject; // for ease in getting objects
     241          199 :     Array1D_string AlphArray;        // Alpha input items for object
     242          199 :     Array1D_string cAlphaFields;     // Alpha field names
     243          199 :     Array1D_string cNumericFields;   // Numeric field names
     244          199 :     Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     245          199 :     Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     246          199 :     bool ErrorsFound(false);
     247              :     bool NodeListError; // Flag for node list error
     248              :     bool UniqueNodeError;
     249              :     static constexpr std::string_view RoutineName("GetZonePlenumInput: "); // include trailing blank space
     250          199 :     std::string InducedNodeListName;
     251              : 
     252          199 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:ReturnPlenum", NumArgs, NumAlphas, NumNums);
     253          199 :     MaxNums = NumNums;
     254          199 :     MaxAlphas = NumAlphas;
     255          199 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "AirLoopHVAC:SupplyPlenum", NumArgs, NumAlphas, NumNums);
     256          199 :     MaxNums = max(NumNums, MaxNums);
     257          199 :     MaxAlphas = max(NumAlphas, MaxAlphas);
     258          199 :     AlphArray.allocate(MaxAlphas);
     259          199 :     cAlphaFields.allocate(MaxAlphas);
     260          199 :     cNumericFields.allocate(MaxNums);
     261          199 :     NumArray.dimension(MaxNums, 0.0);
     262          199 :     lAlphaBlanks.dimension(MaxAlphas, true);
     263          199 :     lNumericBlanks.dimension(MaxNums, true);
     264          199 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumArgs, NumAlphas, NumNums);
     265          199 :     NodeNums.dimension(NumArgs, 0);
     266              : 
     267          199 :     InducedNodeListName = "";
     268              : 
     269          199 :     state.dataZonePlenum->NumZoneReturnPlenums = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:ReturnPlenum");
     270          199 :     state.dataZonePlenum->NumZoneSupplyPlenums = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "AirLoopHVAC:SupplyPlenum");
     271              : 
     272          199 :     if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
     273          191 :         state.dataZonePlenum->ZoneRetPlenCond.allocate(state.dataZonePlenum->NumZoneReturnPlenums);
     274              :     }
     275          199 :     if (state.dataZonePlenum->NumZoneSupplyPlenums > 0) {
     276            6 :         state.dataZonePlenum->ZoneSupPlenCond.allocate(state.dataZonePlenum->NumZoneSupplyPlenums);
     277              :     }
     278              : 
     279          199 :     InitUniqueNodeCheck(state, "AirLoopHVAC:ReturnPlenum");
     280          484 :     for (int ZonePlenumNum = 1; ZonePlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++ZonePlenumNum) {
     281              : 
     282          285 :         CurrentModuleObject = "AirLoopHVAC:ReturnPlenum";
     283              : 
     284          285 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     285              :                                                                  CurrentModuleObject,
     286              :                                                                  ZonePlenumNum,
     287              :                                                                  AlphArray,
     288              :                                                                  NumAlphas,
     289              :                                                                  NumArray,
     290              :                                                                  NumNums,
     291              :                                                                  IOStat,
     292              :                                                                  lNumericBlanks,
     293              :                                                                  lAlphaBlanks,
     294              :                                                                  cAlphaFields,
     295              :                                                                  cNumericFields);
     296          285 :         Util::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, ErrorsFound);
     297              : 
     298          285 :         auto &thisRetPlenum = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum);
     299          285 :         thisRetPlenum.ZonePlenumName = AlphArray(1);
     300              : 
     301              :         // Check if this zone is also used in another return plenum
     302          285 :         IOStat = Util::FindItemInList(AlphArray(2), state.dataZonePlenum->ZoneRetPlenCond, &ZoneReturnPlenumConditions::ZoneName, ZonePlenumNum - 1);
     303          285 :         if (IOStat != 0) {
     304            0 :             ShowSevereError(state,
     305            0 :                             format("{}{} \"{}\" is used more than once as a {}.", RoutineName, cAlphaFields(2), AlphArray(2), CurrentModuleObject));
     306            0 :             ShowContinueError(state, format("..Only one {} object may be connected to a given zone.", CurrentModuleObject));
     307            0 :             ShowContinueError(state, format("..occurs in {} = {}", CurrentModuleObject, AlphArray(1)));
     308            0 :             ErrorsFound = true;
     309              :         }
     310          285 :         thisRetPlenum.ZoneName = AlphArray(2);
     311              :         // put the X-Ref to the zone heat balance data structure
     312          285 :         thisRetPlenum.ActualZoneNum = Util::FindItemInList(AlphArray(2), state.dataHeatBal->Zone);
     313          285 :         if (thisRetPlenum.ActualZoneNum == 0) {
     314            0 :             ShowSevereError(state, format("For {} = {}, {} = {} not found.", CurrentModuleObject, AlphArray(1), cAlphaFields(2), AlphArray(2)));
     315            0 :             ErrorsFound = true;
     316            0 :             continue;
     317              :         } else {
     318          285 :             state.dataHeatBal->Zone(thisRetPlenum.ActualZoneNum).IsReturnPlenum = true;
     319          285 :             state.dataHeatBal->Zone(thisRetPlenum.ActualZoneNum).PlenumCondNum = ZonePlenumNum;
     320              :         }
     321              :         //  Check if this zone is used as a controlled zone
     322          285 :         ZoneEquipConfigLoop = Util::FindItemInList(AlphArray(2), state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::ZoneName);
     323          285 :         if (ZoneEquipConfigLoop != 0) {
     324            0 :             ShowSevereError(
     325              :                 state,
     326            0 :                 format(
     327              :                     "{}{} \"{}\" is a controlled zone. It cannot be used as a {}", RoutineName, cAlphaFields(2), AlphArray(2), CurrentModuleObject));
     328            0 :             ShowContinueError(state, format("..occurs in {} = {}", CurrentModuleObject, AlphArray(1)));
     329            0 :             ErrorsFound = true;
     330              :         }
     331              : 
     332          285 :         thisRetPlenum.ZoneNodeName = AlphArray(3);
     333          285 :         thisRetPlenum.ZoneNodeNum = GetOnlySingleNode(state,
     334          285 :                                                       AlphArray(3),
     335              :                                                       ErrorsFound,
     336              :                                                       DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPlenum,
     337          285 :                                                       AlphArray(1),
     338              :                                                       DataLoopNode::NodeFluidType::Air,
     339              :                                                       DataLoopNode::ConnectionType::ZoneNode,
     340              :                                                       NodeInputManager::CompFluidStream::Primary,
     341              :                                                       ObjectIsNotParent);
     342              :         // Insert the Plenum Zone Number into the Zone Heat Balance data structure for later reference
     343          285 :         state.dataHeatBal->Zone(thisRetPlenum.ActualZoneNum).SystemZoneNodeNumber = thisRetPlenum.ZoneNodeNum;
     344              :         // SpaceHB TODO: For now, assign the same system node to the spaces in the zone
     345          570 :         for (int spaceNum : state.dataHeatBal->Zone(thisRetPlenum.ActualZoneNum).spaceIndexes) {
     346          285 :             state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = thisRetPlenum.ZoneNodeNum;
     347          285 :         }
     348              : 
     349          285 :         thisRetPlenum.OutletNode = GetOnlySingleNode(state,
     350          285 :                                                      AlphArray(4),
     351              :                                                      ErrorsFound,
     352              :                                                      DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPlenum,
     353          285 :                                                      AlphArray(1),
     354              :                                                      DataLoopNode::NodeFluidType::Air,
     355              :                                                      DataLoopNode::ConnectionType::Outlet,
     356              :                                                      NodeInputManager::CompFluidStream::Primary,
     357              :                                                      ObjectIsNotParent);
     358              : 
     359          285 :         InducedNodeListName = AlphArray(5);
     360          285 :         NodeListError = false;
     361          570 :         GetNodeNums(state,
     362              :                     InducedNodeListName,
     363              :                     NumNodes,
     364              :                     NodeNums,
     365              :                     NodeListError,
     366              :                     DataLoopNode::NodeFluidType::Air,
     367              :                     DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPlenum,
     368          285 :                     thisRetPlenum.ZonePlenumName,
     369              :                     DataLoopNode::ConnectionType::InducedAir,
     370              :                     NodeInputManager::CompFluidStream::Primary,
     371              :                     ObjectIsNotParent,
     372              :                     false,
     373          285 :                     cAlphaFields(5));
     374              : 
     375          285 :         if (!NodeListError) {
     376          285 :             thisRetPlenum.NumInducedNodes = NumNodes;
     377          285 :             thisRetPlenum.InducedNode.allocate(thisRetPlenum.NumInducedNodes);
     378          285 :             thisRetPlenum.InducedMassFlowRate.allocate(thisRetPlenum.NumInducedNodes);
     379          285 :             thisRetPlenum.InducedMassFlowRateMaxAvail.allocate(thisRetPlenum.NumInducedNodes);
     380          285 :             thisRetPlenum.InducedMassFlowRateMinAvail.allocate(thisRetPlenum.NumInducedNodes);
     381          285 :             thisRetPlenum.InducedTemp.allocate(thisRetPlenum.NumInducedNodes);
     382          285 :             thisRetPlenum.InducedHumRat.allocate(thisRetPlenum.NumInducedNodes);
     383          285 :             thisRetPlenum.InducedEnthalpy.allocate(thisRetPlenum.NumInducedNodes);
     384          285 :             thisRetPlenum.InducedPressure.allocate(thisRetPlenum.NumInducedNodes);
     385          285 :             thisRetPlenum.InducedCO2.allocate(thisRetPlenum.NumInducedNodes);
     386          285 :             thisRetPlenum.InducedGenContam.allocate(thisRetPlenum.NumInducedNodes);
     387          285 :             thisRetPlenum.InducedMassFlowRate = 0.0;
     388          285 :             thisRetPlenum.InducedMassFlowRateMaxAvail = 0.0;
     389          285 :             thisRetPlenum.InducedMassFlowRateMinAvail = 0.0;
     390          285 :             thisRetPlenum.InducedTemp = 0.0;
     391          285 :             thisRetPlenum.InducedHumRat = 0.0;
     392          285 :             thisRetPlenum.InducedEnthalpy = 0.0;
     393          285 :             thisRetPlenum.InducedPressure = 0.0;
     394          285 :             thisRetPlenum.InducedCO2 = 0.0;
     395          285 :             thisRetPlenum.InducedGenContam = 0.0;
     396          311 :             for (NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
     397           26 :                 thisRetPlenum.InducedNode(NodeNum) = NodeNums(NodeNum);
     398           26 :                 UniqueNodeError = false;
     399           26 :                 if (!CheckPurchasedAirForReturnPlenum(state, ZonePlenumNum)) {
     400           52 :                     CheckUniqueNodeNumbers(state, "Return Plenum Induced Air Nodes", UniqueNodeError, NodeNums(NodeNum), CurrentModuleObject);
     401           26 :                     if (UniqueNodeError) {
     402            0 :                         ShowContinueError(state, format("Occurs for ReturnPlenum = {}", AlphArray(1)));
     403            0 :                         ErrorsFound = true;
     404              :                     }
     405           26 :                     PIUInducesPlenumAir(state, thisRetPlenum.InducedNode(NodeNum), ZonePlenumNum);
     406              :                 }
     407              :             }
     408              :         } else {
     409            0 :             ShowContinueError(
     410              :                 state,
     411            0 :                 format("Invalid Induced Air Outlet Node or NodeList name in AirLoopHVAC:ReturnPlenum object = {}", thisRetPlenum.ZonePlenumName));
     412            0 :             ErrorsFound = true;
     413              :         }
     414              : 
     415          285 :         thisRetPlenum.NumInletNodes = NumAlphas - 5;
     416              : 
     417          976 :         for (auto &e : state.dataZonePlenum->ZoneRetPlenCond) {
     418          691 :             e.InitFlag = true;
     419          285 :         }
     420              : 
     421          285 :         thisRetPlenum.InletNode.allocate(thisRetPlenum.NumInletNodes);
     422          285 :         thisRetPlenum.InletMassFlowRate.allocate(thisRetPlenum.NumInletNodes);
     423          285 :         thisRetPlenum.InletMassFlowRateMaxAvail.allocate(thisRetPlenum.NumInletNodes);
     424          285 :         thisRetPlenum.InletMassFlowRateMinAvail.allocate(thisRetPlenum.NumInletNodes);
     425          285 :         thisRetPlenum.InletTemp.allocate(thisRetPlenum.NumInletNodes);
     426          285 :         thisRetPlenum.InletHumRat.allocate(thisRetPlenum.NumInletNodes);
     427          285 :         thisRetPlenum.InletEnthalpy.allocate(thisRetPlenum.NumInletNodes);
     428          285 :         thisRetPlenum.InletPressure.allocate(thisRetPlenum.NumInletNodes);
     429          285 :         thisRetPlenum.ZoneEqNum.allocate(thisRetPlenum.NumInletNodes);
     430              : 
     431          285 :         thisRetPlenum.InletNode = 0;
     432          285 :         thisRetPlenum.InletMassFlowRate = 0.0;
     433          285 :         thisRetPlenum.InletMassFlowRateMaxAvail = 0.0;
     434          285 :         thisRetPlenum.InletMassFlowRateMinAvail = 0.0;
     435          285 :         thisRetPlenum.InletTemp = 0.0;
     436          285 :         thisRetPlenum.InletHumRat = 0.0;
     437          285 :         thisRetPlenum.InletEnthalpy = 0.0;
     438          285 :         thisRetPlenum.InletPressure = 0.0;
     439          285 :         thisRetPlenum.OutletMassFlowRate = 0.0;
     440          285 :         thisRetPlenum.OutletMassFlowRateMaxAvail = 0.0;
     441          285 :         thisRetPlenum.OutletMassFlowRateMinAvail = 0.0;
     442          285 :         thisRetPlenum.OutletTemp = 0.0;
     443          285 :         thisRetPlenum.OutletHumRat = 0.0;
     444          285 :         thisRetPlenum.OutletEnthalpy = 0.0;
     445          285 :         thisRetPlenum.OutletPressure = 0.0;
     446          285 :         thisRetPlenum.ZoneTemp = 0.0;
     447          285 :         thisRetPlenum.ZoneHumRat = 0.0;
     448          285 :         thisRetPlenum.ZoneEnthalpy = 0.0;
     449              : 
     450         1601 :         for (NodeNum = 1; NodeNum <= thisRetPlenum.NumInletNodes; ++NodeNum) {
     451              : 
     452         2632 :             thisRetPlenum.InletNode(NodeNum) = GetOnlySingleNode(state,
     453         1316 :                                                                  AlphArray(5 + NodeNum),
     454              :                                                                  ErrorsFound,
     455              :                                                                  DataLoopNode::ConnectionObjectType::AirLoopHVACReturnPlenum,
     456         1316 :                                                                  AlphArray(1),
     457              :                                                                  DataLoopNode::NodeFluidType::Air,
     458              :                                                                  DataLoopNode::ConnectionType::Inlet,
     459              :                                                                  NodeInputManager::CompFluidStream::Primary,
     460              :                                                                  ObjectIsNotParent);
     461              :         }
     462              : 
     463              :     } // end AirLoopHVAC:ReturnPlenum Loop
     464          199 :     EndUniqueNodeCheck(state, "AirLoopHVAC:ReturnPlenum");
     465              : 
     466          207 :     for (int ZonePlenumNum = 1; ZonePlenumNum <= state.dataZonePlenum->NumZoneSupplyPlenums; ++ZonePlenumNum) {
     467            8 :         CurrentModuleObject = "AirLoopHVAC:SupplyPlenum";
     468              : 
     469            8 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     470              :                                                                  CurrentModuleObject,
     471              :                                                                  ZonePlenumNum,
     472              :                                                                  AlphArray,
     473              :                                                                  NumAlphas,
     474              :                                                                  NumArray,
     475              :                                                                  NumNums,
     476              :                                                                  IOStat,
     477              :                                                                  lNumericBlanks,
     478              :                                                                  lAlphaBlanks,
     479              :                                                                  cAlphaFields,
     480              :                                                                  cNumericFields);
     481            8 :         Util::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, ErrorsFound);
     482              : 
     483            8 :         auto &thisSupPlenum = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum);
     484            8 :         thisSupPlenum.ZonePlenumName = AlphArray(1);
     485              : 
     486              :         // Check if this zone is also used in another plenum
     487            8 :         IOStat = Util::FindItemInList(AlphArray(2), state.dataZonePlenum->ZoneSupPlenCond, &ZoneSupplyPlenumConditions::ZoneName, ZonePlenumNum - 1);
     488            8 :         if (IOStat != 0) {
     489            0 :             ShowSevereError(state,
     490            0 :                             format("{}{} \"{}\" is used more than once as a {}.", RoutineName, cAlphaFields(2), AlphArray(2), CurrentModuleObject));
     491            0 :             ShowContinueError(state, format("..Only one {} object may be connected to a given zone.", CurrentModuleObject));
     492            0 :             ShowContinueError(state, format("..occurs in {} = {}", CurrentModuleObject, AlphArray(1)));
     493            0 :             ErrorsFound = true;
     494              :         }
     495            8 :         if (state.dataZonePlenum->NumZoneReturnPlenums > 0) { // Check if this zone is also used in another plenum
     496            2 :             IOStat = Util::FindItemInList(AlphArray(2), state.dataZonePlenum->ZoneRetPlenCond, &ZoneReturnPlenumConditions::ZoneName);
     497            2 :             if (IOStat != 0) {
     498            0 :                 ShowSevereError(state,
     499            0 :                                 format("{}{} \"{}\" is used more than once as a {} or AirLoopHVAC:ReturnPlenum.",
     500              :                                        RoutineName,
     501              :                                        cAlphaFields(2),
     502              :                                        AlphArray(2),
     503              :                                        CurrentModuleObject));
     504            0 :                 ShowContinueError(state,
     505            0 :                                   format("..Only one {} or AirLoopHVAC:ReturnPlenum object may be connected to a given zone.", CurrentModuleObject));
     506            0 :                 ShowContinueError(state, format("..occurs in {} = {}", CurrentModuleObject, AlphArray(1)));
     507            0 :                 ErrorsFound = true;
     508              :             }
     509              :         }
     510            8 :         thisSupPlenum.ZoneName = AlphArray(2);
     511              :         // put the X-Ref to the zone heat balance data structure
     512            8 :         thisSupPlenum.ActualZoneNum = Util::FindItemInList(AlphArray(2), state.dataHeatBal->Zone);
     513            8 :         if (thisSupPlenum.ActualZoneNum == 0) {
     514            0 :             ShowSevereError(state, format("For {} = {}, {} = {} not found.", CurrentModuleObject, AlphArray(1), cAlphaFields(2), AlphArray(2)));
     515            0 :             ErrorsFound = true;
     516            0 :             continue;
     517              :         } else {
     518            8 :             state.dataHeatBal->Zone(thisSupPlenum.ActualZoneNum).IsSupplyPlenum = true;
     519            8 :             state.dataHeatBal->Zone(thisSupPlenum.ActualZoneNum).PlenumCondNum = ZonePlenumNum;
     520              :         }
     521              :         //  Check if this zone is used as a controlled zone
     522            8 :         if (std::any_of(state.dataZoneEquip->ZoneEquipConfig.begin(), state.dataZoneEquip->ZoneEquipConfig.end(), [](EquipConfiguration const &e) {
     523           10 :                 return e.IsControlled;
     524              :             })) {
     525            8 :             ZoneEquipConfigLoop = Util::FindItemInList(AlphArray(2), state.dataZoneEquip->ZoneEquipConfig, &EquipConfiguration::ZoneName);
     526            8 :             if (ZoneEquipConfigLoop != 0) {
     527            0 :                 ShowSevereError(state,
     528            0 :                                 format("{}{} \"{}\" is a controlled zone. It cannot be used as a {} or AirLoopHVAC:ReturnPlenum.",
     529              :                                        RoutineName,
     530              :                                        cAlphaFields(2),
     531              :                                        AlphArray(2),
     532              :                                        CurrentModuleObject));
     533            0 :                 ShowContinueError(state, format("..occurs in {} = {}", CurrentModuleObject, AlphArray(1)));
     534            0 :                 ErrorsFound = true;
     535              :             }
     536              :         }
     537              :         // Check if this is also used as a return plenum
     538              :         //  *** This next IF loop looks wrong.  Sent e-mail to Peter/Brent 8/14/08 for clarification ****
     539              :         //      IF (NumZoneReturnPlenums > 0) THEN
     540              :         //        IOSTAT=Util::FindItemInList(AlphArray(1),ZoneRetPlenCond%ZoneName,NumZoneReturnPlenums)
     541              :         //        IF (IOStat /= 0) THEN
     542              :         //          CALL ShowSevereError(state, RoutineName//'Plenum "'//TRIM(AlphArray(2))//  &
     543              :         //                               '" is a controlled zone.  It cannot be used as a '//  &
     544              :         //                               'SUPPLY PLENUM or RETURN PLENUM.')
     545              :         //          CALL ShowContinueError(state, '..occurs in '//TRIM(CurrentModuleObject)//' = '//TRIM(AlphArray(1)))
     546              :         //          ErrorsFound=.TRUE.
     547              :         //        ENDIF
     548              :         //      ENDIF
     549              : 
     550            8 :         thisSupPlenum.ZoneNodeName = AlphArray(3);
     551            8 :         thisSupPlenum.ZoneNodeNum = GetOnlySingleNode(state,
     552            8 :                                                       AlphArray(3),
     553              :                                                       ErrorsFound,
     554              :                                                       DataLoopNode::ConnectionObjectType::AirLoopHVACSupplyPlenum,
     555            8 :                                                       AlphArray(1),
     556              :                                                       DataLoopNode::NodeFluidType::Air,
     557              :                                                       DataLoopNode::ConnectionType::ZoneNode,
     558              :                                                       NodeInputManager::CompFluidStream::Primary,
     559              :                                                       ObjectIsNotParent);
     560              :         // Insert the Plenum Zone Number into the Zone Heat Balance data structure for later reference
     561            8 :         state.dataHeatBal->Zone(thisSupPlenum.ActualZoneNum).SystemZoneNodeNumber = thisSupPlenum.ZoneNodeNum;
     562              :         // SpaceHB TODO: For now, assign the same system node to the spaces in the zone
     563           16 :         for (int spaceNum : state.dataHeatBal->Zone(thisSupPlenum.ActualZoneNum).spaceIndexes) {
     564            8 :             state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = thisSupPlenum.ZoneNodeNum;
     565            8 :         }
     566              : 
     567            8 :         thisSupPlenum.InletNode = GetOnlySingleNode(state,
     568            8 :                                                     AlphArray(4),
     569              :                                                     ErrorsFound,
     570              :                                                     DataLoopNode::ConnectionObjectType::AirLoopHVACSupplyPlenum,
     571            8 :                                                     AlphArray(1),
     572              :                                                     DataLoopNode::NodeFluidType::Air,
     573              :                                                     DataLoopNode::ConnectionType::Inlet,
     574              :                                                     NodeInputManager::CompFluidStream::Primary,
     575              :                                                     ObjectIsNotParent);
     576              : 
     577            8 :         thisSupPlenum.NumOutletNodes = NumAlphas - 4;
     578              : 
     579           20 :         for (auto &e : state.dataZonePlenum->ZoneSupPlenCond) {
     580           12 :             e.InitFlag = true;
     581            8 :         }
     582              : 
     583            8 :         thisSupPlenum.OutletNode.allocate(thisSupPlenum.NumOutletNodes);
     584            8 :         thisSupPlenum.OutletMassFlowRate.allocate(thisSupPlenum.NumOutletNodes);
     585            8 :         thisSupPlenum.OutletMassFlowRateMaxAvail.allocate(thisSupPlenum.NumOutletNodes);
     586            8 :         thisSupPlenum.OutletMassFlowRateMinAvail.allocate(thisSupPlenum.NumOutletNodes);
     587            8 :         thisSupPlenum.OutletTemp.allocate(thisSupPlenum.NumOutletNodes);
     588            8 :         thisSupPlenum.OutletHumRat.allocate(thisSupPlenum.NumOutletNodes);
     589            8 :         thisSupPlenum.OutletEnthalpy.allocate(thisSupPlenum.NumOutletNodes);
     590            8 :         thisSupPlenum.OutletPressure.allocate(thisSupPlenum.NumOutletNodes);
     591              : 
     592            8 :         thisSupPlenum.OutletNode = 0;
     593            8 :         thisSupPlenum.OutletMassFlowRate = 0.0;
     594            8 :         thisSupPlenum.OutletMassFlowRateMaxAvail = 0.0;
     595            8 :         thisSupPlenum.OutletMassFlowRateMinAvail = 0.0;
     596            8 :         thisSupPlenum.OutletTemp = 0.0;
     597            8 :         thisSupPlenum.OutletHumRat = 0.0;
     598            8 :         thisSupPlenum.OutletEnthalpy = 0.0;
     599            8 :         thisSupPlenum.OutletPressure = 0.0;
     600            8 :         thisSupPlenum.InletMassFlowRate = 0.0;
     601            8 :         thisSupPlenum.InletMassFlowRateMaxAvail = 0.0;
     602            8 :         thisSupPlenum.InletMassFlowRateMinAvail = 0.0;
     603            8 :         thisSupPlenum.InletTemp = 0.0;
     604            8 :         thisSupPlenum.InletHumRat = 0.0;
     605            8 :         thisSupPlenum.InletEnthalpy = 0.0;
     606            8 :         thisSupPlenum.InletPressure = 0.0;
     607            8 :         thisSupPlenum.ZoneTemp = 0.0;
     608            8 :         thisSupPlenum.ZoneHumRat = 0.0;
     609            8 :         thisSupPlenum.ZoneEnthalpy = 0.0;
     610              : 
     611           20 :         for (NodeNum = 1; NodeNum <= thisSupPlenum.NumOutletNodes; ++NodeNum) {
     612              : 
     613           24 :             thisSupPlenum.OutletNode(NodeNum) = GetOnlySingleNode(state,
     614           12 :                                                                   AlphArray(4 + NodeNum),
     615              :                                                                   ErrorsFound,
     616              :                                                                   DataLoopNode::ConnectionObjectType::AirLoopHVACSupplyPlenum,
     617           12 :                                                                   AlphArray(1),
     618              :                                                                   DataLoopNode::NodeFluidType::Air,
     619              :                                                                   DataLoopNode::ConnectionType::Outlet,
     620              :                                                                   NodeInputManager::CompFluidStream::Primary,
     621              :                                                                   ObjectIsNotParent);
     622              :         }
     623              : 
     624              :     } // end AirLoopHVAC:SupplyPlenum Loop
     625              : 
     626          199 :     AlphArray.deallocate();
     627          199 :     NumArray.deallocate();
     628          199 :     cAlphaFields.deallocate();
     629          199 :     cNumericFields.deallocate();
     630          199 :     lAlphaBlanks.deallocate();
     631          199 :     lNumericBlanks.deallocate();
     632          199 :     NodeNums.deallocate();
     633              : 
     634          199 :     if (ErrorsFound) {
     635            0 :         ShowFatalError(state, format("{}Errors found in input.  Preceding condition(s) cause termination.", RoutineName));
     636              :     }
     637          199 : }
     638              : 
     639      2613527 : void InitAirZoneReturnPlenum(EnergyPlusData &state, int const ZonePlenumNum)
     640              : {
     641              : 
     642              :     // SUBROUTINE INFORMATION:
     643              :     //       AUTHOR         Peter Graham Ellis
     644              :     //       DATE WRITTEN   November 2000
     645              :     //       MODIFIED       na
     646              :     //       RE-ENGINEERED  na
     647              : 
     648              :     // PURPOSE OF THIS SUBROUTINE:
     649              :     // This subroutine is for initializations of the ZonePlenum components.
     650              : 
     651              :     // METHODOLOGY EMPLOYED:
     652              :     // Uses the status flags to trigger events.
     653              : 
     654              :     // Using/Aliasing
     655              : 
     656              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     657              :     int InletNode;
     658              :     int ZoneNodeNum;
     659              :     int NodeNum;
     660              : 
     661              :     // Do the one time initializations
     662      2613527 :     if (state.dataZonePlenum->InitAirZoneReturnPlenumOneTimeFlag) {
     663              : 
     664              :         // For each zone with a return air plenum put the ZoneRetPlenCond number for the return air plenum
     665              :         // in the ZoneEquipConfig array for the zone. This allows direct access of the zone's return air
     666              :         // plenum conditions, such as plenum temperature and air flow. Also establish and save connections
     667              :         // to the Air Distribution Units. This is needed for the simple duct leakage calculation.
     668              : 
     669          476 :         for (int ZonePlenumLoop = 1; ZonePlenumLoop <= state.dataZonePlenum->NumZoneReturnPlenums; ++ZonePlenumLoop) {
     670          285 :             int NumADUsToPlen = 0;
     671          285 :             if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).NumInletNodes > 0) {
     672         1601 :                 for (int InletNodeLoop = 1; InletNodeLoop <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).NumInletNodes; ++InletNodeLoop) {
     673         1316 :                     InletNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).InletNode(InletNodeLoop);
     674              :                     // Loop through ZoneEquipConfig's and look for return air node value = InletNode
     675        16784 :                     for (int ZoneEquipConfigLoop = 1; ZoneEquipConfigLoop <= state.dataGlobal->NumOfZones; ++ZoneEquipConfigLoop) {
     676        15468 :                         if (!state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigLoop).IsControlled) {
     677         2626 :                             continue;
     678              :                         }
     679        25684 :                         for (int retNode = 1; retNode <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigLoop).NumReturnNodes; ++retNode) {
     680        12842 :                             if (state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigLoop).ReturnNode(retNode) == InletNode) {
     681         1311 :                                 state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigLoop).ReturnNodePlenumNum = ZonePlenumLoop;
     682         1311 :                                 state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).ZoneEqNum(InletNodeLoop) = ZoneEquipConfigLoop;
     683              :                             }
     684              :                         }
     685              :                     }
     686              :                     // count the ADUs that can leak to this plenum
     687        14208 :                     for (int ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
     688        12892 :                         if (state.dataDefineEquipment->AirDistUnit(ADUNum).ZoneEqNum ==
     689        12892 :                             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).ZoneEqNum(InletNodeLoop)) {
     690         1326 :                             state.dataDefineEquipment->AirDistUnit(ADUNum).RetPlenumNum = ZonePlenumLoop;
     691         1326 :                             ++NumADUsToPlen;
     692              :                         }
     693              :                     }
     694              :                 }
     695              :             }
     696          285 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).ADUIndex.allocate(NumADUsToPlen);
     697          285 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).NumADUs = NumADUsToPlen;
     698              :             // fill the list of air distribution units that can leak to this plenum
     699          285 :             if (NumADUsToPlen > 0) {
     700          284 :                 int ADUsToPlenIndex = 0;
     701         3039 :                 for (int ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
     702         2755 :                     if (state.dataDefineEquipment->AirDistUnit(ADUNum).RetPlenumNum == ZonePlenumLoop) {
     703         1326 :                         ++ADUsToPlenIndex;
     704         1326 :                         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumLoop).ADUIndex(ADUsToPlenIndex) = ADUNum;
     705              :                     }
     706              :                 }
     707              :             }
     708              :         }
     709              : 
     710              :         // Check that all ADUs with leakage found a return plenum
     711         1564 :         for (int ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
     712         1373 :             auto &thisADU(state.dataDefineEquipment->AirDistUnit(ADUNum));
     713              :             // TODO: the first half of this IF condition was a duplicated OR, if issues around this code, might want to check the history of this line
     714         1373 :             if (thisADU.DownStreamLeak && (thisADU.RetPlenumNum == 0)) {
     715            0 :                 ShowWarningError(state,
     716            0 :                                  format("No return plenum found for simple duct leakage for ZoneHVAC:AirDistributionUnit={} in Zone={}",
     717            0 :                                         thisADU.Name,
     718            0 :                                         state.dataZoneEquip->ZoneEquipConfig(thisADU.ZoneEqNum).ZoneName));
     719            0 :                 ShowContinueError(state, "Leakage will be ignored for this ADU.");
     720            0 :                 thisADU.UpStreamLeak = false;
     721            0 :                 thisADU.DownStreamLeak = false;
     722            0 :                 thisADU.UpStreamLeakFrac = 0.0;
     723            0 :                 thisADU.DownStreamLeakFrac = 0.0;
     724              :             }
     725              :         }
     726              : 
     727          191 :         state.dataZonePlenum->InitAirZoneReturnPlenumOneTimeFlag = false;
     728              :     }
     729              : 
     730              :     // Do the Begin Environment initializations
     731      2613527 :     if (state.dataZonePlenum->InitAirZoneReturnPlenumEnvrnFlag && state.dataGlobal->BeginEnvrnFlag) {
     732              : 
     733         3058 :         for (int PlenumZoneNum = 1; PlenumZoneNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumZoneNum) {
     734              : 
     735         1865 :             ZoneNodeNum = state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).ZoneNodeNum;
     736         1865 :             state.dataLoopNodes->Node(ZoneNodeNum).Temp = 20.0;
     737         1865 :             state.dataLoopNodes->Node(ZoneNodeNum).MassFlowRate = 0.0;
     738         1865 :             state.dataLoopNodes->Node(ZoneNodeNum).Quality = 1.0;
     739         1865 :             state.dataLoopNodes->Node(ZoneNodeNum).Press = state.dataEnvrn->OutBaroPress;
     740         1865 :             state.dataLoopNodes->Node(ZoneNodeNum).HumRat = state.dataEnvrn->OutHumRat;
     741         1865 :             state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy =
     742         1865 :                 PsyHFnTdbW(state.dataLoopNodes->Node(ZoneNodeNum).Temp, state.dataLoopNodes->Node(ZoneNodeNum).HumRat);
     743              : 
     744         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).ZoneTemp = 20.0;
     745         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).ZoneHumRat = 0.0;
     746         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).ZoneEnthalpy = 0.0;
     747         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletTemp = 0.0;
     748         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletHumRat = 0.0;
     749         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletEnthalpy = 0.0;
     750         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletPressure = 0.0;
     751         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletMassFlowRate = 0.0;
     752         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletMassFlowRateMaxAvail = 0.0;
     753         1865 :             state.dataZonePlenum->ZoneRetPlenCond(PlenumZoneNum).InletMassFlowRateMinAvail = 0.0;
     754              :         }
     755              : 
     756         1193 :         state.dataZonePlenum->InitAirZoneReturnPlenumEnvrnFlag = false;
     757              :     }
     758              : 
     759      2613527 :     if (!state.dataGlobal->BeginEnvrnFlag) {
     760      2598989 :         state.dataZonePlenum->InitAirZoneReturnPlenumEnvrnFlag = true;
     761              :     }
     762              : 
     763              :     // Transfer the node data to ZoneRetPlenCond data structure
     764     15164620 :     for (NodeNum = 1; NodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++NodeNum) {
     765              : 
     766     12551093 :         InletNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletNode(NodeNum);
     767              :         // Set all of the inlet mass flow variables from the nodes
     768     12551093 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate(NodeNum) = state.dataLoopNodes->Node(InletNode).MassFlowRate;
     769     12551093 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail(NodeNum) =
     770     12551093 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail;
     771     12551093 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail(NodeNum) =
     772     12551093 :             state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail;
     773              :         //    ! Set all of the inlet state variables from the inlet nodes
     774              :         //    ZoneRetPlenCond(ZonePlenumNum)%InletTemp(NodeNum)         = Node(InletNode)%Temp
     775              :         //    ZoneRetPlenCond(ZonePlenumNum)%InletHumRat(NodeNum)       = Node(InletNode)%HumRat
     776              :         //    ZoneRetPlenCond(ZonePlenumNum)%InletEnthalpy(NodeNum)     = Node(InletNode)%Enthalpy
     777     12551093 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletPressure(NodeNum) = state.dataLoopNodes->Node(InletNode).Press;
     778              :     }
     779              : 
     780      2613527 :     ZoneNodeNum = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeNum;
     781              :     // Set the induced air flow rates and conditions
     782      2809910 :     for (NodeNum = 1; NodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes; ++NodeNum) {
     783       196383 :         int InducedNode = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedNode(NodeNum);
     784       196383 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRate(NodeNum) = state.dataLoopNodes->Node(InducedNode).MassFlowRate;
     785       196383 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRateMaxAvail(NodeNum) =
     786       196383 :             state.dataLoopNodes->Node(InducedNode).MassFlowRateMaxAvail;
     787       196383 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRateMinAvail(NodeNum) =
     788       196383 :             state.dataLoopNodes->Node(InducedNode).MassFlowRateMinAvail;
     789              : 
     790       196383 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedTemp(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
     791       196383 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedHumRat(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).HumRat;
     792       196383 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedEnthalpy(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy;
     793       196383 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedPressure(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).Press;
     794       196383 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
     795            0 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedCO2(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).CO2;
     796              :         }
     797       196383 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
     798            0 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedGenContam(NodeNum) = state.dataLoopNodes->Node(ZoneNodeNum).GenContam;
     799              :         }
     800              :     }
     801              : 
     802              :     // Add stuff to calculate conduction inputs to the zone plenum
     803              :     // Now load the zone conditions
     804      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneTemp = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
     805      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneHumRat = state.dataLoopNodes->Node(ZoneNodeNum).HumRat;
     806      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneEnthalpy = state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy;
     807      2613527 : }
     808              : 
     809        78236 : void InitAirZoneSupplyPlenum(EnergyPlusData &state, int const ZonePlenumNum, bool const FirstHVACIteration, bool const FirstCall)
     810              : {
     811              : 
     812              :     // SUBROUTINE INFORMATION:
     813              :     //       AUTHOR         Peter Graham Ellis
     814              :     //       DATE WRITTEN   March 2000
     815              :     //       MODIFIED       na
     816              :     //       RE-ENGINEERED  na
     817              : 
     818              :     // PURPOSE OF THIS SUBROUTINE:
     819              :     // This subroutine is for initializations of the ZonePlenum components.
     820              : 
     821              :     // METHODOLOGY EMPLOYED:
     822              :     // Similar to the Zone Splitter component but with interactions to the plenum zone.
     823              : 
     824              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     825              :     int InletNode;
     826              :     int OutletNode;
     827              :     int ZoneNodeNum;
     828              :     int NodeIndex;
     829              : 
     830              :     // Do the Begin Environment initializations
     831        78236 :     if (state.dataZonePlenum->MyEnvrnFlag && state.dataGlobal->BeginEnvrnFlag) {
     832              : 
     833           92 :         for (int PlenumZoneNum = 1; PlenumZoneNum <= state.dataZonePlenum->NumZoneSupplyPlenums; ++PlenumZoneNum) {
     834              : 
     835           54 :             ZoneNodeNum = state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).ZoneNodeNum;
     836           54 :             auto &node = state.dataLoopNodes->Node(ZoneNodeNum);
     837           54 :             node.Temp = 20.0;
     838           54 :             node.MassFlowRate = 0.0;
     839           54 :             node.Quality = 1.0;
     840           54 :             node.Press = state.dataEnvrn->OutBaroPress;
     841           54 :             node.HumRat = state.dataEnvrn->OutHumRat;
     842           54 :             node.Enthalpy = PsyHFnTdbW(node.Temp, node.HumRat);
     843              : 
     844           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).ZoneTemp = 20.0;
     845           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).ZoneHumRat = 0.0;
     846           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).ZoneEnthalpy = 0.0;
     847           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletTemp = 0.0;
     848           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletHumRat = 0.0;
     849           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletEnthalpy = 0.0;
     850           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletPressure = 0.0;
     851           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletMassFlowRate = 0.0;
     852           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletMassFlowRateMaxAvail = 0.0;
     853           54 :             state.dataZonePlenum->ZoneSupPlenCond(PlenumZoneNum).InletMassFlowRateMinAvail = 0.0;
     854              :         }
     855              : 
     856           38 :         state.dataZonePlenum->MyEnvrnFlag = false;
     857              :     }
     858              : 
     859        78236 :     if (!state.dataGlobal->BeginEnvrnFlag) {
     860        77380 :         state.dataZonePlenum->MyEnvrnFlag = true;
     861              :     }
     862              : 
     863              :     // Do the following initializations (every time step): This should be the info from
     864              :     // the previous components outlets or the node data in this section.
     865              : 
     866        78236 :     InletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletNode;
     867        78236 :     auto const &inletNode = state.dataLoopNodes->Node(InletNode);
     868        78236 :     ZoneNodeNum = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeNum;
     869        78236 :     auto &zoneNode = state.dataLoopNodes->Node(ZoneNodeNum);
     870              : 
     871        78236 :     if (FirstHVACIteration && FirstCall) {
     872        19592 :         if (inletNode.MassFlowRate > 0.0) {
     873        14453 :             zoneNode.MassFlowRate = inletNode.MassFlowRate;
     874        36258 :             for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
     875        21805 :                 OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
     876        21805 :                 state.dataLoopNodes->Node(OutletNode).MassFlowRate =
     877        21805 :                     inletNode.MassFlowRate / state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes;
     878              :             }
     879              :         }
     880        19592 :         if (inletNode.MassFlowRateMaxAvail > 0.0) {
     881        14453 :             zoneNode.MassFlowRateMaxAvail = inletNode.MassFlowRateMaxAvail;
     882        36258 :             for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
     883        21805 :                 OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
     884        21805 :                 state.dataLoopNodes->Node(OutletNode).MassFlowRateMaxAvail =
     885        21805 :                     inletNode.MassFlowRateMaxAvail / state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes;
     886              :             }
     887              :         }
     888              : 
     889              :     } // For FirstHVACIteration and FirstCall
     890              : 
     891        78236 :     if (FirstCall) {
     892              : 
     893        39118 :         if (inletNode.MassFlowRateMaxAvail == 0.0) { // For Node inlet Max Avail = 0.0
     894              : 
     895        20522 :             for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
     896        10283 :                 OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
     897        10283 :                 auto &outletNode = state.dataLoopNodes->Node(OutletNode);
     898        10283 :                 outletNode.MassFlowRate = 0.0;
     899        10283 :                 outletNode.MassFlowRateMaxAvail = 0.0;
     900        10283 :                 outletNode.MassFlowRateMinAvail = 0.0;
     901              :             }
     902              : 
     903        10239 :             zoneNode.MassFlowRate = 0.0;
     904        10239 :             zoneNode.MassFlowRateMaxAvail = 0.0;
     905        10239 :             zoneNode.MassFlowRateMinAvail = 0.0;
     906              : 
     907              :         } // For Node inlet Max Avail = 0.0
     908              : 
     909              :         // Add stuff to calculate conduction inputs to the zone plenum
     910              :         // Now load the zone conditions
     911        39118 :         state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneTemp = zoneNode.Temp;
     912        39118 :         state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneHumRat = zoneNode.HumRat;
     913        39118 :         state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneEnthalpy = zoneNode.Enthalpy;
     914              : 
     915        92972 :         for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
     916        53854 :             OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
     917        53854 :             auto &outletNode = state.dataLoopNodes->Node(OutletNode);
     918        53854 :             outletNode.Press = inletNode.Press;
     919        53854 :             outletNode.Quality = inletNode.Quality;
     920              :         }
     921              : 
     922        39118 :         zoneNode.Press = inletNode.Press;
     923        39118 :         zoneNode.Quality = inletNode.Quality;
     924              : 
     925              :     } else { // On the second call from the ZoneEquipManager this is where the flows are passed back to
     926              :         // the supply plenum inlet.
     927        92972 :         for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
     928        53854 :             OutletNode = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletNode(NodeIndex);
     929        53854 :             auto const &outletNode = state.dataLoopNodes->Node(OutletNode);
     930        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRate(NodeIndex) = outletNode.MassFlowRate;
     931        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail(NodeIndex) = outletNode.MassFlowRateMaxAvail;
     932        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail(NodeIndex) = outletNode.MassFlowRateMinAvail;
     933              :         }
     934              : 
     935              :     } // For FirstCall
     936        78236 : }
     937              : 
     938      2613527 : void CalcAirZoneReturnPlenum(EnergyPlusData &state, int const ZonePlenumNum)
     939              : {
     940              : 
     941              :     // SUBROUTINE INFORMATION:
     942              :     //       AUTHOR         Peter Graham Ellis
     943              :     //       DATE WRITTEN   November 2000
     944              :     //       MODIFIED       na
     945              :     //       RE-ENGINEERED  na
     946              : 
     947              :     // Using/Aliasing
     948              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     949      2613527 :     int InletNodeNum(0);            // inlet node number
     950      2613527 :     int IndNum(0);                  // induced air index
     951      2613527 :     int ADUListIndex(0);            // air distribution unit index in zone return plenum data structure
     952      2613527 :     Real64 TotIndMassFlowRate(0.0); // total induced air mass flow rate [kg/s]
     953              : 
     954              :     // Reset the totals to zero before they are summed.
     955      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate = 0.0;
     956      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail = 0.0;
     957      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail = 0.0;
     958      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletTemp = 0.0;
     959      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletHumRat = 0.0;
     960      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure = 0.0;
     961      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletEnthalpy = 0.0;
     962      2613527 :     TotIndMassFlowRate = 0.0;
     963              : 
     964     15164620 :     for (InletNodeNum = 1; InletNodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++InletNodeNum) {
     965     12551093 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate +=
     966     12551093 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate(InletNodeNum);
     967     12551093 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail +=
     968     12551093 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail(InletNodeNum);
     969     12551093 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail +=
     970     12551093 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail(InletNodeNum);
     971              :     }
     972              : 
     973      2613527 :     if (state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate > 0.0) {
     974              : 
     975              :         // "Momentum balance" to get outlet air pressure
     976     12315490 :         for (InletNodeNum = 1; InletNodeNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInletNodes; ++InletNodeNum) {
     977              : 
     978     10185056 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure +=
     979     10185056 :                 state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletPressure(InletNodeNum) *
     980     10185056 :                 state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletMassFlowRate(InletNodeNum) /
     981     10185056 :                 state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate;
     982              :         }
     983              : 
     984              :     } else {
     985              :         // Mass Flow in air loop is zero and loop is not operating.
     986              :         // Arbitrarily set the output to the first inlet leg
     987       483093 :         state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletPressure = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InletPressure(1);
     988              :     }
     989              : 
     990              :     // add in the leak flow rate, if any. Don't alter the pressure calc (it is not used anyway)
     991     15205190 :     for (ADUListIndex = 1; ADUListIndex <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumADUs; ++ADUListIndex) {
     992     12591663 :         int ADUNum = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ADUIndex(ADUListIndex);
     993     12591663 :         if (state.dataDefineEquipment->AirDistUnit(ADUNum).UpStreamLeak || state.dataDefineEquipment->AirDistUnit(ADUNum).DownStreamLeak) {
     994       242380 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate +=
     995       242380 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateUpStrLk +
     996       242380 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateDnStrLk;
     997       242380 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail +=
     998       242380 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).MaxAvailDelta;
     999       242380 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail +=
    1000       242380 :                 state.dataDefineEquipment->AirDistUnit(ADUNum).MinAvailDelta;
    1001              :         }
    1002              :     }
    1003              :     // Sum up induced air flow rate
    1004      2809910 :     for (IndNum = 1; IndNum <= state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).NumInducedNodes; ++IndNum) {
    1005       196383 :         TotIndMassFlowRate += state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).InducedMassFlowRate(IndNum);
    1006              :     }
    1007              : 
    1008      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate -= TotIndMassFlowRate;
    1009              : 
    1010              :     // Set the Plenum Outlet to the Zone Node conditions
    1011      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletHumRat = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneHumRat;
    1012      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletEnthalpy = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneEnthalpy;
    1013      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletTemp = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneTemp;
    1014              :     // make sure the MassFlowMaxAvail >= MassFlowRate
    1015      2613527 :     state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail =
    1016      2613527 :         max(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail,
    1017      2613527 :             state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletMassFlowRate);
    1018      2613527 : }
    1019              : 
    1020        78236 : void CalcAirZoneSupplyPlenum(EnergyPlusData &state, int const ZonePlenumNum, bool const FirstCall)
    1021              : {
    1022              : 
    1023              :     // SUBROUTINE INFORMATION:
    1024              :     //       AUTHOR         Peter Graham Ellis
    1025              :     //       DATE WRITTEN   March 2000
    1026              :     //       MODIFIED       na
    1027              :     //       RE-ENGINEERED  na
    1028              : 
    1029              :     // METHODOLOGY EMPLOYED:
    1030              :     // Similar to the Zone Splitter component but with interactions to the plenum zone.
    1031              : 
    1032              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1033              :     int NodeIndex;
    1034              : 
    1035              :     // The first time through the State properties are passed through
    1036        78236 :     if (FirstCall) {
    1037              :         // Moisture balance to get outlet air humidity ratio
    1038        92972 :         for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
    1039        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletHumRat(NodeIndex) =
    1040        53854 :                 state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneHumRat;
    1041              :         }
    1042              : 
    1043              :         // Energy balance to get outlet air enthalpy
    1044        92972 :         for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
    1045        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletEnthalpy(NodeIndex) =
    1046        53854 :                 state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneEnthalpy;
    1047              :         }
    1048              : 
    1049              :         // Set outlet temperatures equal to inlet temperature
    1050        92972 :         for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
    1051        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletTemp(NodeIndex) =
    1052        53854 :                 state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneTemp;
    1053              :         }
    1054              : 
    1055              :     } else {
    1056              :         // This is the second time through and this is where the mass flows from the outlets are
    1057              :         // summed and then assigned upstream to the inlet node.
    1058        39118 :         state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRate = 0.0;
    1059        39118 :         state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail = 0.0;
    1060        39118 :         state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail = 0.0;
    1061        92972 :         for (NodeIndex = 1; NodeIndex <= state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).NumOutletNodes; ++NodeIndex) {
    1062        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRate +=
    1063        53854 :                 state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRate(NodeIndex);
    1064        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMaxAvail +=
    1065        53854 :                 state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMaxAvail(NodeIndex);
    1066        53854 :             state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletMassFlowRateMinAvail +=
    1067        53854 :                 state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).OutletMassFlowRateMinAvail(NodeIndex);
    1068              :         }
    1069              :     }
    1070        78236 : }
    1071              : 
    1072              : // End Algorithm Section of the Module
    1073              : // *****************************************************************************
    1074              : 
    1075              : // Beginning of Update subroutines for the ZonePlenum Module
    1076              : // *****************************************************************************
    1077              : 
    1078      2613527 : void UpdateAirZoneReturnPlenum(EnergyPlusData &state, int const ZonePlenumNum)
    1079              : {
    1080              : 
    1081              :     // SUBROUTINE INFORMATION:
    1082              :     //       AUTHOR         Peter Graham Ellis
    1083              :     //       DATE WRITTEN   November 2000
    1084              : 
    1085              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1086      2613527 :     auto const &zoneRetPlenCond = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum);
    1087      2613527 :     auto &outletNode = state.dataLoopNodes->Node(zoneRetPlenCond.OutletNode);
    1088      2613527 :     auto const &inletNode = state.dataLoopNodes->Node(zoneRetPlenCond.InletNode(1));
    1089      2613527 :     auto &zoneNode = state.dataLoopNodes->Node(zoneRetPlenCond.ZoneNodeNum);
    1090              : 
    1091              :     // Set the outlet air nodes of the ZonePlenum
    1092      2613527 :     outletNode.MassFlowRate = zoneRetPlenCond.OutletMassFlowRate;
    1093      2613527 :     outletNode.MassFlowRateMaxAvail = zoneRetPlenCond.OutletMassFlowRateMaxAvail;
    1094      2613527 :     outletNode.MassFlowRateMinAvail = zoneRetPlenCond.OutletMassFlowRateMinAvail;
    1095              : 
    1096      2613527 :     zoneNode.MassFlowRate = zoneRetPlenCond.OutletMassFlowRate;
    1097      2613527 :     zoneNode.MassFlowRateMaxAvail = zoneRetPlenCond.OutletMassFlowRateMaxAvail;
    1098      2613527 :     zoneNode.MassFlowRateMinAvail = zoneRetPlenCond.OutletMassFlowRateMinAvail;
    1099      2613527 :     zoneNode.Press = zoneRetPlenCond.OutletPressure;
    1100              : 
    1101      2613527 :     outletNode.Temp = zoneRetPlenCond.OutletTemp;
    1102      2613527 :     outletNode.HumRat = zoneRetPlenCond.OutletHumRat;
    1103      2613527 :     outletNode.Enthalpy = zoneRetPlenCond.OutletEnthalpy;
    1104      2613527 :     outletNode.Press = zoneRetPlenCond.OutletPressure;
    1105      2809910 :     for (int IndNum = 1; IndNum <= zoneRetPlenCond.NumInducedNodes; ++IndNum) {
    1106       196383 :         int InducedNode = zoneRetPlenCond.InducedNode(IndNum);
    1107       196383 :         auto &inducedNode = state.dataLoopNodes->Node(InducedNode);
    1108       196383 :         inducedNode.Temp = zoneRetPlenCond.InducedTemp(IndNum);
    1109       196383 :         inducedNode.HumRat = zoneRetPlenCond.InducedHumRat(IndNum);
    1110       196383 :         inducedNode.Enthalpy = zoneRetPlenCond.InducedEnthalpy(IndNum);
    1111       196383 :         inducedNode.Press = zoneRetPlenCond.InducedPressure(IndNum);
    1112       196383 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1113            0 :             inducedNode.CO2 = zoneRetPlenCond.InducedCO2(IndNum);
    1114              :         }
    1115       196383 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    1116            0 :             inducedNode.GenContam = zoneRetPlenCond.InducedGenContam(IndNum);
    1117              :         }
    1118       196383 :         inducedNode.Quality = inletNode.Quality;
    1119              :     }
    1120              : 
    1121              :     // Set the outlet nodes for properties that are just pass through and not used
    1122      2613527 :     outletNode.Quality = inletNode.Quality;
    1123      2613527 :     zoneNode.Quality = inletNode.Quality;
    1124              : 
    1125              :     // Set the outlet node contaminant properties if needed. The zone contaminant conditions are calculated in ZoneContaminantPredictorCorrector
    1126      2613527 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1127            0 :         if (zoneRetPlenCond.OutletMassFlowRate > 0.0) {
    1128              :             // CO2 balance to get outlet air CO2
    1129            0 :             outletNode.CO2 = 0.0;
    1130            0 :             for (int InletNodeNum = 1; InletNodeNum <= zoneRetPlenCond.NumInletNodes; ++InletNodeNum) {
    1131            0 :                 outletNode.CO2 += state.dataLoopNodes->Node(zoneRetPlenCond.InletNode(InletNodeNum)).CO2 *
    1132            0 :                                   zoneRetPlenCond.InletMassFlowRate(InletNodeNum) / zoneRetPlenCond.OutletMassFlowRate;
    1133              :             }
    1134            0 :             zoneNode.CO2 = outletNode.CO2;
    1135              :         } else {
    1136            0 :             outletNode.CO2 = zoneNode.CO2;
    1137              :         }
    1138              :     }
    1139      2613527 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    1140            0 :         if (zoneRetPlenCond.OutletMassFlowRate > 0.0) {
    1141              :             // GenContam balance to get outlet air GenContam
    1142            0 :             outletNode.GenContam = 0.0;
    1143            0 :             for (int InletNodeNum = 1; InletNodeNum <= zoneRetPlenCond.NumInletNodes; ++InletNodeNum) {
    1144            0 :                 outletNode.GenContam += state.dataLoopNodes->Node(zoneRetPlenCond.InletNode(InletNodeNum)).GenContam *
    1145            0 :                                         zoneRetPlenCond.InletMassFlowRate(InletNodeNum) / zoneRetPlenCond.OutletMassFlowRate;
    1146              :             }
    1147            0 :             zoneNode.GenContam = outletNode.GenContam;
    1148              :         } else {
    1149            0 :             outletNode.GenContam = zoneNode.GenContam;
    1150              :         }
    1151              :     }
    1152      2613527 : }
    1153              : 
    1154        78236 : void UpdateAirZoneSupplyPlenum(EnergyPlusData &state, int const ZonePlenumNum, bool &PlenumInletChanged, bool const FirstCall)
    1155              : {
    1156              : 
    1157              :     // SUBROUTINE INFORMATION:
    1158              :     //       AUTHOR         Peter Graham Ellis
    1159              :     //       DATE WRITTEN   March 2000
    1160              : 
    1161              :     // METHODOLOGY EMPLOYED:
    1162              :     // Similar to the Zone Splitter component but with interactions to the plenum zone.
    1163              : 
    1164              :     // SUBROUTINE PARAMETER DEFINITIONS:
    1165        78236 :     Real64 constexpr FlowRateToler = 0.01; // Tolerance for mass flow rate convergence (in kg/s)
    1166              : 
    1167              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1168        78236 :     auto const &zoneSupPlenCon = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum);
    1169        78236 :     auto &inletNode = state.dataLoopNodes->Node(zoneSupPlenCon.InletNode);
    1170        78236 :     auto &zoneNode = state.dataLoopNodes->Node(zoneSupPlenCon.ZoneNodeNum);
    1171              : 
    1172              :     // On the FirstCall the State properties are passed through and the mass flows are not dealt with
    1173        78236 :     if (FirstCall) {
    1174              :         // Set the outlet nodes for properties that just pass through and not used
    1175        92972 :         for (int NodeIndex = 1; NodeIndex <= zoneSupPlenCon.NumOutletNodes; ++NodeIndex) {
    1176        53854 :             int OutletNode = zoneSupPlenCon.OutletNode(NodeIndex);
    1177        53854 :             auto &outletNode = state.dataLoopNodes->Node(OutletNode);
    1178        53854 :             outletNode.Temp = zoneSupPlenCon.OutletTemp(NodeIndex);
    1179        53854 :             outletNode.HumRat = zoneSupPlenCon.OutletHumRat(NodeIndex);
    1180        53854 :             outletNode.Enthalpy = zoneSupPlenCon.OutletEnthalpy(NodeIndex);
    1181        53854 :             if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1182            0 :                 outletNode.CO2 = inletNode.CO2;
    1183              :             }
    1184        53854 :             if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    1185            0 :                 outletNode.GenContam = inletNode.GenContam;
    1186              :             }
    1187              :         }
    1188              : 
    1189        39118 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1190            0 :             zoneNode.CO2 = inletNode.CO2;
    1191              :         }
    1192        39118 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
    1193            0 :             zoneNode.GenContam = inletNode.GenContam;
    1194              :         }
    1195              : 
    1196              :     } else {
    1197              :         // The second time through just updates the mass flow conditions back upstream to the inlet.
    1198        39118 :         if (std::abs(inletNode.MassFlowRate - zoneSupPlenCon.InletMassFlowRate) > FlowRateToler) {
    1199        10027 :             PlenumInletChanged = true;
    1200              :         }
    1201              : 
    1202        39118 :         inletNode.MassFlowRate = zoneSupPlenCon.InletMassFlowRate;
    1203        39118 :         inletNode.MassFlowRateMaxAvail = zoneSupPlenCon.InletMassFlowRateMaxAvail;
    1204        39118 :         inletNode.MassFlowRateMinAvail = zoneSupPlenCon.InletMassFlowRateMinAvail;
    1205              : 
    1206        39118 :         zoneNode.MassFlowRate = zoneSupPlenCon.InletMassFlowRate;
    1207        39118 :         zoneNode.MassFlowRateMaxAvail = zoneSupPlenCon.InletMassFlowRateMaxAvail;
    1208        39118 :         zoneNode.MassFlowRateMinAvail = zoneSupPlenCon.InletMassFlowRateMinAvail;
    1209              : 
    1210              :     } // For FirstCall
    1211        78236 : }
    1212              : 
    1213            5 : int GetReturnPlenumIndex(EnergyPlusData &state, int const ExNodeNum)
    1214              : {
    1215              : 
    1216              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1217              :     int WhichPlenum; // index to return plenum
    1218              : 
    1219              :     // Obtains and Allocates ZonePlenum related parameters from input file
    1220            5 :     if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
    1221            1 :         GetZonePlenumInput(state);
    1222            1 :         state.dataZonePlenum->GetInputFlag = false;
    1223              :     }
    1224              : 
    1225            5 :     WhichPlenum = 0;
    1226            5 :     if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
    1227            9 :         for (int PlenumNum = 1; PlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumNum) {
    1228            5 :             if (ExNodeNum != state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).OutletNode) {
    1229            4 :                 continue;
    1230              :             }
    1231            1 :             WhichPlenum = PlenumNum;
    1232            1 :             break;
    1233              :         }
    1234            5 :         if (WhichPlenum == 0) {
    1235            4 :             for (int PlenumNum = 1; PlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumNum) {
    1236           10 :                 for (int InducedNodeNum = 1; InducedNodeNum <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInducedNodes; ++InducedNodeNum) {
    1237           10 :                     if (ExNodeNum != state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InducedNode(InducedNodeNum)) {
    1238            6 :                         continue;
    1239              :                     }
    1240            4 :                     WhichPlenum = PlenumNum;
    1241            4 :                     break;
    1242              :                 }
    1243            4 :                 if (WhichPlenum > 0) {
    1244            4 :                     break;
    1245              :                 }
    1246              :             }
    1247              :         }
    1248              :     }
    1249              : 
    1250            5 :     return WhichPlenum;
    1251              : }
    1252              : 
    1253            5 : void GetReturnPlenumName(EnergyPlusData &state, int const ReturnPlenumIndex, std::string &ReturnPlenumName)
    1254              : {
    1255              : 
    1256              :     // Obtains and Allocates ZonePlenum related parameters from input file
    1257            5 :     if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
    1258            0 :         GetZonePlenumInput(state);
    1259            0 :         state.dataZonePlenum->GetInputFlag = false;
    1260              :     }
    1261              : 
    1262            5 :     ReturnPlenumName = " ";
    1263            5 :     if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
    1264            5 :         ReturnPlenumName = state.dataZonePlenum->ZoneRetPlenCond(ReturnPlenumIndex).ZonePlenumName;
    1265              :     }
    1266            5 : }
    1267              : 
    1268            4 : int getReturnPlenumIndexFromInletNode(EnergyPlusData &state, int const InNodeNum)
    1269              : {
    1270              : 
    1271              :     // Obtains and Allocates ZonePlenum related parameters from input file
    1272            4 :     if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
    1273            4 :         GetZonePlenumInput(state);
    1274            4 :         state.dataZonePlenum->GetInputFlag = false;
    1275              :     }
    1276              : 
    1277            4 :     int thisPlenum = 0;
    1278            4 :     if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
    1279            0 :         for (int PlenumNum = 1; PlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumNum) {
    1280            0 :             for (int InNodeCtr = 1; InNodeCtr <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInletNodes; ++InNodeCtr) {
    1281            0 :                 if (InNodeNum != state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InletNode(InNodeCtr)) {
    1282            0 :                     continue;
    1283              :                 }
    1284            0 :                 thisPlenum = PlenumNum;
    1285            0 :                 break;
    1286              :             }
    1287            0 :             if (thisPlenum > 0) {
    1288            0 :                 break;
    1289              :             }
    1290              :         }
    1291              :     }
    1292              : 
    1293            4 :     return thisPlenum;
    1294              : }
    1295              : 
    1296            3 : bool ValidateInducedNode(EnergyPlusData &state, int const InduceNodeNum, int const NumReturnNodes, Array1D<int> const &ReturnNode)
    1297              : {
    1298              :     // Ensure induced node is used as inlet node of zoe equipment
    1299            3 :     bool Nodefound = false;
    1300              : 
    1301              :     // Obtains and Allocates ZonePlenum related parameters from input file
    1302            3 :     if (state.dataZonePlenum->GetInputFlag) { // First time subroutine has been entered
    1303            1 :         GetZonePlenumInput(state);
    1304            1 :         state.dataZonePlenum->GetInputFlag = false;
    1305              :     }
    1306              : 
    1307            3 :     if (state.dataZonePlenum->NumZoneReturnPlenums > 0) {
    1308            3 :         for (int PlenumNum = 1; PlenumNum <= state.dataZonePlenum->NumZoneReturnPlenums; ++PlenumNum) {
    1309            6 :             for (int InduceNodeCtr = 1; InduceNodeCtr <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInducedNodes; ++InduceNodeCtr) {
    1310            6 :                 if (InduceNodeNum == state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InducedNode(InduceNodeCtr)) {
    1311           10 :                     for (int InNodeCtr = 1; InNodeCtr <= state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).NumInletNodes; ++InNodeCtr) {
    1312           17 :                         for (int ReturnNodeNum = 1; ReturnNodeNum <= NumReturnNodes; ++ReturnNodeNum) {
    1313           10 :                             if (ReturnNode(ReturnNodeNum) != state.dataZonePlenum->ZoneRetPlenCond(PlenumNum).InletNode(InNodeCtr)) {
    1314            7 :                                 continue;
    1315              :                             }
    1316            3 :                             Nodefound = true;
    1317            3 :                             break;
    1318              :                         }
    1319           10 :                         if (Nodefound) {
    1320            3 :                             break;
    1321              :                         }
    1322              :                     }
    1323              :                 }
    1324            6 :                 if (Nodefound) {
    1325            3 :                     break;
    1326              :                 }
    1327              :             }
    1328            3 :             if (Nodefound) {
    1329            3 :                 break;
    1330              :             }
    1331              :         }
    1332              :     }
    1333              : 
    1334            3 :     return Nodefound;
    1335              : }
    1336              : 
    1337              : } // namespace EnergyPlus::ZonePlenum
        

Generated by: LCOV version 2.0-1