LCOV - code coverage report
Current view: top level - EnergyPlus - MundtSimMgr.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 0.0 % 302 0
Test Date: 2025-06-02 12:03:30 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) {
     130            0 :                 ShowFatalError(state, "ManageMundtModel: Errors in setting up Mundt Model. Preceding condition(s) cause termination.");
     131              :             }
     132              : 
     133              :             // perform Mundt model calculations
     134            0 :             CalcDispVent1Node(state, ZoneNum);
     135              :         }
     136              : 
     137              :         // transfer data from air domain back to surface domain for the specified zone
     138            0 :         SetSurfHBDataForDispVent1Node(state, ZoneNum);
     139            0 :     }
     140              : 
     141              :     //*****************************************************************************************
     142              : 
     143            0 :     void InitDispVent1Node(EnergyPlusData &state)
     144              :     {
     145              : 
     146              :         // SUBROUTINE INFORMATION:
     147              :         //       AUTHOR         Chanvit Chantrasrisalai
     148              :         //       DATE WRITTEN   February 2004
     149              :         //       MODIFIED       na
     150              :         //       RE-ENGINEERED  na
     151              : 
     152              :         // PURPOSE OF THIS SUBROUTINE:
     153              :         //     initialize Mundt-model variables
     154              : 
     155              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     156              :         int NodeNum;            // index for air nodes
     157              :         int ZoneIndex;          // index for zones
     158              :         int NumOfAirNodes;      // total number of nodes in each zone
     159              :         int NumOfMundtZones;    // number of zones using the Mundt model
     160              :         int MundtZoneIndex;     // index for zones using the Mundt model
     161              :         int MaxNumOfSurfs;      // maximum of number of surfaces
     162              :         int MaxNumOfFloorSurfs; // maximum of number of surfaces
     163              :         int MaxNumOfAirNodes;   // maximum of number of air nodes
     164              :         int MaxNumOfRoomNodes;  // maximum of number of nodes connected to walls
     165              :         int RoomNodesCount;     // number of nodes connected to walls
     166              :         int FloorSurfCount;     // number of nodes connected to walls
     167              :         int AirNodeBeginNum;    // index number of the first air node for this zone
     168              :         int AirNodeNum;         // index for air nodes
     169              :         bool AirNodeFoundFlag;  // flag used for error check
     170              :         bool ErrorsFound;       // true if errors found in init
     171              : 
     172              :         // allocate and initialize zone data
     173            0 :         state.dataMundtSimMgr->ZoneData.allocate(state.dataGlobal->NumOfZones);
     174            0 :         for (auto &e : state.dataMundtSimMgr->ZoneData) {
     175            0 :             e.NumOfSurfs = 0;
     176            0 :             e.MundtZoneIndex = 0;
     177              :         }
     178              : 
     179              :         // get zone data
     180            0 :         NumOfMundtZones = 0;
     181            0 :         MaxNumOfSurfs = 0;
     182            0 :         MaxNumOfFloorSurfs = 0;
     183            0 :         MaxNumOfAirNodes = 0;
     184            0 :         MaxNumOfRoomNodes = 0;
     185            0 :         ErrorsFound = false;
     186            0 :         for (ZoneIndex = 1; ZoneIndex <= state.dataGlobal->NumOfZones; ++ZoneIndex) {
     187            0 :             auto const &thisZone = state.dataHeatBal->Zone(ZoneIndex);
     188            0 :             if (state.dataRoomAir->AirModel(ZoneIndex).AirModel == RoomAir::RoomAirModel::DispVent1Node) {
     189              :                 // find number of zones using the Mundt model
     190            0 :                 ++NumOfMundtZones;
     191              :                 // find maximum number of surfaces in zones using the Mundt model
     192            0 :                 int NumOfSurfs = 0;
     193            0 :                 for (int spaceNum : thisZone.spaceIndexes) {
     194            0 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     195            0 :                     for (int surfNum = thisSpace.HTSurfaceFirst; surfNum <= thisSpace.HTSurfaceLast; ++surfNum) {
     196            0 :                         state.dataMundtSimMgr->ZoneData(ZoneIndex).HBsurfaceIndexes.emplace_back(surfNum);
     197            0 :                         ++NumOfSurfs;
     198              :                     }
     199            0 :                     MaxNumOfSurfs = max(MaxNumOfSurfs, NumOfSurfs);
     200              :                     // find maximum number of air nodes in zones using the Mundt model
     201            0 :                     NumOfAirNodes = state.dataRoomAir->TotNumOfZoneAirNodes(ZoneIndex);
     202            0 :                     MaxNumOfAirNodes = max(MaxNumOfAirNodes, NumOfAirNodes);
     203              :                     // assign zone data
     204            0 :                     state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs = NumOfSurfs;
     205            0 :                     state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex = NumOfMundtZones;
     206            0 :                 }
     207              :             }
     208              :         }
     209              : 
     210              :         // allocate and initialize surface and air-node data
     211            0 :         state.dataMundtSimMgr->ID1dSurf.allocate(MaxNumOfSurfs);
     212            0 :         state.dataMundtSimMgr->TheseSurfIDs.allocate(MaxNumOfSurfs);
     213            0 :         state.dataMundtSimMgr->MundtAirSurf.allocate(MaxNumOfSurfs, NumOfMundtZones);
     214            0 :         state.dataMundtSimMgr->LineNode.allocate(MaxNumOfAirNodes, NumOfMundtZones);
     215            0 :         for (int SurfNum = 1; SurfNum <= MaxNumOfSurfs; ++SurfNum) {
     216            0 :             state.dataMundtSimMgr->ID1dSurf(SurfNum) = SurfNum;
     217              :         }
     218            0 :         for (auto &e : state.dataMundtSimMgr->MundtAirSurf) {
     219            0 :             e.Area = 0.0;
     220            0 :             e.Temp = 25.0;
     221            0 :             e.Hc = 0.0;
     222            0 :             e.TMeanAir = 25.0;
     223              :         }
     224            0 :         for (auto &e : state.dataMundtSimMgr->LineNode) {
     225            0 :             e.AirNodeName.clear();
     226            0 :             e.ClassType = RoomAir::AirNodeType::Invalid;
     227            0 :             e.Height = 0.0;
     228            0 :             e.Temp = 25.0;
     229              :         }
     230              : 
     231              :         // get constant data (unchanged over time) for surfaces and air nodes
     232            0 :         for (MundtZoneIndex = 1; MundtZoneIndex <= NumOfMundtZones; ++MundtZoneIndex) {
     233            0 :             for (ZoneIndex = 1; ZoneIndex <= state.dataGlobal->NumOfZones; ++ZoneIndex) {
     234            0 :                 auto &thisZone = state.dataHeatBal->Zone(ZoneIndex);
     235            0 :                 if (state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex == MundtZoneIndex) {
     236              :                     // get surface data
     237            0 :                     for (int surfNum = 1; surfNum <= state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs; ++surfNum) {
     238            0 :                         state.dataMundtSimMgr->MundtAirSurf(surfNum, MundtZoneIndex).Area =
     239            0 :                             state.dataSurface->Surface(state.dataMundtSimMgr->ZoneData(ZoneIndex).HBsurfaceIndexes(surfNum)).Area;
     240              :                     }
     241              : 
     242              :                     // get air node data
     243            0 :                     RoomNodesCount = 0;
     244            0 :                     FloorSurfCount = 0;
     245            0 :                     for (NodeNum = 1; NodeNum <= state.dataRoomAir->TotNumOfZoneAirNodes(ZoneIndex); ++NodeNum) {
     246              : 
     247            0 :                         state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex)
     248            0 :                             .SurfMask.allocate(state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs);
     249              : 
     250            0 :                         if (NodeNum == 1) {
     251            0 :                             AirNodeBeginNum = NodeNum;
     252              :                         }
     253              : 
     254              :                         // error check for debugging
     255            0 :                         if (AirNodeBeginNum > state.dataRoomAir->TotNumOfAirNodes) {
     256            0 :                             ShowFatalError(state, "An array bound exceeded. Error in InitMundtModel subroutine of MundtSimMgr.");
     257              :                         }
     258              : 
     259            0 :                         AirNodeFoundFlag = false;
     260            0 :                         for (AirNodeNum = AirNodeBeginNum; AirNodeNum <= state.dataRoomAir->TotNumOfAirNodes; ++AirNodeNum) {
     261            0 :                             if (Util::SameString(state.dataRoomAir->AirNode(AirNodeNum).ZoneName, thisZone.Name)) {
     262            0 :                                 state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType = state.dataRoomAir->AirNode(AirNodeNum).ClassType;
     263            0 :                                 state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).AirNodeName = state.dataRoomAir->AirNode(AirNodeNum).Name;
     264            0 :                                 state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).Height = state.dataRoomAir->AirNode(AirNodeNum).Height;
     265            0 :                                 state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).SurfMask = state.dataRoomAir->AirNode(AirNodeNum).SurfMask;
     266            0 :                                 SetupOutputVariable(state,
     267              :                                                     "Room Air Node Air Temperature",
     268              :                                                     Constant::Units::C,
     269            0 :                                                     state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).Temp,
     270              :                                                     OutputProcessor::TimeStepType::System,
     271              :                                                     OutputProcessor::StoreType::Average,
     272            0 :                                                     state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).AirNodeName);
     273              : 
     274            0 :                                 AirNodeBeginNum = AirNodeNum + 1;
     275            0 :                                 AirNodeFoundFlag = true;
     276              : 
     277            0 :                                 break;
     278              :                             }
     279              :                         }
     280              : 
     281              :                         // error check for debugging
     282            0 :                         if (!AirNodeFoundFlag) {
     283            0 :                             ShowSevereError(state, format("InitMundtModel: Air Node in Zone=\"{}\" is not found.", thisZone.Name));
     284            0 :                             ErrorsFound = true;
     285            0 :                             continue;
     286              :                         }
     287              : 
     288              :                         // count air nodes connected to walls in each zone
     289            0 :                         if (state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType == RoomAir::AirNodeType::Mundt) {
     290            0 :                             ++RoomNodesCount;
     291              :                         }
     292              : 
     293              :                         // count floors in each zone
     294            0 :                         if (state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType == RoomAir::AirNodeType::Floor) {
     295            0 :                             FloorSurfCount += count(state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).SurfMask);
     296              :                         }
     297              :                     }
     298              :                     // got data for this zone so exit the zone loop
     299            0 :                     if (AirNodeFoundFlag) {
     300            0 :                         break;
     301              :                     }
     302              :                 }
     303              :             }
     304              : 
     305            0 :             MaxNumOfRoomNodes = max(MaxNumOfRoomNodes, RoomNodesCount);
     306            0 :             MaxNumOfFloorSurfs = max(MaxNumOfFloorSurfs, FloorSurfCount);
     307              :         }
     308              : 
     309            0 :         if (ErrorsFound) {
     310            0 :             ShowFatalError(state, "InitMundtModel: Preceding condition(s) cause termination.");
     311              :         }
     312              : 
     313              :         // allocate arrays
     314            0 :         state.dataMundtSimMgr->RoomNodeIDs.allocate(MaxNumOfRoomNodes);
     315            0 :         state.dataMundtSimMgr->FloorSurfSetIDs.allocate(MaxNumOfFloorSurfs);
     316            0 :         state.dataMundtSimMgr->FloorSurf.allocate(MaxNumOfFloorSurfs);
     317            0 :     }
     318              : 
     319              :     //*****************************************************************************************
     320              : 
     321            0 :     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              :         Real64 SumSysMCp;        // zone sum of air system MassFlowRate*Cp
     339              :         Real64 SumSysMCpT;       // zone sum of air system MassFlowRate*Cp*T
     340              :         Real64 MassFlowRate;     // mass flowrate
     341              :         Real64 NodeTemp;         // node temperature
     342              :         int ZoneNode;            // index number for specified zone node
     343              :         Real64 ZoneMassFlowRate; // zone mass flowrate
     344              :         int ZoneEquipConfigNum;  // index number for zone equipment configuration
     345              :         Real64 ZoneMult;         // total zone multiplier
     346              :         Real64 RetAirConvGain;
     347              : 
     348            0 :         auto const &Zone(state.dataHeatBal->Zone);
     349              : 
     350              :         // determine ZoneEquipConfigNum for this zone
     351            0 :         ZoneEquipConfigNum = ZoneNum;
     352              :         // check whether this zone is a controlled zone or not
     353            0 :         if (!Zone(ZoneNum).IsControlled) {
     354            0 :             ShowFatalError(state, format("Zones must be controlled for Mundt air model. No system serves zone {}", Zone(ZoneNum).Name));
     355            0 :             return;
     356              :         }
     357              : 
     358              :         // determine information required by Mundt model
     359            0 :         state.dataMundtSimMgr->ZoneHeight = Zone(ZoneNum).CeilingHeight;
     360            0 :         state.dataMundtSimMgr->ZoneFloorArea = Zone(ZoneNum).FloorArea;
     361            0 :         ZoneMult = Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier;
     362              : 
     363              :         // supply air flowrate is the same as zone air flowrate
     364            0 :         ZoneNode = Zone(ZoneNum).SystemZoneNodeNumber;
     365            0 :         state.dataMundtSimMgr->ZoneAirDensity =
     366            0 :             PsyRhoAirFnPbTdbW(state,
     367            0 :                               state.dataEnvrn->OutBaroPress,
     368            0 :                               state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT,
     369            0 :                               PsyWFnTdpPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT, state.dataEnvrn->OutBaroPress));
     370            0 :         ZoneMassFlowRate = state.dataLoopNodes->Node(ZoneNode).MassFlowRate;
     371            0 :         state.dataMundtSimMgr->SupplyAirVolumeRate = ZoneMassFlowRate / state.dataMundtSimMgr->ZoneAirDensity;
     372            0 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     373            0 :         if (ZoneMassFlowRate <= 0.0001) {
     374              :             // system is off
     375            0 :             state.dataMundtSimMgr->QsysCoolTot = 0.0;
     376              :         } else {
     377              :             // determine supply air conditions
     378            0 :             SumSysMCp = 0.0;
     379            0 :             SumSysMCpT = 0.0;
     380            0 :             for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).NumInletNodes; ++NodeNum) {
     381            0 :                 NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).Temp;
     382            0 :                 MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).MassFlowRate;
     383            0 :                 CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
     384            0 :                 SumSysMCp += MassFlowRate * CpAir;
     385            0 :                 SumSysMCpT += MassFlowRate * CpAir * NodeTemp;
     386              :             }
     387              :             // prevent dividing by zero due to zero supply air flow rate
     388            0 :             if (SumSysMCp <= 0.0) {
     389            0 :                 state.dataMundtSimMgr->SupplyAirTemp =
     390            0 :                     state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(1)).Temp;
     391              :             } else {
     392              :                 // a weighted average of the inlet temperatures
     393            0 :                 state.dataMundtSimMgr->SupplyAirTemp = SumSysMCpT / SumSysMCp;
     394              :             }
     395              :             // determine cooling load
     396            0 :             CpAir = PsyCpAirFnW(thisZoneHB.airHumRat);
     397            0 :             state.dataMundtSimMgr->QsysCoolTot =
     398            0 :                 -(SumSysMCpT - ZoneMassFlowRate * CpAir * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
     399              :         }
     400              :         // determine heat gains
     401            0 :         state.dataMundtSimMgr->ConvIntGain = InternalHeatGains::zoneSumAllInternalConvectionGains(state, ZoneNum);
     402            0 :         state.dataMundtSimMgr->ConvIntGain += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) +
     403            0 :                                               thisZoneHB.SysDepZoneLoadsLagged + thisZoneHB.NonAirSystemResponse / ZoneMult;
     404              : 
     405              :         // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very
     406              :         // low or zero)
     407            0 :         if (Zone(ZoneNum).NoHeatToReturnAir) {
     408            0 :             RetAirConvGain = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, 0);
     409            0 :             state.dataMundtSimMgr->ConvIntGain += RetAirConvGain;
     410              :         }
     411              : 
     412            0 :         state.dataMundtSimMgr->QventCool =
     413            0 :             -thisZoneHB.MCPI * (Zone(ZoneNum).OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
     414              : 
     415              :         // get surface data
     416            0 :         for (int SurfNum = 1; SurfNum <= state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs; ++SurfNum) {
     417            0 :             state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).Temp =
     418            0 :                 state.dataHeatBalSurf->SurfTempIn(state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum));
     419            0 :             state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).Hc =
     420            0 :                 state.dataHeatBalSurf->SurfHConvInt(state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum));
     421              :         }
     422              :     }
     423              : 
     424              :     //*****************************************************************************************
     425              : 
     426            0 :     void SetupDispVent1Node(EnergyPlusData &state,
     427              :                             int const ZoneNum, // index number for the specified zone
     428              :                             bool &ErrorsFound  // true if problems setting up model
     429              :     )
     430              :     {
     431              : 
     432              :         // SUBROUTINE INFORMATION:
     433              :         //       AUTHOR         Brent Griffith
     434              :         //       DATE WRITTEN   Febraury 2002
     435              :         //       RE-ENGINEERED  June 2003, EnergyPlus Implementation (CC)
     436              :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     437              : 
     438              :         // PURPOSE OF THIS SUBROUTINE:
     439              :         //   Subroutine must be called once before main model calculation
     440              :         //   need to pass some zone characteristics only once
     441              :         //   initializes module level variables, collect info from Air Data Manager
     442              : 
     443              :         // METHODOLOGY EMPLOYED:
     444              :         // na
     445              : 
     446              :         // REFERENCES:
     447              :         // na
     448              : 
     449              :         // Locals
     450              :         // SUBROUTINE ARGUMENT DEFINITIONS:
     451              : 
     452              :         // SUBROUTINE PARAMETER DEFINITIONS:
     453              :         // na
     454              : 
     455              :         // INTERFACE BLOCK SPECIFICATIONS:
     456              :         // na
     457              : 
     458              :         // DERIVED TYPE DEFINITIONS:
     459              :         // na
     460              : 
     461              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     462              :         int NodeNum; // index for air nodes
     463              : 
     464              :         // set up air node ID
     465            0 :         state.dataMundtSimMgr->NumRoomNodes = 0;
     466            0 :         for (NodeNum = 1; NodeNum <= state.dataRoomAir->TotNumOfZoneAirNodes(ZoneNum); ++NodeNum) {
     467            0 :             switch (state.dataMundtSimMgr->LineNode(NodeNum, state.dataMundtSimMgr->MundtZoneNum).ClassType) {
     468            0 :             case RoomAir::AirNodeType::Inlet: { // inlet
     469            0 :                 state.dataMundtSimMgr->SupplyNodeID = NodeNum;
     470            0 :             } break;
     471            0 :             case RoomAir::AirNodeType::Floor: { // floor
     472            0 :                 state.dataMundtSimMgr->MundtFootAirID = NodeNum;
     473            0 :             } break;
     474            0 :             case RoomAir::AirNodeType::Control: { // thermostat
     475            0 :                 state.dataMundtSimMgr->TstatNodeID = NodeNum;
     476            0 :             } break;
     477            0 :             case RoomAir::AirNodeType::Ceiling: { // ceiling
     478            0 :                 state.dataMundtSimMgr->MundtCeilAirID = NodeNum;
     479            0 :             } break;
     480            0 :             case RoomAir::AirNodeType::Mundt: { // wall
     481            0 :                 ++state.dataMundtSimMgr->NumRoomNodes;
     482            0 :                 state.dataMundtSimMgr->RoomNodeIDs(state.dataMundtSimMgr->NumRoomNodes) = NodeNum;
     483            0 :             } break;
     484            0 :             case RoomAir::AirNodeType::Return: { // return
     485            0 :                 state.dataMundtSimMgr->ReturnNodeID = NodeNum;
     486            0 :             } break;
     487            0 :             default: {
     488            0 :                 ShowSevereError(state, "SetupMundtModel: Non-Standard Type of Air Node for Mundt Model");
     489            0 :                 ErrorsFound = true;
     490            0 :             } break;
     491              :             }
     492              :         }
     493              : 
     494              :         //  get number of floors in the zone and setup FloorSurfSetIDs
     495            0 :         if (state.dataMundtSimMgr->MundtFootAirID > 0) {
     496            0 :             state.dataMundtSimMgr->NumFloorSurfs =
     497            0 :                 count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     498            0 :             state.dataMundtSimMgr->FloorSurfSetIDs =
     499            0 :                 pack(state.dataMundtSimMgr->ID1dSurf,
     500            0 :                      state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     501              :             // initialize floor surface data (a must since NumFloorSurfs is varied among zones)
     502            0 :             for (auto &e : state.dataMundtSimMgr->FloorSurf) {
     503            0 :                 e.Temp = 25.0;
     504            0 :                 e.Hc = 0.0;
     505            0 :                 e.Area = 0.0;
     506              :             }
     507              :             // get floor surface data
     508            0 :             for (int SurfNum = 1; SurfNum <= state.dataMundtSimMgr->NumFloorSurfs; ++SurfNum) {
     509            0 :                 state.dataMundtSimMgr->FloorSurf(SurfNum).Temp =
     510            0 :                     state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Temp;
     511            0 :                 state.dataMundtSimMgr->FloorSurf(SurfNum).Hc =
     512            0 :                     state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Hc;
     513            0 :                 state.dataMundtSimMgr->FloorSurf(SurfNum).Area =
     514            0 :                     state.dataMundtSimMgr->MundtAirSurf(state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), state.dataMundtSimMgr->MundtZoneNum).Area;
     515              :             }
     516              :         } else {
     517            0 :             ShowSevereError(state, format("SetupMundtModel: Mundt model has no FloorAirNode, Zone={}", state.dataHeatBal->Zone(ZoneNum).Name));
     518            0 :             ErrorsFound = true;
     519              :         }
     520            0 :     }
     521              : 
     522              :     //*****************************************************************************************
     523              : 
     524            0 :     void CalcDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     525              :     {
     526              : 
     527              :         // SUBROUTINE INFORMATION:
     528              :         //       AUTHOR         Brent Griffith
     529              :         //       DATE WRITTEN   September 2001
     530              :         //       RE-ENGINEERED  July 2003, EnergyPlus Implementation (CC)
     531              :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     532              : 
     533              :         // PURPOSE OF THIS SUBROUTINE:
     534              :         //   Compute the simplified version of Mundt and store results in Air data Manager
     535              :         //   argument passing is plentiful but are IN and nothing out.
     536              :         //   these variables are scaler conditions at current HB day,timestep, and iteration
     537              :         //   This subroutine is USE'ed by heat balance driver (top level module)
     538              : 
     539              :         // METHODOLOGY EMPLOYED:
     540              :         //   apply Mundt's simple model for delta Temp head-foot and update values in Air data manager.
     541              : 
     542              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     543              :         Real64 TAirFoot;        // air temperature at the floor
     544              :         Real64 TAirCeil;        // air temperature at the ceiling
     545              :         Real64 TLeaving;        // air temperature leaving zone (= return air temp)
     546              :         Real64 TControlPoint;   // air temperature at thermostat
     547              :         Real64 Slope;           // vertical air temperature gradient (slope) from Mundt equations
     548              :         Real64 QequipConvFloor; // convective gain at the floor due to internal heat sources
     549              :         Real64 QSensInfilFloor; // convective gain at the floor due to infiltration
     550              :         Real64 FloorSumHAT;     // sum of hci*area*temp at the floor
     551              :         Real64 FloorSumHA;      // sum of hci*area at the floor
     552              :         Real64 TThisNode;       // dummy variable for air node temp
     553              :         int NodeNum;            // index for air nodes
     554              :         int SurfNum;            // index for surfaces
     555              :         int SurfCounted;        // number of surfaces assciated with an air node
     556              : 
     557              :         //   apply floor splits
     558            0 :         QequipConvFloor = state.dataRoomAir->ConvectiveFloorSplit(ZoneNum) * state.dataMundtSimMgr->ConvIntGain;
     559            0 :         QSensInfilFloor = -state.dataRoomAir->InfiltratFloorSplit(ZoneNum) * state.dataMundtSimMgr->QventCool;
     560              : 
     561              :         // Begin computations for Mundt model
     562              : 
     563              :         // do summations for floor surfaces of this zone
     564            0 :         FloorSumHAT = 0.0;
     565            0 :         FloorSumHA = 0.0;
     566            0 :         for (auto const &s : state.dataMundtSimMgr->FloorSurf) {
     567            0 :             FloorSumHAT += s.Area * s.Hc * s.Temp;
     568            0 :             FloorSumHA += s.Area * s.Hc;
     569              :         }
     570              : 
     571              :         // Eq 2.2 in ASHRAE RP 1222 Final report
     572            0 :         TAirFoot =
     573            0 :             ((state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate * state.dataMundtSimMgr->SupplyAirTemp) +
     574            0 :              (FloorSumHAT) + QequipConvFloor + QSensInfilFloor) /
     575            0 :             ((state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate) + (FloorSumHA));
     576              : 
     577              :         // prevent dividing by zero due to zero cooling load (or zero supply air flow rate)
     578            0 :         if (state.dataMundtSimMgr->QsysCoolTot <= 0.0) {
     579            0 :             TLeaving = state.dataMundtSimMgr->SupplyAirTemp;
     580              :         } else {
     581              :             // Eq 2.3 in ASHRAE RP 1222 Final report
     582            0 :             TLeaving =
     583            0 :                 (state.dataMundtSimMgr->QsysCoolTot / (state.dataMundtSimMgr->ZoneAirDensity * CpAir * state.dataMundtSimMgr->SupplyAirVolumeRate)) +
     584            0 :                 state.dataMundtSimMgr->SupplyAirTemp;
     585              :         }
     586              : 
     587              :         // Eq 2.4 in ASHRAE RP 1222 Final report
     588            0 :         Slope = (TLeaving - TAirFoot) /
     589            0 :                 (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     590            0 :                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).Height);
     591              :         // check slope
     592            0 :         if (Slope > MaxSlope) {
     593            0 :             Slope = MaxSlope;
     594            0 :             TAirFoot = TLeaving -
     595            0 :                        (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     596            0 :                                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtFootAirID, state.dataMundtSimMgr->MundtZoneNum).Height));
     597              :         }
     598            0 :         if (Slope < MinSlope) { // pretty much vertical
     599            0 :             Slope = MinSlope;
     600            0 :             TAirFoot = TLeaving;
     601              :         }
     602              : 
     603              :         // Eq 2.4 in ASHRAE RP 1222 Final report
     604            0 :         TAirCeil =
     605            0 :             TLeaving - (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     606            0 :                                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).Height));
     607              : 
     608            0 :         TControlPoint =
     609            0 :             TLeaving - (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     610            0 :                                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Height));
     611              : 
     612              :         // determine air node temperatures in this zone
     613            0 :         SetNodeResult(state, state.dataMundtSimMgr->SupplyNodeID, state.dataMundtSimMgr->SupplyAirTemp);
     614            0 :         SetNodeResult(state, state.dataMundtSimMgr->ReturnNodeID, TLeaving);
     615            0 :         SetNodeResult(state, state.dataMundtSimMgr->MundtCeilAirID, TAirCeil);
     616            0 :         SetNodeResult(state, state.dataMundtSimMgr->MundtFootAirID, TAirFoot);
     617            0 :         SetNodeResult(state, state.dataMundtSimMgr->TstatNodeID, TControlPoint);
     618              : 
     619            0 :         for (SurfNum = 1; SurfNum <= state.dataMundtSimMgr->NumFloorSurfs; ++SurfNum) {
     620            0 :             SetSurfTmeanAir(state, state.dataMundtSimMgr->FloorSurfSetIDs(SurfNum), TAirFoot);
     621              :         }
     622              : 
     623            0 :         SurfCounted = count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     624            0 :         state.dataMundtSimMgr->TheseSurfIDs =
     625            0 :             pack(state.dataMundtSimMgr->ID1dSurf,
     626            0 :                  state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->MundtCeilAirID, state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     627            0 :         for (SurfNum = 1; SurfNum <= SurfCounted; ++SurfNum) {
     628            0 :             SetSurfTmeanAir(state, state.dataMundtSimMgr->TheseSurfIDs(SurfNum), TAirCeil);
     629              :         }
     630              : 
     631            0 :         for (NodeNum = 1; NodeNum <= state.dataMundtSimMgr->NumRoomNodes; ++NodeNum) {
     632            0 :             TThisNode =
     633              :                 TLeaving -
     634            0 :                 (Slope * (state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Height -
     635            0 :                           state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).Height));
     636            0 :             SetNodeResult(state, state.dataMundtSimMgr->RoomNodeIDs(NodeNum), TThisNode);
     637            0 :             SurfCounted =
     638            0 :                 count(state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     639            0 :             state.dataMundtSimMgr->TheseSurfIDs =
     640            0 :                 pack(state.dataMundtSimMgr->ID1dSurf,
     641            0 :                      state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->RoomNodeIDs(NodeNum), state.dataMundtSimMgr->MundtZoneNum).SurfMask);
     642            0 :             for (SurfNum = 1; SurfNum <= SurfCounted; ++SurfNum) {
     643            0 :                 SetSurfTmeanAir(state, state.dataMundtSimMgr->TheseSurfIDs(SurfNum), TThisNode);
     644              :             }
     645              :         }
     646            0 :     }
     647              : 
     648              :     //*****************************************************************************************
     649              : 
     650            0 :     void SetNodeResult(EnergyPlusData &state,
     651              :                        int const NodeID,       // node ID
     652              :                        Real64 const TempResult // temperature for the specified air node
     653              :     )
     654              :     {
     655              : 
     656              :         // SUBROUTINE INFORMATION:
     657              :         //       AUTHOR         Brent Griffith
     658              :         //       DATE WRITTEN   September 2002
     659              :         //       RE-ENGINEERED  April 2003, Weixiu Kong, EnergyPlus Implementation
     660              :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     661              : 
     662              :         // PURPOSE OF THIS SUBROUTINE:
     663              :         //   provide set routine for reporting results
     664              :         //   to AirDataManager from air model
     665              : 
     666              :         // METHODOLOGY EMPLOYED:
     667              :         // na
     668              : 
     669              :         // REFERENCES:
     670              :         // na
     671              : 
     672              :         // USE STATEMENTS:
     673              :         // na
     674              : 
     675              :         // Locals
     676              :         // SUBROUTINE ARGUMENT DEFINITIONS:
     677              : 
     678              :         // SUBROUTINE PARAMETER DEFINITIONS:
     679              :         // na
     680              : 
     681              :         // INTERFACE BLOCK SPECIFICATIONS:
     682              :         // na
     683              : 
     684              :         // DERIVED TYPE DEFINITIONS:
     685              :         // na
     686              : 
     687              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     688              :         // na
     689              : 
     690            0 :         state.dataMundtSimMgr->LineNode(NodeID, state.dataMundtSimMgr->MundtZoneNum).Temp = TempResult;
     691            0 :     }
     692              : 
     693              :     //*****************************************************************************************
     694              : 
     695            0 :     void SetSurfTmeanAir(EnergyPlusData &state,
     696              :                          int const SurfID,    // surface ID
     697              :                          Real64 const TeffAir // temperature of air node adjacent to the specified surface
     698              :     )
     699              :     {
     700              : 
     701              :         // SUBROUTINE INFORMATION:
     702              :         //       AUTHOR         Brent Griffith
     703              :         //       DATE WRITTEN   September 2002
     704              :         //       RE-ENGINEERED  April 2003, Wiexiu Kong, EnergyPlus Implementation
     705              :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     706              : 
     707              :         // PURPOSE OF THIS SUBROUTINE:
     708              :         //   provide set routine for air model prediction of
     709              :         //   effective air for single surface
     710              : 
     711            0 :         state.dataMundtSimMgr->MundtAirSurf(SurfID, state.dataMundtSimMgr->MundtZoneNum).TMeanAir = TeffAir;
     712            0 :     }
     713              : 
     714              :     //*****************************************************************************************
     715              : 
     716            0 :     void SetSurfHBDataForDispVent1Node(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     717              :     {
     718              : 
     719              :         // SUBROUTINE INFORMATION:
     720              :         //       AUTHOR         Chanvit Chantrasrisalai
     721              :         //       DATE WRITTEN   July 2003
     722              :         //       MODIFIED       February 2004, fix allocate-deallocate problem (CC)
     723              :         //       RE-ENGINEERED  na
     724              : 
     725              :         // PURPOSE OF THIS SUBROUTINE:
     726              :         //     map data from air domain back to surface domain for each particular zone
     727              : 
     728              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     729              :         Real64 DeltaTemp; // dummy variable for temperature difference
     730              : 
     731              :         // get surface info
     732            0 :         int NumOfSurfs = state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs;
     733              : 
     734            0 :         if ((state.dataMundtSimMgr->SupplyAirVolumeRate > 0.0001) &&
     735            0 :             (state.dataMundtSimMgr->QsysCoolTot > 0.0001)) { // Controlled zone when the system is on
     736              : 
     737            0 :             if (state.dataRoomAir->AirModel(ZoneNum).TempCoupleScheme == RoomAir::CouplingScheme::Direct) {
     738              :                 // Use direct coupling scheme to report air temperatures back to surface/system domains
     739              :                 // a) Bulk air temperatures -> TempEffBulkAir(SurfNum)
     740            0 :                 for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
     741            0 :                     int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
     742            0 :                     state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) =
     743            0 :                         state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).TMeanAir;
     744              :                     // set flag for reference air temperature
     745            0 :                     state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
     746            0 :                     state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
     747              :                 }
     748              :                 // b) Average zone air temperature -> ZT(ZoneNum)
     749              :                 // For Mundt model, average room air is the weighted value of floor and ceiling air temps
     750              :                 // TRoomAverage = ( LineNode( MundtCeilAirID, MundtZoneNum ).Temp + LineNode( MundtFootAirID, MundtZoneNum ).Temp ) / 2;
     751              :                 // ZT(ZoneNum) = TRoomAverage
     752              :                 // c) Leaving-zone air temperature -> Node(ZoneNode)%Temp
     753            0 :                 int ZoneNodeNum = state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber;
     754            0 :                 state.dataLoopNodes->Node(ZoneNodeNum).Temp =
     755            0 :                     state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
     756              :                 // d) Thermostat air temperature -> TempTstatAir(ZoneNum)
     757            0 :                 state.dataHeatBalFanSys->TempTstatAir(ZoneNum) =
     758            0 :                     state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
     759              :             } else {
     760              :                 // Use indirect coupling scheme to report air temperatures back to surface/system domains
     761              :                 // a) Bulk air temperatures -> TempEffBulkAir(SurfNum)
     762            0 :                 for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
     763            0 :                     int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
     764            0 :                     DeltaTemp = state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).TMeanAir -
     765            0 :                                 state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
     766            0 :                     state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum).setpt + DeltaTemp;
     767              :                     // set flag for reference air temperature
     768            0 :                     state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
     769            0 :                     state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
     770              :                 }
     771              :                 // b) Average zone air temperature -> ZT(ZoneNum)
     772              :                 // For Mundt model, average room air is the weighted value of floor and ceiling air temps
     773              :                 // TRoomAverage = ( LineNode( MundtCeilAirID, MundtZoneNum ).Temp + LineNode( MundtFootAirID, MundtZoneNum ).Temp ) / 2;
     774              :                 // DeltaTemp = TRoomAverage - LineNode( TstatNodeID, MundtZoneNum ).Temp;
     775              :                 // ZT(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp
     776              :                 // c) Leaving-zone air temperature -> Node(ZoneNode)%Temp
     777            0 :                 int ZoneNodeNum = state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber;
     778            0 :                 DeltaTemp = state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->ReturnNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp -
     779            0 :                             state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp;
     780            0 :                 state.dataLoopNodes->Node(ZoneNodeNum).Temp = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum).setpt + DeltaTemp;
     781              :                 // d) Thermostat air temperature -> TempTstatAir(ZoneNum)
     782            0 :                 state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum)
     783            0 :                                                                      .ZT; // for indirect coupling, control air temp is equal to mean air temp?
     784              :             }
     785              :             // set flag to indicate that Mundt model is used for this zone at the present time
     786            0 :             state.dataRoomAir->AirModel(ZoneNum).SimAirModel = true;
     787              :         } else { // Controlled zone when the system is off --> Use the mixing model instead of the Mundt model
     788              :             // Bulk air temperatures -> TempEffBulkAir(SurfNum)
     789            0 :             for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) {
     790            0 :                 int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum);
     791            0 :                 state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
     792              :                 // set flag for reference air temperature
     793            0 :                 state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp;
     794            0 :                 state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)];
     795              :             }
     796              :             // set flag to indicate that Mundt model is NOT used for this zone at the present time
     797            0 :             state.dataRoomAir->AirModel(ZoneNum).SimAirModel = false;
     798              :         }
     799            0 :     }
     800              : 
     801              :     //*****************************************************************************************
     802              : 
     803              : } // namespace RoomAir
     804              : 
     805              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1