LCOV - code coverage report
Current view: top level - EnergyPlus - MundtSimMgr.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 0.0 % 298 0
Test Date: 2025-05-22 16:09:37 Functions: 0.0 % 8 0

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

Generated by: LCOV version 2.0-1