LCOV - code coverage report
Current view: top level - EnergyPlus - RoomAirModelUserTempPattern.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 285 331 86.1 %
Date: 2024-08-23 23:50:59 Functions: 11 11 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // ObjexxFCL Headers
      49             : #include <ObjexxFCL/Array.functions.hh>
      50             : #include <ObjexxFCL/Array1D.hh>
      51             : #include <ObjexxFCL/ArrayS.functions.hh>
      52             : #include <ObjexxFCL/Fmath.hh>
      53             : #include <ObjexxFCL/member.functions.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      57             : #include <EnergyPlus/DataEnvironment.hh>
      58             : #include <EnergyPlus/DataErrorTracking.hh>
      59             : #include <EnergyPlus/DataHVACGlobals.hh>
      60             : #include <EnergyPlus/DataHeatBalFanSys.hh>
      61             : #include <EnergyPlus/DataHeatBalance.hh>
      62             : #include <EnergyPlus/DataLoopNode.hh>
      63             : #include <EnergyPlus/DataRoomAirModel.hh>
      64             : #include <EnergyPlus/DataSurfaces.hh>
      65             : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      66             : #include <EnergyPlus/DataZoneEquipment.hh>
      67             : #include <EnergyPlus/FluidProperties.hh>
      68             : #include <EnergyPlus/General.hh>
      69             : #include <EnergyPlus/InternalHeatGains.hh>
      70             : #include <EnergyPlus/OutputProcessor.hh>
      71             : #include <EnergyPlus/Psychrometrics.hh>
      72             : #include <EnergyPlus/RoomAirModelUserTempPattern.hh>
      73             : #include <EnergyPlus/ScheduleManager.hh>
      74             : #include <EnergyPlus/UtilityRoutines.hh>
      75             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      76             : 
      77             : namespace EnergyPlus::RoomAir {
      78             : 
      79             : // MODULE INFORMATION:
      80             : //       AUTHOR         Brent Griffith
      81             : //       DATE WRITTEN   August 2005 (started in January 2004)
      82             : //       RE-ENGINEERED
      83             : 
      84             : // PURPOSE OF THIS MODULE:
      85             : // This module is the main module for running the
      86             : // user-defined temperature pattern model.
      87             : // This "air model" doesn't predict anything about the room air
      88             : // but provides a method for users to model the
      89             : // impact of non-uniform air temps.  the distribution of air temperatures
      90             : // is defined by the user and referred to as a "pattern"
      91             : 
      92             : // METHODOLOGY EMPLOYED:
      93             : // This module contains all subroutines required by the
      94             : // user defined temperature pattern roomair modeling.
      95             : // See DataRoomAir.cc for variable declarations
      96             : 
      97             : // Functions
      98             : 
      99       37269 : void ManageUserDefinedPatterns(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     100             : {
     101             : 
     102             :     // SUBROUTINE INFORMATION:
     103             :     //       AUTHOR         Brent Griffith
     104             :     //       DATE WRITTEN   January 2004/Aug 2005
     105             :     //       MODIFIED       na
     106             :     //       RE-ENGINEERED  na
     107             : 
     108             :     // PURPOSE OF THIS SUBROUTINE:
     109             :     //  manage the user-defined air temp. distribution model
     110             : 
     111             :     // transfer data from surface domain to air domain for the specified zone
     112       37269 :     InitTempDistModel(state, ZoneNum);
     113             : 
     114       37269 :     GetSurfHBDataForTempDistModel(state, ZoneNum);
     115             : 
     116             :     // perform TempDist model calculations
     117       37269 :     CalcTempDistModel(state, ZoneNum);
     118             : 
     119             :     // transfer data from air domain back to surface domain for the specified zone
     120       37269 :     SetSurfHBDataForTempDistModel(state, ZoneNum);
     121       37269 : }
     122             : 
     123             : //****************************************************
     124             : 
     125       37269 : void InitTempDistModel(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     126             : {
     127             : 
     128             :     // SUBROUTINE INFORMATION:
     129             :     //       AUTHOR         <author>
     130             :     //       DATE WRITTEN   <date_written>
     131             : 
     132       37269 :     if (state.dataRoomAirModelTempPattern->MyOneTimeFlag) {
     133           1 :         state.dataRoomAirModelTempPattern->MyEnvrnFlag.dimension(state.dataGlobal->NumOfZones, true);
     134           1 :         state.dataRoomAirModelTempPattern->MyOneTimeFlag = false;
     135             :     }
     136             : 
     137       37269 :     auto &patternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
     138       37269 :     if (state.dataGlobal->BeginEnvrnFlag && state.dataRoomAirModelTempPattern->MyEnvrnFlag(ZoneNum)) {
     139          81 :         patternZoneInfo.TairMean = 23.0;
     140          81 :         patternZoneInfo.Tstat = 23.0;
     141          81 :         patternZoneInfo.Tleaving = 23.0;
     142          81 :         patternZoneInfo.Texhaust = 23.0;
     143          81 :         patternZoneInfo.Gradient = 0.0;
     144        3780 :         for (int SurfNum = 1; SurfNum <= patternZoneInfo.totNumSurfs; ++SurfNum) {
     145        3699 :             patternZoneInfo.Surf(SurfNum).TadjacentAir = 23.0;
     146             :         }
     147          81 :         state.dataRoomAirModelTempPattern->MyEnvrnFlag(ZoneNum) = false;
     148             :     }
     149             : 
     150       37269 :     if (!state.dataGlobal->BeginEnvrnFlag) state.dataRoomAirModelTempPattern->MyEnvrnFlag(ZoneNum) = true;
     151             : 
     152             :     // init report variable
     153       37269 :     patternZoneInfo.Gradient = 0.0;
     154       37269 : }
     155             : 
     156       37269 : void GetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     157             : {
     158             : 
     159             :     // SUBROUTINE INFORMATION:
     160             :     //       AUTHOR         B. Griffith
     161             :     //       DATE WRITTEN   August 2005
     162             : 
     163             :     // PURPOSE OF THIS SUBROUTINE:
     164             :     //  map data from Heat Balance domain to Room Air Modeling Domain
     165             :     //  for the current zone, (only need mean air temp)
     166             :     //  also acts as an init routine
     167             : 
     168             :     // METHODOLOGY EMPLOYED:
     169             :     // use ZT from DataHeatBalFanSys
     170             : 
     171       37269 :     auto &patternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
     172       37269 :     auto const &zoneHeatBal = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     173             :     // intialize in preperation for calculations
     174       37269 :     patternZoneInfo.Tstat = zoneHeatBal.MAT;
     175       37269 :     patternZoneInfo.Tleaving = zoneHeatBal.MAT;
     176       37269 :     patternZoneInfo.Texhaust = zoneHeatBal.MAT;
     177     1739220 :     for (auto &e : patternZoneInfo.Surf)
     178     1701951 :         e.TadjacentAir = zoneHeatBal.MAT;
     179             : 
     180             :     // the only input this method needs is the zone MAT or ZT or ZTAV  ?  (original was ZT)
     181       37269 :     patternZoneInfo.TairMean = zoneHeatBal.MAT; // this is lagged from previous corrector result
     182       37269 : }
     183             : 
     184             : //*****************************************************************************************
     185             : 
     186       37269 : void CalcTempDistModel(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     187             : {
     188             : 
     189             :     // SUBROUTINE INFORMATION:
     190             :     //       AUTHOR         Brent Griffith
     191             :     //       DATE WRITTEN   August 2005
     192             :     //       MODIFIED
     193             :     //       RE-ENGINEERED
     194             : 
     195             :     // PURPOSE OF THIS SUBROUTINE:
     196             :     // figure out which pattern is scheduled and call
     197             :     // appropriate subroutine
     198             : 
     199             :     // Using/Aliasing
     200             :     using General::FindNumberInList;
     201             :     using ScheduleManager::GetCurrentScheduleValue;
     202             : 
     203       37269 :     auto &patternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
     204             :     // first determine availability
     205       37269 :     Real64 AvailTest = GetCurrentScheduleValue(state, patternZoneInfo.AvailSchedID);
     206             : 
     207       37269 :     if ((AvailTest != 1.0) || (!patternZoneInfo.IsUsed)) {
     208             :         // model not to be used. Use complete mixing method
     209             : 
     210        3470 :         patternZoneInfo.Tstat = patternZoneInfo.TairMean;
     211        3470 :         patternZoneInfo.Tleaving = patternZoneInfo.TairMean;
     212        3470 :         patternZoneInfo.Texhaust = patternZoneInfo.TairMean;
     213      164825 :         for (auto &e : patternZoneInfo.Surf)
     214      161355 :             e.TadjacentAir = patternZoneInfo.TairMean;
     215             : 
     216        3470 :         return;
     217             : 
     218             :     } else { // choose pattern and call subroutine
     219             : 
     220       33799 :         int CurntPatternKey = GetCurrentScheduleValue(state, patternZoneInfo.PatternSchedID);
     221             : 
     222       33799 :         int CurPatrnID = FindNumberInList(CurntPatternKey, state.dataRoomAir->AirPattern, &TemperaturePattern::PatrnID);
     223             : 
     224       33799 :         if (CurPatrnID == 0) {
     225             :             // throw error here ? way to test schedules before getting to this point?
     226           0 :             ShowFatalError(state, format("User defined room air pattern index not found: {}", CurntPatternKey));
     227           0 :             return;
     228             :         }
     229             : 
     230       33799 :         switch (state.dataRoomAir->AirPattern(CurPatrnID).PatternMode) {
     231       10389 :         case UserDefinedPatternType::ConstGradTemp: {
     232       10389 :             FigureConstGradPattern(state, CurPatrnID, ZoneNum);
     233       10389 :         } break;
     234       17760 :         case UserDefinedPatternType::TwoGradInterp: {
     235       17760 :             FigureTwoGradInterpPattern(state, CurPatrnID, ZoneNum);
     236       17760 :         } break;
     237        4842 :         case UserDefinedPatternType::NonDimenHeight: {
     238        4842 :             FigureHeightPattern(state, CurPatrnID, ZoneNum);
     239        4842 :         } break;
     240         808 :         case UserDefinedPatternType::SurfMapTemp: {
     241         808 :             FigureSurfMapPattern(state, CurPatrnID, ZoneNum);
     242         808 :         } break;
     243           0 :         default: {
     244           0 :             assert(false);
     245             :         } break;
     246             :         }
     247             :     } // availability control construct
     248             : }
     249             : 
     250         808 : void FigureSurfMapPattern(EnergyPlusData &state, int const PattrnID, int const ZoneNum)
     251             : {
     252             : 
     253             :     // SUBROUTINE INFORMATION:
     254             :     //       AUTHOR         B Griffith
     255             :     //       DATE WRITTEN   August 2005
     256             :     //       MODIFIED       na
     257             :     //       RE-ENGINEERED  na
     258             : 
     259             :     // PURPOSE OF THIS SUBROUTINE:
     260             :     // main calculation routine for surface pattern
     261             : 
     262             :     // METHODOLOGY EMPLOYED:
     263             :     // simple polling and applying prescribed
     264             :     // delta Tai's to current mean air temp
     265             :     // on a surface by surface basis
     266             : 
     267             :     // Using/Aliasing
     268             :     using General::FindNumberInList;
     269             : 
     270         808 :     auto &patternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
     271         808 :     auto &pattern = state.dataRoomAir->AirPattern(PattrnID);
     272         808 :     Real64 Tmean = patternZoneInfo.TairMean;
     273             : 
     274       40400 :     for (int i = 1; i <= patternZoneInfo.totNumSurfs; ++i) {
     275             :         // cycle through zone surfaces and look for match
     276       39592 :         int found = FindNumberInList(patternZoneInfo.Surf(i).SurfID, pattern.MapPatrn.SurfID, pattern.MapPatrn.NumSurfs);
     277       39592 :         if (found != 0) { // if surf is in map then assign, else give it MAT
     278        7272 :             patternZoneInfo.Surf(i).TadjacentAir = pattern.MapPatrn.DeltaTai(found) + Tmean;
     279             :         } else {
     280       32320 :             patternZoneInfo.Surf(i).TadjacentAir = Tmean;
     281             :         }
     282             :     }
     283             : 
     284         808 :     patternZoneInfo.Tstat = pattern.DeltaTstat + Tmean;
     285         808 :     patternZoneInfo.Tleaving = pattern.DeltaTleaving + Tmean;
     286         808 :     patternZoneInfo.Texhaust = pattern.DeltaTexhaust + Tmean;
     287         808 : }
     288             : 
     289        4842 : void FigureHeightPattern(EnergyPlusData &state, int const PattrnID, int const ZoneNum)
     290             : {
     291             : 
     292             :     // SUBROUTINE INFORMATION:
     293             :     //       AUTHOR         B Griffith
     294             :     //       DATE WRITTEN   August 2005
     295             : 
     296             :     // PURPOSE OF THIS SUBROUTINE:
     297             :     // calculate the pattern for non-dimensional vertical profile
     298             : 
     299             :     // METHODOLOGY EMPLOYED:
     300             :     // treat profile as lookup table and interpolate
     301             : 
     302             :     // Using/Aliasing
     303             :     using FluidProperties::FindArrayIndex;
     304             : 
     305             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     306             : 
     307        4842 :     auto &patternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
     308        4842 :     auto &pattern = state.dataRoomAir->AirPattern(PattrnID);
     309        4842 :     Real64 tmpDeltaTai = 0.0;
     310        4842 :     Real64 Tmean = patternZoneInfo.TairMean;
     311             : 
     312      197185 :     for (int i = 1; i <= patternZoneInfo.totNumSurfs; ++i) {
     313             : 
     314      192343 :         Real64 zeta = patternZoneInfo.Surf(i).Zeta;
     315      192343 :         int lowSideID = FindArrayIndex(zeta, pattern.VertPatrn.ZetaPatrn);
     316      192343 :         int highSideID = lowSideID + 1;
     317      192343 :         if (lowSideID == 0) lowSideID = 1; // protect against array bounds
     318             : 
     319      192343 :         Real64 lowSideZeta = pattern.VertPatrn.ZetaPatrn(lowSideID);
     320      192343 :         Real64 hiSideZeta = (highSideID <= isize(pattern.VertPatrn.ZetaPatrn)) ? pattern.VertPatrn.ZetaPatrn(highSideID) : lowSideZeta;
     321             : 
     322      192343 :         if ((hiSideZeta - lowSideZeta) != 0.0) {
     323      182659 :             Real64 fractBtwn = (zeta - lowSideZeta) / (hiSideZeta - lowSideZeta);
     324      182659 :             tmpDeltaTai = pattern.VertPatrn.DeltaTaiPatrn(lowSideID) +
     325      182659 :                           fractBtwn * (pattern.VertPatrn.DeltaTaiPatrn(highSideID) - pattern.VertPatrn.DeltaTaiPatrn(lowSideID));
     326             : 
     327             :         } else { // would divide by zero, using low side value
     328             : 
     329        9684 :             tmpDeltaTai = pattern.VertPatrn.DeltaTaiPatrn(lowSideID);
     330             :         }
     331             : 
     332      192343 :         patternZoneInfo.Surf(i).TadjacentAir = tmpDeltaTai + Tmean;
     333             : 
     334             :     } // surfaces in this zone
     335             : 
     336        4842 :     patternZoneInfo.Tstat = pattern.DeltaTstat + Tmean;
     337        4842 :     patternZoneInfo.Tleaving = pattern.DeltaTleaving + Tmean;
     338        4842 :     patternZoneInfo.Texhaust = pattern.DeltaTexhaust + Tmean;
     339        4842 : }
     340             : 
     341       17760 : void FigureTwoGradInterpPattern(EnergyPlusData &state, int const PattrnID, int const ZoneNum)
     342             : {
     343             : 
     344             :     // SUBROUTINE INFORMATION:
     345             :     //       AUTHOR         B Griffith
     346             :     //       DATE WRITTEN   Aug 2005
     347             : 
     348             :     // PURPOSE OF THIS SUBROUTINE:
     349             :     // calculate two gradient interpolation pattern
     350             : 
     351             :     // METHODOLOGY EMPLOYED:
     352             :     // Case statement controls how interpolations are done
     353             :     // based on user selected mode.
     354             :     // calculations vary by mode
     355             : 
     356             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     357             :     Real64 Grad; // vertical temperature gradient C/m
     358             : 
     359       17760 :     auto &patternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
     360       17760 :     auto &pattern = state.dataRoomAir->AirPattern(PattrnID);
     361             : 
     362       17760 :     if (state.dataRoomAirModelTempPattern->MyOneTimeFlag2) {
     363           1 :         state.dataRoomAirModelTempPattern->SetupOutputFlag.dimension(state.dataGlobal->NumOfZones, true); // init
     364           1 :         state.dataRoomAirModelTempPattern->MyOneTimeFlag2 = false;
     365             :     }
     366             : 
     367       17760 :     if (state.dataRoomAirModelTempPattern->SetupOutputFlag(ZoneNum)) {
     368          12 :         SetupOutputVariable(state,
     369             :                             "Room Air Zone Vertical Temperature Gradient",
     370             :                             Constant::Units::K_m,
     371           6 :                             patternZoneInfo.Gradient,
     372             :                             OutputProcessor::TimeStepType::System,
     373             :                             OutputProcessor::StoreType::Average,
     374           6 :                             patternZoneInfo.ZoneName);
     375             : 
     376           6 :         state.dataRoomAirModelTempPattern->SetupOutputFlag(ZoneNum) = false;
     377             :     }
     378             : 
     379       17760 :     Real64 Tmean = patternZoneInfo.TairMean;
     380             : 
     381       17760 :     auto const &twoGrad = pattern.TwoGradPatrn;
     382             :     // determine gradient depending on mode
     383       17760 :     switch (pattern.TwoGradPatrn.InterpolationMode) {
     384        2670 :     case UserDefinedPatternMode::OutdoorDryBulb: {
     385        2670 :         Grad = OutdoorDryBulbGrad(state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp,
     386        2670 :                                   twoGrad.UpperBoundTempScale,
     387        2670 :                                   twoGrad.HiGradient,
     388        2670 :                                   twoGrad.LowerBoundTempScale,
     389        2670 :                                   twoGrad.LowGradient);
     390        2670 :     } break;
     391        4402 :     case UserDefinedPatternMode::ZoneAirTemp: {
     392        4402 :         if (Tmean >= twoGrad.UpperBoundTempScale) {
     393        1250 :             Grad = twoGrad.HiGradient;
     394        3152 :         } else if (Tmean <= twoGrad.LowerBoundTempScale) {
     395        2164 :             Grad = twoGrad.LowGradient;
     396         988 :         } else if ((twoGrad.UpperBoundTempScale - twoGrad.LowerBoundTempScale) == 0.0) {
     397             :             // bad user input, trapped during get input
     398           0 :             Grad = twoGrad.LowGradient;
     399             :         } else {
     400         988 :             Grad = twoGrad.LowGradient + ((Tmean - twoGrad.LowerBoundTempScale) / (twoGrad.UpperBoundTempScale - twoGrad.LowerBoundTempScale)) *
     401         988 :                                              (twoGrad.HiGradient - twoGrad.LowGradient);
     402             :         }
     403        4402 :     } break;
     404        2406 :     case UserDefinedPatternMode::DeltaOutdoorZone: {
     405        2406 :         Real64 DeltaT = state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp - Tmean;
     406        2406 :         if (DeltaT >= twoGrad.UpperBoundTempScale) {
     407         576 :             Grad = twoGrad.HiGradient;
     408        1830 :         } else if (DeltaT <= twoGrad.LowerBoundTempScale) {
     409        1131 :             Grad = twoGrad.LowGradient;
     410         699 :         } else if ((twoGrad.UpperBoundTempScale - twoGrad.LowerBoundTempScale) == 0.0) {
     411           0 :             Grad = twoGrad.LowGradient;
     412             :         } else {
     413         699 :             Grad = twoGrad.LowGradient + ((DeltaT - twoGrad.LowerBoundTempScale) / (twoGrad.UpperBoundTempScale - twoGrad.LowerBoundTempScale)) *
     414         699 :                                              (twoGrad.HiGradient - twoGrad.LowGradient);
     415             :         }
     416        2406 :     } break;
     417        4141 :     case UserDefinedPatternMode::SensibleCooling: {
     418        4141 :         Real64 CoolLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).airSysCoolRate;
     419        4141 :         if (CoolLoad >= twoGrad.UpperBoundHeatRateScale) {
     420         270 :             Grad = twoGrad.HiGradient;
     421             : 
     422        3871 :         } else if (CoolLoad <= twoGrad.LowerBoundHeatRateScale) {
     423             : 
     424        2487 :             Grad = twoGrad.LowGradient;
     425             :         } else { // interpolate
     426        1384 :             if ((twoGrad.UpperBoundHeatRateScale - twoGrad.LowerBoundHeatRateScale) == 0.0) {
     427           0 :                 Grad = twoGrad.LowGradient;
     428             :             } else {
     429             : 
     430        1384 :                 Grad = twoGrad.LowGradient +
     431        1384 :                        ((CoolLoad - twoGrad.LowerBoundHeatRateScale) / (twoGrad.UpperBoundHeatRateScale - twoGrad.LowerBoundHeatRateScale)) *
     432        1384 :                            (twoGrad.HiGradient - twoGrad.LowGradient);
     433             :             }
     434             :         }
     435        4141 :     } break;
     436        4141 :     case UserDefinedPatternMode::SensibleHeating: {
     437        4141 :         Real64 HeatLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).airSysHeatRate;
     438        4141 :         if (HeatLoad >= twoGrad.UpperBoundHeatRateScale) {
     439        2260 :             Grad = twoGrad.HiGradient;
     440        1881 :         } else if (HeatLoad <= twoGrad.LowerBoundHeatRateScale) {
     441        1880 :             Grad = twoGrad.LowGradient;
     442           1 :         } else if ((twoGrad.UpperBoundHeatRateScale - twoGrad.LowerBoundHeatRateScale) == 0.0) {
     443           0 :             Grad = twoGrad.LowGradient;
     444             :         } else {
     445           1 :             Grad = twoGrad.LowGradient +
     446           1 :                    ((HeatLoad - twoGrad.LowerBoundHeatRateScale) / (twoGrad.UpperBoundHeatRateScale - twoGrad.LowerBoundHeatRateScale)) *
     447           1 :                        (twoGrad.HiGradient - twoGrad.LowGradient);
     448             :         }
     449        4141 :     } break;
     450           0 :     default:
     451           0 :         break;
     452             :     }
     453             : 
     454       17760 :     Real64 ZetaTmean = 0.5; // by definition,
     455             : 
     456      852640 :     for (int i = 1; i <= patternZoneInfo.totNumSurfs; ++i) {
     457      834880 :         Real64 zeta = patternZoneInfo.Surf(i).Zeta;
     458      834880 :         Real64 DeltaHeight = -1.0 * (ZetaTmean - zeta) * patternZoneInfo.ZoneHeight;
     459      834880 :         patternZoneInfo.Surf(i).TadjacentAir = (DeltaHeight * Grad) + Tmean;
     460             :     }
     461             : 
     462       17760 :     patternZoneInfo.Tstat = -1.0 * (0.5 * patternZoneInfo.ZoneHeight - twoGrad.TstatHeight) * Grad + Tmean;
     463       17760 :     patternZoneInfo.Tleaving = -1.0 * (0.5 * patternZoneInfo.ZoneHeight - twoGrad.TleavingHeight) * Grad + Tmean;
     464       17760 :     patternZoneInfo.Texhaust = -1.0 * (0.5 * patternZoneInfo.ZoneHeight - twoGrad.TexhaustHeight) * Grad + Tmean;
     465       17760 :     patternZoneInfo.Gradient = Grad;
     466       17760 : }
     467             : 
     468        2670 : Real64 OutdoorDryBulbGrad(Real64 DryBulbTemp, // Zone(ZoneNum).OutDryBulbTemp
     469             :                           Real64 UpperBound,  // RoomAirPattern(PattrnID).TwoGradPatrn.UpperBoundTempScale
     470             :                           Real64 HiGradient,  // RoomAirPattern(PattrnID).TwoGradPatrn.HiGradient
     471             :                           Real64 LowerBound,  // RoomAirPattern(PattrnID).TwoGradPatrn.LowerBoundTempScale
     472             :                           Real64 LowGradient  // RoomAirPattern(PattrnID).TwoGradPatrn.LowGradient
     473             : )
     474             : {
     475        2670 :     if (DryBulbTemp >= UpperBound) {
     476        1069 :         return HiGradient;
     477        1601 :     } else if (DryBulbTemp <= LowerBound) {
     478        1395 :         return LowGradient;
     479         206 :     } else if ((UpperBound - LowerBound) == 0.0) {
     480           0 :         return LowGradient;
     481             :     } else {
     482         206 :         return LowGradient + ((DryBulbTemp - LowerBound) / (UpperBound - LowerBound)) * (HiGradient - LowGradient);
     483             :     }
     484             : }
     485             : 
     486       10389 : void FigureConstGradPattern(EnergyPlusData &state, int const PattrnID, int const ZoneNum)
     487             : {
     488             : 
     489             :     // SUBROUTINE INFORMATION:
     490             :     //       AUTHOR         B. Griffith
     491             :     //       DATE WRITTEN   August 2005
     492             : 
     493       10389 :     auto &patternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
     494       10389 :     auto &pattern = state.dataRoomAir->AirPattern(PattrnID);
     495       10389 :     Real64 Tmean = patternZoneInfo.TairMean;  // MAT
     496       10389 :     Real64 Grad = pattern.GradPatrn.Gradient; // Vertical temperature gradient
     497             : 
     498       10389 :     Real64 ZetaTmean = 0.5; // non-dimensional height for MAT
     499             : 
     500      484170 :     for (int i = 1; i <= patternZoneInfo.totNumSurfs; ++i) {
     501      473781 :         Real64 zeta = patternZoneInfo.Surf(i).Zeta;
     502      473781 :         Real64 DeltaHeight = -1.0 * (ZetaTmean - zeta) * patternZoneInfo.ZoneHeight;
     503      473781 :         patternZoneInfo.Surf(i).TadjacentAir = DeltaHeight * Grad + Tmean;
     504             :     }
     505             : 
     506       10389 :     patternZoneInfo.Tstat = pattern.DeltaTstat + Tmean;
     507       10389 :     patternZoneInfo.Tleaving = pattern.DeltaTleaving + Tmean;
     508       10389 :     patternZoneInfo.Texhaust = pattern.DeltaTexhaust + Tmean;
     509       10389 : }
     510             : 
     511             : //*****************************************************************************************
     512             : 
     513         402 : Real64 FigureNDheightInZone(EnergyPlusData &state, int const thisHBsurf) // index in main Surface array
     514             : {
     515             :     // FUNCTION INFORMATION:
     516             :     //       AUTHOR         B.Griffith
     517             :     //       DATE WRITTEN   aug 2005, Jan2004
     518             : 
     519             :     // PURPOSE OF THIS FUNCTION:
     520             :     // return a non-dimensional height zeta
     521             : 
     522             :     // METHODOLOGY EMPLOYED:
     523             :     // figure average floor height (follows code in surfacegeometry.cc
     524             :     // use ceiling height from Zone structure
     525             :     // non dimensionalize surface's centroid's Z value
     526             : 
     527             :     // FUNCTION PARAMETER DEFINITIONS:
     528         402 :     Real64 constexpr TolValue(0.0001);
     529             : 
     530             :     // Get the centroid height for the surface
     531         402 :     Real64 Zcm = state.dataSurface->Surface(thisHBsurf).Centroid.z;
     532         402 :     auto &zone = state.dataHeatBal->Zone(state.dataSurface->Surface(thisHBsurf).Zone);
     533             : 
     534             :     // this next Do block is copied from SurfaceGeometry.cc with modification for just floor Z
     535             :     // used find floor z.
     536         402 :     int FloorCount = 0;
     537         402 :     Real64 ZFlrAvg = 0.0;
     538         402 :     Real64 ZMax = 0.0;
     539         402 :     Real64 ZMin = 0.0;
     540         402 :     int Count = 0;
     541         804 :     for (int spaceNum : zone.spaceIndexes) {
     542         402 :         auto &thisSpace = state.dataHeatBal->space(spaceNum);
     543       18860 :         for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
     544       18458 :             auto const &surf = state.dataSurface->Surface(SurfNum);
     545       18458 :             if (surf.Class == DataSurfaces::SurfaceClass::Floor) {
     546             :                 // Use Average Z for surface, more important for roofs than floors...
     547         402 :                 ++FloorCount;
     548         402 :                 Real64 Z1 = minval(surf.Vertex, &Vector3<Real64>::z);
     549         402 :                 Real64 Z2 = maxval(surf.Vertex, &Vector3<Real64>::z);
     550         402 :                 ZFlrAvg += (Z1 + Z2) / 2.0;
     551       18056 :             } else if (surf.Class == DataSurfaces::SurfaceClass::Wall) {
     552             :                 // Use Wall calculation in case no floor in zone
     553       14472 :                 ++Count;
     554       14472 :                 if (Count == 1) {
     555         402 :                     ZMax = surf.Vertex(1).z;
     556         402 :                     ZMin = ZMax;
     557             :                 }
     558       14472 :                 ZMax = max(ZMax, maxval(surf.Vertex, &Vector3<Real64>::z));
     559       14472 :                 ZMin = min(ZMin, minval(surf.Vertex, &Vector3<Real64>::z));
     560             :             }
     561             :         }
     562         402 :     }
     563             : 
     564         402 :     ZFlrAvg = (FloorCount > 0.0) ? (ZFlrAvg / FloorCount) : ZMin;
     565             : 
     566         402 :     Real64 ZoneZorig = ZFlrAvg; // Z floor  [M]
     567         402 :     Real64 ZoneCeilHeight = zone.CeilingHeight;
     568             : 
     569             :     // first check if some basic things are reasonable
     570             : 
     571         402 :     Real64 SurfMinZ = minval(state.dataSurface->Surface(thisHBsurf).Vertex, &Vector3<Real64>::z);
     572         402 :     Real64 SurfMaxZ = maxval(state.dataSurface->Surface(thisHBsurf).Vertex, &Vector3<Real64>::z);
     573             : 
     574         402 :     if (SurfMinZ < (ZoneZorig - TolValue)) {
     575           0 :         if (state.dataGlobal->DisplayExtraWarnings) {
     576           0 :             ShowWarningError(state, "RoomAirModelUserTempPattern: Problem in non-dimensional height calculation");
     577           0 :             ShowContinueError(state, format("too low surface: {} in zone: {}", state.dataSurface->Surface(thisHBsurf).Name, zone.Name));
     578           0 :             ShowContinueError(state, format("**** Average floor height of zone is: {:.3R}", ZoneZorig));
     579           0 :             ShowContinueError(state, format("**** Surface minimum height is: {:.3R}", SurfMinZ));
     580             :         } else {
     581           0 :             ++state.dataErrTracking->TotalRoomAirPatternTooLow;
     582             :         }
     583             :     }
     584             : 
     585         402 :     if (SurfMaxZ > (ZoneZorig + ZoneCeilHeight + TolValue)) {
     586           0 :         if (state.dataGlobal->DisplayExtraWarnings) {
     587           0 :             ShowWarningError(state, "RoomAirModelUserTempPattern: Problem in non-dimensional height calculation");
     588           0 :             ShowContinueError(state, format(" too high surface: {} in zone: {}", state.dataSurface->Surface(thisHBsurf).Name, zone.Name));
     589           0 :             ShowContinueError(state, format("**** Average Ceiling height of zone is: {:.3R}", (ZoneZorig + ZoneCeilHeight)));
     590           0 :             ShowContinueError(state, format("**** Surface Maximum height is: {:.3R}", SurfMaxZ));
     591             :         } else {
     592           0 :             ++state.dataErrTracking->TotalRoomAirPatternTooHigh;
     593             :         }
     594             :     }
     595             : 
     596             :     // non dimensionalize.
     597         402 :     Real64 Zeta = (Zcm - ZoneZorig) / ZoneCeilHeight;
     598         402 :     if (Zeta > 0.99)
     599           9 :         Zeta = 0.99;
     600         393 :     else if (Zeta < 0.01)
     601           9 :         Zeta = 0.01;
     602             : 
     603         402 :     return Zeta;
     604             : }
     605             : 
     606             : //***************************************************
     607             : 
     608       37269 : void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // index number for the specified zone
     609             : {
     610             : 
     611             :     // SUBROUTINE INFORMATION:
     612             :     //       AUTHOR         Brent Griffith
     613             :     //       DATE WRITTEN   August 2005,Feb. 2004
     614             : 
     615             :     // PURPOSE OF THIS SUBROUTINE:
     616             :     //  map data from air domain back to surface domain for each zone
     617             :     //  collects code couples to remote data structures
     618             : 
     619             :     // METHODOLOGY EMPLOYED:
     620             :     // sets values in Heat balance variables
     621             : 
     622             :     // Using/Aliasing
     623             :     using HVAC::RetTempMax;
     624             :     using HVAC::RetTempMin;
     625             :     using InternalHeatGains::SumAllReturnAirLatentGains;
     626             :     using Psychrometrics::PsyCpAirFnW;
     627             :     using Psychrometrics::PsyHFnTdbW;
     628             :     using Psychrometrics::PsyHgAirFnWTdb;
     629             :     using Psychrometrics::PsyRhoAirFnPbTdbW;
     630             : 
     631             :     // set air system leaving node conditions
     632             :     // this is not so easy.  THis task is normally done in CalcZoneLeavingConditions
     633             :     //  but efforts to do this update there were not successful.
     634             :     //  Need to revisit how to best implement this. Ended up taking code from CalcZoneLeavingConditions
     635             :     //  ZoneNum is already equal to ActualZoneNum , changed block of source
     636             : 
     637       37269 :     auto &patternZoneInfo = state.dataRoomAir->AirPatternZoneInfo(ZoneNum);
     638             : 
     639       37269 :     if (patternZoneInfo.ZoneNodeID != 0) {
     640             :         // the zone system node should get the conditions leaving the zone (but before return air heat gains are added).
     641       37269 :         state.dataLoopNodes->Node(patternZoneInfo.ZoneNodeID).Temp = patternZoneInfo.Tleaving;
     642             :     }
     643             : 
     644             :     // What if ZoneNodeID is 0?
     645             : 
     646       37269 :     auto &zoneNode = state.dataLoopNodes->Node(patternZoneInfo.ZoneNodeID);
     647       37269 :     auto &zone = state.dataHeatBal->Zone(ZoneNum);
     648       37269 :     auto &zoneHeatBal = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     649             : 
     650       37269 :     int ZoneMult = zone.Multiplier * zone.ListMultiplier;
     651             : 
     652       74538 :     for (int returnNodeNum : state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNode) {
     653             :         // BEGIN BLOCK of code from CalcZoneLeavingConditions*********************************
     654       37269 :         auto &returnNode = state.dataLoopNodes->Node(returnNodeNum);
     655             : 
     656             :         // RETURN AIR HEAT GAIN from the Lights statement; this heat gain is stored in
     657             :         // Add sensible heat gain from refrigerated cases with under case returns
     658       37269 :         Real64 QRetAir = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, returnNodeNum);
     659             : 
     660       37269 :         Real64 CpAir = PsyCpAirFnW(zoneNode.HumRat);
     661             : 
     662             :         // Need to add the energy to the return air from lights and from airflow windows. Where the heat
     663             :         // is added depends on if there is system flow or not.  If there is system flow the heat is added
     664             :         // to the Zone Return Node.  If there is no system flow then the heat is added back to the zone in the
     665             :         // Correct step through the SysDepZoneLoads variable.
     666             : 
     667       37269 :         Real64 MassFlowRA = returnNode.MassFlowRate / ZoneMult;
     668       37269 :         Real64 TempZoneAir = patternZoneInfo.Tleaving; // key difference from
     669       37269 :         Real64 TempRetAir = TempZoneAir;
     670       37269 :         Real64 WinGapFlowToRA = 0.0;
     671       37269 :         Real64 WinGapTtoRA = 0.0;
     672       37269 :         Real64 WinGapFlowTtoRA = 0.0;
     673             : 
     674       37269 :         if (zone.HasAirFlowWindowReturn) {
     675           0 :             for (int spaceNum : zone.spaceIndexes) {
     676           0 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
     677           0 :                 for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
     678           0 :                     if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0 &&
     679           0 :                         state.dataSurface->SurfWinAirflowDestination(SurfNum) == DataSurfaces::WindowAirFlowDestination::Return) {
     680             :                         Real64 FlowThisTS =
     681           0 :                             PsyRhoAirFnPbTdbW(
     682           0 :                                 state, state.dataEnvrn->OutBaroPress, state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum), zoneNode.HumRat) *
     683           0 :                             state.dataSurface->SurfWinAirflowThisTS(SurfNum) * state.dataSurface->Surface(SurfNum).Width;
     684           0 :                         WinGapFlowToRA += FlowThisTS;
     685           0 :                         WinGapFlowTtoRA += FlowThisTS * state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum);
     686             :                     }
     687             :                 }
     688           0 :             }
     689             :         }
     690       37269 :         if (WinGapFlowToRA > 0.0) WinGapTtoRA = WinGapFlowTtoRA / WinGapFlowToRA;
     691             : 
     692       37269 :         if (!zone.NoHeatToReturnAir) {
     693       37269 :             if (MassFlowRA > 0.0) {
     694       36909 :                 if (WinGapFlowToRA > 0.0) {
     695             :                     // Add heat-to-return from window gap airflow
     696           0 :                     if (MassFlowRA >= WinGapFlowToRA) {
     697           0 :                         TempRetAir = (WinGapFlowTtoRA + (MassFlowRA - WinGapFlowToRA) * TempZoneAir) / MassFlowRA;
     698             :                     } else {
     699             :                         // All of return air comes from flow through airflow windows
     700           0 :                         TempRetAir = WinGapTtoRA;
     701             :                         // Put heat from window airflow that exceeds return air flow into zone air
     702           0 :                         zoneHeatBal.SysDepZoneLoads += (WinGapFlowToRA - MassFlowRA) * CpAir * (WinGapTtoRA - TempZoneAir);
     703             :                     }
     704             :                 }
     705             :                 // Add heat-to-return from lights
     706       36909 :                 TempRetAir += QRetAir / (MassFlowRA * CpAir);
     707       36909 :                 if (TempRetAir > RetTempMax) {
     708           1 :                     returnNode.Temp = RetTempMax;
     709           1 :                     if (!state.dataGlobal->ZoneSizingCalc) {
     710           0 :                         zoneHeatBal.SysDepZoneLoads += CpAir * MassFlowRA * (TempRetAir - RetTempMax);
     711             :                     }
     712       36908 :                 } else if (TempRetAir < RetTempMin) {
     713           0 :                     returnNode.Temp = RetTempMin;
     714           0 :                     if (!state.dataGlobal->ZoneSizingCalc) {
     715           0 :                         zoneHeatBal.SysDepZoneLoads += CpAir * MassFlowRA * (TempRetAir - RetTempMin);
     716             :                     }
     717             :                 } else {
     718       36908 :                     returnNode.Temp = TempRetAir;
     719             :                 }
     720             :             } else { // No return air flow
     721             :                 // Assign all heat-to-return from window gap airflow to zone air
     722         360 :                 if (WinGapFlowToRA > 0.0) zoneHeatBal.SysDepZoneLoads += WinGapFlowToRA * CpAir * (WinGapTtoRA - TempZoneAir);
     723             :                 // Assign all heat-to-return from lights to zone air
     724         360 :                 if (QRetAir > 0.0) zoneHeatBal.SysDepZoneLoads += QRetAir;
     725         360 :                 returnNode.Temp = zoneNode.Temp;
     726             :             }
     727             :         } else {
     728           0 :             returnNode.Temp = zoneNode.Temp;
     729             :         }
     730             : 
     731             :         // Update the rest of the Return Air Node conditions, if the return air system exists!
     732       37269 :         returnNode.Press = zoneNode.Press;
     733             : 
     734       37269 :         Real64 H2OHtOfVap = PsyHgAirFnWTdb(zoneNode.HumRat, returnNode.Temp);
     735             : 
     736             :         // Include impact of under case returns for refrigerated display cases when updateing return node
     737             :         // humidity ratio
     738       37269 :         if (!zone.NoHeatToReturnAir) {
     739       37269 :             if (MassFlowRA > 0) {
     740       36909 :                 Real64 SumRetAirLatentGainRate = SumAllReturnAirLatentGains(state, ZoneNum, returnNodeNum);
     741       36909 :                 returnNode.HumRat = zoneNode.HumRat + (SumRetAirLatentGainRate / (H2OHtOfVap * MassFlowRA));
     742             :             } else {
     743             :                 // If no mass flow rate exists, include the latent HVAC case credit with the latent Zone case credit
     744         360 :                 returnNode.HumRat = zoneNode.HumRat;
     745         360 :                 state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToZone += state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToHVAC;
     746             :                 // shouldn't the HVAC term be zeroed out then?
     747         360 :                 Real64 SumRetAirLatentGainRate = SumAllReturnAirLatentGains(state, ZoneNum, 0);
     748         360 :                 zoneHeatBal.latentGain += SumRetAirLatentGainRate;
     749             :             }
     750             :         } else {
     751           0 :             returnNode.HumRat = zoneNode.HumRat;
     752           0 :             state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToZone += state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToHVAC;
     753             :             // shouldn't the HVAC term be zeroed out then?
     754             : 
     755           0 :             zoneHeatBal.latentGain += SumAllReturnAirLatentGains(state, ZoneNum, returnNodeNum);
     756             :         }
     757             : 
     758       37269 :         returnNode.Enthalpy = PsyHFnTdbW(returnNode.Temp, returnNode.HumRat);
     759             : 
     760             :         // END BLOCK of code from CalcZoneLeavingConditions*********************************
     761             :     }
     762             : 
     763             :     // set exhaust node leaving temp if present
     764       37269 :     if (allocated(patternZoneInfo.ExhaustAirNodeID)) {
     765       45551 :         for (int exhaustAirNodeID : patternZoneInfo.ExhaustAirNodeID) {
     766        8282 :             state.dataLoopNodes->Node(exhaustAirNodeID).Temp = patternZoneInfo.Texhaust;
     767             :         }
     768             :     }
     769             : 
     770             :     // set thermostat reading for air system .
     771       37269 :     state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = patternZoneInfo.Tstat;
     772             : 
     773             :     // set results for all surface
     774       74538 :     for (int spaceNum : zone.spaceIndexes) {
     775       37269 :         auto &thisSpace = state.dataHeatBal->space(spaceNum);
     776     1739220 :         for (int i = thisSpace.HTSurfaceFirst, j = 0; i <= thisSpace.HTSurfaceLast; ++i) {
     777     1701951 :             state.dataHeatBal->SurfTempEffBulkAir(i) = patternZoneInfo.Surf(++j).TadjacentAir;
     778             :         }
     779       37269 :     }
     780             : 
     781             :     // set flag for reference air temperature mode
     782       74538 :     for (int spaceNum : zone.spaceIndexes) {
     783       37269 :         auto &thisSpace = state.dataHeatBal->space(spaceNum);
     784     1739220 :         for (int i = thisSpace.HTSurfaceFirst; i <= thisSpace.HTSurfaceLast; ++i) {
     785     1701951 :             state.dataSurface->SurfTAirRef(i) = DataSurfaces::RefAirTemp::AdjacentAirTemp;
     786     1701951 :             state.dataSurface->SurfTAirRefRpt(i) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(i)];
     787             :         }
     788       37269 :     }
     789       37269 : }
     790             : 
     791             : //*****************************************************************************************
     792             : 
     793             : } // namespace EnergyPlus::RoomAir

Generated by: LCOV version 1.14