LCOV - code coverage report
Current view: top level - EnergyPlus - MundtSimMgr.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 265 299 88.6 %
Date: 2024-08-24 18:31:18 Functions: 8 8 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // ObjexxFCL Headers
      49             : #include <ObjexxFCL/Array.functions.hh>
      50             : #include <ObjexxFCL/Fmath.hh>
      51             : 
      52             : // EnergyPlus Headers
      53             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      54             : #include <EnergyPlus/DataEnvironment.hh>
      55             : #include <EnergyPlus/DataHeatBalFanSys.hh>
      56             : #include <EnergyPlus/DataHeatBalSurface.hh>
      57             : #include <EnergyPlus/DataHeatBalance.hh>
      58             : #include <EnergyPlus/DataLoopNode.hh>
      59             : #include <EnergyPlus/DataRoomAirModel.hh>
      60             : #include <EnergyPlus/DataSurfaces.hh>
      61             : #include <EnergyPlus/DataZoneEquipment.hh>
      62             : #include <EnergyPlus/InternalHeatGains.hh>
      63             : #include <EnergyPlus/MundtSimMgr.hh>
      64             : #include <EnergyPlus/OutputProcessor.hh>
      65             : #include <EnergyPlus/Psychrometrics.hh>
      66             : #include <EnergyPlus/UtilityRoutines.hh>
      67             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      68             : 
      69             : namespace EnergyPlus {
      70             : 
      71             : namespace RoomAir {
      72             : 
      73             :     // MODULE INFORMATION:
      74             :     //       AUTHOR         Brent Griffith
      75             :     //       DATE WRITTEN   February 2002
      76             :     //       RE-ENGINEERED  June 2003, EnergyPlus Implementation (CC)
      77             :     //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
      78             : 
      79             :     // PURPOSE OF THIS MODULE:
      80             :     // This module is the main module for running the
      81             :     // nodal air Mundt model...
      82             : 
      83             :     // METHODOLOGY EMPLOYED:
      84             :     // This module contains all subroutines required by the mundt model.
      85             :     // The following modules from AirToolkit included in this module are:
      86             :     // 1) MundtSimMgr Module,
      87             :     // 2) MundtInputMgr Module, and
      88             :     // 3) DataMundt Module,
      89             : 
      90             :     // REFERENCES:
      91             :     // AirToolkit source code
      92             : 
      93             :     // OTHER NOTES:
      94             :     // na
      95             : 
      96             :     // Data
      97             :     // MODULE PARAMETER DEFINITIONS:
      98             :     Real64 constexpr CpAir(1005.0);   // Specific heat of air
      99             :     Real64 constexpr MinSlope(0.001); // Bound on result from Mundt model
     100             :     Real64 constexpr MaxSlope(5.0);   // Bound on result from Mundt Model
     101             : 
     102             :     // MODULE VARIABLE DECLARATIONS:
     103             : 
     104       17080 :     void ManageDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     105             :     {
     106             : 
     107             :         // SUBROUTINE INFORMATION:
     108             :         //       AUTHOR         Chanvit Chantrasrisalai
     109             :         //       DATE WRITTEN   July 2003
     110             :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     111             :         //       RE-ENGINEERED  na
     112             : 
     113             :         // PURPOSE OF THIS SUBROUTINE:
     114             :         //   manage the Mundt model
     115             : 
     116             :         bool ErrorsFound;
     117             : 
     118             :         // initialize Mundt model data
     119       17080 :         if (state.dataHeatBal->MundtFirstTimeFlag) {
     120           2 :             InitDispVent1Node(state);
     121           2 :             state.dataHeatBal->MundtFirstTimeFlag = false;
     122             :         }
     123             : 
     124             :         // identify the current zone index for zones using Mundt model
     125       17080 :         state.dataMundtSimMgr->MundtZoneNum = state.dataMundtSimMgr->ZoneData(ZoneNum).MundtZoneIndex;
     126             : 
     127             :         // transfer data from surface domain to air domain for the specified zone
     128       17080 :         GetSurfHBDataForDispVent1Node(state, ZoneNum);
     129             : 
     130             :         // use the Mundt model only for cooling case
     131       17080 :         if ((state.dataMundtSimMgr->SupplyAirVolumeRate > 0.0001) && (state.dataMundtSimMgr->QsysCoolTot > 0.0001)) {
     132             : 
     133             :             // setup Mundt model
     134        8626 :             ErrorsFound = false;
     135        8626 :             SetupDispVent1Node(state, ZoneNum, ErrorsFound);
     136        8626 :             if (ErrorsFound) ShowFatalError(state, "ManageMundtModel: Errors in setting up Mundt Model. Preceding condition(s) cause termination.");
     137             : 
     138             :             // perform Mundt model calculations
     139        8626 :             CalcDispVent1Node(state, ZoneNum);
     140             :         }
     141             : 
     142             :         // transfer data from air domain back to surface domain for the specified zone
     143       17080 :         SetSurfHBDataForDispVent1Node(state, ZoneNum);
     144       17080 :     }
     145             : 
     146             :     //*****************************************************************************************
     147             : 
     148           2 :     void InitDispVent1Node(EnergyPlusData &state)
     149             :     {
     150             : 
     151             :         // SUBROUTINE INFORMATION:
     152             :         //       AUTHOR         Chanvit Chantrasrisalai
     153             :         //       DATE WRITTEN   February 2004
     154             :         //       MODIFIED       na
     155             :         //       RE-ENGINEERED  na
     156             : 
     157             :         // PURPOSE OF THIS SUBROUTINE:
     158             :         //     initialize Mundt-model variables
     159             : 
     160             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     161             :         int NodeNum;            // index for air nodes
     162             :         int ZoneIndex;          // index for zones
     163             :         int NumOfAirNodes;      // total number of nodes in each zone
     164             :         int NumOfMundtZones;    // number of zones using the Mundt model
     165             :         int MundtZoneIndex;     // index for zones using the Mundt model
     166             :         int MaxNumOfSurfs;      // maximum of number of surfaces
     167             :         int MaxNumOfFloorSurfs; // maximum of number of surfaces
     168             :         int MaxNumOfAirNodes;   // maximum of number of air nodes
     169             :         int MaxNumOfRoomNodes;  // maximum of number of nodes connected to walls
     170             :         int RoomNodesCount;     // number of nodes connected to walls
     171             :         int FloorSurfCount;     // number of nodes connected to walls
     172             :         int AirNodeBeginNum;    // index number of the first air node for this zone
     173             :         int AirNodeNum;         // index for air nodes
     174             :         bool AirNodeFoundFlag;  // flag used for error check
     175             :         bool ErrorsFound;       // true if errors found in init
     176             : 
     177             :         // allocate and initialize zone data
     178           2 :         state.dataMundtSimMgr->ZoneData.allocate(state.dataGlobal->NumOfZones);
     179          10 :         for (auto &e : state.dataMundtSimMgr->ZoneData) {
     180           8 :             e.NumOfSurfs = 0;
     181           8 :             e.MundtZoneIndex = 0;
     182             :         }
     183             : 
     184             :         // get zone data
     185           2 :         NumOfMundtZones = 0;
     186           2 :         MaxNumOfSurfs = 0;
     187           2 :         MaxNumOfFloorSurfs = 0;
     188           2 :         MaxNumOfAirNodes = 0;
     189           2 :         MaxNumOfRoomNodes = 0;
     190           2 :         ErrorsFound = false;
     191          10 :         for (ZoneIndex = 1; ZoneIndex <= state.dataGlobal->NumOfZones; ++ZoneIndex) {
     192           8 :             auto &thisZone = state.dataHeatBal->Zone(ZoneIndex);
     193           8 :             if (state.dataRoomAir->AirModel(ZoneIndex).AirModel == RoomAir::RoomAirModel::DispVent1Node) {
     194             :                 // find number of zones using the Mundt model
     195           4 :                 ++NumOfMundtZones;
     196             :                 // find maximum number of surfaces in zones using the Mundt model
     197           4 :                 int NumOfSurfs = 0;
     198           8 :                 for (int spaceNum : thisZone.spaceIndexes) {
     199           4 :                     auto &thisSpace = state.dataHeatBal->space(spaceNum);
     200          92 :                     for (int surfNum = thisSpace.HTSurfaceFirst; surfNum <= thisSpace.HTSurfaceLast; ++surfNum) {
     201          88 :                         state.dataMundtSimMgr->ZoneData(ZoneIndex).HBsurfaceIndexes.emplace_back(surfNum);
     202          88 :                         ++NumOfSurfs;
     203             :                     }
     204           4 :                     MaxNumOfSurfs = max(MaxNumOfSurfs, NumOfSurfs);
     205             :                     // find maximum number of air nodes in zones using the Mundt model
     206           4 :                     NumOfAirNodes = state.dataRoomAir->TotNumOfZoneAirNodes(ZoneIndex);
     207           4 :                     MaxNumOfAirNodes = max(MaxNumOfAirNodes, NumOfAirNodes);
     208             :                     // assign zone data
     209           4 :                     state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs = NumOfSurfs;
     210           4 :                     state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex = NumOfMundtZones;
     211           4 :                 }
     212             :             }
     213             :         }
     214             : 
     215             :         // allocate and initialize surface and air-node data
     216           2 :         state.dataMundtSimMgr->ID1dSurf.allocate(MaxNumOfSurfs);
     217           2 :         state.dataMundtSimMgr->TheseSurfIDs.allocate(MaxNumOfSurfs);
     218           2 :         state.dataMundtSimMgr->MundtAirSurf.allocate(MaxNumOfSurfs, NumOfMundtZones);
     219           2 :         state.dataMundtSimMgr->LineNode.allocate(MaxNumOfAirNodes, NumOfMundtZones);
     220          46 :         for (int SurfNum = 1; SurfNum <= MaxNumOfSurfs; ++SurfNum)
     221          44 :             state.dataMundtSimMgr->ID1dSurf(SurfNum) = SurfNum;
     222          90 :         for (auto &e : state.dataMundtSimMgr->MundtAirSurf) {
     223          88 :             e.Area = 0.0;
     224          88 :             e.Temp = 25.0;
     225          88 :             e.Hc = 0.0;
     226          88 :             e.TMeanAir = 25.0;
     227             :         }
     228          38 :         for (auto &e : state.dataMundtSimMgr->LineNode) {
     229          36 :             e.AirNodeName.clear();
     230          36 :             e.ClassType = RoomAir::AirNodeType::Invalid;
     231          36 :             e.Height = 0.0;
     232          36 :             e.Temp = 25.0;
     233             :         }
     234             : 
     235             :         // get constant data (unchanged over time) for surfaces and air nodes
     236           6 :         for (MundtZoneIndex = 1; MundtZoneIndex <= NumOfMundtZones; ++MundtZoneIndex) {
     237          10 :             for (ZoneIndex = 1; ZoneIndex <= state.dataGlobal->NumOfZones; ++ZoneIndex) {
     238          10 :                 auto &thisZone = state.dataHeatBal->Zone(ZoneIndex);
     239          10 :                 if (state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex == MundtZoneIndex) {
     240             :                     // get surface data
     241          92 :                     for (int surfNum = 1; surfNum <= state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs; ++surfNum) {
     242          88 :                         state.dataMundtSimMgr->MundtAirSurf(surfNum, MundtZoneIndex).Area =
     243          88 :                             state.dataSurface->Surface(state.dataMundtSimMgr->ZoneData(ZoneIndex).HBsurfaceIndexes(surfNum)).Area;
     244             :                     }
     245             : 
     246             :                     // get air node data
     247           4 :                     RoomNodesCount = 0;
     248           4 :                     FloorSurfCount = 0;
     249          40 :                     for (NodeNum = 1; NodeNum <= state.dataRoomAir->TotNumOfZoneAirNodes(ZoneIndex); ++NodeNum) {
     250             : 
     251          36 :                         state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex)
     252          36 :                             .SurfMask.allocate(state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs);
     253             : 
     254          36 :                         if (NodeNum == 1) {
     255           4 :                             AirNodeBeginNum = NodeNum;
     256             :                         }
     257             : 
     258             :                         // error check for debugging
     259          36 :                         if (AirNodeBeginNum > state.dataRoomAir->TotNumOfAirNodes) {
     260           0 :                             ShowFatalError(state, "An array bound exceeded. Error in InitMundtModel subroutine of MundtSimMgr.");
     261             :                         }
     262             : 
     263          36 :                         AirNodeFoundFlag = false;
     264          54 :                         for (AirNodeNum = AirNodeBeginNum; AirNodeNum <= state.dataRoomAir->TotNumOfAirNodes; ++AirNodeNum) {
     265          54 :                             if (Util::SameString(state.dataRoomAir->AirNode(AirNodeNum).ZoneName, thisZone.Name)) {
     266          36 :                                 state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType = state.dataRoomAir->AirNode(AirNodeNum).ClassType;
     267          36 :                                 state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).AirNodeName = state.dataRoomAir->AirNode(AirNodeNum).Name;
     268          36 :                                 state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).Height = state.dataRoomAir->AirNode(AirNodeNum).Height;
     269          36 :                                 state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).SurfMask = state.dataRoomAir->AirNode(AirNodeNum).SurfMask;
     270          72 :                                 SetupOutputVariable(state,
     271             :                                                     "Room Air Node Air Temperature",
     272             :                                                     Constant::Units::C,
     273          36 :                                                     state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).Temp,
     274             :                                                     OutputProcessor::TimeStepType::System,
     275             :                                                     OutputProcessor::StoreType::Average,
     276          36 :                                                     state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).AirNodeName);
     277             : 
     278          36 :                                 AirNodeBeginNum = AirNodeNum + 1;
     279          36 :                                 AirNodeFoundFlag = true;
     280             : 
     281          36 :                                 break;
     282             :                             }
     283             :                         }
     284             : 
     285             :                         // error check for debugging
     286          36 :                         if (!AirNodeFoundFlag) {
     287           0 :                             ShowSevereError(state, format("InitMundtModel: Air Node in Zone=\"{}\" is not found.", thisZone.Name));
     288           0 :                             ErrorsFound = true;
     289           0 :                             continue;
     290             :                         }
     291             : 
     292             :                         // count air nodes connected to walls in each zone
     293          36 :                         if (state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType == RoomAir::AirNodeType::Mundt) {
     294          16 :                             ++RoomNodesCount;
     295             :                         }
     296             : 
     297             :                         // count floors in each zone
     298          36 :                         if (state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType == RoomAir::AirNodeType::Floor) {
     299           4 :                             FloorSurfCount += count(state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).SurfMask);
     300             :                         }
     301             :                     }
     302             :                     // got data for this zone so exit the zone loop
     303           4 :                     if (AirNodeFoundFlag) break;
     304             :                 }
     305             :             }
     306             : 
     307           4 :             MaxNumOfRoomNodes = max(MaxNumOfRoomNodes, RoomNodesCount);
     308           4 :             MaxNumOfFloorSurfs = max(MaxNumOfFloorSurfs, FloorSurfCount);
     309             :         }
     310             : 
     311           2 :         if (ErrorsFound) ShowFatalError(state, "InitMundtModel: Preceding condition(s) cause termination.");
     312             : 
     313             :         // allocate arrays
     314           2 :         state.dataMundtSimMgr->RoomNodeIDs.allocate(MaxNumOfRoomNodes);
     315           2 :         state.dataMundtSimMgr->FloorSurfSetIDs.allocate(MaxNumOfFloorSurfs);
     316           2 :         state.dataMundtSimMgr->FloorSurf.allocate(MaxNumOfFloorSurfs);
     317           2 :     }
     318             : 
     319             :     //*****************************************************************************************
     320             : 
     321       17080 :     void GetSurfHBDataForDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     322             :     {
     323             : 
     324             :         // SUBROUTINE INFORMATION:
     325             :         //       AUTHOR         Weixiu Kong
     326             :         //       DATE WRITTEN   April 2003
     327             :         //       MODIFIED       July 2003 (CC)
     328             :         //                      February 2004, fix allocate-deallocate problem (CC)
     329             : 
     330             :         // PURPOSE OF THIS SUBROUTINE:
     331             :         //     map data from surface domain to air domain for each particular zone
     332             : 
     333             :         using Psychrometrics::PsyCpAirFnW;
     334             :         using Psychrometrics::PsyRhoAirFnPbTdbW;
     335             :         using Psychrometrics::PsyWFnTdpPb;
     336             : 
     337             :         Real64 CpAir;            // specific heat
     338             :         int NodeNum;             // index for air nodes
     339             :         Real64 SumSysMCp;        // zone sum of air system MassFlowRate*Cp
     340             :         Real64 SumSysMCpT;       // zone sum of air system MassFlowRate*Cp*T
     341             :         Real64 MassFlowRate;     // mass flowrate
     342             :         Real64 NodeTemp;         // node temperature
     343             :         int ZoneNode;            // index number for specified zone node
     344             :         Real64 ZoneMassFlowRate; // zone mass flowrate
     345             :         int ZoneEquipConfigNum;  // index number for zone equipment configuration
     346             :         Real64 ZoneMult;         // total zone multiplier
     347             :         Real64 RetAirConvGain;
     348             : 
     349       17080 :         auto &Zone(state.dataHeatBal->Zone);
     350             : 
     351             :         // determine ZoneEquipConfigNum for this zone
     352       17080 :         ZoneEquipConfigNum = ZoneNum;
     353             :         // check whether this zone is a controlled zone or not
     354       17080 :         if (!Zone(ZoneNum).IsControlled) {
     355           0 :             ShowFatalError(state, format("Zones must be controlled for Mundt air model. No system serves zone {}", Zone(ZoneNum).Name));
     356           0 :             return;
     357             :         }
     358             : 
     359             :         // determine information required by Mundt model
     360       17080 :         state.dataMundtSimMgr->ZoneHeight = Zone(ZoneNum).CeilingHeight;
     361       17080 :         state.dataMundtSimMgr->ZoneFloorArea = Zone(ZoneNum).FloorArea;
     362       17080 :         ZoneMult = Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier;
     363             : 
     364             :         // supply air flowrate is the same as zone air flowrate
     365       17080 :         ZoneNode = Zone(ZoneNum).SystemZoneNodeNumber;
     366       34160 :         state.dataMundtSimMgr->ZoneAirDensity =
     367       34160 :             PsyRhoAirFnPbTdbW(state,
     368       17080 :                               state.dataEnvrn->OutBaroPress,
     369       17080 :                               state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT,
     370       17080 :                               PsyWFnTdpPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT, state.dataEnvrn->OutBaroPress));
     371       17080 :         ZoneMassFlowRate = state.dataLoopNodes->Node(ZoneNode).MassFlowRate;
     372       17080 :         state.dataMundtSimMgr->SupplyAirVolumeRate = ZoneMassFlowRate / state.dataMundtSimMgr->ZoneAirDensity;
     373       17080 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     374       17080 :         if (ZoneMassFlowRate <= 0.0001) {
     375             :             // system is off
     376         351 :             state.dataMundtSimMgr->QsysCoolTot = 0.0;
     377             :         } else {
     378             :             // determine supply air conditions
     379       16729 :             SumSysMCp = 0.0;
     380       16729 :             SumSysMCpT = 0.0;
     381       33458 :             for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).NumInletNodes; ++NodeNum) {
     382       16729 :                 NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).Temp;
     383       16729 :                 MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).MassFlowRate;
     384       16729 :                 CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
     385       16729 :                 SumSysMCp += MassFlowRate * CpAir;
     386       16729 :                 SumSysMCpT += MassFlowRate * CpAir * NodeTemp;
     387             :             }
     388             :             // prevent dividing by zero due to zero supply air flow rate
     389       16729 :             if (SumSysMCp <= 0.0) {
     390           0 :                 state.dataMundtSimMgr->SupplyAirTemp =
     391           0 :                     state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(1)).Temp;
     392             :             } else {
     393             :                 // a weighted average of the inlet temperatures
     394       16729 :                 state.dataMundtSimMgr->SupplyAirTemp = SumSysMCpT / SumSysMCp;
     395             :             }
     396             :             // determine cooling load
     397       16729 :             CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
     398       16729 :             state.dataMundtSimMgr->QsysCoolTot =
     399       16729 :                 -(SumSysMCpT - ZoneMassFlowRate * CpAir * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
     400             :         }
     401             :         // determine heat gains
     402       17080 :         state.dataMundtSimMgr->ConvIntGain = InternalHeatGains::zoneSumAllInternalConvectionGains(state, ZoneNum);
     403       17080 :         state.dataMundtSimMgr->ConvIntGain += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) +
     404       17080 :                                               thisZoneHB.SysDepZoneLoadsLagged + thisZoneHB.NonAirSystemResponse / ZoneMult;
     405             : 
     406             :         // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very
     407             :         // low or zero)
     408       17080 :         if (Zone(ZoneNum).NoHeatToReturnAir) {
     409           0 :             RetAirConvGain = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, 0);
     410           0 :             state.dataMundtSimMgr->ConvIntGain += RetAirConvGain;
     411             :         }
     412             : 
     413       34160 :         state.dataMundtSimMgr->QventCool =
     414       17080 :             -thisZoneHB.MCPI * (Zone(ZoneNum).OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
     415             : 
     416             :         // get surface data
     417      392840 :         for (int SurfNum = 1; SurfNum <= state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs; ++SurfNum) {
     418      375760 :             state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).Temp =
     419      375760 :                 state.dataHeatBalSurf->SurfTempIn(state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum));
     420      375760 :             state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).Hc =
     421      375760 :                 state.dataHeatBalSurf->SurfHConvInt(state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum));
     422             :         }
     423             :     }
     424             : 
     425             :     //*****************************************************************************************
     426             : 
     427        8626 :     void SetupDispVent1Node(EnergyPlusData &state,
     428             :                             int const ZoneNum, // index number for the specified zone
     429             :                             bool &ErrorsFound  // true if problems setting up model
     430             :     )
     431             :     {
     432             : 
     433             :         // SUBROUTINE INFORMATION:
     434             :         //       AUTHOR         Brent Griffith
     435             :         //       DATE WRITTEN   Febraury 2002
     436             :         //       RE-ENGINEERED  June 2003, EnergyPlus Implementation (CC)
     437             :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     438             : 
     439             :         // PURPOSE OF THIS SUBROUTINE:
     440             :         //   Subroutine must be called once before main model calculation
     441             :         //   need to pass some zone characteristics only once
     442             :         //   initializes module level variables, collect info from Air Data Manager
     443             : 
     444             :         // METHODOLOGY EMPLOYED:
     445             :         // na
     446             : 
     447             :         // REFERENCES:
     448             :         // na
     449             : 
     450             :         // Locals
     451             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     452             : 
     453             :         // SUBROUTINE PARAMETER DEFINITIONS:
     454             :         // na
     455             : 
     456             :         // INTERFACE BLOCK SPECIFICATIONS:
     457             :         // na
     458             : 
     459             :         // DERIVED TYPE DEFINITIONS:
     460             :         // na
     461             : 
     462             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     463             :         int NodeNum; // index for air nodes
     464             :         int SurfNum; // index for surfaces
     465             : 
     466             :         // set up air node ID
     467        8626 :         state.dataMundtSimMgr->NumRoomNodes = 0;
     468       86260 :         for (NodeNum = 1; NodeNum <= state.dataRoomAir->TotNumOfZoneAirNodes(ZoneNum); ++NodeNum) {
     469       77634 :             switch (state.dataMundtSimMgr->LineNode(NodeNum, state.dataMundtSimMgr->MundtZoneNum).ClassType) {
     470        8626 :             case RoomAir::AirNodeType::Inlet: { // inlet
     471        8626 :                 state.dataMundtSimMgr->SupplyNodeID = NodeNum;
     472        8626 :             } break;
     473        8626 :             case RoomAir::AirNodeType::Floor: { // floor
     474        8626 :                 state.dataMundtSimMgr->MundtFootAirID = NodeNum;
     475        8626 :             } break;
     476        8626 :             case RoomAir::AirNodeType::Control: { // thermostat
     477        8626 :                 state.dataMundtSimMgr->TstatNodeID = NodeNum;
     478        8626 :             } break;
     479        8626 :             case RoomAir::AirNodeType::Ceiling: { // ceiling
     480        8626 :                 state.dataMundtSimMgr->MundtCeilAirID = NodeNum;
     481        8626 :             } break;
     482       34504 :             case RoomAir::AirNodeType::Mundt: { // wall
     483       34504 :                 ++state.dataMundtSimMgr->NumRoomNodes;
     484       34504 :                 state.dataMundtSimMgr->RoomNodeIDs(state.dataMundtSimMgr->NumRoomNodes) = NodeNum;
     485       34504 :             } break;
     486        8626 :             case RoomAir::AirNodeType::Return: { // return
     487        8626 :                 state.dataMundtSimMgr->ReturnNodeID = NodeNum;
     488        8626 :             } break;
     489           0 :             default: {
     490           0 :                 ShowSevereError(state, "SetupMundtModel: Non-Standard Type of Air Node for Mundt Model");
     491           0 :                 ErrorsFound = true;
     492           0 :             } break;
     493             :             }
     494             :         }
     495             : 
     496             :         //  get number of floors in the zone and setup FloorSurfSetIDs
     497        8626 :         if (state.dataMundtSimMgr->MundtFootAirID > 0) {
     498       17252 :             state.dataMundtSimMgr->NumFloorSurfs =
     499        8626 :                 count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     500        8626 :             state.dataMundtSimMgr->FloorSurfSetIDs =
     501       17252 :                 pack(state.dataMundtSimMgr->ID1dSurf,
     502       17252 :                      state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     503             :             // initialize floor surface data (a must since NumFloorSurfs is varied among zones)
     504       25878 :             for (auto &e : state.dataMundtSimMgr->FloorSurf) {
     505       17252 :                 e.Temp = 25.0;
     506       17252 :                 e.Hc = 0.0;
     507       17252 :                 e.Area = 0.0;
     508             :             }
     509             :             // get floor surface data
     510       25878 :             for (SurfNum = 1; SurfNum <= state.dataMundtSimMgr->NumFloorSurfs; ++SurfNum) {
     511       17252 :                 state.dataMundtSimMgr->FloorSurf(SurfNum).Temp =
     512       17252 :                     state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Temp;
     513       17252 :                 state.dataMundtSimMgr->FloorSurf(SurfNum).Hc =
     514       17252 :                     state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Hc;
     515       17252 :                 state.dataMundtSimMgr->FloorSurf(SurfNum).Area =
     516       17252 :                     state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Area;
     517             :             }
     518             :         } else {
     519           0 :             ShowSevereError(state, format("SetupMundtModel: Mundt model has no FloorAirNode, Zone={}", state.dataHeatBal->Zone(ZoneNum).Name));
     520           0 :             ErrorsFound = true;
     521             :         }
     522        8626 :     }
     523             : 
     524             :     //*****************************************************************************************
     525             : 
     526        8626 :     void CalcDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     527             :     {
     528             : 
     529             :         // SUBROUTINE INFORMATION:
     530             :         //       AUTHOR         Brent Griffith
     531             :         //       DATE WRITTEN   September 2001
     532             :         //       RE-ENGINEERED  July 2003, EnergyPlus Implementation (CC)
     533             :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     534             : 
     535             :         // PURPOSE OF THIS SUBROUTINE:
     536             :         //   Compute the simplified version of Mundt and store results in Air data Manager
     537             :         //   argument passing is plentiful but are IN and nothing out.
     538             :         //   these variables are scaler conditions at current HB day,timestep, and iteration
     539             :         //   This subroutine is USE'ed by heat balance driver (top level module)
     540             : 
     541             :         // METHODOLOGY EMPLOYED:
     542             :         //   apply Mundt's simple model for delta Temp head-foot and update values in Air data manager.
     543             : 
     544             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     545             :         Real64 TAirFoot;        // air temperature at the floor
     546             :         Real64 TAirCeil;        // air temperature at the ceiling
     547             :         Real64 TLeaving;        // air temperature leaving zone (= return air temp)
     548             :         Real64 TControlPoint;   // air temperature at thermostat
     549             :         Real64 Slope;           // vertical air temperature gradient (slope) from Mundt equations
     550             :         Real64 QequipConvFloor; // convective gain at the floor due to internal heat sources
     551             :         Real64 QSensInfilFloor; // convective gain at the floor due to infiltration
     552             :         Real64 FloorSumHAT;     // sum of hci*area*temp at the floor
     553             :         Real64 FloorSumHA;      // sum of hci*area at the floor
     554             :         Real64 TThisNode;       // dummy variable for air node temp
     555             :         int NodeNum;            // index for air nodes
     556             :         int SurfNum;            // index for surfaces
     557             :         int SurfCounted;        // number of surfaces assciated with an air node
     558             : 
     559             :         //   apply floor splits
     560        8626 :         QequipConvFloor = state.dataRoomAir->ConvectiveFloorSplit(ZoneNum) * state.dataMundtSimMgr->ConvIntGain;
     561        8626 :         QSensInfilFloor = -state.dataRoomAir->InfiltratFloorSplit(ZoneNum) * state.dataMundtSimMgr->QventCool;
     562             : 
     563             :         // Begin computations for Mundt model
     564             : 
     565             :         // do summations for floor surfaces of this zone
     566        8626 :         FloorSumHAT = 0.0;
     567        8626 :         FloorSumHA = 0.0;
     568       25878 :         for (auto const &s : state.dataMundtSimMgr->FloorSurf) {
     569       17252 :             FloorSumHAT += s.Area * s.Hc * s.Temp;
     570       17252 :             FloorSumHA += s.Area * s.Hc;
     571             :         }
     572             : 
     573             :         // Eq 2.2 in ASHRAE RP 1222 Final report
     574        8626 :         TAirFoot =
     575        8626 :             ((state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate * state.dataMundtSimMgr->SupplyAirTemp) +
     576        8626 :              (FloorSumHAT) + QequipConvFloor + QSensInfilFloor) /
     577        8626 :             ((state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate) + (FloorSumHA));
     578             : 
     579             :         // prevent dividing by zero due to zero cooling load (or zero supply air flow rate)
     580        8626 :         if (state.dataMundtSimMgr->QsysCoolTot <= 0.0) {
     581           0 :             TLeaving = state.dataMundtSimMgr->SupplyAirTemp;
     582             :         } else {
     583             :             // Eq 2.3 in ASHRAE RP 1222 Final report
     584        8626 :             TLeaving =
     585        8626 :                 (state.dataMundtSimMgr->QsysCoolTot / (state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate)) +
     586        8626 :                 state.dataMundtSimMgr->SupplyAirTemp;
     587             :         }
     588             : 
     589             :         // Eq 2.4 in ASHRAE RP 1222 Final report
     590       17252 :         Slope = (TLeaving - TAirFoot) /
     591        8626 :                 (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     592        8626 :                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).Height);
     593             :         // check slope
     594        8626 :         if (Slope > MaxSlope) {
     595           0 :             Slope = MaxSlope;
     596           0 :             TAirFoot = TLeaving -
     597           0 :                        (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     598           0 :                                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).Height));
     599             :         }
     600        8626 :         if (Slope < MinSlope) { // pretty much vertical
     601           3 :             Slope = MinSlope;
     602           3 :             TAirFoot = TLeaving;
     603             :         }
     604             : 
     605             :         // Eq 2.4 in ASHRAE RP 1222 Final report
     606        8626 :         TAirCeil =
     607        8626 :             TLeaving - (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     608        8626 :                                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).Height));
     609             : 
     610        8626 :         TControlPoint =
     611        8626 :             TLeaving - (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     612        8626 :                                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Height));
     613             : 
     614             :         // determine air node temperatures in this zone
     615        8626 :         SetNodeResult(state, state.dataMundtSimMgr->SupplyNodeID, state.dataMundtSimMgr->SupplyAirTemp);
     616        8626 :         SetNodeResult(state, state.dataMundtSimMgr->ReturnNodeID, TLeaving);
     617        8626 :         SetNodeResult(state, state.dataMundtSimMgr->MundtCeilAirID, TAirCeil);
     618        8626 :         SetNodeResult(state, state.dataMundtSimMgr->MundtFootAirID, TAirFoot);
     619        8626 :         SetNodeResult(state, state.dataMundtSimMgr->TstatNodeID, TControlPoint);
     620             : 
     621       25878 :         for (SurfNum = 1; SurfNum <= state.dataMundtSimMgr->NumFloorSurfs; ++SurfNum) {
     622       17252 :             SetSurfTmeanAir(state, state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), TAirFoot);
     623             :         }
     624             : 
     625        8626 :         SurfCounted = count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     626        8626 :         state.dataMundtSimMgr->TheseSurfIDs =
     627       17252 :             pack(state.dataMundtSimMgr->ID1dSurf,
     628       17252 :                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     629       25878 :         for (SurfNum = 1; SurfNum <= SurfCounted; ++SurfNum) {
     630       17252 :             SetSurfTmeanAir(state, state.dataMundtSimMgr->TheseSurfIDs(SurfNum), TAirCeil);
     631             :         }
     632             : 
     633       43130 :         for (NodeNum = 1; NodeNum <= state.dataMundtSimMgr->NumRoomNodes; ++NodeNum) {
     634       34504 :             TThisNode =
     635             :                 TLeaving -
     636       34504 :                 (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     637       34504 :                           state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).Height));
     638       34504 :             SetNodeResult(state, state.dataMundtSimMgr->RoomNodeIDs(NodeNum), TThisNode);
     639       34504 :             SurfCounted =
     640       34504 :                 count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     641       34504 :             state.dataMundtSimMgr->TheseSurfIDs =
     642       69008 :                 pack(state.dataMundtSimMgr->ID1dSurf,
     643       69008 :                      state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     644      189772 :             for (SurfNum = 1; SurfNum <= SurfCounted; ++SurfNum) {
     645      155268 :                 SetSurfTmeanAir(state, state.dataMundtSimMgr->TheseSurfIDs(SurfNum), TThisNode);
     646             :             }
     647             :         }
     648        8626 :     }
     649             : 
     650             :     //*****************************************************************************************
     651             : 
     652       77634 :     void SetNodeResult(EnergyPlusData &state,
     653             :                        int const NodeID,       // node ID
     654             :                        Real64 const TempResult // temperature for the specified air node
     655             :     )
     656             :     {
     657             : 
     658             :         // SUBROUTINE INFORMATION:
     659             :         //       AUTHOR         Brent Griffith
     660             :         //       DATE WRITTEN   September 2002
     661             :         //       RE-ENGINEERED  April 2003, Weixiu Kong, EnergyPlus Implementation
     662             :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     663             : 
     664             :         // PURPOSE OF THIS SUBROUTINE:
     665             :         //   provide set routine for reporting results
     666             :         //   to AirDataManager from air model
     667             : 
     668             :         // METHODOLOGY EMPLOYED:
     669             :         // na
     670             : 
     671             :         // REFERENCES:
     672             :         // na
     673             : 
     674             :         // USE STATEMENTS:
     675             :         // na
     676             : 
     677             :         // Locals
     678             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     679             : 
     680             :         // SUBROUTINE PARAMETER DEFINITIONS:
     681             :         // na
     682             : 
     683             :         // INTERFACE BLOCK SPECIFICATIONS:
     684             :         // na
     685             : 
     686             :         // DERIVED TYPE DEFINITIONS:
     687             :         // na
     688             : 
     689             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     690             :         // na
     691             : 
     692       77634 :         state.dataMundtSimMgr->LineNode(NodeID, state.dataMundtSimMgr->MundtZoneNum).Temp = TempResult;
     693       77634 :     }
     694             : 
     695             :     //*****************************************************************************************
     696             : 
     697      189772 :     void SetSurfTmeanAir(EnergyPlusData &state,
     698             :                          int const SurfID,    // surface ID
     699             :                          Real64 const TeffAir // temperature of air node adjacent to the specified surface
     700             :     )
     701             :     {
     702             : 
     703             :         // SUBROUTINE INFORMATION:
     704             :         //       AUTHOR         Brent Griffith
     705             :         //       DATE WRITTEN   September 2002
     706             :         //       RE-ENGINEERED  April 2003, Wiexiu Kong, EnergyPlus Implementation
     707             :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     708             : 
     709             :         // PURPOSE OF THIS SUBROUTINE:
     710             :         //   provide set routine for air model prediction of
     711             :         //   effective air for single surface
     712             : 
     713      189772 :         state.dataMundtSimMgr->MundtAirSurf(SurfID, state.dataMundtSimMgr->MundtZoneNum).TMeanAir = TeffAir;
     714      189772 :     }
     715             : 
     716             :     //*****************************************************************************************
     717             : 
     718       17080 :     void SetSurfHBDataForDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     719             :     {
     720             : 
     721             :         // SUBROUTINE INFORMATION:
     722             :         //       AUTHOR         Chanvit Chantrasrisalai
     723             :         //       DATE WRITTEN   July 2003
     724             :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     725             :         //       RE-ENGINEERED  na
     726             : 
     727             :         // PURPOSE OF THIS SUBROUTINE:
     728             :         //     map data from air domain back to surface domain for each particular zone
     729             : 
     730             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     731             :         int ZoneNodeNum;  // index number of the zone node
     732             :         Real64 DeltaTemp; // dummy variable for temperature difference
     733             : 
     734             :         // get surface info
     735       17080 :         int NumOfSurfs = state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs;
     736             : 
     737       33809 :         if ((state.dataMundtSimMgr->SupplyAirVolumeRate > 0.0001) &&
     738       16729 :             (state.dataMundtSimMgr->QsysCoolTot > 0.0001)) { // Controlled zone when the system is on
     739             : 
     740        8626 :             if (state.dataRoomAir->AirModel(ZoneNum).TempCoupleScheme == RoomAir::CouplingScheme::Direct) {
     741             :                 // Use direct coupling scheme to report air temperatures back to surface/system domains
     742             :                 // a) Bulk air temperatures -> TempEffBulkAir(SurfNum)
     743      198398 :                 for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
     744      189772 :                     int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
     745      189772 :                     state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) =
     746      189772 :                         state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).TMeanAir;
     747             :                     // set flag for reference air temperature
     748      189772 :                     state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
     749      189772 :                     state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
     750             :                 }
     751             :                 // b) Average zone air temperature -> ZT(ZoneNum)
     752             :                 // For Mundt model, average room air is the weighted value of floor and ceiling air temps
     753             :                 // TRoomAverage = ( LineNode( MundtCeilAirID, MundtZoneNum ).Temp + LineNode( MundtFootAirID, MundtZoneNum ).Temp ) / 2;
     754             :                 // ZT(ZoneNum) = TRoomAverage
     755             :                 // c) Leaving-zone air temperature -> Node(ZoneNode)%Temp
     756        8626 :                 ZoneNodeNum = state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber;
     757        8626 :                 state.dataLoopNodes->Node(ZoneNodeNum).Temp =
     758        8626 :                     state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
     759             :                 // d) Thermostat air temperature -> TempTstatAir(ZoneNum)
     760        8626 :                 state.dataHeatBalFanSys->TempTstatAir(ZoneNum) =
     761        8626 :                     state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
     762             :             } else {
     763             :                 // Use indirect coupling scheme to report air temperatures back to surface/system domains
     764             :                 // a) Bulk air temperatures -> TempEffBulkAir(SurfNum)
     765           0 :                 for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
     766           0 :                     int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
     767           0 :                     DeltaTemp = state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).TMeanAir -
     768           0 :                                 state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
     769           0 :                     state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp;
     770             :                     // set flag for reference air temperature
     771           0 :                     state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
     772           0 :                     state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
     773             :                 }
     774             :                 // b) Average zone air temperature -> ZT(ZoneNum)
     775             :                 // For Mundt model, average room air is the weighted value of floor and ceiling air temps
     776             :                 // TRoomAverage = ( LineNode( MundtCeilAirID, MundtZoneNum ).Temp + LineNode( MundtFootAirID, MundtZoneNum ).Temp ) / 2;
     777             :                 // DeltaTemp = TRoomAverage - LineNode( TstatNodeID, MundtZoneNum ).Temp;
     778             :                 // ZT(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp
     779             :                 // c) Leaving-zone air temperature -> Node(ZoneNode)%Temp
     780           0 :                 ZoneNodeNum = state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber;
     781           0 :                 DeltaTemp = state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp -
     782           0 :                             state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
     783           0 :                 state.dataLoopNodes->Node(ZoneNodeNum).Temp = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp;
     784             :                 // d) Thermostat air temperature -> TempTstatAir(ZoneNum)
     785           0 :                 state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum)
     786           0 :                                                                      .ZT; // for indirect coupling, control air temp is equal to mean air temp?
     787             :             }
     788             :             // set flag to indicate that Mundt model is used for this zone at the present time
     789        8626 :             state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
     790             :         } else { // Controlled zone when the system is off --> Use the mixing model instead of the Mundt model
     791             :             // Bulk air temperatures -> TempEffBulkAir(SurfNum)
     792      194442 :             for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
     793      185988 :                 int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
     794      185988 :                 state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
     795             :                 // set flag for reference air temperature
     796      185988 :                 state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp;
     797      185988 :                 state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
     798             :             }
     799             :             // set flag to indicate that Mundt model is NOT used for this zone at the present time
     800        8454 :             state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
     801             :         }
     802       17080 :     }
     803             : 
     804             :     //*****************************************************************************************
     805             : 
     806             : } // namespace RoomAir
     807             : 
     808             : } // namespace EnergyPlus

Generated by: LCOV version 1.14