LCOV - code coverage report
Current view: top level - EnergyPlus - HeatBalanceSurfaceManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 62.7 % 5893 3692
Test Date: 2025-06-02 12:03:30 Functions: 87.2 % 47 41

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // C++ Headers
      49              : #include <algorithm>
      50              : #include <cassert>
      51              : #include <cmath>
      52              : // ObjexxFCL Headers
      53              : #include <ObjexxFCL/Array.functions.hh>
      54              : #include <ObjexxFCL/Array1D.hh>
      55              : #include <ObjexxFCL/Array2D.hh>
      56              : #include <ObjexxFCL/Fmath.hh>
      57              : #include <ObjexxFCL/string.functions.hh>
      58              : 
      59              : // EnergyPlus Headers
      60              : #include <AirflowNetwork/Solver.hpp>
      61              : #include <EnergyPlus/ChilledCeilingPanelSimple.hh>
      62              : #include <EnergyPlus/Construction.hh>
      63              : #include <EnergyPlus/ConvectionCoefficients.hh>
      64              : #include <EnergyPlus/CurveManager.hh>
      65              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      66              : #include <EnergyPlus/DataContaminantBalance.hh>
      67              : #include <EnergyPlus/DataDaylighting.hh>
      68              : #include <EnergyPlus/DataDaylightingDevices.hh>
      69              : #include <EnergyPlus/DataEnvironment.hh>
      70              : #include <EnergyPlus/DataHeatBalFanSys.hh>
      71              : #include <EnergyPlus/DataHeatBalSurface.hh>
      72              : #include <EnergyPlus/DataHeatBalance.hh>
      73              : #include <EnergyPlus/DataLoopNode.hh>
      74              : #include <EnergyPlus/DataMoistureBalance.hh>
      75              : #include <EnergyPlus/DataMoistureBalanceEMPD.hh>
      76              : #include <EnergyPlus/DataRoomAirModel.hh>
      77              : #include <EnergyPlus/DataRuntimeLanguage.hh>
      78              : #include <EnergyPlus/DataSizing.hh>
      79              : #include <EnergyPlus/DataSurfaces.hh>
      80              : #include <EnergyPlus/DataSystemVariables.hh>
      81              : #include <EnergyPlus/DataViewFactorInformation.hh>
      82              : #include <EnergyPlus/DataWindowEquivalentLayer.hh>
      83              : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      84              : #include <EnergyPlus/DataZoneEquipment.hh>
      85              : #include <EnergyPlus/DaylightingDevices.hh>
      86              : #include <EnergyPlus/DaylightingManager.hh>
      87              : #include <EnergyPlus/DisplayRoutines.hh>
      88              : #include <EnergyPlus/EcoRoofManager.hh>
      89              : #include <EnergyPlus/ElectricBaseboardRadiator.hh>
      90              : #include <EnergyPlus/ExtendedHeatIndex.hh>
      91              : #include <EnergyPlus/FileSystem.hh>
      92              : #include <EnergyPlus/HWBaseboardRadiator.hh>
      93              : #include <EnergyPlus/HeatBalFiniteDiffManager.hh>
      94              : #include <EnergyPlus/HeatBalanceAirManager.hh>
      95              : #include <EnergyPlus/HeatBalanceHAMTManager.hh>
      96              : #include <EnergyPlus/HeatBalanceIntRadExchange.hh>
      97              : #include <EnergyPlus/HeatBalanceKivaManager.hh>
      98              : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
      99              : #include <EnergyPlus/HighTempRadiantSystem.hh>
     100              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
     101              : #include <EnergyPlus/InternalHeatGains.hh>
     102              : #include <EnergyPlus/LowTempRadiantSystem.hh>
     103              : #include <EnergyPlus/MoistureBalanceEMPDManager.hh>
     104              : #include <EnergyPlus/OutputProcessor.hh>
     105              : #include <EnergyPlus/OutputReportPredefined.hh>
     106              : #include <EnergyPlus/OutputReportTabular.hh>
     107              : #include <EnergyPlus/Psychrometrics.hh>
     108              : #include <EnergyPlus/ScheduleManager.hh>
     109              : #include <EnergyPlus/SolarShading.hh>
     110              : #include <EnergyPlus/SteamBaseboardRadiator.hh>
     111              : #include <EnergyPlus/SurfaceGeometry.hh>
     112              : #include <EnergyPlus/SwimmingPool.hh>
     113              : #include <EnergyPlus/ThermalComfort.hh>
     114              : #include <EnergyPlus/TranspiredCollector.hh>
     115              : #include <EnergyPlus/UtilityRoutines.hh>
     116              : #include <EnergyPlus/WindowComplexManager.hh>
     117              : #include <EnergyPlus/WindowEquivalentLayer.hh>
     118              : #include <EnergyPlus/WindowManager.hh>
     119              : #include <EnergyPlus/WindowManagerExteriorData.hh>
     120              : #include <EnergyPlus/WindowManagerExteriorThermal.hh>
     121              : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
     122              : #include <WCECommon.hpp>
     123              : #include <WCEMultiLayerOptics.hpp>
     124              : #include <WCESingleLayerOptics.hpp>
     125              : #include <WCETarcog.hpp>
     126              : 
     127              : namespace EnergyPlus::HeatBalanceSurfaceManager {
     128              : 
     129              : // Module containing the routines dealing with the Heat Balance of the surfaces
     130              : 
     131              : // MODULE INFORMATION:
     132              : //       MODIFIED       DJS (PSU Dec 2006) to add ecoroof
     133              : 
     134              : // PURPOSE OF THIS MODULE:
     135              : // To encapsulate the data and algorithms required to
     136              : // manage the simulation of the surface heat balance for the building.
     137              : 
     138              : // REFERENCES:
     139              : // The heat balance method is outlined in the "TARP Reference Manual", NIST, NBSIR 83-2655, Feb 1983.
     140              : // The methods are also summarized in many BSO Theses and papers.
     141              : 
     142              : // OTHER NOTES:
     143              : // This module was created from IBLAST subroutines
     144              : 
     145       249946 : void ManageSurfaceHeatBalance(EnergyPlusData &state)
     146              : {
     147              : 
     148              :     // SUBROUTINE INFORMATION:
     149              :     //       AUTHOR         Richard Liesen
     150              :     //       DATE WRITTEN   January 1998
     151              : 
     152              :     // PURPOSE OF THIS SUBROUTINE:
     153              :     // This subroutine manages the heat surface balance method of calculating
     154              :     // building thermal loads.  It is called from the HeatBalanceManager
     155              :     // at the time step level.  This driver manages the calls to all of
     156              :     // the other drivers and simulation algorithms.
     157              : 
     158       249946 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
     159          103 :         DisplayString(state, "Initializing Surfaces");
     160              :     }
     161       249946 :     InitSurfaceHeatBalance(state); // Initialize all heat balance related parameters
     162              : 
     163              :     // Solve the zone heat balance 'Detailed' solution
     164              :     // Call the outside and inside surface heat balances
     165       249946 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
     166          103 :         DisplayString(state, "Calculate Outside Surface Heat Balance");
     167              :     }
     168       249946 :     CalcHeatBalanceOutsideSurf(state);
     169       249946 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
     170          103 :         DisplayString(state, "Calculate Inside Surface Heat Balance");
     171              :     }
     172       249946 :     CalcHeatBalanceInsideSurf(state);
     173              : 
     174              :     // The air heat balance must be called before the temperature history
     175              :     // updates because there may be a radiant system in the building
     176       249946 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
     177          103 :         DisplayString(state, "Calculate Air Heat Balance");
     178              :     }
     179       249946 :     HeatBalanceAirManager::ManageAirHeatBalance(state);
     180              : 
     181              :     // IF NECESSARY, do one final "average" heat balance pass.  This is only
     182              :     // necessary if a radiant system is present and it was actually on for
     183              :     // part or all of the time step.
     184       249945 :     UpdateFinalSurfaceHeatBalance(state);
     185              : 
     186              :     // Before we leave the Surface Manager the thermal histories need to be updated
     187       249945 :     if (state.dataHeatBal->AnyCTF || state.dataHeatBal->AnyEMPD) {
     188       200973 :         UpdateThermalHistories(state); // Update the thermal histories
     189              :     }
     190              : 
     191       249945 :     if (state.dataHeatBal->AnyCondFD) {
     192       342804 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     193       293832 :             auto const &surface = state.dataSurface->Surface(SurfNum);
     194       293832 :             int const ConstrNum = surface.Construction;
     195       293832 :             if (ConstrNum <= 0) {
     196            0 :                 continue; // Shading surface, not really a heat transfer surface
     197              :             }
     198       293832 :             if (state.dataConstruction->Construct(ConstrNum).TypeIsWindow) {
     199            0 :                 continue; //  Windows simulated in Window module
     200              :             }
     201       293832 :             if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CondFD) {
     202            0 :                 continue;
     203              :             }
     204       293832 :             state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).UpdateMoistureBalance();
     205              :         }
     206              :     }
     207              : 
     208       249945 :     ThermalComfort::ManageThermalComfort(state, false); // "Record keeping" for the zone
     209              : 
     210       249945 :     ReportSurfaceHeatBalance(state);
     211       249945 :     if (state.dataGlobal->ZoneSizingCalc) {
     212        83022 :         OutputReportTabular::GatherComponentLoadsSurface(state);
     213              :     }
     214              : 
     215       249945 :     CalcThermalResilience(state);
     216              : 
     217       249945 :     if (state.dataOutRptTab->displayThermalResilienceSummary) {
     218        69935 :         ReportThermalResilience(state);
     219              :     }
     220              : 
     221       249945 :     if (state.dataOutRptTab->displayCO2ResilienceSummary) {
     222           38 :         ReportCO2Resilience(state);
     223              :     }
     224              : 
     225       249945 :     if (state.dataOutRptTab->displayVisualResilienceSummary) {
     226           38 :         ReportVisualResilience(state);
     227              :     }
     228              : 
     229       249945 :     state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime = false;
     230       249945 : }
     231              : 
     232              : // Beginning Initialization Section of the Module
     233              : //******************************************************************************
     234              : 
     235       249957 : void UpdateVariableAbsorptances(EnergyPlusData &state)
     236              : {
     237       249957 :     auto &s_mat = state.dataMaterial;
     238       249960 :     for (int surfNum : state.dataSurface->AllVaryAbsOpaqSurfaceList) {
     239            3 :         auto const &thisConstruct = state.dataConstruction->Construct(state.dataSurface->Surface(surfNum).Construction);
     240            3 :         auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
     241            3 :         assert(thisMaterial != nullptr);
     242            3 :         if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::Scheduled) {
     243            1 :             if (thisMaterial->absorpThermalVarSched != nullptr) {
     244            1 :                 state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
     245              :             }
     246            1 :             if (thisMaterial->absorpSolarVarSched != nullptr) {
     247            0 :                 state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) = max(min(thisMaterial->absorpThermalVarSched->getCurrentVal(), 0.9999), 0.0001);
     248              :             }
     249              :         } else {
     250              :             Real64 triggerValue;
     251            2 :             if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceTemperature) {
     252            2 :                 triggerValue = state.dataHeatBalSurf->SurfTempOut(surfNum);
     253            0 :             } else if (thisMaterial->absorpVarCtrlSignal == Material::VariableAbsCtrlSignal::SurfaceReceivedSolarRadiation) {
     254            0 :                 triggerValue = state.dataHeatBal->SurfQRadSWOutIncident(surfNum);
     255              :             } else { // controlled by heating cooling mode
     256            0 :                 int zoneNum = state.dataSurface->Surface(surfNum).Zone;
     257            0 :                 bool isCooling = (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).TotalOutputRequired < 0);
     258            0 :                 triggerValue = static_cast<Real64>(isCooling);
     259              :             }
     260            2 :             if (thisMaterial->absorpThermalVarCurve != nullptr) {
     261            2 :                 state.dataHeatBalSurf->SurfAbsThermalExt(surfNum) =
     262            2 :                     max(min(thisMaterial->absorpThermalVarCurve->value(state, triggerValue), 0.9999), 0.0001);
     263              :             }
     264            2 :             if (thisMaterial->absorpSolarVarCurve != nullptr) {
     265            2 :                 state.dataHeatBalSurf->SurfAbsSolarExt(surfNum) =
     266            2 :                     max(min(thisMaterial->absorpSolarVarCurve->value(state, triggerValue), 0.9999), 0.0001);
     267              :             }
     268              :         }
     269       249957 :     }
     270       249957 : }
     271              : 
     272       249956 : void InitSurfaceHeatBalance(EnergyPlusData &state)
     273              : {
     274              : 
     275              :     // SUBROUTINE INFORMATION:
     276              :     //       AUTHOR         Richard J. Liesen
     277              :     //       DATE WRITTEN   January 1998
     278              :     //       MODIFIED       Nov. 1999, FCW,
     279              :     //                      Move ComputeIntThermalAbsorpFactors
     280              :     //                      so called every timestep
     281              :     //       MODIFIED       Aug. 2017
     282              :     //                      Add initializations of surface data to linked air node value if defined
     283              : 
     284              :     // PURPOSE OF THIS SUBROUTINE:
     285              :     // This subroutine is for surface initializations within the
     286              :     // heat balance.
     287              : 
     288              :     // METHODOLOGY EMPLOYED:
     289              :     // Uses the status flags to trigger record keeping events.
     290              : 
     291              :     //    // Using/Aliasing
     292              :     //    using namespace SolarShading;
     293              :     //    using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
     294              :     //    using HeatBalFiniteDiffManager::InitHeatBalFiniteDiff;
     295              :     //    using InternalHeatGains::ManageInternalHeatGains;
     296              :     //
     297              :     //    auto &Surface = state.dataSurface->Surface;
     298              :     //
     299       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     300          112 :         DisplayString(state, "Initializing Outdoor environment for Surfaces");
     301              :     }
     302              : 
     303              :     // set zone level wind dir to global value
     304              :     // Initialize zone outdoor environmental variables
     305              :     // Bulk Initialization for Temperatures & WindSpeed
     306              :     // using the zone, modify the zone  Dry/Wet BulbTemps
     307              : 
     308              :     // Initialize surface outdoor environmental variables
     309              :     // Bulk Initialization for Temperatures & WindSpeed
     310              :     // using the surface centroids, modify the surface Dry/Wet BulbTemps
     311       249956 :     DataSurfaces::SetSurfaceOutBulbTempAt(state);
     312       249956 :     DataSurfaces::CheckSurfaceOutBulbTempAt(state);
     313              : 
     314       249956 :     DataSurfaces::SetSurfaceWindSpeedAt(state);
     315       249956 :     DataSurfaces::SetSurfaceWindDirAt(state);
     316       249956 :     if (state.dataGlobal->AnyLocalEnvironmentsInModel) {
     317           21 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     318           18 :             if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) {
     319            1 :                 auto const &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode);
     320            1 :                 state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb;
     321            1 :                 state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb;
     322            1 :                 state.dataSurface->SurfOutWindSpeed(SurfNum) = linkedNode.OutAirWindSpeed;
     323            1 :                 state.dataSurface->SurfOutWindDir(SurfNum) = linkedNode.OutAirWindDir;
     324              :             }
     325              :         }
     326              :     }
     327              :     // Overwriting surface and zone level environmental data with EMS override value
     328       249956 :     if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     329       867072 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
     330       750999 :             if (state.dataSurface->SurfOutDryBulbTempEMSOverrideOn(SurfNum)) {
     331            0 :                 state.dataSurface->SurfOutDryBulbTemp(SurfNum) = state.dataSurface->SurfOutDryBulbTempEMSOverrideValue(SurfNum);
     332              :             }
     333       750999 :             if (state.dataSurface->SurfOutWetBulbTempEMSOverrideOn(SurfNum)) {
     334            0 :                 state.dataSurface->SurfOutWetBulbTemp(SurfNum) = state.dataSurface->SurfOutWetBulbTempEMSOverrideValue(SurfNum);
     335              :             }
     336       750999 :             if (state.dataSurface->SurfWindSpeedEMSOverrideOn(SurfNum)) {
     337            0 :                 state.dataSurface->SurfOutWindSpeed(SurfNum) = state.dataSurface->SurfWindSpeedEMSOverrideValue(SurfNum);
     338              :             }
     339       750999 :             if (state.dataSurface->SurfWindDirEMSOverrideOn(SurfNum)) {
     340            0 :                 state.dataSurface->SurfOutWindDir(SurfNum) = state.dataSurface->SurfWindDirEMSOverrideValue(SurfNum);
     341              :             }
     342       750999 :             if (state.dataSurface->SurfViewFactorGroundEMSOverrideOn(SurfNum)) {
     343         1354 :                 state.dataSurface->Surface(SurfNum).ViewFactorGround = state.dataSurface->SurfViewFactorGroundEMSOverrideValue(SurfNum);
     344              :             }
     345              :         }
     346              :     }
     347              : 
     348              :     // Do the Begin Simulation initializations
     349       249956 :     if (state.dataGlobal->BeginSimFlag) {
     350          112 :         AllocateSurfaceHeatBalArrays(state); // Allocate the Module Arrays before any inits take place
     351          224 :         state.dataHeatBalSurf->InterZoneWindow =
     352          112 :             std::any_of(state.dataViewFactor->EnclSolInfo.begin(),
     353          224 :                         state.dataViewFactor->EnclSolInfo.end(),
     354          140 :                         [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; });
     355              :     }
     356       249956 :     if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) {
     357          244 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
     358          281 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     359          149 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     360          149 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
     361          149 :                 int const lastSurf = thisSpace.HTSurfaceLast;
     362          941 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
     363          792 :                     int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above
     364          792 :                     auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
     365          792 :                     state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
     366          792 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
     367          792 :                     state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisConstruct.OutsideRoughness;
     368          792 :                     state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisConstruct.OutsideAbsorpSolar;
     369          792 :                     state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisConstruct.OutsideAbsorpThermal;
     370              :                 }
     371          132 :             }
     372              :         }
     373              :     }
     374              : 
     375              :     // variable thermal solar absorptance overrides
     376       249956 :     UpdateVariableAbsorptances(state);
     377              : 
     378              :     // Do the Begin Environment initializations
     379       249956 :     if (state.dataGlobal->BeginEnvrnFlag) {
     380          483 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     381          103 :             DisplayString(state, "Initializing Temperature and Flux Histories");
     382              :         }
     383          483 :         InitThermalAndFluxHistories(state); // Set initial temperature and flux histories
     384              :     }
     385              : 
     386              :     // Calc movable insulation properties
     387       249956 :     if (state.dataSurface->AnyMovableInsulation) {
     388            0 :         EvalOutsideMovableInsulation(state);
     389            0 :         EvalInsideMovableInsulation(state);
     390              :     }
     391              : 
     392              :     // There are no daily initializations done in this portion of the surface heat balance
     393              :     // There are no hourly initializations done in this portion of the surface heat balance
     394              : 
     395       249956 :     GetGroundSurfacesReflectanceAverage(state);
     396              : 
     397              :     // Need to be called each timestep in order to check if surface points to new construction (EMS) and if does then
     398              :     // complex fenestration needs to be initialized for additional states
     399       249956 :     SolarShading::TimestepInitComplexFenestration(state);
     400              : 
     401              :     // Calculate exterior-surface multipliers that account for anisotropy of
     402              :     // sky radiance
     403       249956 :     if (state.dataEnvrn->SunIsUp && state.dataEnvrn->DifSolarRad > 0.0) {
     404        71212 :         SolarShading::AnisoSkyViewFactors(state);
     405              :     } else {
     406       178744 :         state.dataSolarShading->SurfAnisoSkyMult = 0.0;
     407              :     }
     408              : 
     409              :     // Set shading flag for exterior windows (except flags related to daylighting) and
     410              :     // window construction (unshaded or shaded) to be used in heat balance calculation
     411       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     412          112 :         DisplayString(state, "Initializing Window Shading");
     413              :     }
     414              : 
     415       249956 :     SolarShading::WindowShadingManager(state);
     416              : 
     417       249956 :     SolarShading::CheckGlazingShadingStatusChange(state);
     418              : 
     419              :     // Calculate factors that are used to determine how much long-wave radiation from internal
     420              :     // gains is absorbed by interior surfaces
     421       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     422          112 :         DisplayString(state, "Computing Interior Absorption Factors");
     423              :     }
     424       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     425          112 :         HeatBalanceIntRadExchange::InitInteriorRadExchange(state);
     426              :     }
     427       249956 :     ComputeIntThermalAbsorpFactors(state);
     428              : 
     429              :     // Calculate factors for diffuse solar absorbed by room surfaces and interior shades
     430       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     431          112 :         DisplayString(state, "Computing Interior Diffuse Solar Absorption Factors");
     432              :     }
     433       249956 :     ComputeIntSWAbsorpFactors(state);
     434              : 
     435       249956 :     if (state.dataHeatBalSurf->InterZoneWindow) {
     436            1 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     437            0 :             DisplayString(state, "Computing Interior Diffuse Solar Exchange through Interzone Windows");
     438              :         }
     439            1 :         ComputeDifSolExcZonesWIZWindows(state);
     440              :     }
     441              : 
     442       249956 :     Dayltg::initDaylighting(state, state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime);
     443              : 
     444       499912 :     HeatBalanceIntRadExchange::CalcInteriorRadExchange(
     445       249956 :         state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, "Main");
     446              : 
     447       249956 :     if (state.dataSurface->AirflowWindows) {
     448            0 :         SolarShading::WindowGapAirflowControl(state);
     449              :     }
     450              : 
     451              :     // The order of these initializations is important currently.  Over time we hope to
     452              :     //  take the appropriate parts of these inits to the other heat balance managers
     453       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     454          112 :         DisplayString(state, "Initializing Solar Heat Gains");
     455              :     }
     456              : 
     457       249956 :     InitSolarHeatGains(state);
     458              : 
     459       249956 :     Dayltg::manageDaylighting(state);
     460              : 
     461       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     462          112 :         DisplayString(state, "Initializing Internal Heat Gains");
     463              :     }
     464       249956 :     InternalHeatGains::ManageInternalHeatGains(state, false);
     465       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     466          112 :         DisplayString(state, "Initializing Interior Solar Distribution");
     467              :     }
     468       249956 :     InitIntSolarDistribution(state);
     469              : 
     470       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     471          112 :         DisplayString(state, "Initializing Interior Convection Coefficients");
     472              :     }
     473       249956 :     Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempInTmp);
     474              : 
     475       249956 :     if (state.dataGlobal->BeginSimFlag) { // Now's the time to report surfaces, if desired
     476              :         //    if (firstTime) CALL DisplayString('Reporting Surfaces')
     477              :         //    CALL ReportSurfaces
     478          112 :         if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     479          112 :             DisplayString(state, "Gathering Information for Predefined Reporting");
     480              :         }
     481          112 :         GatherForPredefinedReport(state);
     482              :     }
     483              : 
     484              :     // Initialize the temperature history terms for conduction through the surfaces
     485       249956 :     if (state.dataHeatBal->AnyCondFD) {
     486        48972 :         HeatBalFiniteDiffManager::InitHeatBalFiniteDiff(state);
     487              :     }
     488              : 
     489       586606 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     490       706903 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     491       370253 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     492       370253 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
     493       370253 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
     494      2350605 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
     495      1980352 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
     496      1980352 :                 if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
     497       293832 :                     surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
     498       293832 :                     continue;
     499              :                 }
     500              :                 // Outside surface temp of "normal" windows not needed in Window5 calculation approach
     501              :                 // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
     502              : 
     503      1686520 :                 int const ConstrNum = surface.Construction;
     504      1686520 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
     505      1686520 :                 state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0;
     506      1686520 :                 state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0;
     507      1686520 :                 if (construct.NumCTFTerms <= 1) {
     508       626878 :                     continue;
     509              :                 }
     510              : 
     511      7592810 :                 for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
     512              :                     // [ l11 ] == ( 1, Term + 1, SurfNum ), [ l12 ] == ( 1, Term + 1, SurfNum )
     513              : 
     514              :                     // Sign convention for the various terms in the following two equations
     515              :                     // is based on the form of the Conduction Transfer Function equation
     516              :                     // given by:
     517              :                     // Qin,now  = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old)
     518              :                     // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old)
     519              :                     // In both equations, flux is positive from outside to inside.
     520              : 
     521              :                     // Tuned Aliases and linear indexing
     522      6533168 :                     Real64 const ctf_cross(construct.CTFCross[Term]);
     523              : 
     524      6533168 :                     Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
     525      6533168 :                     Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
     526      6533168 :                     Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum));
     527      6533168 :                     Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum));
     528      6533168 :                     state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) +=
     529      6533168 :                         ctf_cross * TH11 - construct.CTFInside[Term] * TH12 + construct.CTFFlux[Term] * QH12;
     530              : 
     531      6533168 :                     state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) +=
     532      6533168 :                         construct.CTFOutside[Term] * TH11 - ctf_cross * TH12 + construct.CTFFlux[Term] * QH11;
     533              :                 }
     534              :             }
     535       336650 :         }
     536              :     }
     537       249956 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
     538            0 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     539            0 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     540            0 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     541            0 :                 int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
     542            0 :                 int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
     543            0 :                 for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
     544            0 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
     545            0 :                     int const ConstrNum = surface.Construction;
     546            0 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
     547            0 :                     if (!construct.SourceSinkPresent) {
     548            0 :                         continue;
     549              :                     }
     550            0 :                     if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF &&
     551            0 :                         surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) {
     552            0 :                         continue;
     553              :                     }
     554            0 :                     state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0;
     555            0 :                     state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0;
     556            0 :                     if (construct.NumCTFTerms <= 1) {
     557            0 :                         continue;
     558              :                     }
     559            0 :                     for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) {
     560            0 :                         Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum));
     561            0 :                         Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum));
     562            0 :                         Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1));
     563              : 
     564            0 :                         state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn[Term] * QsrcHist1;
     565              : 
     566            0 :                         state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut[Term] * QsrcHist1;
     567              : 
     568            0 :                         state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) +=
     569            0 :                             construct.CTFTSourceOut[Term] * TH11 + construct.CTFTSourceIn[Term] * TH12 + construct.CTFTSourceQ[Term] * QsrcHist1 +
     570            0 :                             construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1);
     571              : 
     572            0 :                         state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) +=
     573            0 :                             construct.CTFTUserOut[Term] * TH11 + construct.CTFTUserIn[Term] * TH12 + construct.CTFTUserSource[Term] * QsrcHist1 +
     574            0 :                             construct.CTFFlux[Term] * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1);
     575              :                     }
     576              :                 }
     577            0 :             } // ...end of surfaces DO loop for initializing temperature history terms for the surface heat balances
     578              :         }
     579              :     }
     580              : 
     581              :     // Zero out all of the radiant system heat balance coefficient arrays
     582       586606 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
     583       706903 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
     584       370253 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     585       370253 :             int const firstSurf = thisSpace.HTSurfaceFirst;
     586       370253 :             int const lastSurf = thisSpace.HTSurfaceLast;
     587      2439169 :             for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
     588      2068916 :                 state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0;
     589      2068916 :                 state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0;
     590      2068916 :                 state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0;
     591      2068916 :                 state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0;
     592      2068916 :                 state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0;
     593      2068916 :                 state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0;
     594              : 
     595      2068916 :                 state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
     596      2068916 :                 state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0;
     597      2068916 :                 state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0;
     598      2068916 :                 state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0;
     599              : 
     600              :             } // ...end of Zone Surf loop
     601       336650 :         }
     602              :     } // ...end of Zone loop
     603              : 
     604       249980 :     for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
     605           24 :         auto &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
     606           24 :         thisSurfQRadFromHVAC.HTRadSys = 0.0;
     607           24 :         thisSurfQRadFromHVAC.HWBaseboard = 0.0;
     608           24 :         thisSurfQRadFromHVAC.SteamBaseboard = 0.0;
     609           24 :         thisSurfQRadFromHVAC.ElecBaseboard = 0.0;
     610           24 :         thisSurfQRadFromHVAC.CoolingPanel = 0.0;
     611       249956 :     }
     612              : 
     613       249956 :     if (state.dataGlobal->ZoneSizingCalc) {
     614        83022 :         GatherComponentLoadsSurfAbsFact(state);
     615              :     }
     616              : 
     617       249956 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
     618          112 :         DisplayString(state, "Completed Initializing Surface Heat Balance");
     619              :     }
     620       249956 :     state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime = false;
     621       249956 : }
     622              : 
     623          114 : void GatherForPredefinedReport(EnergyPlusData &state)
     624              : {
     625              : 
     626              :     // SUBROUTINE INFORMATION:
     627              :     //       AUTHOR         Jason Glazer
     628              :     //       DATE WRITTEN   August 2006
     629              : 
     630              :     // PURPOSE OF THIS SUBROUTINE:
     631              :     // This subroutine reports the information for the predefined reports
     632              :     // related to envelope components.
     633              : 
     634              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     635          114 :     std::string surfName;
     636              :     Real64 mult;
     637              :     Real64 curAzimuth;
     638              :     Real64 curTilt;
     639              :     Real64 windowArea;
     640              :     Real64 frameWidth;
     641              :     Real64 frameArea;
     642              :     Real64 dividerArea;
     643              :     // counts for object count report
     644          114 :     int SurfaceClassCount = int(DataSurfaces::SurfaceClass::Num);
     645          114 :     Array1D_int numSurfaces(SurfaceClassCount);
     646          114 :     Array1D_int numExtSurfaces(SurfaceClassCount);
     647              :     int frameDivNum;
     648              :     bool isExterior;
     649          114 :     Array1D<Real64> computedNetArea; // holds the gross wall area minus the window and door areas
     650              : 
     651              :     // the following variables are for the CalcNominalWindowCond call but only SHGCSummer is needed
     652              :     Real64 nomCond;
     653              :     Real64 SHGCSummer;
     654              :     Real64 TransSolNorm;
     655              :     Real64 TransVisNorm;
     656              :     Real64 nomUfact;
     657              :     int errFlag;
     658              :     int curWSC;
     659              :     // following variables are totals for fenestration table
     660          114 :     Real64 windowAreaWMult(0.0);
     661          114 :     Real64 fenTotArea(0.0);
     662          114 :     Real64 fenTotAreaNorth(0.0);
     663          114 :     Real64 fenTotAreaNonNorth(0.0);
     664          114 :     Real64 ufactArea(0.0);
     665          114 :     Real64 ufactAreaNorth(0.0);
     666          114 :     Real64 ufactAreaNonNorth(0.0);
     667          114 :     Real64 shgcArea(0.0);
     668          114 :     Real64 shgcAreaNorth(0.0);
     669          114 :     Real64 shgcAreaNonNorth(0.0);
     670          114 :     Real64 vistranArea(0.0);
     671          114 :     Real64 vistranAreaNorth(0.0);
     672          114 :     Real64 vistranAreaNonNorth(0.0);
     673          114 :     Real64 intFenTotArea(0.0);
     674          114 :     Real64 intUfactArea(0.0);
     675          114 :     Real64 intShgcArea(0.0);
     676          114 :     Real64 intVistranArea(0.0);
     677              :     bool isNorth;
     678              : 
     679          114 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WinShadingType::Num)> WindowShadingTypeNames = {
     680              :         "No Shade",  // 0
     681              :         "Shade Off", // 1
     682              :         "Interior Shade",
     683              :         "Switchable Glazing",
     684              :         "Exterior Shade",
     685              :         "Exterior Screen",
     686              :         "Interior Blind",
     687              :         "Exterior Blind",
     688              :         "Between Glass Shade",
     689              :         "Between Glass Blind",
     690              :     };
     691              : 
     692          114 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::WindowShadingControlType::Num)> WindowShadingControlTypeNames = {
     693              :         "Uncontrolled",
     694              :         "AlwaysOn",
     695              :         "AlwaysOff",
     696              :         "OnIfScheduleAllows",
     697              :         "OnIfHighSolarOnWindow",
     698              :         "OnIfHighHorizontalSolar",
     699              :         "OnIfHighOutdoorAirTemperature",
     700              :         "OnIfHighZoneAirTemperature",
     701              :         "OnIfHighZoneCooling",
     702              :         "OnIfHighGlare",
     703              :         "MeetDaylightIlluminanceSetpoint",
     704              :         "OnNightIfLowOutdoorTempAndOffDay",
     705              :         "OnNightIfLowInsideTempAndOffDay",
     706              :         "OnNightIfHeatingAndOffDay",
     707              :         "OnNightIfLowOutdoorTempAndOnDayIfCooling",
     708              :         "OnNightIfHeatingAndOnDayIfCooling",
     709              :         "OffNightAndOnDayIfCoolingAndHighSolarOnWindow",
     710              :         "OnNightAndOnDayIfCoolingAndHighSolarOnWindow",
     711              :         "OnIfHighOutdoorAirTempAndHighSolarOnWindow",
     712              :         "OnIfHighOutdoorAirTempAndHighHorizontalSolar",
     713              :         "OnIfHighZoneAirTempAndHighSolarOnWindow",
     714              :         "OnIfHighZoneAirTempAndHighHorizontalSolar"};
     715              : 
     716          114 :     constexpr std::array<std::string_view, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcProductNames = {
     717              :         "CasementDouble", "CasementSingle",   "DualAction",
     718              :         "Fixed",          "Garage",           "Greenhouse",
     719              :         "HingedEscape",   "HorizontalSlider", "Jal",
     720              :         "Pivoted",        "ProjectingSingle", "ProjectingDual",
     721              :         "DoorSidelite",   "Skylight",         "SlidingPatioDoor",
     722              :         "CurtainWall",    "SpandrelPanel",    "SideHingedDoor",
     723              :         "DoorTransom",    "TropicalAwning",   "TubularDaylightingDevice",
     724              :         "VerticalSlider"};
     725              : 
     726          114 :     constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcWidth = {
     727              :         // width in meters from Table 4-3 of NFRC 100-2020
     728              :         1.200, 0.600, 1.200, //  CasementDouble,  CasementSingle,    DualAction,
     729              :         1.200, 2.134, 1.500, //  Fixed,           Garage,            Greenhouse,
     730              :         1.500, 1.500, 1.200, //  HingedEscape,    HorizontalSlider,  Jal,
     731              :         1.200, 1.500, 1.500, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     732              :         0.600, 1.200, 2.000, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     733              :         2.000, 2.000, 1.920, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     734              :         2.000, 1.500, 0.350, //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     735              :         1.200                //  VerticalSlider,
     736              :     };
     737              : 
     738          114 :     constexpr std::array<Real64, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcHeight = {
     739              :         // height in meters from Table 4-3 of NFRC 100-2020
     740              :         1.500, 1.500, 1.500, //  CasementDouble,  CasementSingle,    DualAction,
     741              :         1.500, 2.134, 1.200, //  Fixed,           Garage,            Greenhouse,
     742              :         1.200, 1.200, 1.500, //  HingedEscape,    HorizontalSlider,  Jal,
     743              :         1.500, 1.200, 0.600, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     744              :         2.090, 1.200, 2.000, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     745              :         2.000, 1.200, 2.090, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     746              :         0.600, 1.200, 0.350, //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     747              :         1.500                //  VerticalSlider,
     748              :     };
     749              : 
     750          114 :     constexpr std::array<DataSurfaces::NfrcVisionType, static_cast<int>(DataSurfaces::NfrcProductOptions::Num)> NfrcVision = {
     751              :         DataSurfaces::NfrcVisionType::DualHorizontal, DataSurfaces::NfrcVisionType::Single,
     752              :         DataSurfaces::NfrcVisionType::DualVertical, //  CasementDouble,  CasementSingle,    DualAction,
     753              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     754              :         DataSurfaces::NfrcVisionType::Single, //  Fixed,           Garage,            Greenhouse,
     755              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::DualHorizontal,
     756              :         DataSurfaces::NfrcVisionType::Single, //  HingedEscape,    HorizontalSlider,  Jal,
     757              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     758              :         DataSurfaces::NfrcVisionType::DualHorizontal, //  Pivoted,         ProjectingSingle,  ProjectingDual,
     759              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     760              :         DataSurfaces::NfrcVisionType::DualHorizontal, //  DoorSidelite,    Skylight,          SlidingPatioDoor,
     761              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     762              :         DataSurfaces::NfrcVisionType::Single, //  CurtainWall,     SpandrelPanel,     SideHingedDoor,
     763              :         DataSurfaces::NfrcVisionType::Single,         DataSurfaces::NfrcVisionType::Single,
     764              :         DataSurfaces::NfrcVisionType::Single,      //  DoorTransom,     TropicalAwning,    TubularDaylightingDevice,
     765              :         DataSurfaces::NfrcVisionType::DualVertical //  VerticalSlider
     766              :     };
     767              : 
     768          114 :     numSurfaces = 0;
     769          114 :     numExtSurfaces = 0;
     770              : 
     771          114 :     computedNetArea.allocate(state.dataSurface->TotSurfaces);
     772          114 :     computedNetArea = 0.0; // start at zero, add wall area and subtract window and door area
     773              : 
     774              :     // set up for EIO <FenestrationAssembly> output
     775          114 :     if (state.dataHeatBal->TotFrameDivider > 0 && state.dataGeneral->Constructions) {
     776            0 :         print(state.files.eio,
     777              :               "{}\n",
     778              :               "! <FenestrationAssembly>,Construction Name,Frame and Divider Name,NFRC Product Type,"
     779              :               "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
     780              :     }
     781              :     static constexpr std::string_view FenestrationAssemblyFormat("FenestrationAssembly,{},{},{},{:.3R},{:.3R},{:.3R}\n");
     782          114 :     std::vector<std::pair<int, int>> uniqConsFrame;
     783          114 :     std::pair<int, int> consAndFrame;
     784              : 
     785              :     // set up for EIO <FenestrationShadedState> output
     786          114 :     bool fenestrationShadedStateHeaderShown(false);
     787              :     static constexpr std::string_view FenestrationShadedStateFormat("FenestrationShadedState,{},{:.3R},{:.3R},{:.3R},{},{},{:.3R},{:.3R},{:.3R}\n");
     788          114 :     std::vector<std::pair<int, int>> uniqShdConsFrame;
     789          114 :     std::pair<int, int> shdConsAndFrame;
     790              : 
     791          948 :     for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
     792          834 :         auto &surface = state.dataSurface->Surface(iSurf);
     793          834 :         surfName = surface.Name;
     794              :         // only exterior surfaces including underground
     795          834 :         if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
     796          216 :             (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
     797          618 :             isExterior = true;
     798          618 :             switch (surface.Class) {
     799          543 :             case DataSurfaces::SurfaceClass::Wall:
     800              :             case DataSurfaces::SurfaceClass::Floor:
     801              :             case DataSurfaces::SurfaceClass::Roof: {
     802          543 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
     803          543 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
     804          543 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
     805          543 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
     806          543 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpCons, surfName, construct.Name);
     807          543 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpZone, surfName, thisZone.Name);
     808          543 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpSpace, surfName, thisSpace.Name);
     809          543 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
     810          543 :                 OutputReportPredefined::PreDefTableEntry(
     811          543 :                     state, state.dataOutRptPredefined->pdchOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
     812          543 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpGrArea, surfName, surface.GrossArea * mult);
     813          543 :                 computedNetArea(iSurf) += surface.GrossArea * mult;
     814          543 :                 curAzimuth = surface.Azimuth;
     815              :                 // Round to two decimals, like the display in tables
     816              :                 // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
     817          543 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
     818          543 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpAzimuth, surfName, curAzimuth);
     819          543 :                 curTilt = surface.Tilt;
     820          543 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpTilt, surfName, curTilt);
     821          543 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
     822          362 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
     823           80 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "N");
     824          282 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
     825           82 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "E");
     826          200 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
     827          121 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "S");
     828           79 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
     829           79 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpDir, surfName, "W");
     830              :                     }
     831              :                 }
     832          543 :             } break;
     833           58 :             case DataSurfaces::SurfaceClass::Window:
     834              :             case DataSurfaces::SurfaceClass::TDD_Dome: {
     835           58 :                 auto &construct = state.dataConstruction->Construct(surface.Construction);
     836           58 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
     837           58 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
     838           58 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
     839           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenCons, surfName, construct.Name);
     840           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenZone, surfName, thisZone.Name);
     841           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSpace, surfName, thisSpace.Name);
     842              :                 // if the construction report is requested the SummerSHGC is already calculated
     843           58 :                 if (construct.SummerSHGC != 0) {
     844           39 :                     SHGCSummer = construct.SummerSHGC;
     845           39 :                     TransVisNorm = construct.VisTransNorm;
     846              :                 } else {
     847              :                     // must calculate Summer SHGC
     848           19 :                     if (!construct.WindowTypeEQL) {
     849           19 :                         Window::CalcNominalWindowCond(state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
     850           19 :                         construct.SummerSHGC = SHGCSummer;
     851           19 :                         construct.VisTransNorm = TransVisNorm;
     852           19 :                         construct.SolTransNorm = TransSolNorm;
     853              :                     }
     854              :                 }
     855              :                 // include the frame area if present
     856           58 :                 windowArea = surface.GrossArea;
     857           58 :                 frameArea = 0.0;
     858           58 :                 dividerArea = 0.0;
     859           58 :                 frameDivNum = surface.FrameDivider;
     860           58 :                 if (frameDivNum != 0) {
     861            3 :                     auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
     862            3 :                     frameWidth = frameDivider.FrameWidth;
     863            3 :                     frameArea = (surface.Height + 2.0 * frameWidth) * (surface.Width + 2.0 * frameWidth) - (surface.Height * surface.Width);
     864            3 :                     windowArea += frameArea;
     865            3 :                     dividerArea = frameDivider.DividerWidth * (frameDivider.HorDividers * surface.Width + frameDivider.VertDividers * surface.Height -
     866            3 :                                                                frameDivider.HorDividers * frameDivider.VertDividers * frameDivider.DividerWidth);
     867            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameDivName, surfName, frameDivider.Name);
     868            3 :                     OutputReportPredefined::PreDefTableEntry(
     869            3 :                         state, state.dataOutRptPredefined->pdchFenFrameConductance, surfName, frameDivider.FrameConductance, 3);
     870            3 :                     OutputReportPredefined::PreDefTableEntry(
     871            3 :                         state, state.dataOutRptPredefined->pdchFenDividerConductance, surfName, frameDivider.DividerConductance, 3);
     872              : 
     873              :                     // report the selected NRFC product type (specific sizes) and the NFRC rating for the assembly (glass + frame + divider)
     874            3 :                     std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
     875            3 :                     const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
     876            3 :                     const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
     877            3 :                     const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
     878              : 
     879            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemNfrcType, surfName, NFRCname);
     880              : 
     881            3 :                     Real64 uValueAssembly = 0.0;
     882            3 :                     Real64 shgcAssembly = 0.0;
     883            3 :                     Real64 vtAssembly = 0.0;
     884              : 
     885            3 :                     Window::GetWindowAssemblyNfrcForReport(
     886              :                         state, iSurf, surface.Construction, windowWidth, windowHeight, vision, uValueAssembly, shgcAssembly, vtAssembly);
     887            3 :                     if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
     888            0 :                         state.dataHeatBal->NominalU(surface.Construction) =
     889            0 :                             Window::GetIGUUValueForNFRCReport(state, iSurf, surface.Construction, windowWidth, windowHeight);
     890            0 :                         SHGCSummer = Window::GetSHGCValueForNFRCReporting(state, iSurf, surface.Construction, windowWidth, windowHeight);
     891              :                     }
     892            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemUfact, surfName, uValueAssembly, 3);
     893            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemSHGC, surfName, shgcAssembly, 3);
     894            3 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAssemVisTr, surfName, vtAssembly, 3);
     895              : 
     896              :                     // output EIO <FenestrationAssembly> for each unique combination of construction and frame/divider
     897            3 :                     if (state.dataGeneral->Constructions) {
     898            0 :                         consAndFrame = std::make_pair(surface.Construction, frameDivNum);
     899            0 :                         if (std::find(uniqConsFrame.begin(), uniqConsFrame.end(), consAndFrame) == uniqConsFrame.end()) {
     900            0 :                             uniqConsFrame.push_back(consAndFrame);
     901            0 :                             print(state.files.eio,
     902              :                                   FenestrationAssemblyFormat,
     903            0 :                                   construct.Name,
     904            0 :                                   frameDivider.Name,
     905              :                                   NFRCname,
     906              :                                   uValueAssembly,
     907              :                                   shgcAssembly,
     908              :                                   vtAssembly);
     909              :                         }
     910              :                     }
     911              :                 }
     912           58 :                 windowAreaWMult = windowArea * mult;
     913           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAreaOf1, surfName, windowArea);
     914           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenFrameAreaOf1, surfName, frameArea);
     915           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDividerAreaOf1, surfName, dividerArea);
     916          116 :                 OutputReportPredefined::PreDefTableEntry(
     917           58 :                     state, state.dataOutRptPredefined->pdchFenGlassAreaOf1, surfName, windowArea - (frameArea + dividerArea));
     918           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, surfName, windowAreaWMult);
     919           58 :                 computedNetArea(surface.BaseSurf) -= windowAreaWMult;
     920           58 :                 nomUfact = state.dataHeatBal->NominalU(surface.Construction);
     921           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, surfName, nomUfact, 3);
     922              : 
     923           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, surfName, SHGCSummer, 3);
     924           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, surfName, TransVisNorm, 3);
     925           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenParent, surfName, surface.BaseSurfName);
     926           58 :                 curAzimuth = surface.Azimuth;
     927              :                 // Round to two decimals, like the display in tables
     928           58 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
     929           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenAzimuth, surfName, curAzimuth);
     930           58 :                 isNorth = false;
     931           58 :                 curTilt = surface.Tilt;
     932           58 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenTilt, surfName, curTilt);
     933           58 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
     934           55 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
     935           11 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "N");
     936           11 :                         isNorth = true;
     937           44 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
     938            9 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "E");
     939           35 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
     940           29 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "S");
     941            6 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
     942            6 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenDir, surfName, "W");
     943              :                     }
     944              :                 }
     945              : 
     946              :                 // Report table for every shading control state
     947           58 :                 const unsigned int totalStates = surface.windowShadingControlList.size();
     948           58 :                 if (frameDivNum != 0) {
     949            3 :                     auto const &frameDivider = state.dataSurface->FrameDivider(frameDivNum);
     950            3 :                     for (unsigned int i = 0; i < totalStates; ++i) {
     951            0 :                         const Real64 windowWidth = NfrcWidth[static_cast<int>(frameDivider.NfrcProductType)];
     952            0 :                         const Real64 windowHeight = NfrcHeight[static_cast<int>(frameDivider.NfrcProductType)];
     953            0 :                         const DataSurfaces::NfrcVisionType vision = NfrcVision[static_cast<int>(frameDivider.NfrcProductType)];
     954              : 
     955            0 :                         const int stateConstrNum = surface.shadedConstructionList[i];
     956            0 :                         const Real64 stateUValue = Window::GetIGUUValueForNFRCReport(state, iSurf, stateConstrNum, windowWidth, windowHeight);
     957            0 :                         const Real64 stateSHGC = Window::GetSHGCValueForNFRCReporting(state, iSurf, stateConstrNum, windowWidth, windowHeight);
     958            0 :                         std::string const &constructionName = state.dataConstruction->Construct(stateConstrNum).Name;
     959              : 
     960            0 :                         OutputReportPredefined::PreDefTableEntry(
     961            0 :                             state, state.dataOutRptPredefined->pdchFenShdFrameDiv, constructionName, frameDivider.Name);
     962            0 :                         OutputReportPredefined::PreDefTableEntry(
     963            0 :                             state, state.dataOutRptPredefined->pdchFenShdUfact, constructionName, stateUValue, 3);
     964            0 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenShdSHGC, constructionName, stateSHGC, 3);
     965            0 :                         OutputReportPredefined::PreDefTableEntry(state,
     966            0 :                                                                  state.dataOutRptPredefined->pdchFenShdVisTr,
     967              :                                                                  constructionName,
     968            0 :                                                                  state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
     969            0 :                                                                  3);
     970              : 
     971            0 :                         Real64 stateAssemblyUValue{0.0};
     972            0 :                         Real64 stateAssemblySHGC{0.0};
     973            0 :                         Real64 stateAssemblyVT{0.0};
     974              : 
     975            0 :                         Window::GetWindowAssemblyNfrcForReport(
     976              :                             state, iSurf, stateConstrNum, windowWidth, windowHeight, vision, stateAssemblyUValue, stateAssemblySHGC, stateAssemblyVT);
     977              : 
     978            0 :                         std::string_view NFRCname = NfrcProductNames[static_cast<int>(frameDivider.NfrcProductType)];
     979            0 :                         OutputReportPredefined::PreDefTableEntry(
     980            0 :                             state, state.dataOutRptPredefined->pdchFenShdAssemNfrcType, constructionName, NFRCname);
     981              : 
     982            0 :                         OutputReportPredefined::PreDefTableEntry(
     983            0 :                             state, state.dataOutRptPredefined->pdchFenShdAssemUfact, constructionName, stateAssemblyUValue, 3);
     984            0 :                         OutputReportPredefined::PreDefTableEntry(
     985            0 :                             state, state.dataOutRptPredefined->pdchFenShdAssemSHGC, constructionName, stateAssemblySHGC, 3);
     986            0 :                         OutputReportPredefined::PreDefTableEntry(
     987            0 :                             state, state.dataOutRptPredefined->pdchFenShdAssemVisTr, constructionName, stateAssemblyVT, 3);
     988              : 
     989            0 :                         if (state.dataGeneral->Constructions) {
     990            0 :                             if (!fenestrationShadedStateHeaderShown) {
     991            0 :                                 print(state.files.eio,
     992              :                                       "{}\n",
     993              :                                       "! <FenestrationShadedState>,Construction Name,Glass U-Factor {W/m2-K},"
     994              :                                       "Glass SHGC, Glass Visible Transmittance, Frame and Divider Name,NFRC Product Type,"
     995              :                                       "Assembly U-Factor {W/m2-K},Assembly SHGC,Assembly Visible Transmittance");
     996            0 :                                 fenestrationShadedStateHeaderShown = true;
     997              :                             }
     998              : 
     999            0 :                             shdConsAndFrame = std::make_pair(stateConstrNum, frameDivNum);
    1000            0 :                             if (std::find(uniqShdConsFrame.begin(), uniqShdConsFrame.end(), shdConsAndFrame) == uniqShdConsFrame.end()) {
    1001            0 :                                 uniqShdConsFrame.push_back(shdConsAndFrame);
    1002            0 :                                 print(state.files.eio,
    1003              :                                       FenestrationShadedStateFormat,
    1004              :                                       constructionName,
    1005              :                                       stateUValue,
    1006              :                                       stateSHGC,
    1007            0 :                                       state.dataConstruction->Construct(stateConstrNum).VisTransNorm,
    1008            0 :                                       frameDivider.Name,
    1009              :                                       NFRCname,
    1010              :                                       stateAssemblyUValue,
    1011              :                                       stateAssemblySHGC,
    1012              :                                       stateAssemblyVT);
    1013              :                             }
    1014              :                         }
    1015              :                     }
    1016              :                 }
    1017              : 
    1018           58 :                 curWSC = surface.activeWindowShadingControl;
    1019              :                 // compute totals for area weighted averages
    1020           58 :                 fenTotArea += windowAreaWMult;
    1021           58 :                 ufactArea += nomUfact * windowAreaWMult;
    1022           58 :                 shgcArea += SHGCSummer * windowAreaWMult;
    1023           58 :                 vistranArea += TransVisNorm * windowAreaWMult;
    1024           58 :                 if (isNorth) {
    1025           11 :                     fenTotAreaNorth += windowAreaWMult;
    1026           11 :                     ufactAreaNorth += nomUfact * windowAreaWMult;
    1027           11 :                     shgcAreaNorth += SHGCSummer * windowAreaWMult;
    1028           11 :                     vistranAreaNorth += TransVisNorm * windowAreaWMult;
    1029              :                 } else {
    1030           47 :                     fenTotAreaNonNorth += windowAreaWMult;
    1031           47 :                     ufactAreaNonNorth += nomUfact * windowAreaWMult;
    1032           47 :                     shgcAreaNonNorth += SHGCSummer * windowAreaWMult;
    1033           47 :                     vistranAreaNonNorth += TransVisNorm * windowAreaWMult;
    1034              :                 }
    1035              :                 // shading
    1036           58 :                 if (surface.HasShadeControl) {
    1037            8 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "Yes");
    1038           16 :                     OutputReportPredefined::PreDefTableEntry(
    1039           16 :                         state, state.dataOutRptPredefined->pdchWscName, surfName, state.dataSurface->WindowShadingControl(curWSC).Name);
    1040              :                     // shading report
    1041           16 :                     OutputReportPredefined::PreDefTableEntry(
    1042              :                         state,
    1043            8 :                         state.dataOutRptPredefined->pdchWscShading,
    1044              :                         surfName,
    1045            8 :                         WindowShadingTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).ShadingType)]);
    1046           16 :                     OutputReportPredefined::PreDefTableEntry(
    1047              :                         state,
    1048            8 :                         state.dataOutRptPredefined->pdchWscControl,
    1049              :                         surfName,
    1050            8 :                         WindowShadingControlTypeNames[int(state.dataSurface->WindowShadingControl(curWSC).shadingControlType)]);
    1051              : 
    1052              :                     // output list of all possible shading constructions for shaded windows including those with storms
    1053            8 :                     std::string names;
    1054           16 :                     for (int construction : surface.shadedConstructionList) {
    1055            8 :                         if (!names.empty()) {
    1056            0 :                             names.append("; ");
    1057              :                         }
    1058            8 :                         names.append(state.dataConstruction->Construct(construction).Name);
    1059            8 :                     }
    1060            8 :                     for (int construction : surface.shadedStormWinConstructionList) {
    1061            0 :                         if (!names.empty()) {
    1062            0 :                             names.append("; ");
    1063              :                         }
    1064            0 :                         names.append(state.dataConstruction->Construct(construction).Name);
    1065            8 :                     }
    1066            8 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscShadCons, surfName, names);
    1067              : 
    1068            8 :                     if (state.dataSurface->WindowShadingControl(curWSC).GlareControlIsActive) {
    1069            0 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "Yes");
    1070              :                     } else {
    1071            8 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWscGlare, surfName, "No");
    1072              :                     }
    1073            8 :                 } else {
    1074           50 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSwitchable, surfName, "No");
    1075              :                 }
    1076           58 :             } break;
    1077            1 :             case DataSurfaces::SurfaceClass::Door: {
    1078            1 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1079            1 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1080            1 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1081            2 :                 OutputReportPredefined::PreDefTableEntry(
    1082            2 :                     state, state.dataOutRptPredefined->pdchDrCons, surfName, state.dataConstruction->Construct(surface.Construction).Name);
    1083            1 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrZone, surfName, thisZone.Name);
    1084            1 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrSpace, surfName, thisSpace.Name);
    1085            1 :                 OutputReportPredefined::PreDefTableEntry(
    1086            1 :                     state, state.dataOutRptPredefined->pdchDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1087            1 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrGrArea, surfName, surface.GrossArea * mult);
    1088            1 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchDrParent, surfName, surface.BaseSurfName);
    1089            1 :                 computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
    1090            1 :             } break;
    1091           16 :             default:
    1092           16 :                 break;
    1093              :             }
    1094          618 :         } else {
    1095              :             // interior surfaces
    1096          216 :             isExterior = false;
    1097          216 :             if ((surface.Class == DataSurfaces::SurfaceClass::Wall) || (surface.Class == DataSurfaces::SurfaceClass::Floor) ||
    1098           18 :                 (surface.Class == DataSurfaces::SurfaceClass::Roof) || (surface.Class == DataSurfaces::SurfaceClass::IntMass)) {
    1099          214 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1100          214 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1101          214 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1102          214 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1103          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpCons, surfName, construct.Name);
    1104          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpZone, surfName, thisZone.Name);
    1105          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpSpace, surfName, thisSpace.Name);
    1106          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAdjSurf, surfName, surface.ExtBoundCondName);
    1107          428 :                 OutputReportPredefined::PreDefTableEntry(
    1108          214 :                     state, state.dataOutRptPredefined->pdchIntOpRefl, surfName, 1 - construct.OutsideAbsorpSolar);
    1109          214 :                 OutputReportPredefined::PreDefTableEntry(
    1110          214 :                     state, state.dataOutRptPredefined->pdchIntOpUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1111          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpGrArea, surfName, surface.GrossArea * mult);
    1112          214 :                 computedNetArea(iSurf) += surface.GrossArea * mult;
    1113          214 :                 curAzimuth = surface.Azimuth;
    1114              :                 // Round to two decimals, like the display in tables
    1115              :                 // (PreDefTableEntry uses a fortran style write, that rounds rather than trim)
    1116          214 :                 curAzimuth = round(curAzimuth * 100.0) / 100.0;
    1117          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpAzimuth, surfName, curAzimuth);
    1118          214 :                 curTilt = surface.Tilt;
    1119          214 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpTilt, surfName, curTilt);
    1120          214 :                 if ((curTilt >= 60.0) && (curTilt < 180.0)) {
    1121          126 :                     if ((curAzimuth >= 315.0) || (curAzimuth < 45.0)) {
    1122           67 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "N");
    1123           59 :                     } else if ((curAzimuth >= 45.0) && (curAzimuth < 135.0)) {
    1124           36 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "E");
    1125           23 :                     } else if ((curAzimuth >= 135.0) && (curAzimuth < 225.0)) {
    1126           13 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "S");
    1127           10 :                     } else if ((curAzimuth >= 225.0) && (curAzimuth < 315.0)) {
    1128           10 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpDir, surfName, "W");
    1129              :                     }
    1130              :                 }
    1131              :                 // interior window report
    1132          216 :             } else if ((surface.Class == DataSurfaces::SurfaceClass::Window) || (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome)) {
    1133            0 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1134            0 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1135            0 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier * surface.Multiplier;
    1136            0 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1137            0 :                 if (!has_prefix(surface.Name,
    1138              :                                 "iz-")) { // don't count created interzone surfaces that are mirrors of other surfaces
    1139            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenCons, surfName, construct.Name);
    1140            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenZone, surfName, thisZone.Name);
    1141            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSpace, surfName, thisSpace.Name);
    1142              :                     // include the frame area if present
    1143            0 :                     windowArea = surface.GrossArea;
    1144            0 :                     if (surface.FrameDivider != 0) {
    1145            0 :                         frameWidth = state.dataSurface->FrameDivider(surface.FrameDivider).FrameWidth;
    1146            0 :                         frameArea = (surface.Height + 2 * frameWidth) * (surface.Width + 2 * frameWidth) - (surface.Height * surface.Width);
    1147            0 :                         windowArea += frameArea;
    1148              :                     }
    1149            0 :                     windowAreaWMult = windowArea * mult;
    1150            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenAreaOf1, surfName, windowArea);
    1151            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, surfName, windowAreaWMult);
    1152            0 :                     computedNetArea(surface.BaseSurf) -= windowAreaWMult;
    1153            0 :                     nomUfact = state.dataHeatBal->NominalU(surface.Construction);
    1154            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, surfName, nomUfact, 3);
    1155            0 :                     if (!construct.TypeIsAirBoundary) {
    1156              :                         // Solar properties not applicable for air boundary surfaces
    1157              :                         // if the construction report is requested the SummerSHGC is already calculated
    1158            0 :                         if (construct.SummerSHGC != 0) {
    1159            0 :                             SHGCSummer = construct.SummerSHGC;
    1160            0 :                             TransVisNorm = construct.VisTransNorm;
    1161              :                         } else {
    1162              :                             // must calculate Summer SHGC
    1163            0 :                             if (!construct.WindowTypeEQL) {
    1164            0 :                                 Window::CalcNominalWindowCond(
    1165              :                                     state, surface.Construction, 2, nomCond, SHGCSummer, TransSolNorm, TransVisNorm, errFlag);
    1166              :                             }
    1167              :                         }
    1168            0 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, surfName, SHGCSummer, 3);
    1169            0 :                         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, surfName, TransVisNorm, 3);
    1170              :                         // compute totals for area weighted averages
    1171            0 :                         intShgcArea += SHGCSummer * windowAreaWMult;
    1172            0 :                         intVistranArea += TransVisNorm * windowAreaWMult;
    1173              :                     }
    1174            0 :                     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenParent, surfName, surface.BaseSurfName);
    1175              :                     // compute totals for area weighted averages
    1176            0 :                     intFenTotArea += windowAreaWMult;
    1177            0 :                     intUfactArea += nomUfact * windowAreaWMult;
    1178              :                 }
    1179            2 :             } else if (surface.Class == DataSurfaces::SurfaceClass::Door) {
    1180            2 :                 auto const &construct = state.dataConstruction->Construct(surface.Construction);
    1181            2 :                 auto const &thisZone = state.dataHeatBal->Zone(surface.Zone);
    1182            2 :                 mult = thisZone.Multiplier * thisZone.ListMultiplier;
    1183            2 :                 auto const &thisSpace = state.dataHeatBal->space(surface.spaceNum);
    1184            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrCons, surfName, construct.Name);
    1185            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrZone, surfName, thisZone.Name);
    1186            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrSpace, surfName, thisSpace.Name);
    1187            2 :                 OutputReportPredefined::PreDefTableEntry(
    1188            2 :                     state, state.dataOutRptPredefined->pdchIntDrUfactNoFilm, surfName, state.dataHeatBal->NominalU(surface.Construction), 3);
    1189            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrGrArea, surfName, surface.GrossArea * mult);
    1190            2 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntDrParent, surfName, surface.BaseSurfName);
    1191            2 :                 computedNetArea(surface.BaseSurf) -= surface.GrossArea * mult;
    1192              :             }
    1193              :         }
    1194          834 :         int currSurfaceClass = int(surface.Class);
    1195          834 :         assert(currSurfaceClass < int(DataSurfaces::SurfaceClass::Num));
    1196          834 :         assert(currSurfaceClass > int(DataSurfaces::SurfaceClass::None));
    1197          834 :         ++numSurfaces(currSurfaceClass);
    1198          834 :         if (isExterior) {
    1199          618 :             ++numExtSurfaces(currSurfaceClass);
    1200              :         }
    1201          834 :         if (surface.Class == DataSurfaces::SurfaceClass::Window) {
    1202           58 :             if (surface.OriginalClass == DataSurfaces::SurfaceClass::GlassDoor || surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    1203            4 :                 ++numSurfaces((int)surface.OriginalClass);
    1204            4 :                 if (isExterior) {
    1205            4 :                     ++numExtSurfaces((int)surface.OriginalClass);
    1206              :                 }
    1207              :             }
    1208              :         }
    1209          114 :     }
    1210              :     // for fins and overhangs just add them explicitly since not otherwise classified
    1211          114 :     int totOverhangs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang") +
    1212          114 :                        state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Overhang:Projection");
    1213          114 :     numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
    1214          114 :     numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)) = totOverhangs;
    1215          114 :     int totFins = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin") +
    1216          114 :                   state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Shading:Fin:Projection");
    1217          114 :     numSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
    1218          114 :     numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)) = totFins;
    1219              :     // go through all the surfaces again and this time insert the net area results
    1220          948 :     for (int iSurf : state.dataSurface->AllSurfaceListReportOrder) {
    1221          834 :         auto const &surface = state.dataSurface->Surface(iSurf);
    1222          834 :         DataSurfaces::SurfaceClass const SurfaceClass(surface.Class);
    1223              :         // exterior surfaces including underground
    1224          834 :         if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::Ground) ||
    1225          216 :             (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) || (surface.ExtBoundCond == DataSurfaces::KivaFoundation)) {
    1226          618 :             if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
    1227              :                 (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
    1228          543 :                 surfName = surface.Name;
    1229          543 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchOpNetArea, surfName, computedNetArea(iSurf));
    1230              :             }
    1231              :         } else {
    1232          216 :             if ((SurfaceClass == DataSurfaces::SurfaceClass::Wall) || (SurfaceClass == DataSurfaces::SurfaceClass::Floor) ||
    1233              :                 (SurfaceClass == DataSurfaces::SurfaceClass::Roof)) {
    1234          211 :                 surfName = surface.Name;
    1235          211 :                 OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntOpNetArea, surfName, computedNetArea(iSurf));
    1236              :             }
    1237              :         } // interior surfaces
    1238          114 :     }
    1239              :     // total
    1240          114 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Total or Average", fenTotArea);
    1241          114 :     if (fenTotArea > 0.0) {
    1242           24 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", ufactArea / fenTotArea, 3);
    1243           24 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", shgcArea / fenTotArea, 3);
    1244           24 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", vistranArea / fenTotArea, 3);
    1245              :     } else {
    1246           90 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Total or Average", "-");
    1247           90 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Total or Average", "-");
    1248           90 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Total or Average", "-");
    1249              :     }
    1250              :     // north
    1251          114 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "North Total or Average", fenTotAreaNorth);
    1252          114 :     if (fenTotAreaNorth > 0.0) {
    1253           12 :         OutputReportPredefined::PreDefTableEntry(
    1254           12 :             state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", ufactAreaNorth / fenTotAreaNorth, 3);
    1255           12 :         OutputReportPredefined::PreDefTableEntry(
    1256           12 :             state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", shgcAreaNorth / fenTotAreaNorth, 3);
    1257           12 :         OutputReportPredefined::PreDefTableEntry(
    1258           18 :             state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", vistranAreaNorth / fenTotAreaNorth, 3);
    1259              :     } else {
    1260          108 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "North Total or Average", "-");
    1261          108 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "North Total or Average", "-");
    1262          108 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "North Total or Average", "-");
    1263              :     }
    1264              :     // non-north
    1265          114 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenArea, "Non-North Total or Average", fenTotAreaNonNorth);
    1266          114 :     if (fenTotAreaNonNorth > 0.0) {
    1267           46 :         OutputReportPredefined::PreDefTableEntry(
    1268           46 :             state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", ufactAreaNonNorth / fenTotAreaNonNorth, 3);
    1269           46 :         OutputReportPredefined::PreDefTableEntry(
    1270           46 :             state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", shgcAreaNonNorth / fenTotAreaNonNorth, 3);
    1271           46 :         OutputReportPredefined::PreDefTableEntry(
    1272           69 :             state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", vistranAreaNonNorth / fenTotAreaNonNorth, 3);
    1273              :     } else {
    1274           91 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenUfact, "Non-North Total or Average", "-");
    1275           91 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenSHGC, "Non-North Total or Average", "-");
    1276           91 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchFenVisTr, "Non-North Total or Average", "-");
    1277              :     }
    1278              :     // interior fenestration totals
    1279          114 :     OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenArea, "Total or Average", intFenTotArea);
    1280          114 :     if (intFenTotArea > 0.0) {
    1281            0 :         OutputReportPredefined::PreDefTableEntry(
    1282            0 :             state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", intUfactArea / intFenTotArea, 3);
    1283            0 :         OutputReportPredefined::PreDefTableEntry(
    1284            0 :             state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", intShgcArea / intFenTotArea, 3);
    1285            0 :         OutputReportPredefined::PreDefTableEntry(
    1286            0 :             state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", intVistranArea / intFenTotArea, 3);
    1287              :     } else {
    1288          114 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenUfact, "Total or Average", "-");
    1289          114 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenSHGC, "Total or Average", "-");
    1290          114 :         OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchIntFenVisTr, "Total or Average", "-");
    1291              :     }
    1292              :     // counts
    1293          114 :     OutputReportPredefined::PreDefTableEntry(
    1294          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Wall", numSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
    1295          114 :     OutputReportPredefined::PreDefTableEntry(
    1296          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Wall", numExtSurfaces(int(DataSurfaces::SurfaceClass::Wall)));
    1297          114 :     OutputReportPredefined::PreDefTableEntry(
    1298          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Floor", numSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
    1299          114 :     OutputReportPredefined::PreDefTableEntry(
    1300          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Floor", numExtSurfaces(int(DataSurfaces::SurfaceClass::Floor)));
    1301          114 :     OutputReportPredefined::PreDefTableEntry(
    1302          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Roof", numSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
    1303          114 :     OutputReportPredefined::PreDefTableEntry(
    1304          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Roof", numExtSurfaces(int(DataSurfaces::SurfaceClass::Roof)));
    1305          114 :     OutputReportPredefined::PreDefTableEntry(
    1306          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Internal Mass", numSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
    1307          114 :     OutputReportPredefined::PreDefTableEntry(
    1308          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Internal Mass", numExtSurfaces(int(DataSurfaces::SurfaceClass::IntMass)));
    1309          114 :     OutputReportPredefined::PreDefTableEntry(
    1310          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Building Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
    1311          114 :     OutputReportPredefined::PreDefTableEntry(
    1312          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Building Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_B)));
    1313          114 :     OutputReportPredefined::PreDefTableEntry(
    1314          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Fixed Detached Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
    1315          114 :     OutputReportPredefined::PreDefTableEntry(
    1316          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Fixed Detached Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Detached_F)));
    1317          114 :     OutputReportPredefined::PreDefTableEntry(
    1318          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Window", numSurfaces(int(DataSurfaces::SurfaceClass::Window)));
    1319          114 :     OutputReportPredefined::PreDefTableEntry(
    1320          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Window", numExtSurfaces(int(DataSurfaces::SurfaceClass::Window)));
    1321          114 :     OutputReportPredefined::PreDefTableEntry(
    1322          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Door", numSurfaces(int(DataSurfaces::SurfaceClass::Door)));
    1323          114 :     OutputReportPredefined::PreDefTableEntry(
    1324          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::Door)));
    1325          114 :     OutputReportPredefined::PreDefTableEntry(
    1326          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Glass Door", numSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
    1327          114 :     OutputReportPredefined::PreDefTableEntry(
    1328          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Glass Door", numExtSurfaces(int(DataSurfaces::SurfaceClass::GlassDoor)));
    1329          114 :     OutputReportPredefined::PreDefTableEntry(
    1330          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Shading", numSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
    1331          114 :     OutputReportPredefined::PreDefTableEntry(
    1332          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Shading", numExtSurfaces(int(DataSurfaces::SurfaceClass::Shading)));
    1333          114 :     OutputReportPredefined::PreDefTableEntry(
    1334          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Overhang", numSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
    1335          114 :     OutputReportPredefined::PreDefTableEntry(
    1336          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Overhang", numExtSurfaces(int(DataSurfaces::SurfaceClass::Overhang)));
    1337          114 :     OutputReportPredefined::PreDefTableEntry(
    1338          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Fin", numSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
    1339          114 :     OutputReportPredefined::PreDefTableEntry(
    1340          114 :         state, state.dataOutRptPredefined->pdchSurfCntExt, "Fin", numExtSurfaces(int(DataSurfaces::SurfaceClass::Fin)));
    1341          114 :     OutputReportPredefined::PreDefTableEntry(
    1342          114 :         state, state.dataOutRptPredefined->pdchSurfCntTot, "Tubular Daylighting Device Dome", numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
    1343          114 :     OutputReportPredefined::PreDefTableEntry(state,
    1344          114 :                                              state.dataOutRptPredefined->pdchSurfCntExt,
    1345              :                                              "Tubular Daylighting Device Dome",
    1346          114 :                                              numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Dome)));
    1347          114 :     OutputReportPredefined::PreDefTableEntry(state,
    1348          114 :                                              state.dataOutRptPredefined->pdchSurfCntTot,
    1349              :                                              "Tubular Daylighting Device Diffuser",
    1350          114 :                                              numSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
    1351          114 :     OutputReportPredefined::PreDefTableEntry(state,
    1352          114 :                                              state.dataOutRptPredefined->pdchSurfCntExt,
    1353              :                                              "Tubular Daylighting Device Diffuser",
    1354          114 :                                              numExtSurfaces(int(DataSurfaces::SurfaceClass::TDD_Diffuser)));
    1355          114 : }
    1356              : 
    1357          145 : void AllocateSurfaceHeatBalArrays(EnergyPlusData &state)
    1358              : {
    1359              : 
    1360              :     // SUBROUTINE INFORMATION:
    1361              :     //       AUTHOR         Richard Liesen
    1362              :     //       DATE WRITTEN   February 1998
    1363              : 
    1364              :     // METHODOLOGY EMPLOYED:
    1365              :     // Uses the status flags to trigger variable allocation.
    1366              : 
    1367              :     // Use the total number of surfaces to allocate variables to avoid a surface number limit
    1368          145 :     state.dataHeatBalSurf->SurfCTFConstInPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1369          145 :     state.dataHeatBalSurf->SurfCTFConstOutPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1370          145 :     state.dataHeatBalSurf->SurfCTFCross0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1371          145 :     state.dataHeatBalSurf->SurfCTFInside0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1372          145 :     state.dataHeatBalSurf->SurfTempOutHist.dimension(state.dataSurface->TotSurfaces, 0.0);
    1373          145 :     state.dataHeatBalSurf->SurfCTFSourceIn0.dimension(state.dataSurface->TotSurfaces, 0.0);
    1374          145 :     state.dataHeatBalSurf->SurfQSourceSinkHist.dimension(state.dataSurface->TotSurfaces, 0.0);
    1375          145 :     state.dataHeatBalSurf->SurfIsAdiabatic.dimension(state.dataSurface->TotSurfaces, 0);
    1376          145 :     state.dataHeatBalSurf->SurfIsSourceOrSink.dimension(state.dataSurface->TotSurfaces, 0);
    1377          145 :     state.dataHeatBalSurf->SurfIsOperatingPool.dimension(state.dataSurface->TotSurfaces, 0);
    1378          145 :     state.dataHeatBalSurf->SurfTempTerm.dimension(state.dataSurface->TotSurfaces, 0);
    1379          145 :     state.dataHeatBalSurf->SurfTempDiv.dimension(state.dataSurface->TotSurfaces, 0);
    1380          145 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    1381            2 :         state.dataHeatBalFanSys->CTFTsrcConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1382            2 :         state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0);
    1383              :     }
    1384              : 
    1385          145 :     state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp);
    1386          145 :     state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1387          145 :     state.dataHeatBalSurf->SurfHConvExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1388          145 :     state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1389          145 :     state.dataHeatBalSurf->SurfHSkyExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1390          145 :     state.dataHeatBalSurf->SurfHGrdExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1391          145 :     state.dataHeatBalSurf->SurfHSrdSurfExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1392              : 
    1393          145 :     state.dataHeatBalSurf->SurfTempIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1394          145 :     state.dataHeatBalSurf->SurfTempInsOld.dimension(state.dataSurface->TotSurfaces, 0.0);
    1395          145 :     state.dataHeatBalSurf->SurfTempInTmp.dimension(state.dataSurface->TotSurfaces, 0.0);
    1396          145 :     state.dataHeatBalSurfMgr->RefAirTemp.dimension(state.dataSurface->TotSurfaces, 0.0);
    1397          145 :     state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1398              : 
    1399          145 :     state.dataHeatBal->SurfWinQRadSWwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL + 1, 0.0);
    1400          145 :     state.dataHeatBal->SurfWinInitialDifSolwinAbs.dimension(state.dataSurface->TotSurfaces, DataWindowEquivalentLayer::CFSMAXNL, 0.0);
    1401          145 :     state.dataHeatBalSurf->SurfQRadSWOutMvIns.dimension(state.dataSurface->TotSurfaces, 0.0);
    1402          145 :     state.dataHeatBal->SurfQdotRadIntGainsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1403          145 :     state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside.dimension(state.dataSurface->TotSurfaces, 0.0);
    1404          145 :     state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside.dimension(state.dataSurface->TotSurfaces, 0.0);
    1405              : 
    1406          145 :     state.dataHeatBalSurf->SurfInsideTempHist.allocate(Construction::MaxCTFTerms);
    1407          145 :     state.dataHeatBalSurf->SurfOutsideTempHist.allocate(Construction::MaxCTFTerms);
    1408          145 :     state.dataHeatBalSurf->SurfInsideFluxHist.allocate(Construction::MaxCTFTerms);
    1409          145 :     state.dataHeatBalSurf->SurfOutsideFluxHist.allocate(Construction::MaxCTFTerms);
    1410         2900 :     for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
    1411         2755 :         state.dataHeatBalSurf->SurfInsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1412         2755 :         state.dataHeatBalSurf->SurfOutsideTempHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1413         2755 :         state.dataHeatBalSurf->SurfInsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1414         2755 :         state.dataHeatBalSurf->SurfOutsideFluxHist(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1415              :     }
    1416              : 
    1417          145 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1418           26 :         state.dataHeatBalSurf->SurfCurrNumHist.dimension(state.dataSurface->TotSurfaces, 0);
    1419              : 
    1420           26 :         state.dataHeatBalSurf->SurfInsideTempHistMaster.allocate(Construction::MaxCTFTerms);
    1421           26 :         state.dataHeatBalSurf->SurfOutsideTempHistMaster.allocate(Construction::MaxCTFTerms);
    1422           26 :         state.dataHeatBalSurf->SurfInsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
    1423           26 :         state.dataHeatBalSurf->SurfOutsideFluxHistMaster.allocate(Construction::MaxCTFTerms);
    1424              : 
    1425          520 :         for (int loop = 1; loop <= Construction::MaxCTFTerms; ++loop) {
    1426          494 :             state.dataHeatBalSurf->SurfInsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1427          494 :             state.dataHeatBalSurf->SurfOutsideTempHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1428          494 :             state.dataHeatBalSurf->SurfInsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1429          494 :             state.dataHeatBalSurf->SurfOutsideFluxHistMaster(loop).dimension(state.dataSurface->TotSurfaces, 0);
    1430              :         }
    1431              :     }
    1432              : 
    1433          145 :     state.dataHeatBalSurf->SurfTempOut.dimension(state.dataSurface->TotSurfaces, 0.0);
    1434          145 :     state.dataHeatBalSurf->SurfTempInMovInsRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1435          145 :     state.dataHeatBalSurf->SurfQConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1436          145 :     state.dataHeatBalSurf->SurfQdotConvInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1437          145 :     state.dataHeatBalSurf->SurfQdotConvInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1438              : 
    1439          145 :     state.dataHeatBalSurf->SurfQRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1440          145 :     state.dataHeatBalSurf->SurfQdotRadNetSurfInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1441              : 
    1442          145 :     state.dataHeatBalSurf->SurfQRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1443          145 :     state.dataHeatBalSurf->SurfQdotRadSolarInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1444          145 :     state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1445              : 
    1446          145 :     state.dataHeatBalSurf->SurfQRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1447          145 :     state.dataHeatBalSurf->SurfQdotRadLightsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1448              : 
    1449          145 :     state.dataHeatBalSurf->SurfQRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1450          145 :     state.dataHeatBalSurf->SurfQdotRadIntGainsInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1451              : 
    1452          145 :     state.dataHeatBalSurf->SurfQRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1453          145 :     state.dataHeatBalSurf->SurfQdotRadHVACInRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1454          145 :     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1455              : 
    1456          145 :     state.dataHeatBalSurf->SurfQConvOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1457          145 :     state.dataHeatBalSurf->SurfQdotConvOutPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1458          145 :     state.dataHeatBalSurf->SurfQdotConvOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1459              : 
    1460          145 :     state.dataHeatBalSurf->SurfQdotRadOutRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1461          145 :     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1462          145 :     state.dataHeatBalSurf->SurfQRadOutReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1463              : 
    1464          145 :     state.dataHeatBalSurf->SurfQAirExtReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1465          145 :     state.dataHeatBalSurf->SurfQHeatEmiReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1466              : 
    1467          145 :     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1468          145 :     state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport.dimension(state.dataSurface->TotSurfaces, 0.0);
    1469              : 
    1470          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1471          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1472          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1473          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1474          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1475              : 
    1476          145 :     state.dataHeatBalSurf->SurfOpaqOutFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1477          145 :     state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1478          145 :     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1479          145 :     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1480          145 :     state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1481              : 
    1482          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1483          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1484          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1485          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1486          145 :     state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1487              : 
    1488          145 :     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1489          145 :     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep.dimension(state.dataSurface->TotSurfaces, 0.0);
    1490          145 :     state.dataHeatBalSurf->SurfOpaqStorageCond.dimension(state.dataSurface->TotSurfaces, 0.0);
    1491          145 :     state.dataHeatBalSurf->SurfOpaqStorageCondFlux.dimension(state.dataSurface->TotSurfaces, 0.0);
    1492          145 :     state.dataHeatBalSurf->SurfOpaqStorageCondEnergy.dimension(state.dataSurface->TotSurfaces, 0.0);
    1493              : 
    1494          145 :     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed.dimension(state.dataSurface->TotSurfaces, 0.0);
    1495              : 
    1496          145 :     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1497          145 :     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1498              : 
    1499          145 :     state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1500          145 :     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
    1501          145 :     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans.dimension(state.dataSurface->TotSurfaces, 0.0);
    1502              : 
    1503          145 :     state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1504          145 :     state.dataHeatBalSurf->SurfQdotRadLightsInPerArea.dimension(state.dataSurface->TotSurfaces, 0.0);
    1505              : 
    1506          145 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    1507            2 :         state.dataHeatBalSurf->SurfTempSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1508            2 :         state.dataHeatBalSurf->SurfTempUserLoc.dimension(state.dataSurface->TotSurfaces, 0.0);
    1509            2 :         state.dataHeatBalSurf->SurfTsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1510            2 :         state.dataHeatBalSurf->SurfTuserHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1511            2 :         state.dataHeatBalSurf->SurfQsrcHist.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1512            2 :         state.dataHeatBalSurf->SurfTsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1513            2 :         state.dataHeatBalSurf->SurfTuserHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1514            2 :         state.dataHeatBalSurf->SurfQsrcHistM.dimension(state.dataSurface->TotSurfaces, Construction::MaxCTFTerms, 0.0);
    1515              :     }
    1516              : 
    1517          145 :     state.dataHeatBalFanSys->RadSysTiHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1518          145 :     state.dataHeatBalFanSys->RadSysTiHBToutCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1519          145 :     state.dataHeatBalFanSys->RadSysTiHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1520          145 :     state.dataHeatBalFanSys->RadSysToHBConstCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1521          145 :     state.dataHeatBalFanSys->RadSysToHBTinCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1522          145 :     state.dataHeatBalFanSys->RadSysToHBQsrcCoef.dimension(state.dataSurface->TotSurfaces, 0.0);
    1523          145 :     state.dataHeatBalFanSys->QRadSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1524          145 :     state.dataHeatBalFanSys->TCondFDSourceNode.dimension(state.dataSurface->TotSurfaces, 15.0);
    1525          145 :     state.dataHeatBalFanSys->surfQRadFromHVAC.allocate(state.dataSurface->TotSurfaces);
    1526          145 :     state.dataHeatBalFanSys->QRadSurfAFNDuct.dimension(state.dataSurface->TotSurfaces, 0.0);
    1527              : 
    1528              :     // allocate terms used for pool surface heat balance
    1529          145 :     state.dataHeatBalFanSys->QPoolSurfNumerator.dimension(state.dataSurface->TotSurfaces, 0.0);
    1530          145 :     state.dataHeatBalFanSys->PoolHeatTransCoefs.dimension(state.dataSurface->TotSurfaces, 0.0);
    1531              : 
    1532              :     // allocate term used as sink for PV electricity
    1533          145 :     state.dataHeatBalFanSys->QPVSysSource.dimension(state.dataSurface->TotSurfaces, 0.0);
    1534              : 
    1535              :     // Allocate the moisture balance arrays
    1536          145 :     state.dataMstBal->TempOutsideAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1537          145 :     state.dataMstBal->RhoVaporAirOut.dimension(state.dataSurface->TotSurfaces, 0.0);
    1538          145 :     state.dataMstBal->RhoVaporSurfIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1539          145 :     state.dataMstBal->RhoVaporAirIn.dimension(state.dataSurface->TotSurfaces, 0.0);
    1540          145 :     state.dataMstBal->HConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1541          145 :     state.dataMstBal->HMassConvExtFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1542          145 :     state.dataMstBal->HConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1543          145 :     state.dataMstBal->HMassConvInFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1544          145 :     state.dataMstBal->HSkyFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1545          145 :     state.dataMstBal->HGrndFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1546          145 :     state.dataMstBal->HAirFD.dimension(state.dataSurface->TotSurfaces, 0.0);
    1547              : 
    1548          145 :     state.dataSurface->SurfSkySolarInc.dimension(state.dataSurface->TotSurfaces, 0);
    1549          145 :     state.dataSurface->SurfGndSolarInc.dimension(state.dataSurface->TotSurfaces, 0);
    1550              : 
    1551          145 :     state.dataHeatBalSurf->SurfAbsSolarExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1552          145 :     state.dataHeatBalSurf->SurfAbsThermalExt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1553          145 :     state.dataHeatBalSurf->SurfRoughnessExt.dimension(state.dataSurface->TotSurfaces, Material::SurfaceRoughness::Invalid);
    1554          145 :     state.dataHeatBalSurf->SurfAbsSolarInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1555          145 :     state.dataHeatBalSurf->SurfAbsThermalInt.dimension(state.dataSurface->TotSurfaces, 0.0);
    1556              : 
    1557          145 :     DisplayString(state, "Setting up Surface Reporting Variables");
    1558              :     // Setup surface report variables CurrentModuleObject='Opaque Surfaces'
    1559         1164 :     for (int loop = 1; loop <= state.dataSurface->TotSurfaces; ++loop) {
    1560         1019 :         auto &surface = state.dataSurface->Surface(loop);
    1561         1019 :         if (!surface.HeatTransSurf) {
    1562           24 :             continue;
    1563              :         }
    1564         1990 :         SetupOutputVariable(state,
    1565              :                             "Surface Inside Face Temperature",
    1566              :                             Constant::Units::C,
    1567          995 :                             state.dataHeatBalSurf->SurfTempIn(loop),
    1568              :                             OutputProcessor::TimeStepType::Zone,
    1569              :                             OutputProcessor::StoreType::Average,
    1570          995 :                             surface.Name);
    1571         1990 :         SetupOutputVariable(state,
    1572              :                             "Surface Inside Face Interior Movable Insulation Temperature",
    1573              :                             Constant::Units::C,
    1574          995 :                             state.dataHeatBalSurf->SurfTempInMovInsRep(loop),
    1575              :                             OutputProcessor::TimeStepType::Zone,
    1576              :                             OutputProcessor::StoreType::Average,
    1577          995 :                             surface.Name);
    1578              : 
    1579          995 :         if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
    1580         1990 :             SetupOutputVariable(state,
    1581              :                                 "Surface Outside Face Temperature",
    1582              :                                 Constant::Units::C,
    1583          995 :                                 state.dataHeatBalSurf->SurfTempOut(loop),
    1584              :                                 OutputProcessor::TimeStepType::Zone,
    1585              :                                 OutputProcessor::StoreType::Average,
    1586          995 :                                 surface.Name);
    1587              :         }
    1588              : 
    1589         1990 :         SetupOutputVariable(state,
    1590              :                             "Surface Inside Face Adjacent Air Temperature",
    1591              :                             Constant::Units::C,
    1592          995 :                             state.dataHeatBal->SurfTempEffBulkAir(loop),
    1593              :                             OutputProcessor::TimeStepType::Zone,
    1594              :                             OutputProcessor::StoreType::Average,
    1595          995 :                             surface.Name);
    1596         1990 :         SetupOutputVariable(state,
    1597              :                             "Surface Inside Face Convection Heat Transfer Coefficient",
    1598              :                             Constant::Units::W_m2K,
    1599          995 :                             state.dataHeatBalSurf->SurfHConvInt(loop),
    1600              :                             OutputProcessor::TimeStepType::Zone,
    1601              :                             OutputProcessor::StoreType::Average,
    1602          995 :                             surface.Name);
    1603         1990 :         SetupOutputVariable(state,
    1604              :                             "Surface Inside Face Convection Heat Gain Rate",
    1605              :                             Constant::Units::W,
    1606          995 :                             state.dataHeatBalSurf->SurfQdotConvInRep(loop),
    1607              :                             OutputProcessor::TimeStepType::Zone,
    1608              :                             OutputProcessor::StoreType::Average,
    1609          995 :                             surface.Name);
    1610         1990 :         SetupOutputVariable(state,
    1611              :                             "Surface Inside Face Convection Heat Gain Rate per Area",
    1612              :                             Constant::Units::W_m2,
    1613          995 :                             state.dataHeatBalSurf->SurfQdotConvInPerArea(loop),
    1614              :                             OutputProcessor::TimeStepType::Zone,
    1615              :                             OutputProcessor::StoreType::Average,
    1616          995 :                             surface.Name);
    1617         1990 :         SetupOutputVariable(state,
    1618              :                             "Surface Inside Face Convection Heat Gain Energy",
    1619              :                             Constant::Units::J,
    1620          995 :                             state.dataHeatBalSurf->SurfQConvInRep(loop),
    1621              :                             OutputProcessor::TimeStepType::Zone,
    1622              :                             OutputProcessor::StoreType::Sum,
    1623          995 :                             surface.Name);
    1624              : 
    1625         1990 :         SetupOutputVariable(state,
    1626              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate",
    1627              :                             Constant::Units::W,
    1628          995 :                             state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(loop),
    1629              :                             OutputProcessor::TimeStepType::Zone,
    1630              :                             OutputProcessor::StoreType::Average,
    1631          995 :                             surface.Name);
    1632         1990 :         SetupOutputVariable(state,
    1633              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Rate per Area",
    1634              :                             Constant::Units::W_m2,
    1635          995 :                             state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(loop),
    1636              :                             OutputProcessor::TimeStepType::Zone,
    1637              :                             OutputProcessor::StoreType::Average,
    1638          995 :                             surface.Name);
    1639         1990 :         SetupOutputVariable(state,
    1640              :                             "Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy",
    1641              :                             Constant::Units::J,
    1642          995 :                             state.dataHeatBalSurf->SurfQRadNetSurfInRep(loop),
    1643              :                             OutputProcessor::TimeStepType::Zone,
    1644              :                             OutputProcessor::StoreType::Sum,
    1645          995 :                             surface.Name);
    1646              : 
    1647          995 :         if (surface.Class != DataSurfaces::SurfaceClass::Window) {
    1648         1880 :             SetupOutputVariable(state,
    1649              :                                 "Surface Inside Face Solar Radiation Heat Gain Rate",
    1650              :                                 Constant::Units::W,
    1651          940 :                                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(loop),
    1652              :                                 OutputProcessor::TimeStepType::Zone,
    1653              :                                 OutputProcessor::StoreType::Average,
    1654          940 :                                 surface.Name);
    1655         1880 :             SetupOutputVariable(state,
    1656              :                                 "Surface Inside Face Solar Radiation Heat Gain Rate per Area",
    1657              :                                 Constant::Units::W_m2,
    1658          940 :                                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(loop),
    1659              :                                 OutputProcessor::TimeStepType::Zone,
    1660              :                                 OutputProcessor::StoreType::Average,
    1661          940 :                                 surface.Name);
    1662         1880 :             SetupOutputVariable(state,
    1663              :                                 "Surface Inside Face Solar Radiation Heat Gain Energy",
    1664              :                                 Constant::Units::J,
    1665          940 :                                 state.dataHeatBalSurf->SurfQRadSolarInRep(loop),
    1666              :                                 OutputProcessor::TimeStepType::Zone,
    1667              :                                 OutputProcessor::StoreType::Sum,
    1668          940 :                                 surface.Name);
    1669              : 
    1670         1880 :             SetupOutputVariable(state,
    1671              :                                 "Surface Inside Face Lights Radiation Heat Gain Rate",
    1672              :                                 Constant::Units::W,
    1673          940 :                                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(loop),
    1674              :                                 OutputProcessor::TimeStepType::Zone,
    1675              :                                 OutputProcessor::StoreType::Average,
    1676          940 :                                 surface.Name);
    1677         1880 :             SetupOutputVariable(state,
    1678              :                                 "Surface Inside Face Lights Radiation Heat Gain Rate per Area",
    1679              :                                 Constant::Units::W_m2,
    1680          940 :                                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(loop),
    1681              :                                 OutputProcessor::TimeStepType::Zone,
    1682              :                                 OutputProcessor::StoreType::Average,
    1683          940 :                                 surface.Name);
    1684         1880 :             SetupOutputVariable(state,
    1685              :                                 "Surface Inside Face Lights Radiation Heat Gain Energy",
    1686              :                                 Constant::Units::J,
    1687          940 :                                 state.dataHeatBalSurf->SurfQRadLightsInRep(loop),
    1688              :                                 OutputProcessor::TimeStepType::Zone,
    1689              :                                 OutputProcessor::StoreType::Sum,
    1690          940 :                                 surface.Name);
    1691              :         }
    1692              : 
    1693         1990 :         SetupOutputVariable(state,
    1694              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Rate",
    1695              :                             Constant::Units::W,
    1696          995 :                             state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(loop),
    1697              :                             OutputProcessor::TimeStepType::Zone,
    1698              :                             OutputProcessor::StoreType::Average,
    1699          995 :                             surface.Name);
    1700         1990 :         SetupOutputVariable(state,
    1701              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Rate per Area",
    1702              :                             Constant::Units::W_m2,
    1703          995 :                             state.dataHeatBal->SurfQdotRadIntGainsInPerArea(loop),
    1704              :                             OutputProcessor::TimeStepType::Zone,
    1705              :                             OutputProcessor::StoreType::Average,
    1706          995 :                             surface.Name);
    1707         1990 :         SetupOutputVariable(state,
    1708              :                             "Surface Inside Face Internal Gains Radiation Heat Gain Energy",
    1709              :                             Constant::Units::J,
    1710          995 :                             state.dataHeatBalSurf->SurfQRadIntGainsInRep(loop),
    1711              :                             OutputProcessor::TimeStepType::Zone,
    1712              :                             OutputProcessor::StoreType::Sum,
    1713          995 :                             surface.Name);
    1714              : 
    1715         1990 :         SetupOutputVariable(state,
    1716              :                             "Surface Inside Face System Radiation Heat Gain Rate",
    1717              :                             Constant::Units::W,
    1718          995 :                             state.dataHeatBalSurf->SurfQdotRadHVACInRep(loop),
    1719              :                             OutputProcessor::TimeStepType::Zone,
    1720              :                             OutputProcessor::StoreType::Average,
    1721          995 :                             surface.Name);
    1722         1990 :         SetupOutputVariable(state,
    1723              :                             "Surface Inside Face System Radiation Heat Gain Rate per Area",
    1724              :                             Constant::Units::W_m2,
    1725          995 :                             state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(loop),
    1726              :                             OutputProcessor::TimeStepType::Zone,
    1727              :                             OutputProcessor::StoreType::Average,
    1728          995 :                             surface.Name);
    1729         1990 :         SetupOutputVariable(state,
    1730              :                             "Surface Inside Face System Radiation Heat Gain Energy",
    1731              :                             Constant::Units::J,
    1732          995 :                             state.dataHeatBalSurf->SurfQRadHVACInRep(loop),
    1733              :                             OutputProcessor::TimeStepType::Zone,
    1734              :                             OutputProcessor::StoreType::Sum,
    1735          995 :                             surface.Name);
    1736              : 
    1737          995 :         if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment || state.dataGlobal->DisplayAdvancedReportVariables) {
    1738         1432 :             SetupOutputVariable(state,
    1739              :                                 "Surface Outside Face Outdoor Air Drybulb Temperature",
    1740              :                                 Constant::Units::C,
    1741          716 :                                 state.dataSurface->SurfOutDryBulbTemp(loop),
    1742              :                                 OutputProcessor::TimeStepType::Zone,
    1743              :                                 OutputProcessor::StoreType::Average,
    1744          716 :                                 surface.Name);
    1745         1432 :             SetupOutputVariable(state,
    1746              :                                 "Surface Outside Face Outdoor Air Wetbulb Temperature",
    1747              :                                 Constant::Units::C,
    1748          716 :                                 state.dataSurface->SurfOutWetBulbTemp(loop),
    1749              :                                 OutputProcessor::TimeStepType::Zone,
    1750              :                                 OutputProcessor::StoreType::Average,
    1751          716 :                                 surface.Name);
    1752         1432 :             SetupOutputVariable(state,
    1753              :                                 "Surface Outside Face Outdoor Air Wind Speed",
    1754              :                                 Constant::Units::m_s,
    1755          716 :                                 state.dataSurface->SurfOutWindSpeed(loop),
    1756              :                                 OutputProcessor::TimeStepType::Zone,
    1757              :                                 OutputProcessor::StoreType::Average,
    1758          716 :                                 surface.Name);
    1759         1432 :             SetupOutputVariable(state,
    1760              :                                 "Surface Outside Face Outdoor Air Wind Direction",
    1761              :                                 Constant::Units::deg,
    1762          716 :                                 state.dataSurface->SurfOutWindDir(loop),
    1763              :                                 OutputProcessor::TimeStepType::Zone,
    1764              :                                 OutputProcessor::StoreType::Average,
    1765          716 :                                 surface.Name);
    1766         1432 :             SetupOutputVariable(state,
    1767              :                                 "Surface Outside Face Convection Heat Gain Rate",
    1768              :                                 Constant::Units::W,
    1769          716 :                                 state.dataHeatBalSurf->SurfQdotConvOutRep(loop),
    1770              :                                 OutputProcessor::TimeStepType::Zone,
    1771              :                                 OutputProcessor::StoreType::Average,
    1772          716 :                                 surface.Name);
    1773         1432 :             SetupOutputVariable(state,
    1774              :                                 "Surface Outside Face Convection Heat Gain Rate per Area",
    1775              :                                 Constant::Units::W_m2,
    1776          716 :                                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(loop),
    1777              :                                 OutputProcessor::TimeStepType::Zone,
    1778              :                                 OutputProcessor::StoreType::Average,
    1779          716 :                                 surface.Name);
    1780         1432 :             SetupOutputVariable(state,
    1781              :                                 "Surface Outside Face Convection Heat Gain Energy",
    1782              :                                 Constant::Units::J,
    1783          716 :                                 state.dataHeatBalSurf->SurfQConvOutReport(loop),
    1784              :                                 OutputProcessor::TimeStepType::Zone,
    1785              :                                 OutputProcessor::StoreType::Sum,
    1786          716 :                                 surface.Name);
    1787         1432 :             SetupOutputVariable(state,
    1788              :                                 "Surface Outside Face Convection Heat Transfer Coefficient",
    1789              :                                 Constant::Units::W_m2K,
    1790          716 :                                 state.dataHeatBalSurf->SurfHConvExt(loop),
    1791              :                                 OutputProcessor::TimeStepType::Zone,
    1792              :                                 OutputProcessor::StoreType::Average,
    1793          716 :                                 surface.Name);
    1794         1432 :             SetupOutputVariable(state,
    1795              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Rate",
    1796              :                                 Constant::Units::W,
    1797          716 :                                 state.dataHeatBalSurf->SurfQdotRadOutRep(loop),
    1798              :                                 OutputProcessor::TimeStepType::Zone,
    1799              :                                 OutputProcessor::StoreType::Average,
    1800          716 :                                 surface.Name);
    1801         1432 :             SetupOutputVariable(state,
    1802              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Rate per Area",
    1803              :                                 Constant::Units::W_m2,
    1804          716 :                                 state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(loop),
    1805              :                                 OutputProcessor::TimeStepType::Zone,
    1806              :                                 OutputProcessor::StoreType::Average,
    1807          716 :                                 surface.Name);
    1808         1432 :             SetupOutputVariable(state,
    1809              :                                 "Surface Outside Face Net Thermal Radiation Heat Gain Energy",
    1810              :                                 Constant::Units::J,
    1811          716 :                                 state.dataHeatBalSurf->SurfQRadOutReport(loop),
    1812              :                                 OutputProcessor::TimeStepType::Zone,
    1813              :                                 OutputProcessor::StoreType::Sum,
    1814          716 :                                 surface.Name);
    1815         1432 :             SetupOutputVariable(state,
    1816              :                                 "Surface Outside Face Thermal Radiation to Air Heat Transfer Coefficient",
    1817              :                                 Constant::Units::W_m2K,
    1818          716 :                                 state.dataHeatBalSurf->SurfHAirExt(loop),
    1819              :                                 OutputProcessor::TimeStepType::Zone,
    1820              :                                 OutputProcessor::StoreType::Average,
    1821          716 :                                 surface.Name);
    1822         1432 :             SetupOutputVariable(state,
    1823              :                                 "Surface Outside Face Thermal Radiation to Sky Heat Transfer Coefficient",
    1824              :                                 Constant::Units::W_m2K,
    1825          716 :                                 state.dataHeatBalSurf->SurfHSkyExt(loop),
    1826              :                                 OutputProcessor::TimeStepType::Zone,
    1827              :                                 OutputProcessor::StoreType::Average,
    1828          716 :                                 surface.Name);
    1829         1432 :             SetupOutputVariable(state,
    1830              :                                 "Surface Outside Face Thermal Radiation to Ground Heat Transfer Coefficient",
    1831              :                                 Constant::Units::W_m2K,
    1832          716 :                                 state.dataHeatBalSurf->SurfHGrdExt(loop),
    1833              :                                 OutputProcessor::TimeStepType::Zone,
    1834              :                                 OutputProcessor::StoreType::Average,
    1835          716 :                                 surface.Name);
    1836         1432 :             SetupOutputVariable(state,
    1837              :                                 "Surface Outside Face Thermal Radiation to Air Heat Transfer Rate",
    1838              :                                 Constant::Units::W,
    1839          716 :                                 state.dataHeatBalSurf->SurfQAirExtReport(loop),
    1840              :                                 OutputProcessor::TimeStepType::Zone,
    1841              :                                 OutputProcessor::StoreType::Average,
    1842          716 :                                 surface.Name);
    1843         1432 :             SetupOutputVariable(state,
    1844              :                                 "Surface Outside Face Heat Emission to Air Rate",
    1845              :                                 Constant::Units::W,
    1846          716 :                                 state.dataHeatBalSurf->SurfQHeatEmiReport(loop),
    1847              :                                 OutputProcessor::TimeStepType::Zone,
    1848              :                                 OutputProcessor::StoreType::Average,
    1849          716 :                                 surface.Name);
    1850              : 
    1851          716 :             if (surface.Class != DataSurfaces::SurfaceClass::Window) {
    1852         1322 :                 SetupOutputVariable(state,
    1853              :                                     "Surface Outside Face Solar Radiation Heat Gain Rate",
    1854              :                                     Constant::Units::W,
    1855          661 :                                     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(loop),
    1856              :                                     OutputProcessor::TimeStepType::Zone,
    1857              :                                     OutputProcessor::StoreType::Average,
    1858          661 :                                     surface.Name);
    1859         1322 :                 SetupOutputVariable(state,
    1860              :                                     "Surface Outside Face Solar Radiation Heat Gain Rate per Area",
    1861              :                                     Constant::Units::W_m2,
    1862          661 :                                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(loop),
    1863              :                                     OutputProcessor::TimeStepType::Zone,
    1864              :                                     OutputProcessor::StoreType::Average,
    1865          661 :                                     surface.Name);
    1866         1322 :                 SetupOutputVariable(state,
    1867              :                                     "Surface Outside Face Solar Radiation Heat Gain Energy",
    1868              :                                     Constant::Units::J,
    1869          661 :                                     state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(loop),
    1870              :                                     OutputProcessor::TimeStepType::Zone,
    1871              :                                     OutputProcessor::StoreType::Sum,
    1872          661 :                                     surface.Name);
    1873              :             }
    1874              :         }
    1875          995 :         if (surface.Class == DataSurfaces::SurfaceClass::Floor || surface.Class == DataSurfaces::SurfaceClass::Wall ||
    1876          223 :             surface.Class == DataSurfaces::SurfaceClass::IntMass || surface.Class == DataSurfaces::SurfaceClass::Roof ||
    1877           58 :             surface.Class == DataSurfaces::SurfaceClass::Door) {
    1878              :             //      IF (DisplayAdvancedReportVariables) THEN  !CurrentModuleObject='Opaque Surfaces(Advanced)'
    1879         1876 :             SetupOutputVariable(state,
    1880              :                                 "Surface Inside Face Conduction Heat Transfer Rate",
    1881              :                                 Constant::Units::W,
    1882          938 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(loop),
    1883              :                                 OutputProcessor::TimeStepType::Zone,
    1884              :                                 OutputProcessor::StoreType::Average,
    1885          938 :                                 surface.Name);
    1886         1876 :             SetupOutputVariable(state,
    1887              :                                 "Surface Inside Face Conduction Heat Gain Rate",
    1888              :                                 Constant::Units::W,
    1889          938 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(loop),
    1890              :                                 OutputProcessor::TimeStepType::Zone,
    1891              :                                 OutputProcessor::StoreType::Average,
    1892          938 :                                 surface.Name);
    1893         1876 :             SetupOutputVariable(state,
    1894              :                                 "Surface Inside Face Conduction Heat Loss Rate",
    1895              :                                 Constant::Units::W,
    1896          938 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(loop),
    1897              :                                 OutputProcessor::TimeStepType::Zone,
    1898              :                                 OutputProcessor::StoreType::Average,
    1899          938 :                                 surface.Name);
    1900         1876 :             SetupOutputVariable(state,
    1901              :                                 "Surface Inside Face Conduction Heat Transfer Rate per Area",
    1902              :                                 Constant::Units::W_m2,
    1903          938 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(loop),
    1904              :                                 OutputProcessor::TimeStepType::Zone,
    1905              :                                 OutputProcessor::StoreType::Average,
    1906          938 :                                 surface.Name);
    1907         1876 :             SetupOutputVariable(state,
    1908              :                                 "Surface Inside Face Conduction Heat Transfer Energy",
    1909              :                                 Constant::Units::J,
    1910          938 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(loop),
    1911              :                                 OutputProcessor::TimeStepType::Zone,
    1912              :                                 OutputProcessor::StoreType::Sum,
    1913          938 :                                 surface.Name);
    1914              : 
    1915          938 :             if (surface.ExtBoundCond != DataSurfaces::KivaFoundation) {
    1916         1876 :                 SetupOutputVariable(state,
    1917              :                                     "Surface Outside Face Conduction Heat Transfer Rate",
    1918              :                                     Constant::Units::W,
    1919          938 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCond(loop),
    1920              :                                     OutputProcessor::TimeStepType::Zone,
    1921              :                                     OutputProcessor::StoreType::Average,
    1922          938 :                                     surface.Name);
    1923         1876 :                 SetupOutputVariable(state,
    1924              :                                     "Surface Outside Face Conduction Heat Gain Rate",
    1925              :                                     Constant::Units::W,
    1926          938 :                                     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(loop),
    1927              :                                     OutputProcessor::TimeStepType::Zone,
    1928              :                                     OutputProcessor::StoreType::Average,
    1929          938 :                                     surface.Name);
    1930         1876 :                 SetupOutputVariable(state,
    1931              :                                     "Surface Outside Face Conduction Heat Loss Rate",
    1932              :                                     Constant::Units::W,
    1933          938 :                                     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(loop),
    1934              :                                     OutputProcessor::TimeStepType::Zone,
    1935              :                                     OutputProcessor::StoreType::Average,
    1936          938 :                                     surface.Name);
    1937         1876 :                 SetupOutputVariable(state,
    1938              :                                     "Surface Outside Face Conduction Heat Transfer Rate per Area",
    1939              :                                     Constant::Units::W_m2,
    1940          938 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(loop),
    1941              :                                     OutputProcessor::TimeStepType::Zone,
    1942              :                                     OutputProcessor::StoreType::Average,
    1943          938 :                                     surface.Name);
    1944         1876 :                 SetupOutputVariable(state,
    1945              :                                     "Surface Outside Face Conduction Heat Transfer Energy",
    1946              :                                     Constant::Units::J,
    1947          938 :                                     state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(loop),
    1948              :                                     OutputProcessor::TimeStepType::Zone,
    1949              :                                     OutputProcessor::StoreType::Sum,
    1950          938 :                                     surface.Name);
    1951              : 
    1952         1876 :                 SetupOutputVariable(state,
    1953              :                                     "Surface Average Face Conduction Heat Transfer Rate",
    1954              :                                     Constant::Units::W,
    1955          938 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCond(loop),
    1956              :                                     OutputProcessor::TimeStepType::Zone,
    1957              :                                     OutputProcessor::StoreType::Average,
    1958          938 :                                     surface.Name);
    1959         1876 :                 SetupOutputVariable(state,
    1960              :                                     "Surface Average Face Conduction Heat Gain Rate",
    1961              :                                     Constant::Units::W,
    1962          938 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(loop),
    1963              :                                     OutputProcessor::TimeStepType::Zone,
    1964              :                                     OutputProcessor::StoreType::Average,
    1965          938 :                                     surface.Name);
    1966         1876 :                 SetupOutputVariable(state,
    1967              :                                     "Surface Average Face Conduction Heat Loss Rate",
    1968              :                                     Constant::Units::W,
    1969          938 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(loop),
    1970              :                                     OutputProcessor::TimeStepType::Zone,
    1971              :                                     OutputProcessor::StoreType::Average,
    1972          938 :                                     surface.Name);
    1973         1876 :                 SetupOutputVariable(state,
    1974              :                                     "Surface Average Face Conduction Heat Transfer Rate per Area",
    1975              :                                     Constant::Units::W_m2,
    1976          938 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(loop),
    1977              :                                     OutputProcessor::TimeStepType::Zone,
    1978              :                                     OutputProcessor::StoreType::Average,
    1979          938 :                                     surface.Name);
    1980         1876 :                 SetupOutputVariable(state,
    1981              :                                     "Surface Average Face Conduction Heat Transfer Energy",
    1982              :                                     Constant::Units::J,
    1983          938 :                                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(loop),
    1984              :                                     OutputProcessor::TimeStepType::Zone,
    1985              :                                     OutputProcessor::StoreType::Sum,
    1986          938 :                                     surface.Name);
    1987              : 
    1988         1876 :                 SetupOutputVariable(state,
    1989              :                                     "Surface Heat Storage Rate",
    1990              :                                     Constant::Units::W,
    1991          938 :                                     state.dataHeatBalSurf->SurfOpaqStorageCond(loop),
    1992              :                                     OutputProcessor::TimeStepType::Zone,
    1993              :                                     OutputProcessor::StoreType::Average,
    1994          938 :                                     surface.Name);
    1995         1876 :                 SetupOutputVariable(state,
    1996              :                                     "Surface Heat Storage Gain Rate",
    1997              :                                     Constant::Units::W,
    1998          938 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(loop),
    1999              :                                     OutputProcessor::TimeStepType::Zone,
    2000              :                                     OutputProcessor::StoreType::Average,
    2001          938 :                                     surface.Name);
    2002         1876 :                 SetupOutputVariable(state,
    2003              :                                     "Surface Heat Storage Loss Rate",
    2004              :                                     Constant::Units::W,
    2005          938 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(loop),
    2006              :                                     OutputProcessor::TimeStepType::Zone,
    2007              :                                     OutputProcessor::StoreType::Average,
    2008          938 :                                     surface.Name);
    2009         1876 :                 SetupOutputVariable(state,
    2010              :                                     "Surface Heat Storage Rate per Area",
    2011              :                                     Constant::Units::W_m2,
    2012          938 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondFlux(loop),
    2013              :                                     OutputProcessor::TimeStepType::Zone,
    2014              :                                     OutputProcessor::StoreType::Average,
    2015          938 :                                     surface.Name);
    2016         1876 :                 SetupOutputVariable(state,
    2017              :                                     "Surface Heat Storage Energy",
    2018              :                                     Constant::Units::J,
    2019          938 :                                     state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(loop),
    2020              :                                     OutputProcessor::TimeStepType::Zone,
    2021              :                                     OutputProcessor::StoreType::Sum,
    2022          938 :                                     surface.Name);
    2023              :             }
    2024              : 
    2025              :             //      ENDIF
    2026              :             // CurrentModuleObject='Opaque Surfaces'
    2027              : 
    2028         1876 :             SetupOutputVariable(state,
    2029              :                                 "Surface Inside Face Beam Solar Radiation Heat Gain Rate",
    2030              :                                 Constant::Units::W,
    2031          938 :                                 state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(loop),
    2032              :                                 OutputProcessor::TimeStepType::Zone,
    2033              :                                 OutputProcessor::StoreType::Average,
    2034          938 :                                 surface.Name);
    2035              :         }
    2036          995 :         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    2037            2 :             SetupOutputVariable(state,
    2038              :                                 "Surface Internal Source Location Temperature",
    2039              :                                 Constant::Units::C,
    2040            1 :                                 state.dataHeatBalSurf->SurfTempSource(loop),
    2041              :                                 OutputProcessor::TimeStepType::Zone,
    2042              :                                 OutputProcessor::StoreType::Average,
    2043            1 :                                 surface.Name);
    2044            2 :             SetupOutputVariable(state,
    2045              :                                 "Surface Internal User Specified Location Temperature",
    2046              :                                 Constant::Units::C,
    2047            1 :                                 state.dataHeatBalSurf->SurfTempUserLoc(loop),
    2048              :                                 OutputProcessor::TimeStepType::Zone,
    2049              :                                 OutputProcessor::StoreType::Average,
    2050            1 :                                 surface.Name);
    2051              :         }
    2052              : 
    2053          995 :         if (surface.Class == DataSurfaces::SurfaceClass::Window) { // CurrentModuleObject='Windows'
    2054           55 :             auto &surfShade = state.dataSurface->surfShades(loop);
    2055          110 :             SetupOutputVariable(state,
    2056              :                                 "Surface Shading Device Is On Time Fraction",
    2057              :                                 Constant::Units::None,
    2058           55 :                                 state.dataSurface->SurfWinFracTimeShadingDeviceOn(loop),
    2059              :                                 OutputProcessor::TimeStepType::Zone,
    2060              :                                 OutputProcessor::StoreType::Average,
    2061           55 :                                 surface.Name);
    2062           55 :             SetupOutputVariable(state,
    2063              :                                 "Surface Storm Window On Off Status",
    2064              :                                 Constant::Units::None,
    2065           55 :                                 state.dataSurface->SurfWinStormWinFlag(loop),
    2066              :                                 OutputProcessor::TimeStepType::Zone,
    2067              :                                 OutputProcessor::StoreType::Average,
    2068           55 :                                 surface.Name);
    2069          110 :             SetupOutputVariable(state,
    2070              :                                 "Surface Window Blind Slat Angle",
    2071              :                                 Constant::Units::deg,
    2072           55 :                                 surfShade.blind.slatAngDeg,
    2073              :                                 OutputProcessor::TimeStepType::Zone,
    2074              :                                 OutputProcessor::StoreType::Average,
    2075           55 :                                 surface.Name);
    2076              :         }
    2077              :         //    IF (DisplayAdvancedReportVariables) THEN  !CurrentModuleObject='Opaque Surfaces(Advanced)'
    2078          995 :         SetupOutputVariable(state,
    2079              :                             "Surface Inside Face Convection Classification Index",
    2080              :                             Constant::Units::None,
    2081          995 :                             state.dataSurface->surfIntConv(loop).convClassRpt,
    2082              :                             OutputProcessor::TimeStepType::Zone,
    2083              :                             OutputProcessor::StoreType::Average,
    2084          995 :                             surface.Name);
    2085          995 :         SetupOutputVariable(state,
    2086              :                             "Surface Inside Face Convection Model Equation Index",
    2087              :                             Constant::Units::None,
    2088          995 :                             state.dataSurface->surfIntConv(loop).hcModelEqRpt,
    2089              :                             OutputProcessor::TimeStepType::Zone,
    2090              :                             OutputProcessor::StoreType::Average,
    2091          995 :                             surface.Name);
    2092          995 :         SetupOutputVariable(state,
    2093              :                             "Surface Inside Face Convection Reference Air Index",
    2094              :                             Constant::Units::None,
    2095          995 :                             state.dataSurface->SurfTAirRefRpt(loop),
    2096              :                             OutputProcessor::TimeStepType::Zone,
    2097              :                             OutputProcessor::StoreType::Average,
    2098          995 :                             surface.Name);
    2099          995 :         if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    2100          715 :             SetupOutputVariable(state,
    2101              :                                 "Surface Outside Face Convection Classification Index",
    2102              :                                 Constant::Units::None,
    2103          715 :                                 state.dataSurface->surfExtConv(loop).convClassRpt,
    2104              :                                 OutputProcessor::TimeStepType::Zone,
    2105              :                                 OutputProcessor::StoreType::Average,
    2106          715 :                                 surface.Name);
    2107          715 :             SetupOutputVariable(state,
    2108              :                                 "Surface Outside Face Forced Convection Model Equation Index",
    2109              :                                 Constant::Units::None,
    2110          715 :                                 state.dataSurface->surfExtConv(loop).hfModelEqRpt,
    2111              :                                 OutputProcessor::TimeStepType::Zone,
    2112              :                                 OutputProcessor::StoreType::Average,
    2113          715 :                                 surface.Name);
    2114          715 :             SetupOutputVariable(state,
    2115              :                                 "Surface Outside Face Natural Convection Model Equation Index",
    2116              :                                 Constant::Units::None,
    2117          715 :                                 state.dataSurface->surfExtConv(loop).hnModelEqRpt,
    2118              :                                 OutputProcessor::TimeStepType::Zone,
    2119              :                                 OutputProcessor::StoreType::Average,
    2120          715 :                                 surface.Name);
    2121              :         }
    2122              : 
    2123         1990 :         SetupOutputVariable(state,
    2124              :                             "Surface Inside Face Heat Source Gain Rate per Area",
    2125              :                             Constant::Units::W_m2,
    2126          995 :                             state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(loop),
    2127              :                             OutputProcessor::TimeStepType::Zone,
    2128              :                             OutputProcessor::StoreType::Average,
    2129          995 :                             surface.Name);
    2130         1990 :         SetupOutputVariable(state,
    2131              :                             "Surface Outside Face Heat Source Gain Rate per Area",
    2132              :                             Constant::Units::W_m2,
    2133          995 :                             state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(loop),
    2134              :                             OutputProcessor::TimeStepType::Zone,
    2135              :                             OutputProcessor::StoreType::Average,
    2136          995 :                             surface.Name);
    2137              : 
    2138              :         //     ENDIF
    2139          995 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    2140            1 :             SetupOutputVariable(state,
    2141              :                                 "Surface Construction Index",
    2142              :                                 Constant::Units::None,
    2143            1 :                                 surface.Construction,
    2144              :                                 OutputProcessor::TimeStepType::Zone,
    2145              :                                 OutputProcessor::StoreType::Average,
    2146            1 :                                 surface.Name);
    2147              :         }
    2148              :     }
    2149          580 :     SetupOutputVariable(state,
    2150              :                         "Site Total Surface Heat Emission to Air",
    2151              :                         Constant::Units::J,
    2152          145 :                         state.dataHeatBalSurf->SumSurfaceHeatEmission,
    2153              :                         OutputProcessor::TimeStepType::Zone,
    2154              :                         OutputProcessor::StoreType::Sum,
    2155              :                         "Environment");
    2156          145 : }
    2157              : 
    2158          483 : void InitThermalAndFluxHistories(EnergyPlusData &state)
    2159              : {
    2160              : 
    2161              :     // SUBROUTINE INFORMATION:
    2162              :     //       AUTHOR         George Walton
    2163              :     //       DATE WRITTEN   March 1978
    2164              :     //       RE-ENGINEERED  Feb98 (RKS)
    2165              : 
    2166              :     // PURPOSE OF THIS SUBROUTINE:
    2167              :     // This subroutine sets the initial temperature and flux histories
    2168              :     // needed for a stable and reasonable heat balance solution starting
    2169              :     // point.
    2170              : 
    2171              :     // METHODOLOGY EMPLOYED:
    2172              :     // This subroutine assumes that the simulation is at steady state at
    2173              :     // the beginning and then begins to vary.  Thus, the temperatures, the
    2174              :     // fluxes. and their histories can all be set to the same value.  Some
    2175              :     // of the initializations depend on the surface characteristics.  This
    2176              :     // requires a DO loop to perform the proper calculation.
    2177              : 
    2178              :     // REFERENCES:
    2179              :     // (I)BLAST legacy routine INITTH
    2180              : 
    2181              :     // First do the "bulk" initializations of arrays sized to NumOfZones
    2182         1157 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2183          674 :         new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData();
    2184              :         // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
    2185          674 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum);
    2186          674 :         thisZoneHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
    2187          674 :         thisZoneHB.airHumRat = state.dataEnvrn->OutHumRat;
    2188          674 :         state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp;
    2189              :     }
    2190         1205 :     for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    2191          722 :         thisEnclosure.MRT = DataHeatBalance::ZoneInitialTemp;
    2192          483 :     }
    2193              :     // Reset spaceHeatBalance even if doSpaceHeatBalance is false, because spaceHB is used to gether zoneHB in some cases
    2194         1255 :     for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) {
    2195          772 :         new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData();
    2196              :         // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations
    2197          772 :         thisSpaceHB.airHumRatAvg = state.dataEnvrn->OutHumRat;
    2198          772 :         thisSpaceHB.airHumRat = state.dataEnvrn->OutHumRat;
    2199          483 :     }
    2200              : 
    2201              :     // "Bulk" initializations of arrays sized to TotSurfaces
    2202         1157 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2203         1446 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2204          772 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2205          772 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    2206          772 :             int const lastSurf = thisSpace.HTSurfaceLast;
    2207         4894 :             for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2208         4122 :                 state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2209         4122 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;        // module level array
    2210         4122 :                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = DataHeatBalance::SurfInitialTemp;     // module level array
    2211         4122 :                 state.dataHeatBalSurf->SurfHConvInt(SurfNum) = DataHeatBalance::SurfInitialConvCoeff; // module level array
    2212         4122 :                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
    2213         4122 :                 state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
    2214         4122 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
    2215         4122 :                 state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
    2216         4122 :                 state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0;
    2217         4122 :                 state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0;
    2218         4122 :                 state.dataHeatBalSurf->SurfQConvInRep(SurfNum) = 0.0;
    2219         4122 :                 state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0;
    2220         4122 :                 state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0;
    2221         4122 :                 state.dataHeatBalSurf->SurfQRadNetSurfInRep(SurfNum) = 0.0;
    2222         4122 :                 state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0;
    2223         4122 :                 state.dataHeatBalSurf->SurfQRadSolarInRep(SurfNum) = 0.0;
    2224         4122 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0;
    2225         4122 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0;
    2226         4122 :                 state.dataHeatBalSurf->SurfQRadLightsInRep(SurfNum) = 0.0;
    2227         4122 :                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0;
    2228         4122 :                 state.dataHeatBalSurf->SurfQRadIntGainsInRep(SurfNum) = 0.0;
    2229         4122 :                 state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0;
    2230         4122 :                 state.dataHeatBalSurf->SurfQRadHVACInRep(SurfNum) = 0.0;
    2231         4122 :                 state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0;
    2232         4122 :                 state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0;
    2233         4122 :                 state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0;
    2234         4122 :                 state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0;
    2235         4122 :                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0;
    2236         4122 :                 state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0;
    2237         4122 :                 state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0;
    2238         4122 :                 state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0;
    2239         4122 :                 state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0;
    2240         4122 :                 state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0;
    2241              :             } // end of  Surf array
    2242          772 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    2243          772 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    2244          772 :             if (firstSurfOpaq >= 0) {
    2245         4668 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    2246         3896 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0;
    2247         3896 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0;
    2248         3896 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0;
    2249         3896 :                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
    2250              :                 } // end of Zone Surf
    2251              :             }
    2252          772 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2253          772 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2254          772 :             if (firstSurfWin >= 0) {
    2255          998 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2256              :                     // Initialize window frame and divider temperatures
    2257          226 :                     state.dataSurface->SurfWinFrameTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2258          226 :                     state.dataSurface->SurfWinFrameTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2259          226 :                     state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2260          226 :                     state.dataSurface->SurfWinDividerTempIn(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2261          226 :                     state.dataSurface->SurfWinDividerTempInOld(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2262          226 :                     state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2263              : 
    2264              :                     // Initialize previous-timestep shading indicators
    2265          226 :                     state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = DataSurfaces::WinShadingType::NoShade;
    2266          226 :                     state.dataSurface->SurfWinShadingFlag(SurfNum) = DataSurfaces::WinShadingType::NoShade;
    2267              :                 } // end of Zone Surf
    2268              :             }
    2269          674 :         }
    2270              :     } // end of Zone
    2271              : 
    2272              :     // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2)
    2273         1157 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2274         1446 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2275          772 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2276          772 :             int const firstSurf = thisSpace.HTSurfaceFirst;
    2277          772 :             int const lastSurf = thisSpace.HTSurfaceLast;
    2278        15440 :             for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2279        92986 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2280        78318 :                     state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2281        78318 :                     state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2282        78318 :                     state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
    2283        78318 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0;
    2284              :                 }
    2285              :             }
    2286          674 :         }
    2287              :     }
    2288          483 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    2289          236 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2290          252 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2291          126 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2292          126 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    2293          126 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    2294          888 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2295          762 :                     state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
    2296              :                 }
    2297         2520 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2298        16872 :                     for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2299        14478 :                         state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2300        14478 :                         state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = DataHeatBalance::SurfInitialTemp;
    2301        14478 :                         state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
    2302        14478 :                         state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0;
    2303              :                     }
    2304              :                 }
    2305          126 :             }
    2306              :         }
    2307              :     }
    2308          483 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    2309            0 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2310            0 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2311            0 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2312            0 :                 int const firstSurf = thisSpace.HTSurfaceFirst;
    2313            0 :                 int const lastSurf = thisSpace.HTSurfaceLast;
    2314            0 :                 for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) {
    2315            0 :                     for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2316            0 :                         state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2317            0 :                         state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2318            0 :                         state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2319            0 :                         state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = DataHeatBalance::SurfInitialTemp;
    2320            0 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0;
    2321            0 :                         state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0;
    2322              :                     }
    2323              :                 }
    2324            0 :             }
    2325              :         }
    2326              :     }
    2327          483 :     state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
    2328              : 
    2329              :     // Perform other initializations that depend on the surface characteristics
    2330         4190 :     for (int CTFTermNum = 1; CTFTermNum <= state.dataHeatBal->MaxCTFTerms + 1; ++CTFTermNum) {
    2331        38215 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2332        34508 :             auto &surface = state.dataSurface->Surface(SurfNum);
    2333              :             // Reset outside boundary conditions if necessary
    2334        34508 :             if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
    2335        21363 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    2336        13145 :             } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
    2337         2689 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
    2338         2689 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    2339        10456 :             } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
    2340            0 :                 state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) =
    2341            0 :                     state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    2342              :             }
    2343              :             // Initialize the flux histories
    2344        34508 :             state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) =
    2345        34508 :                 state.dataConstruction->Construct(surface.Construction).UValue *
    2346        34508 :                 (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum));
    2347        34508 :             state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2348         3707 :         }
    2349              :     }
    2350         4605 :     for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2351         4122 :         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    2352            0 :             state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TbaffleLast = 20.0;
    2353            0 :             state.dataHeatBal->ExtVentedCavity(state.dataSurface->SurfExtCavNum(SurfNum)).TairLast = 20.0;
    2354              :         }
    2355          483 :     }
    2356              :     // Initialize Kiva convection algorithms
    2357          483 :     for (int SurfNum : state.dataSurface->AllHTKivaSurfaceList) {
    2358            0 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(3.076);
    2359            0 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].f = KIVA_HF_DEF;
    2360            0 :         state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].out = KIVA_CONST_CONV(0.0);
    2361          483 :     }
    2362          483 :     if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) {
    2363          872 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    2364          762 :             auto &surface = state.dataSurface->Surface(SurfNum);
    2365          762 :             if ((surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) || (surface.ExtBoundCond == DataSurfaces::OtherSideCondModeledExt)) {
    2366        11880 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2367        11286 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    2368              :                 }
    2369          762 :             } else if (surface.ExtBoundCond == DataSurfaces::Ground) {
    2370            0 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2371            0 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
    2372            0 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    2373              :                 }
    2374          168 :             } else if (surface.ExtBoundCond == DataSurfaces::GroundFCfactorMethod) {
    2375            0 :                 for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) {
    2376            0 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) =
    2377            0 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    2378              :                 }
    2379              :             }
    2380         3046 :             for (int CTFTermNum = 2; CTFTermNum <= state.dataConstruction->Construct(surface.Construction).NumCTFTerms + 1; ++CTFTermNum) {
    2381         2284 :                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2382         2284 :                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum);
    2383              :             }
    2384          110 :         }
    2385              :     }
    2386              : 
    2387          483 :     if (state.dataSurface->TotOSCM >= 1) {
    2388            2 :         for (int OSCMnum = 1; OSCMnum <= state.dataSurface->TotOSCM; ++OSCMnum) {
    2389            1 :             auto &thisOSC = state.dataSurface->OSCM(OSCMnum);
    2390            1 :             thisOSC.TConv = 20.0;
    2391            1 :             thisOSC.HConv = 4.0;
    2392            1 :             thisOSC.TRad = 20.0;
    2393            1 :             thisOSC.HRad = 4.0;
    2394              :         }
    2395              :     }
    2396          483 : }
    2397              : 
    2398            3 : void EvalOutsideMovableInsulation(EnergyPlusData &state)
    2399              : {
    2400              :     // This subroutine determines whether or not outside movable insulation on opaque surfaces is present at the current time.
    2401            3 :     auto &s_mat = state.dataMaterial;
    2402            3 :     auto &s_surf = state.dataSurface;
    2403              : 
    2404            6 :     for (int SurfNum : s_surf->extMovInsulSurfNums) {
    2405            3 :         auto &movInsul = s_surf->extMovInsuls(SurfNum);
    2406            3 :         Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
    2407            3 :         if (MovInsulSchedVal <= 0) { // Movable insulation not present at current time
    2408            0 :             movInsul.present = false;
    2409            0 :             int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
    2410            0 :             auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
    2411            0 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = thisMaterial->AbsorpSolar;
    2412            0 :             state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = thisMaterial->AbsorpThermal;
    2413            0 :             state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = thisMaterial->Roughness;
    2414            0 :             continue;
    2415            0 :         }
    2416              : 
    2417            3 :         auto const *mat = s_mat->materials(movInsul.matNum);
    2418            3 :         movInsul.present = true;
    2419            3 :         movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
    2420            3 :         if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) {
    2421            2 :             auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
    2422            2 :             assert(matGlass != nullptr);
    2423            2 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
    2424            2 :         } else {
    2425            1 :             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = mat->AbsorpSolar;
    2426              :         }
    2427            3 :         state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = mat->AbsorpThermal;
    2428            3 :         state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = mat->Roughness;
    2429            3 :     }
    2430            3 : }
    2431              : 
    2432            3 : void EvalInsideMovableInsulation(EnergyPlusData &state)
    2433              : {
    2434            3 :     auto &s_mat = state.dataMaterial;
    2435            3 :     auto &s_surf = state.dataSurface;
    2436              :     // This subroutine determines whether or not inside movable insulation is present at the current time.
    2437            6 :     for (int SurfNum : s_surf->intMovInsulSurfNums) {
    2438            3 :         auto &movInsul = s_surf->intMovInsuls(SurfNum);
    2439            3 :         Real64 MovInsulSchedVal = movInsul.sched->getCurrentVal();
    2440            3 :         if (MovInsulSchedVal <= 0.0) { // Movable insulation not present at current time
    2441            0 :             movInsul.present = false;
    2442            0 :             int ConstrNum = s_surf->SurfActiveConstruction(SurfNum);
    2443            0 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    2444            0 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = thisConstruct.InsideAbsorpSolar;
    2445            0 :             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = thisConstruct.InsideAbsorpThermal;
    2446            0 :             continue;
    2447            0 :         }
    2448              : 
    2449            3 :         auto const *mat = s_mat->materials(movInsul.matNum);
    2450              : 
    2451            3 :         movInsul.present = true;
    2452            3 :         movInsul.H = 1.0 / (MovInsulSchedVal * mat->Resistance);
    2453            3 :         if (mat->group == Material::Group::Glass || mat->group == Material::Group::GlassEQL) { // Glass is insulating?
    2454            2 :             auto const *matGlass = dynamic_cast<Material::MaterialFen const *>(mat);
    2455            2 :             assert(matGlass != nullptr);
    2456            2 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = max(0.0, 1.0 - matGlass->Trans - matGlass->ReflectSolBeamFront);
    2457            2 :         } else {
    2458            1 :             state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = mat->AbsorpSolar;
    2459              :         }
    2460            3 :         state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = mat->AbsorpThermal;
    2461            3 :     }
    2462            3 : }
    2463              : 
    2464       249960 : void InitSolarHeatGains(EnergyPlusData &state)
    2465              : {
    2466              : 
    2467              :     // SUBROUTINE INFORMATION:
    2468              :     //       AUTHOR         Anonymous
    2469              :     //       DATE WRITTEN   July 1977
    2470              :     //       MODIFIED       Mar99 (FW): handle movable interior shades and
    2471              :     //                                  switchable glazing
    2472              :     //                      Oct99 (FW): account for Window5 glass calculation approach
    2473              :     //                      May01 (FW): handle interior and exterior blinds
    2474              :     //                      Sep03 (FW): initialize SurfaceWindow%FrameQRadOutAbs
    2475              :     //                      May06 (RR): handle exterior window screens
    2476              :     //       RE-ENGINEERED  Feb98 (RKS)
    2477              : 
    2478              :     // PURPOSE OF THIS SUBROUTINE:
    2479              :     // This subroutine initializes the arrays associated with solar heat
    2480              :     // gains for both individual surfaces and for zones.  As a result,
    2481              :     // this routine sets the following variable arrays:
    2482              :     // QBV(unused), QDV, QC, QD; SurfOpaqQRadSWOutAbs and SurfOpaqQRadSWInAbs (for opaque surfaces);
    2483              :     // SurfWinQRadSWwinAbs (for windows)
    2484              : 
    2485              :     // METHODOLOGY EMPLOYED:
    2486              :     // If the sun is down, all of the pertinent arrays are zeroed.  If the
    2487              :     // sun is up, various calculations are made.
    2488              : 
    2489              :     // REFERENCES:
    2490              :     // (I)BLAST legacy routine QSUN
    2491              : 
    2492       249960 :     auto &s_mat = state.dataMaterial;
    2493       249960 :     auto &Surface = state.dataSurface->Surface;
    2494              : 
    2495              :     // Using/Aliasing
    2496              :     using Dayltg::TransTDD;
    2497              :     using SolarShading::CalcInteriorSolarDistribution;
    2498              :     using namespace DataWindowEquivalentLayer;
    2499              :     using SolarShading::SurfaceScheduledSolarInc;
    2500              :     using SolarShading::WindowScheduledSolarAbs;
    2501              : 
    2502              :     // Why are these globals?
    2503       249960 :     auto &AbsDiffWin = state.dataHeatBalSurfMgr->AbsDiffWin;
    2504       249960 :     auto &AbsDiffWinGnd = state.dataHeatBalSurfMgr->AbsDiffWinGnd;
    2505       249960 :     auto &AbsDiffWinSky = state.dataHeatBalSurfMgr->AbsDiffWinSky;
    2506              : 
    2507       586612 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2508       336652 :         state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = 0.0;
    2509       336652 :         state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = 0.0;
    2510       336652 :         state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = 0.0;
    2511       336652 :         state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = 0.0;
    2512       336652 :         state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = 0.0;
    2513       336652 :         state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = 0.0;
    2514              : 
    2515       336652 :         state.dataHeatBal->ZoneWinHeatGain(zoneNum) = 0.0;
    2516       336652 :         state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = 0.0;
    2517       336652 :         state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = 0.0;
    2518       336652 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) = 0.0;
    2519       336652 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = 0.0;
    2520       336652 :         state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = 0.0;
    2521       336652 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) = 0.0;
    2522       336652 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = 0.0;
    2523       336652 :         state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = 0.0;
    2524              :     }
    2525       602838 :     for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2526       352878 :         state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0;
    2527              :     }
    2528       586612 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2529       706907 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2530       370255 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2531       370255 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    2532       370255 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    2533      2350615 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    2534      1980360 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0;
    2535      1980360 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0;
    2536      1980360 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0;
    2537      1980360 :                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0;
    2538      1980360 :                 state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0;
    2539      1980360 :                 state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0;
    2540      1980360 :                 state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0;
    2541      1980360 :                 state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0;
    2542      1980360 :                 state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0;
    2543              :             }
    2544              : 
    2545       370255 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2546       370255 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2547       458825 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2548              :                 // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains()
    2549        88570 :                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0;
    2550        88570 :                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0;
    2551        88570 :                 state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0;
    2552        88570 :                 state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0;
    2553        88570 :                 state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0;
    2554        88570 :                 state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0;
    2555        88570 :                 state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0;
    2556        88570 :                 state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0;
    2557        88570 :                 state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0;
    2558        88570 :                 state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0;
    2559              :             }
    2560              : 
    2561       458825 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2562        88570 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0;
    2563        88570 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0;
    2564        88570 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0;
    2565        88570 :                 state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0;
    2566        88570 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0;
    2567        88570 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0;
    2568        88570 :                 state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0;
    2569        88570 :                 state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0;
    2570        88570 :                 state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0;
    2571              :             }
    2572       458825 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2573        88570 :                 state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0;
    2574        88570 :                 state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0;
    2575        88570 :                 state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0;
    2576        88570 :                 state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0;
    2577        88570 :                 state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0;
    2578        88570 :                 state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0;
    2579        88570 :                 state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0;
    2580              :             }
    2581      2962040 :             for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
    2582      3211775 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2583       619990 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0;
    2584              :                 }
    2585              :             }
    2586       336652 :         }
    2587              :     }
    2588       249960 :     if (state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
    2589          924 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2590          810 :             state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
    2591          810 :             state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = Surface(SurfNum).ViewFactorGround;
    2592              :         }
    2593              :     }
    2594              :     bool currSolRadPositive =
    2595       249960 :         state.dataEnvrn->SunIsUp && (state.dataEnvrn->BeamSolarRad + state.dataEnvrn->GndSolarRad + state.dataEnvrn->DifSolarRad > 0.0);
    2596       249960 :     bool sunset = (!currSolRadPositive) && state.dataEnvrn->PreviousSolRadPositive;
    2597       249960 :     bool sunIsUpNoRad = state.dataEnvrn->SunIsUp && (!currSolRadPositive);
    2598       249960 :     bool resetSolar = state.dataGlobal->BeginEnvrnFlag || sunIsUpNoRad ||
    2599       249960 :                       sunset; // Reset at (1) Beginning of simulation (2) sunset time, and SunIsUp but not solar time.
    2600       249960 :     state.dataEnvrn->PreviousSolRadPositive = currSolRadPositive;
    2601              : 
    2602       249960 :     if (currSolRadPositive || resetSolar) {
    2603      1166401 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2604      1043435 :             state.dataHeatBal->SurfBmIncInsSurfIntensRep(SurfNum) = 0.0;
    2605      1043435 :             state.dataHeatBal->SurfBmIncInsSurfAmountRep(SurfNum) = 0.0;
    2606      1043435 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) = 0.0;
    2607      1043435 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) = 0.0;
    2608      1043435 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) = 0.0;
    2609              : 
    2610      1043435 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) = 0.0;
    2611      1043435 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = 0.0;
    2612      1043435 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = 0.0;
    2613      1043435 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = 0.0;
    2614              : 
    2615      1043435 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) = 0.0;
    2616      1043435 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) = 0.0;
    2617      1043435 :             state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = 0.0;
    2618      1043435 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) = 0.0;
    2619      1043435 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = 0.0;
    2620              : 
    2621      1043435 :             state.dataSurface->SurfSkySolarInc(SurfNum) = 0.0;
    2622      1043435 :             state.dataSurface->SurfGndSolarInc(SurfNum) = 0.0;
    2623              :         }
    2624       298568 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2625       175602 :             state.dataHeatBal->ZoneTransSolar(enclNum) = 0.0;
    2626       175602 :             state.dataHeatBal->ZoneBmSolFrExtWinsRep(enclNum) = 0.0;
    2627       175602 :             state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclNum) = 0.0;
    2628       175602 :             state.dataHeatBal->ZoneDifSolFrExtWinsRep(enclNum) = 0.0;
    2629       175602 :             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclNum) = 0.0;
    2630       175602 :             state.dataHeatBal->ZoneTransSolarEnergy(enclNum) = 0.0;
    2631       175602 :             state.dataHeatBal->ZoneBmSolFrExtWinsRepEnergy(enclNum) = 0.0;
    2632       175602 :             state.dataHeatBal->ZoneBmSolFrIntWinsRepEnergy(enclNum) = 0.0;
    2633       175602 :             state.dataHeatBal->ZoneDifSolFrExtWinsRepEnergy(enclNum) = 0.0;
    2634       175602 :             state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0;
    2635              :         }
    2636       290055 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    2637       351922 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    2638       184833 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    2639       184833 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    2640       184833 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    2641       229898 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2642        45065 :                     state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0;
    2643        45065 :                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0;
    2644        45065 :                     state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0;
    2645        45065 :                     state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0;
    2646        45065 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    2647        45065 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0;
    2648        45065 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0;
    2649        45065 :                     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0;
    2650        45065 :                     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum) = 0.0;
    2651        45065 :                     state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0;
    2652              :                 }
    2653       229898 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2654        45065 :                     state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0;
    2655        45065 :                     state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0;
    2656        45065 :                     state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0;
    2657        45065 :                     state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0;
    2658        45065 :                     state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0;
    2659        45065 :                     state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0;
    2660        45065 :                     state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0;
    2661        45065 :                     state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0;
    2662        45065 :                     state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0;
    2663        45065 :                     state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0;
    2664        45065 :                     state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0;
    2665        45065 :                     state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0;
    2666        45065 :                     state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0;
    2667              :                 }
    2668       229898 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2669        45065 :                     state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0;
    2670        45065 :                     state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0;
    2671        45065 :                     state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0;
    2672        45065 :                     state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0;
    2673        45065 :                     state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0;
    2674        45065 :                     state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0;
    2675        45065 :                     state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0;
    2676        45065 :                     state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0;
    2677        45065 :                     state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0;
    2678              :                 }
    2679       229898 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2680        45065 :                     state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0;
    2681        45065 :                     state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0;
    2682        45065 :                     state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0;
    2683        45065 :                     state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0;
    2684        45065 :                     state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0;
    2685        45065 :                     state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0;
    2686        45065 :                     state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0;
    2687        45065 :                     state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0;
    2688        45065 :                     state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0;
    2689              :                 }
    2690              : 
    2691       229898 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2692        45065 :                     state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0;
    2693        45065 :                     state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0;
    2694        45065 :                     state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0;
    2695        45065 :                     state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0;
    2696        45065 :                     state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0;
    2697        45065 :                     state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0;
    2698        45065 :                     state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0;
    2699        45065 :                     state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0;
    2700        45065 :                     state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0;
    2701        45065 :                     state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0;
    2702        45065 :                     state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0;
    2703        45065 :                     state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0;
    2704        45065 :                     state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0;
    2705              :                 }
    2706      1467106 :                 for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) {
    2707      1597758 :                     for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2708       315485 :                         state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0;
    2709              :                     }
    2710              :                 }
    2711      1293831 :                 for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) {
    2712      1379388 :                     for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    2713       270390 :                         state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0;
    2714              :                     }
    2715              :                 }
    2716       167089 :             }
    2717              :         }
    2718              :     }
    2719       249960 :     if (resetSolar) {
    2720       122048 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    2721        70297 :             state.dataHeatBal->EnclSolQD(enclosureNum) = 0.0;
    2722        70297 :             state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) = 0.0;
    2723              :         }
    2724              : 
    2725              :         // TTD domes are currently not considered in the window list of a zone
    2726        51751 :         if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) {
    2727            0 :             for (auto &e : state.dataDaylightingDevicesData->TDDPipe) {
    2728            0 :                 e.TransSolBeam = 0.0;
    2729            0 :                 e.TransSolDiff = 0.0;
    2730            0 :                 e.TransVisBeam = 0.0;
    2731            0 :                 e.TransVisDiff = 0.0;
    2732            0 :                 e.TransmittedSolar = 0.0;
    2733            0 :                 int SurfDome = e.Dome;
    2734            0 :                 state.dataSurface->SurfWinTransSolar(SurfDome) = 0.0;
    2735            0 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfDome) = 0.0;
    2736            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfDome) = 0.0;
    2737            0 :                 for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) {
    2738            0 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfDome, Lay) = 0.0;
    2739              :                 }
    2740              :             }
    2741              :         }
    2742              : 
    2743        51751 :         if (state.dataSurface->CalcSolRefl) {
    2744            0 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2745            0 :                 state.dataSurface->SurfBmToBmReflFacObs(SurfNum) = 0.0;
    2746            0 :                 state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) = 0.0;
    2747            0 :                 state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) = 0.0;
    2748              :             }
    2749              :         }
    2750       471547 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2751       419796 :             state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0;
    2752       419796 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = 0.0;
    2753       419796 :             state.dataHeatBal->SurfSWInAbsTotalReport(SurfNum) = 0.0;
    2754       419796 :             state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0;
    2755       419796 :             state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0;
    2756       419796 :             state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0;
    2757       419796 :             state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0;
    2758              :         }
    2759              :     }
    2760       249960 :     if (currSolRadPositive) { // Sun is up, calculate solar quantities
    2761        71216 :         assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
    2762              :                                 state.dataSurface->SurfReflFacBmToDiffSolObs)); // For linear indexing
    2763        71216 :         assert(equal_dimensions(state.dataSurface->SurfReflFacBmToBmSolObs,
    2764              :                                 state.dataSurface->SurfReflFacBmToDiffSolGnd)); // For linear indexing
    2765        71216 :         Real64 GndReflSolarRad = 0.0;
    2766        71216 :         Real64 GndSolarRadInc = max(state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad, 0.0);
    2767              : 
    2768       694866 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2769       623650 :             state.dataSurface->Surface(SurfNum).IncSolMultiplier = GetSurfIncidentSolarMultiplier(state, SurfNum);
    2770              :         }
    2771       694866 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2772       623650 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2773       623650 :             state.dataSurface->SurfSkySolarInc(SurfNum) =
    2774       623650 :                 state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2775       623650 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2776            0 :                 GndReflSolarRad = GndSolarRadInc * SurfIncSolarMultiplier *
    2777            0 :                                   state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2778            0 :                 Surface(SurfNum).GndReflSolarRad = GndReflSolarRad;
    2779              :             } else {
    2780       623650 :                 GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    2781              :             }
    2782       623650 :             state.dataSurface->SurfGndSolarInc(SurfNum) = GndReflSolarRad * Surface(SurfNum).ViewFactorGround;
    2783       623650 :             state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2784       623650 :             state.dataSurface->SurfWinBmGndSolarInc(SurfNum) = 0.0;
    2785              :         }
    2786        71216 :         if (state.dataSurface->CalcSolRefl) {
    2787              :             // [ lSH ] == ( HourOfDay, SurfNum ) // [ lSP ] == ( PreviousHour, SurfNum )
    2788            0 :             Array1D<Real64>::size_type lSH = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->HourOfDay, 1) - 1;
    2789            0 :             Array1D<Real64>::size_type lSP = state.dataSurface->SurfReflFacBmToBmSolObs.index(state.dataGlobal->PreviousHour, 1) - 1;
    2790              :             // For Complex Fenestrations:
    2791            0 :             for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    2792            0 :                 Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2793              : 
    2794            0 :                 Real64 GndSurfReflectance = 0.0;
    2795            0 :                 if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2796            0 :                     GndSurfReflectance =
    2797            0 :                         state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2798              :                 } else {
    2799            0 :                     GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2800              :                 }
    2801            0 :                 Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2802            0 :                 Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2803            0 :                 state.dataSurface->SurfWinSkyGndSolarInc(SurfNum) =
    2804            0 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2805            0 :                 state.dataSurface->SurfWinBmGndSolarInc(SurfNum) =
    2806            0 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2807            0 :                 state.dataSurface->SurfBmToBmReflFacObs(SurfNum) =
    2808            0 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToBmSolObs[lSH + SurfNum] +
    2809            0 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToBmSolObs[lSP + SurfNum];
    2810            0 :                 state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) =
    2811            0 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolObs[lSH + SurfNum] +
    2812            0 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolObs[lSP + SurfNum];
    2813            0 :                 state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) =
    2814            0 :                     state.dataGlobal->WeightNow * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSH + SurfNum] +
    2815            0 :                     state.dataGlobal->WeightPreviousHour * state.dataSurface->SurfReflFacBmToDiffSolGnd[lSP + SurfNum];
    2816              :                 // TH2 CR 9056
    2817            0 :                 state.dataSurface->SurfSkySolarInc(SurfNum) +=
    2818            0 :                     currBeamSolarRad * (state.dataSurface->SurfBmToBmReflFacObs(SurfNum) + state.dataSurface->SurfBmToDiffReflFacObs(SurfNum)) +
    2819            0 :                     currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
    2820            0 :                 state.dataSurface->SurfGndSolarInc(SurfNum) =
    2821            0 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum) +
    2822            0 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2823            0 :                 state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum) = state.dataSurface->SurfReflFacSkySolGnd(SurfNum);
    2824              :             }
    2825              :         }
    2826              : 
    2827        71216 :         SolarShading::CalcWindowProfileAngles(state);
    2828              : 
    2829        71216 :         if (state.dataHeatBal->CalcWindowRevealReflection) {
    2830            0 :             SolarShading::CalcBeamSolarOnWinRevealSurface(state);
    2831              :         }
    2832              : 
    2833        71216 :         if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() && state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
    2834            0 :             SolarShading::CalcAbsorbedOnExteriorOpaqueSurfaces(state);
    2835            0 :             if (state.dataWindowManager->winOpticalModel->isSimplifiedModel()) {
    2836            0 :                 SolarShading::CalcInteriorSolarDistributionWCESimple(state);
    2837              :             }
    2838              :         } else {
    2839        71216 :             SolarShading::CalcInteriorSolarDistribution(state);
    2840              :         }
    2841              : 
    2842       176522 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    2843              : 
    2844              :             // TH 3/24/2010 - QBV is not used!
    2845              :             // unused      QBV(ZoneNum) = (CBZone(ZoneNum) + EnclSolDB(ZoneNum))*BeamSolarRad
    2846              : 
    2847              :             // RJH 08/30/07 - QDV does not seem to ever be used. NOT USED!
    2848              :             // QDV(ZoneNum) = EnclSolDS(ZoneNum)*DifSolarRad &
    2849              :             //                +EnclSolDG(ZoneNum)*GndSolarRad
    2850              : 
    2851              :             // Original QD calc used only for EnclSolQSDifSol and daylighting calcs
    2852              :             // QDforDaylight(ZoneNum)  = EnclSolDB(ZoneNum)*BeamSolarRad  &
    2853              :             //                          +EnclSolDS(ZoneNum)*DifSolarRad  &
    2854              :             //                          +EnclSolDG(ZoneNum)*GndSolarRad
    2855              : 
    2856              :             //  Beam from interior windows (EnclSolDBIntWin) reflected from floor is counted in DayltgInterReflIllFrIntWins,
    2857              :             //  EnclSolDB needs to subtract this part since it is already counted in EnclSolDB.
    2858              :             //  Use EnclSolInitialDifSolReflW (Rob's previous work) as it better counts initial distribution of
    2859              :             //   diffuse solar rather than using weighted area*absorptance
    2860       105306 :             state.dataHeatBal->EnclSolQDforDaylight(enclosureNum) =
    2861       105306 :                 (state.dataHeatBal->EnclSolDB(enclosureNum) - state.dataHeatBal->EnclSolDBIntWin(enclosureNum)) * state.dataEnvrn->BeamSolarRad +
    2862       105306 :                 state.dataHeatBal->EnclSolDBSSG(enclosureNum) + state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
    2863              : 
    2864              :             // to exclude diffuse solar now absorbed/transmitted in CalcWinTransDifSolInitialDistribution
    2865              :             // EnclSolDB(ZoneNum) is Diffuse Solar from beam reflected from interior surfaces
    2866              :             // and transmitted through interior windows
    2867              :             // EnclSolDB is a factor that when multiplied by BeamSolarRad [W/m2] gives Watts
    2868              :             // QD(ZoneNum)  = EnclSolDB(ZoneNum)*BeamSolarRad  &
    2869              :             //                +EnclSolDS(ZoneNum)*DifSolarRad  &
    2870              :             //                +EnclSolDG(ZoneNum)*GndSolarRad
    2871       210612 :             state.dataHeatBal->EnclSolQD(enclosureNum) = state.dataHeatBal->EnclSolDB(enclosureNum) * state.dataEnvrn->BeamSolarRad +
    2872       105306 :                                                          state.dataHeatBal->EnclSolDBSSG(enclosureNum) +
    2873       105306 :                                                          state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum);
    2874              :         }
    2875              : 
    2876              :         // Flux of diffuse solar in each zone
    2877              : 
    2878       176522 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2879       105306 :             state.dataHeatBal->EnclSolQSDifSol(enclNum) = state.dataHeatBal->EnclSolQDforDaylight(enclNum);
    2880              :         }
    2881              : 
    2882        71216 :         if (state.dataHeatBalSurf->InterZoneWindow) {
    2883            0 :             for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2884            0 :                 if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclNum)) {
    2885            0 :                     Real64 EnclSolQSDifSol_sum(0.0); // Accumulator
    2886            0 :                     int lZone(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.index(enclNum,
    2887            0 :                                                                                  1)); // Tuned Linear indexing
    2888            0 :                     for (int otherEnclNum = 1; otherEnclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++otherEnclNum, ++lZone) {
    2889            0 :                         if ((otherEnclNum != enclNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(otherEnclNum))) {
    2890            0 :                             EnclSolQSDifSol_sum += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[lZone] *
    2891            0 :                                                    state.dataHeatBal->EnclSolQDforDaylight(otherEnclNum); // [ lZone ] == ( enclNum, otherEnclNum )
    2892              :                         }
    2893              :                     }
    2894            0 :                     state.dataHeatBal->EnclSolQSDifSol(enclNum) += EnclSolQSDifSol_sum;
    2895              :                 }
    2896              :             }
    2897              :         }
    2898              : 
    2899       176522 :         for (int enclNum = 1; enclNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclNum) {
    2900       105306 :             if (state.dataHeatBalSurf->InterZoneWindow) {
    2901            0 :                 state.dataHeatBal->EnclSolQSDifSol(enclNum) *=
    2902            0 :                     state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclNum, enclNum) * state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
    2903              :             } else {
    2904       105306 :                 state.dataHeatBal->EnclSolQSDifSol(enclNum) *= state.dataViewFactor->EnclSolInfo(enclNum).solVMULT;
    2905              :             }
    2906              :         }
    2907              : 
    2908              :         //    RJH - 09-12-07 commented out report variable calcs here since they refer to old distribution method
    2909              :         //    DO SurfNum = 1, TotSurfaces
    2910              :         //      IF (.NOT. Surface(SurfNum)%HeatTransSurf) CYCLE
    2911              :         //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
    2912              :         //      IF (Surface(SurfNum)%Class == SurfaceClass::Shading) CYCLE
    2913              :         //      ZoneNum = Surface(SurfNum)%Zone
    2914              :         // Diffuse solar entering zone through exterior windows is assumed to be uniformly
    2915              :         // distributed on inside face of surfaces of zone
    2916              :         //      DifIncInsSurfIntensRep(SurfNum) = (EnclSolDS(ZoneNum)*DifSolarRad + EnclSolDG(ZoneNum)*GndSolarRad) /  &
    2917              :         //        Zone(ZoneNum)%TotalSurfArea
    2918              :         //      DifIncInsSurfAmountRep(SurfNum) = (Surface(SurfNum)%Area + SurfaceWindow(SurfNum)%DividerArea) *  &
    2919              :         //        DifIncInsSurfIntensRep(SurfNum)
    2920              :         //      DifIncInsSurfAmountRepEnergy(SurfNum) = DifIncInsSurfAmountRep(SurfNum) * TimeStepZoneSec
    2921              :         //    END DO
    2922              : 
    2923              :         // Calculate Exterior Incident Short Wave (i.e. Solar) Radiation on shading surfaces
    2924        71216 :         if (state.dataSurface->BuildingShadingCount || state.dataSurface->FixedShadingCount || state.dataSurface->AttachedShadingCount) {
    2925        14980 :             for (int SurfNum = state.dataSurface->ShadingSurfaceFirst; SurfNum <= state.dataSurface->ShadingSurfaceLast; SurfNum++) {
    2926        11984 :                 Real64 GndSurfReflectance = 0.0;
    2927        11984 :                 if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2928            0 :                     GndSurfReflectance =
    2929            0 :                         state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2930              :                 } else {
    2931        11984 :                     GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2932              :                 }
    2933              :                 // Cosine of incidence angle and solar incident on outside of surface, for reporting
    2934        11984 :                 Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2935        11984 :                 state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = CosInc;
    2936        11984 :                 Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2937        11984 :                 Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2938        11984 :                 Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2939              :                 // Incident direct (unreflected) beam
    2940        11984 :                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
    2941        11984 :                     currBeamSolarRad * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * CosInc;
    2942              :                 // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2943        11984 :                 state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2944              :                 // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
    2945        11984 :                 state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2946              :                 // Incident diffuse solar from beam-to-diffuse reflection from ground
    2947        11984 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
    2948        11984 :                     currBeamSolarRad * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2949              :                 // Incident diffuse solar from sky diffuse reflection from ground
    2950        11984 :                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
    2951        11984 :                     currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
    2952              :                 // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
    2953              :                 // in SkySolarInc.
    2954        11984 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    2955        11984 :                     state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    2956        11984 :                     state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
    2957              :             }
    2958              :         }
    2959              : 
    2960        71216 :         Array1D<Real64> currBeamSolar(state.dataSurface->TotSurfaces); // Local variable for BeamSolarRad
    2961              : 
    2962       462416 :         for (int SurfNum : state.dataSurface->AllExtSolarSurfaceList) {
    2963       391200 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    2964              :             // Regular surface
    2965       391200 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    2966       391200 :             Real64 currDifSolarRad = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier;
    2967              :             // Cosine of incidence angle and solar incident on outside of surface, for reporting
    2968       391200 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
    2969       391200 :                 state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    2970              : 
    2971              :             // Report variables for various incident solar quantities
    2972              :             // Incident direct (unreflected) beam
    2973       391200 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) =
    2974       391200 :                 currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
    2975       391200 :                 state.dataHeatBal->SurfCosIncidenceAngle(SurfNum);
    2976              : 
    2977       391200 :             Real64 GndSurfReflectance = 0.0;
    2978       391200 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    2979            0 :                 GndSurfReflectance =
    2980            0 :                     state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex).SurfsReflAvg;
    2981              :             } else {
    2982       391200 :                 GndSurfReflectance = state.dataEnvrn->GndReflectance;
    2983              :             }
    2984              :             // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    2985       391200 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = currDifSolarRad * state.dataSolarShading->SurfAnisoSkyMult(SurfNum);
    2986              :             // Incident diffuse solar from sky diffuse reflected from ground plus beam reflected from ground
    2987       391200 :             state.dataHeatBal->SurfQRadSWOutIncidentGndDiffuse(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum);
    2988              :             // Incident diffuse solar from beam-to-diffuse reflection from ground
    2989       391200 :             state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) =
    2990       391200 :                 currBeamSolar(SurfNum) * state.dataEnvrn->SOLCOS(3) * GndSurfReflectance * state.dataSurface->SurfBmToDiffReflFacGnd(SurfNum);
    2991              : 
    2992              :             // Incident diffuse solar from sky diffuse reflection from ground
    2993       391200 :             state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum) =
    2994       391200 :                 currDifSolarRad * GndSurfReflectance * state.dataSurface->SurfSkyDiffReflFacGnd(SurfNum);
    2995              :             // Total incident solar. Beam and sky reflection from obstructions, if calculated, is included
    2996              :             // in SkySolarInc.
    2997              :             // SurfQRadSWOutIncident(SurfNum) = SurfQRadSWOutIncidentBeam(SurfNum) + SkySolarInc + GndSolarInc
    2998              :             // TH2 CR 9056
    2999       391200 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    3000       391200 :                 state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    3001       391200 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum);
    3002              : 
    3003       391200 :             if (state.dataSurface->CalcSolRefl) {
    3004              :                 // Incident beam solar from beam-to-beam (specular) reflection from obstructions
    3005            0 :                 state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) = state.dataSurface->SurfBmToBmReflFacObs(SurfNum) * currBeamSolar(SurfNum);
    3006              :                 // Incident diffuse solar from beam-to-diffuse reflection from obstructions
    3007            0 :                 state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) =
    3008            0 :                     state.dataSurface->SurfBmToDiffReflFacObs(SurfNum) * currBeamSolar(SurfNum);
    3009              :                 // Incident diffuse solar from sky diffuse reflection from obstructions
    3010            0 :                 state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum) = currDifSolarRad * state.dataSurface->SurfReflFacSkySolObs(SurfNum);
    3011              :                 // TH2 CR 9056: Add reflections from obstructions to the total incident
    3012            0 :                 state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) += state.dataHeatBal->SurfQRadSWOutIncBmToBmReflObs(SurfNum) +
    3013            0 :                                                                      state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflObs(SurfNum) +
    3014            0 :                                                                      state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflObs(SurfNum);
    3015              :             }
    3016        71216 :         }
    3017        71216 :         for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
    3018            0 :             int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser; // TDD: Diffuser object number
    3019            0 :             int const SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome;    // TDD: DOME object number
    3020            0 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3021            0 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3022              : 
    3023              :             // Reconstruct the beam, sky, and ground radiation transmittance of just the TDD:DOME and TDD pipe
    3024              :             // by dividing out diffuse solar transmittance of TDD:DIFFUSER
    3025            0 :             Real64 ConInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2);
    3026              : 
    3027            0 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) = ConInc;
    3028            0 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3029            0 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier *
    3030            0 :                                      TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarBeam) / thisConstruct.TransDiff;
    3031              : 
    3032            0 :             state.dataSurface->SurfSkySolarInc(SurfNum) = state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier *
    3033            0 :                                                           state.dataSolarShading->SurfAnisoSkyMult(SurfNum2) *
    3034            0 :                                                           TransTDD(state, PipeNum, ConInc, Dayltg::RadType::SolarAniso) / thisConstruct.TransDiff;
    3035              : 
    3036            0 :             state.dataSurface->SurfGndSolarInc(SurfNum) = state.dataSurface->SurfGndSolarInc(SurfNum2) *
    3037            0 :                                                           state.dataDaylightingDevicesData->TDDPipe(PipeNum).TransSolIso / thisConstruct.TransDiff;
    3038              :             // Incident direct (unreflected) beam
    3039            0 :             state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) = currBeamSolar(SurfNum) *
    3040            0 :                                                                     state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay,
    3041            0 :                                                                                                       state.dataGlobal->TimeStep,
    3042            0 :                                                                                                       SurfNum2) *
    3043              :                                                                     ConInc; // NOTE: sunlit and coninc array set to SurfNum2
    3044              : 
    3045              :             // Incident (unreflected) diffuse solar from sky -- TDD_Diffuser calculated differently
    3046            0 :             state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) = state.dataSurface->SurfSkySolarInc(SurfNum);
    3047            0 :             state.dataHeatBal->SurfQRadSWOutIncident(SurfNum) =
    3048            0 :                 (state.dataHeatBal->SurfQRadSWOutIncidentBeam(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncidentSkyDiffuse(SurfNum) +
    3049            0 :                  state.dataHeatBal->SurfQRadSWOutIncBmToDiffReflGnd(SurfNum) + state.dataHeatBal->SurfQRadSWOutIncSkyDiffReflGnd(SurfNum));
    3050              :         }
    3051              : 
    3052        71216 :         for (int ShelfNum = 1; ShelfNum <= (int)state.dataDaylightingDevicesData->Shelf.size(); ++ShelfNum) {
    3053            0 :             int SurfNum = state.dataDaylightingDevicesData->Shelf(ShelfNum).Window;       // Daylighting shelf object number
    3054            0 :             int OutShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).OutSurf; // Outside daylighting shelf present if > 0
    3055            0 :             state.dataHeatBal->SurfCosIncidenceAngle(SurfNum) =
    3056            0 :                 state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    3057            0 :             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3058            0 :             currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3059              :             // Shelf diffuse solar radiation
    3060              :             Real64 ShelfSolarRad =
    3061            0 :                 (currBeamSolar(SurfNum) * state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) *
    3062            0 :                      state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, OutShelfSurf) +
    3063            0 :                  state.dataEnvrn->DifSolarRad * SurfIncSolarMultiplier * state.dataSolarShading->SurfAnisoSkyMult(OutShelfSurf)) *
    3064            0 :                 state.dataDaylightingDevicesData->Shelf(ShelfNum).OutReflectSol;
    3065              : 
    3066            0 :             GndReflSolarRad = state.dataEnvrn->GndSolarRad * SurfIncSolarMultiplier;
    3067            0 :             if (state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl) {
    3068            0 :                 GndReflSolarRad = state.dataSurface->Surface(SurfNum).GndReflSolarRad;
    3069              :             }
    3070              :             // Add all reflected solar from the outside shelf to the ground solar
    3071              :             // NOTE:  If the shelf blocks part of the view to the ground, the user must reduce the ground view factor!!
    3072            0 :             state.dataSurface->SurfGndSolarInc(SurfNum) =
    3073            0 :                 GndReflSolarRad * Surface(SurfNum).ViewFactorGround + ShelfSolarRad * state.dataDaylightingDevicesData->Shelf(ShelfNum).ViewFactor;
    3074              :         }
    3075              : 
    3076              :         // Calculate Exterior and Interior Absorbed Short Wave Radiation
    3077       170521 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3078       211316 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3079       112011 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3080       112011 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    3081       112011 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    3082       692571 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    3083       580560 :                     int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
    3084       580560 :                     Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3085       580560 :                     currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3086       580560 :                     if (Surface(SurfNum).ExtSolar) {
    3087              :                         Real64 AbsExt =
    3088       348112 :                             state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present)
    3089       348112 :                         state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
    3090       348112 :                             state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) +
    3091       348112 :                             AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum));
    3092              :                     }
    3093       580560 :                     if (ConstrNum > 0) {
    3094       580560 :                         int SurfSolIncPtr = SolarShading::SurfaceScheduledSolarInc(state, SurfNum, ConstrNum);
    3095       580560 :                         if (SurfSolIncPtr == 0) {
    3096       580560 :                             if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) {    // Opaque surface
    3097       580560 :                                 int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number
    3098       580560 :                                 int InShelfSurf = 0;                                                // Inside daylighting shelf surface number
    3099       580560 :                                 if (ShelfNum > 0) {
    3100            0 :                                     InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0
    3101              :                                 }
    3102       580560 :                                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +=
    3103       580560 :                                     state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum);
    3104       580560 :                                 if (InShelfSurf > 0) { // Inside daylighting shelf
    3105              :                                     // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init)
    3106            0 :                                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
    3107            0 :                                         state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area);
    3108              :                                 } else { // Regular surface
    3109       580560 :                                     state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) =
    3110       580560 :                                         state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area;
    3111              :                                 }
    3112              :                             }
    3113              :                         } else {
    3114            0 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum);
    3115              :                         }
    3116              :                     }
    3117              :                 }
    3118       112011 :                 int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    3119       112011 :                 int const lastSurfWin = thisSpace.WindowSurfaceLast;
    3120       143115 :                 for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    3121        31104 :                     auto &surf = state.dataSurface->Surface(SurfNum);
    3122        31104 :                     auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
    3123        31104 :                     if (surf.ExtSolar || surf.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    3124              :                         // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above
    3125        31104 :                         int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3126        31104 :                         auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3127        31104 :                         Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass
    3128        31104 :                         Real64 BeamSolar = currBeamSolar(SurfNum);                         // Local variable for BeamSolarRad
    3129        31104 :                         Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum);  // Sky diffuse solar incident on a surface
    3130        31104 :                         Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum);  // Ground diffuse solar incident on a surface
    3131              : 
    3132        31104 :                         DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3133              : 
    3134        60836 :                         if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed &&
    3135        29732 :                             !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    3136        29732 :                             int TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
    3137        66665 :                             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3138        36933 :                                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
    3139              :                             }
    3140              : 
    3141        29732 :                             if (IS_SHADED(ShadeFlag)) { // Shaded window
    3142              : 
    3143            0 :                                 int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction
    3144            0 :                                 auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3145              : 
    3146            0 :                                 if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on
    3147            0 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3148            0 :                                         state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = constructionSh.AbsDiff(Lay);
    3149              :                                     }
    3150            0 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = constructionSh.AbsDiffShade * (SkySolarInc + GndSolarInc);
    3151              : 
    3152            0 :                                 } else if (ANY_BLIND(ShadeFlag)) { // Blind on
    3153            0 :                                     auto &surfShade = state.dataSurface->surfShades(SurfNum);
    3154            0 :                                     int slatIdxLo = surfShade.blind.slatAngIdxLo;
    3155            0 :                                     int slatIdxHi = surfShade.blind.slatAngIdxHi;
    3156            0 :                                     Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3157              :                                     Real64 AbsDiffBlind;
    3158              : 
    3159              :                                     // For constructions, have to do interpolation whether we have movable slats or not
    3160            0 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3161            0 :                                         auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
    3162            0 :                                         auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
    3163              : 
    3164            0 :                                         AbsDiffWin(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.Abs, dfAbsSlatHi.Sol.Ft.Df.Abs, interpFac);
    3165            0 :                                         AbsDiffWinGnd(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3166            0 :                                         AbsDiffWinSky(Lay) = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3167              :                                     }
    3168              : 
    3169            0 :                                     auto const &tarSlatLo = constructionSh.blindTARs[slatIdxLo];
    3170            0 :                                     auto const &tarSlatHi = constructionSh.blindTARs[slatIdxHi];
    3171            0 :                                     AbsDiffBlind = Interp(tarSlatLo.Sol.Ft.Df.Abs, tarSlatHi.Sol.Ft.Df.Abs, interpFac);
    3172              : 
    3173            0 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc);
    3174              : 
    3175            0 :                                     auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
    3176            0 :                                     if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
    3177            0 :                                         Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt);
    3178              : 
    3179              :                                         // Need to do these interpolations unless we want to cache this in surfShade.blind.
    3180            0 :                                         Real64 AbsDiffBlindGnd = Interp(tarSlatLo.Sol.Ft.Df.AbsGnd, tarSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3181            0 :                                         Real64 AbsDiffBlindSky = Interp(tarSlatLo.Sol.Ft.Df.AbsSky, tarSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3182              : 
    3183            0 :                                         state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) =
    3184            0 :                                             SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) +
    3185            0 :                                             GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky);
    3186              :                                     }
    3187              :                                 }
    3188              : 
    3189              :                                 // Correct for shadowing of divider onto interior shading device (note that dividers are
    3190              :                                 // not allowed in windows with between-glass shade/blind)
    3191              : 
    3192            0 :                                 if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    3193            0 :                                     state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= surfWin.glazedFrac;
    3194              :                                 }
    3195              : 
    3196            0 :                                 if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {        // Switchable glazing
    3197            0 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing
    3198            0 :                                     for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3199            0 :                                         state.dataHeatBalSurfMgr->AbsDiffWin(Lay) =
    3200            0 :                                             Window::InterpSw(SwitchFac, state.dataHeatBalSurfMgr->AbsDiffWin(Lay), constructionSh.AbsDiff(Lay));
    3201              :                                     }
    3202              :                                 }
    3203              : 
    3204              :                             } // End of check if window has shading device on
    3205              : 
    3206        29732 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3207        66665 :                             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3208        36933 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3209        36933 :                                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) +
    3210        36933 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3211              :                                 // SurfWinA is from InteriorSolarDistribution
    3212        36933 :                                 if (ANY_BLIND(ShadeFlag)) {
    3213            0 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3214            0 :                                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3215            0 :                                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3216            0 :                                     auto const *matBlind = dynamic_cast<Material::MaterialBlind const *>(s_mat->materials(surfShade.blind.matNum));
    3217            0 :                                     if (matBlind->SlatOrientation == DataWindowEquivalentLayer::Orientation::Horizontal) {
    3218              : 
    3219            0 :                                         Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle
    3220              : 
    3221            0 :                                         int slatIdxLo = surfShade.blind.slatAngIdxLo;
    3222            0 :                                         int slatIdxHi = surfShade.blind.slatAngIdxLo;
    3223            0 :                                         Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3224            0 :                                         auto const &dfAbsSlatLo = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxLo];
    3225            0 :                                         auto const &dfAbsSlatHi = constructionSh.layerSlatBlindDfAbs(Lay)[slatIdxHi];
    3226              : 
    3227            0 :                                         Real64 AbsDiffGlassLayGnd = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsGnd, dfAbsSlatHi.Sol.Ft.Df.AbsGnd, interpFac);
    3228            0 :                                         Real64 AbsDiffGlassLaySky = Interp(dfAbsSlatLo.Sol.Ft.Df.AbsSky, dfAbsSlatHi.Sol.Ft.Df.AbsSky, interpFac);
    3229              : 
    3230            0 :                                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3231            0 :                                             SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) +
    3232            0 :                                             GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) +
    3233            0 :                                             state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3234              :                                     }
    3235              :                                 }
    3236              :                                 // Total solar absorbed in solid layer (W), for reporting
    3237        36933 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3238        36933 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3239              : 
    3240              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3241        36933 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3242              :                             }
    3243        29732 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3244        29732 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3245              :                             // Need to do it this way for now because of scheduled surface gains. They do work only with
    3246              :                             // BSDF windows and overwriting absorbtances will work only for ordinary windows
    3247              :                             // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF &&
    3248              :                             //   SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL &&
    3249              :                             //   inExtWindowModel->isExternalLibraryModel() ) {
    3250              :                             //   TotSolidLay = Construct( ConstrNum ).TotSolidLayers;
    3251              :                             //   for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) {
    3252              :                             //     SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) *
    3253              :                             //       ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) );
    3254              :                             //   }
    3255         1372 :                         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
    3256            0 :                             int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers;
    3257              :                             // Number of solid layers in fenestration system (glass + shading)
    3258            0 :                             int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState;
    3259              :                             // Current state for Complex Fenestration
    3260              :                             // Examine for schedule surface gain
    3261            0 :                             Real64 SurfSolAbs = SolarShading::WindowScheduledSolarAbs(
    3262              :                                 state,
    3263              :                                 SurfNum,
    3264            0 :                                 ConstrNum); // Pointer to scheduled surface gains object for fenestration systems
    3265              : 
    3266            0 :                             for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    3267            0 :                                 if (SurfSolAbs != 0) {
    3268            0 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) =
    3269            0 :                                         state.dataSurface->FenLayAbsSSG(SurfSolAbs).scheds(Lay)->getCurrentVal();
    3270              :                                     // ABWin(Lay) = SurfWinA(SurfNum,Lay)
    3271            0 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay);
    3272              :                                 } else {
    3273              :                                     // Several notes about this equation.  First part is accounting for diffuse solar radiation for the ground
    3274              :                                     // and from the sky.  Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar
    3275              :                                     // radiation originating from beam on exterior side.  Third item (SurfWinACFOverlap(SurfNum,Lay)) is
    3276              :                                     // accounting for absorptances from beam hitting back of the window which passes through rest of exterior
    3277              :                                     // windows
    3278            0 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3279            0 :                                         state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc +
    3280            0 :                                         state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc +
    3281            0 :                                         state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
    3282            0 :                                         state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar;
    3283              :                                 }
    3284              :                                 // Total solar absorbed in solid layer (W), for reporting
    3285            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3286            0 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3287              : 
    3288              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3289            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3290              :                             }
    3291            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3292            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3293              : 
    3294         1372 :                         } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
    3295         1372 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3296              :                             // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr
    3297              :                             int TotSolidLay =
    3298         1372 :                                 state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL;
    3299         4970 :                             for (int Lay = 1; Lay <= TotSolidLay; ++Lay) {
    3300              :                                 // Absorbed window components include:
    3301              :                                 // (1) beam solar radiation absorbed by all layers in the fenestration
    3302              :                                 // (2) sky and ground reflected diffuse solar radiation absorbed by all layers
    3303              :                                 // (3) diffuse short wave incident on the inside face of the fenestration.  The short wave internal sources
    3304              :                                 //     include light, ...
    3305         3598 :                                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay);
    3306         3598 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3307         3598 :                                     state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar +
    3308         3598 :                                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc);
    3309              : 
    3310              :                                 // Total solar absorbed in solid layer (W), for reporting
    3311         3598 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3312         3598 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3313              : 
    3314              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3315         3598 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3316              :                             }
    3317              : 
    3318         1372 :                             state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3319         1372 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3320            0 :                         } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) {
    3321            0 :                             int SurfNum2 = SurfNum;
    3322            0 :                             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) {
    3323            0 :                                 SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
    3324              :                             }
    3325              : 
    3326              :                             std::pair<Real64, Real64> incomingAngle =
    3327            0 :                                 Window::getSunWCEAngles(state, SurfNum2, SingleLayerOptics::BSDFDirection::Incoming);
    3328            0 :                             Real64 Theta = incomingAngle.first;
    3329            0 :                             Real64 Phi = incomingAngle.second;
    3330              : 
    3331              :                             std::shared_ptr<MultiLayerOptics::CMultiLayerScattered> aLayer =
    3332            0 :                                 Window::CWindowConstructionsSimplified::instance(state).getEquivalentLayer(
    3333            0 :                                     state, FenestrationCommon::WavelengthRange::Solar, ConstrNum);
    3334              : 
    3335            0 :                             size_t totLayers = aLayer->getNumOfLayers();
    3336            0 :                             for (size_t Lay = 1; Lay <= totLayers; ++Lay) {
    3337            0 :                                 Real64 AbWinDiff = aLayer->getAbsorptanceLayer(
    3338              :                                     Lay, FenestrationCommon::Side::Front, FenestrationCommon::ScatteringSimple::Diffuse, Theta, Phi);
    3339              : 
    3340            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3341            0 :                                     AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar;
    3342              : 
    3343              :                                 // Total solar absorbed in solid layer (W), for reporting
    3344            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3345            0 :                                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3346              : 
    3347              :                                 // Total solar absorbed in all glass layers (W), for reporting
    3348            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3349              :                             }
    3350            0 :                         }
    3351              : 
    3352              :                         // Solar absorbed by window frame and dividers
    3353        31104 :                         int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number
    3354        31104 :                         if (FrDivNum > 0) {
    3355            0 :                             Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum);                    // Frame, divider area (m2)
    3356            0 :                             Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m)
    3357            0 :                             Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn;
    3358            0 :                             Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum);
    3359            0 :                             Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth;
    3360            0 :                             Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut;
    3361            0 :                             Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn;
    3362            0 :                             Real64 CosIncAngHorProj = 0.0;  // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection
    3363            0 :                             Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection
    3364            0 :                             Real64 FracSunLit = 0.0;        // Fraction of window sunlit this time step
    3365              :                             Real64 BeamFaceInc;             // Beam solar incident window plane this time step (W/m2)
    3366              :                             Real64 DifSolarFaceInc;         // Diffuse solar incident on window plane this time step (W/m2)
    3367            0 :                             Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier;
    3368            0 :                             Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier;
    3369            0 :                             if (FrArea > 0.0 || DivArea > 0.0) {
    3370            0 :                                 FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum);
    3371            0 :                                 BeamFaceInc = currBeamSolarRad *
    3372            0 :                                               state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) *
    3373              :                                               CosInc;
    3374            0 :                                 DifSolarFaceInc = SkySolarInc + GndSolarInc;
    3375              :                             }
    3376            0 :                             if (FracSunLit > 0.0) {
    3377            0 :                                 if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) ||
    3378            0 :                                     (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) {
    3379              :                                     // Dot products used to calculate beam solar incident on faces of
    3380              :                                     // frame and divider perpendicular to the glass surface.
    3381              :                                     // Note that SOLCOS is the current timestep's solar direction cosines.
    3382              :                                     //                  PhiWin = ASIN(WALCOS(3,SurfNum))
    3383              :                                     Real64 PhiWin =
    3384            0 :                                         std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians)
    3385            0 :                                     Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1));
    3386            0 :                                     Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians)
    3387            0 :                                     Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1));
    3388            0 :                                     Real64 const cos_PhiWin(std::cos(PhiWin));
    3389            0 :                                     Real64 const cos_PhiSun(std::cos(PhiSun));
    3390              :                                     CosIncAngHorProj =
    3391            0 :                                         std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun));
    3392            0 :                                     CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun));
    3393              :                                 }
    3394              :                             }
    3395              :                             // Frame solar
    3396              :                             // (A window shade or blind, if present, is assumed to not shade the frame, so no special
    3397              :                             // treatment of frame solar needed if window has an exterior shade or blind.)
    3398            0 :                             if (FrArea > 0.0) {
    3399            0 :                                 Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside of frame including solar
    3400            0 :                                 Real64 FrIncSolarIn = 0.0; // Total solar incident on inside of frame including solar on frame projection (W/m2)
    3401            0 :                                 Real64 TransDiffGl = 0.0;  // Diffuse solar transmittance
    3402            0 :                                 if (FrProjOut > 0.0 || FrProjIn > 0.0) {
    3403              :                                     Real64 BeamFrHorFaceInc =
    3404            0 :                                         currBeamSolarRad * CosIncAngHorProj *
    3405            0 :                                         (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit /
    3406            0 :                                         FrArea;
    3407              :                                     Real64 BeamFrVertFaceInc =
    3408            0 :                                         currBeamSolarRad * CosIncAngVertProj *
    3409            0 :                                         (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
    3410            0 :                                         FrArea;
    3411              :                                     // Beam solar on outside of frame
    3412            0 :                                     FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut;
    3413            0 :                                     if (FrProjIn > 0.0) {
    3414            0 :                                         Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
    3415            0 :                                         TransDiffGl = thisConstruct.TransDiff;
    3416            0 :                                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3417            0 :                                             Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3418            0 :                                             int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3419            0 :                                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3420            0 :                                             Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
    3421            0 :                                             TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3422            0 :                                             Real64 TransDiffGlSh = constructionSh.TransDiff;
    3423            0 :                                             TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
    3424              :                                         }
    3425              :                                         // Beam solar on inside of frame
    3426            0 :                                         FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl;
    3427              :                                     }
    3428              :                                 }
    3429              :                                 // Beam plus diffuse solar on outside of frame
    3430            0 :                                 FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum));
    3431            0 :                                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) =
    3432            0 :                                     FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3433              :                                 // Add diffuse from beam reflected from window outside reveal surfaces
    3434            0 :                                 state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad *
    3435            0 :                                                                                       state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) *
    3436            0 :                                                                                       state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3437              : 
    3438              :                                 // Beam plus diffuse solar on inside of frame
    3439            0 :                                 FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum);
    3440            0 :                                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3441              :                                 // Add diffuse from beam reflected from window inside reveal surfaces
    3442            0 :                                 state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad *
    3443            0 :                                                                                      state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) *
    3444            0 :                                                                                      state.dataSurface->SurfWinFrameSolAbsorp(SurfNum);
    3445              :                             }
    3446              : 
    3447              :                             // Divider solar
    3448              :                             // (An exterior shade or blind, when in place, is assumed to completely cover the divider.
    3449              :                             // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and
    3450              :                             // DivProjIn will be zero in this case.)
    3451            0 :                             if (DivArea > 0.0) {                                                         // Solar absorbed by window divider
    3452            0 :                                 Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    3453            0 :                                 if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    3454              :                                     // Suspended (between-glass) divider; account for effect glass on outside of divider
    3455              :                                     // (note that outside and inside projection for this type of divider are both zero)
    3456            0 :                                     int MatNumGl = thisConstruct.LayerPoint(1); // Outer glass layer material number
    3457            0 :                                     auto const *thisMaterial = dynamic_cast<Material::MaterialFen *>(s_mat->materials(MatNumGl));
    3458            0 :                                     assert(thisMaterial != nullptr);
    3459            0 :                                     Real64 TransGl = thisMaterial->Trans; // Outer glass layer material number, switched construction
    3460            0 :                                     Real64 ReflGl = thisMaterial->ReflectSolBeamFront;
    3461            0 :                                     Real64 AbsGl = 1.0 - TransGl - ReflGl;
    3462            0 :                                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3463            0 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3464            0 :                                     if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3465            0 :                                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3466            0 :                                         Real64 MatNumGlSh = constructionSh.LayerPoint(1);
    3467            0 :                                         auto const *thisMaterialSh = dynamic_cast<Material::MaterialGlass *>(s_mat->materials(MatNumGlSh));
    3468            0 :                                         assert(thisMaterialSh != nullptr);
    3469            0 :                                         Real64 TransGlSh = thisMaterialSh->Trans;
    3470            0 :                                         Real64 ReflGlSh = thisMaterialSh->ReflectSolBeamFront;
    3471            0 :                                         Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh;
    3472            0 :                                         TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3473            0 :                                         ReflGl = Window::InterpSw(SwitchFac, ReflGl, ReflGlSh);
    3474            0 :                                         AbsGl = Window::InterpSw(SwitchFac, AbsGl, AbsGlSh);
    3475              :                                     }
    3476            0 :                                     Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance
    3477            0 :                                     DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
    3478              :                                 }
    3479              : 
    3480            0 :                                 Real64 BeamDivHorFaceInc = 0.0;  // Beam solar on divider's horizontal outside projection faces (W/m2)
    3481            0 :                                 Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2)
    3482              :                                 // Beam incident on horizontal and vertical projection faces of divider if no exterior shading
    3483            0 :                                 if (DivProjOut > 0.0 && !DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3484            0 :                                     BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers *
    3485            0 :                                                         DivProjOut *
    3486            0 :                                                         (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
    3487              :                                                         FracSunLit / DivArea;
    3488            0 :                                     BeamDivVertFaceInc =
    3489            0 :                                         currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut *
    3490            0 :                                         (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit /
    3491              :                                         DivArea;
    3492              :                                 }
    3493            0 :                                 Real64 DivIncSolarOutBm =
    3494              :                                     0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2)
    3495            0 :                                 Real64 DivIncSolarOutDif =
    3496              :                                     0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2)
    3497            0 :                                 Real64 DivIncSolarInBm =
    3498              :                                     0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2)
    3499            0 :                                 Real64 DivIncSolarInDif =
    3500              :                                     0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2)
    3501            0 :                                 if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) &&
    3502            0 :                                     !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading
    3503            0 :                                     DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc;
    3504            0 :                                     DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3505            0 :                                     if (DivProjIn > 0.0) {
    3506            0 :                                         Real64 TransGl = Window::POLYF(CosInc, thisConstruct.TransSolBeamCoef);
    3507            0 :                                         Real64 TransDiffGl = thisConstruct.TransDiff;                       // Diffuse solar transmittance
    3508            0 :                                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    3509            0 :                                             Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    3510            0 :                                             int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3511            0 :                                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3512              : 
    3513            0 :                                             Real64 TransGlSh = Window::POLYF(CosInc, constructionSh.TransSolBeamCoef);
    3514              :                                             // Outer glass solar trans, refl, absorptance if switched
    3515            0 :                                             TransGl = Window::InterpSw(SwitchFac, TransGl, TransGlSh);
    3516            0 :                                             Real64 TransDiffGlSh = constructionSh.TransDiff;
    3517              :                                             // Diffuse solar transmittance, switched construction
    3518            0 :                                             TransDiffGl = Window::InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh);
    3519              :                                         }
    3520              :                                         // Beam plus diffuse solar on inside of divider
    3521              :                                         // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2)
    3522              :                                         // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2)
    3523              :                                         Real64 BeamDivHorFaceIncIn =
    3524            0 :                                             currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn *
    3525            0 :                                             (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) *
    3526            0 :                                             FracSunLit / DivArea;
    3527              :                                         Real64 BeamDivVertFaceIncIn =
    3528            0 :                                             currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers *
    3529            0 :                                             DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) *
    3530            0 :                                             FracSunLit / DivArea;
    3531            0 :                                         DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn);
    3532            0 :                                         DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum);
    3533              :                                     }
    3534              :                                 } else { // Exterior shade, screen or blind present
    3535              : 
    3536            0 :                                     DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3537            0 :                                     DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum));
    3538            0 :                                     DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
    3539            0 :                                     DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * thisConstruct.TransDiff;
    3540              :                                 }
    3541              : 
    3542            0 :                                 if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) {
    3543              :                                     // No exterior or between-glass shade, screen or blind
    3544            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif);
    3545            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif);
    3546              :                                     // Exterior shade, screen or blind
    3547              : 
    3548            0 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) { // Exterior blind
    3549            0 :                                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3550              : 
    3551            0 :                                     int profIdxLo = surfShade.blind.profAngIdxLo;
    3552            0 :                                     int profIdxHi = surfShade.blind.profAngIdxHi;
    3553            0 :                                     Real64 profInterpFac = surfShade.blind.profAngInterpFac;
    3554              : 
    3555            0 :                                     auto const &btarLo = surfShade.blind.TAR.Sol.Ft.Bm[profIdxLo];
    3556            0 :                                     auto const &btarHi = surfShade.blind.TAR.Sol.Ft.Bm[profIdxHi];
    3557              : 
    3558            0 :                                     Real64 FrontDiffTrans = surfShade.blind.TAR.Sol.Ft.Df.Tra;
    3559            0 :                                     Real64 TBlBmDif = Interp(btarLo.DfTra, btarHi.DfTra, profInterpFac);
    3560              : 
    3561              :                                     // TBlBmBm - Blind beam-beam solar transmittance
    3562            0 :                                     Real64 TBlBmBm = surfShade.blind.bmBmTrans;
    3563            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3564            0 :                                         DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans);
    3565            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3566            0 :                                         DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans);
    3567              : 
    3568            0 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtShade) { // Exterior shade
    3569            0 :                                     int ConstrNumSh = Surface(SurfNum).activeShadedConstruction;
    3570            0 :                                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    3571            0 :                                     auto const *matFen = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(constructionSh.LayerPoint(1)));
    3572            0 :                                     assert(matFen != nullptr);
    3573            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3574            0 :                                         DividerAbs * matFen->Trans * (DivIncSolarOutBm + DivIncSolarOutDif);
    3575            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3576            0 :                                         DividerAbs * matFen->Trans * (DivIncSolarInBm + DivIncSolarInDif);
    3577              : 
    3578            0 :                                 } else if (ShadeFlag == DataSurfaces::WinShadingType::ExtScreen) { // Exterior screen
    3579            0 :                                     int screenNum = surfWin.screenNum;
    3580            0 :                                     auto const *screen = dynamic_cast<Material::MaterialScreen const *>(s_mat->materials(screenNum));
    3581            0 :                                     assert(screen != nullptr);
    3582              : 
    3583            0 :                                     auto &surf = state.dataSurface->Surface(SurfNum);
    3584              :                                     Real64 phi, theta;
    3585            0 :                                     Material::GetRelativePhiTheta(
    3586            0 :                                         surf.Tilt * Constant::DegToRad, surf.Azimuth * Constant::DegToRad, state.dataEnvrn->SOLCOS, phi, theta);
    3587              : #ifdef PRECALC_INTERP_SCREEN
    3588              :                                     int ip1, ip2, it1, it2; // hi/lo phi and theta map indices
    3589              :                                     BilinearInterpCoeffs coeffs;
    3590            0 :                                     Material::GetPhiThetaIndices(phi, theta, screen->dPhi, screen->dTheta, ip1, ip2, it1, it2);
    3591            0 :                                     GetBilinearInterpCoeffs(
    3592            0 :                                         phi, theta, ip1 * screen->dPhi, ip2 * screen->dPhi, it1 * screen->dTheta, it2 * screen->dTheta, coeffs);
    3593            0 :                                     auto const &b11 = screen->btars[ip1][it1];
    3594            0 :                                     auto const &b12 = screen->btars[ip1][it2];
    3595            0 :                                     auto const &b21 = screen->btars[ip2][it1];
    3596            0 :                                     auto const &b22 = screen->btars[ip2][it2];
    3597            0 :                                     Real64 BmDfTrans = BilinearInterp(b11.DfTrans, b12.DfTrans, b21.DfTrans, b22.DfTrans, coeffs);
    3598            0 :                                     Real64 BmBmTrans = BilinearInterp(b11.BmTrans, b12.BmTrans, b21.BmTrans, b22.BmTrans, coeffs);
    3599              : 
    3600            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3601            0 :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
    3602            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3603            0 :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
    3604              : #else  // !PRECALC_INTERP_SCREEN
    3605              :                                     Material::ScreenBmTransAbsRef btar;
    3606              : 
    3607              :                                     Material::CalcScreenTransmittance(state, screen, phi, theta, btar);
    3608              :                                     Real64 BmDfTrans = btar.DfTrans;
    3609              :                                     Real64 BmBmTrans = btar.BmTrans;
    3610              : 
    3611              :                                     state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) =
    3612              :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarOutBm + DivIncSolarOutDif);
    3613              :                                     state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) =
    3614              :                                         DividerAbs * (BmBmTrans + BmDfTrans) * (DivIncSolarInBm + DivIncSolarInDif);
    3615              : #endif // PRECALC_INTERP_SCREEN
    3616              :                                 }
    3617              :                             }
    3618              :                         }
    3619              :                     } // Surface(SurfNum)%ExtSolar
    3620              :                 } // end of surface window loop
    3621        99305 :             } // end of space loop
    3622              :         } // end of zone loop
    3623        71216 :         for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) {
    3624            0 :             int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number
    3625            0 :             int const ConstrNum = Surface(SurfNum).Construction;
    3626            0 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3627            0 :             int const TotGlassLay = thisConstruct.TotGlassLayers; // Number of glass layers
    3628            0 :             state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0;
    3629            0 :             for (int Lay = 1; Lay <= TotGlassLay; ++Lay) {
    3630            0 :                 state.dataHeatBalSurfMgr->AbsDiffWin(Lay) = thisConstruct.AbsDiff(Lay);
    3631            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) =
    3632            0 :                     state.dataHeatBalSurfMgr->AbsDiffWin(Lay) *
    3633            0 :                         (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)) +
    3634            0 :                     state.dataSurface->SurfWinA(SurfNum, Lay) * currBeamSolar(SurfNum);
    3635            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) =
    3636            0 :                     state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area;
    3637            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay);
    3638            0 :                 state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) =
    3639            0 :                     state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3640              :             }
    3641              :         }
    3642              : 
    3643              :         // Average absorbed solar for representative surfaces
    3644        71216 :         if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    3645            0 :             for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3646            0 :                 for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3647            0 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    3648            0 :                     int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    3649            0 :                     int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    3650            0 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    3651            0 :                         auto &surface = state.dataSurface->Surface(surfNum);
    3652            0 :                         if (surface.ConstituentSurfaceNums.size() > 1) {
    3653            0 :                             Real64 QoutAtot = 0.0;
    3654            0 :                             Real64 QinAtot = 0.0;
    3655            0 :                             Real64 Atot = 0.0;
    3656            0 :                             for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3657            0 :                                 QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
    3658            0 :                                 QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area;
    3659            0 :                                 Atot += state.dataSurface->Surface(constSurfNum).Area;
    3660            0 :                             }
    3661              : 
    3662            0 :                             state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot;
    3663            0 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot;
    3664              :                         }
    3665              :                     }
    3666            0 :                     firstSurf = thisSpace.WindowSurfaceFirst;
    3667            0 :                     lastSurf = thisSpace.WindowSurfaceLast;
    3668            0 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    3669            0 :                         auto const &surface = state.dataSurface->Surface(surfNum);
    3670            0 :                         if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) {
    3671              :                             // Absorbed in glazing
    3672              :                             int totalGlassLayers =
    3673            0 :                                 state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers;
    3674            0 :                             for (int layer = 1; layer <= totalGlassLayers; ++layer) {
    3675            0 :                                 Real64 QAtot = 0.0;
    3676            0 :                                 Real64 Atot = 0.0;
    3677            0 :                                 for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3678            0 :                                     QAtot +=
    3679            0 :                                         state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area;
    3680            0 :                                     Atot += state.dataSurface->Surface(constSurfNum).Area;
    3681            0 :                                 }
    3682              : 
    3683            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot;
    3684              :                             }
    3685              : 
    3686              :                             // Absorbed by frame and dividers
    3687            0 :                             if (surface.FrameDivider > 0) {
    3688            0 :                                 if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
    3689            0 :                                     Real64 QoutAtot = 0.0;
    3690            0 :                                     Real64 QinAtot = 0.0;
    3691            0 :                                     Real64 Atot = 0.0;
    3692            0 :                                     for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3693            0 :                                         QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) *
    3694            0 :                                                     state.dataSurface->SurfWinFrameArea(constSurfNum);
    3695            0 :                                         QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) *
    3696            0 :                                                    state.dataSurface->SurfWinFrameArea(constSurfNum);
    3697            0 :                                         Atot += state.dataSurface->SurfWinFrameArea(constSurfNum);
    3698            0 :                                     }
    3699              : 
    3700            0 :                                     state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot;
    3701            0 :                                     state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot;
    3702              :                                 }
    3703            0 :                                 if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
    3704            0 :                                     Real64 QoutAtot = 0.0;
    3705            0 :                                     Real64 QinAtot = 0.0;
    3706            0 :                                     Real64 Atot = 0.0;
    3707            0 :                                     for (int constSurfNum : surface.ConstituentSurfaceNums) {
    3708            0 :                                         QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) *
    3709            0 :                                                     state.dataSurface->SurfWinDividerArea(constSurfNum);
    3710            0 :                                         QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) *
    3711            0 :                                                    state.dataSurface->SurfWinDividerArea(constSurfNum);
    3712            0 :                                         Atot += state.dataSurface->SurfWinDividerArea(constSurfNum);
    3713            0 :                                     }
    3714              : 
    3715            0 :                                     state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot;
    3716            0 :                                     state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot;
    3717              :                                 }
    3718              :                             }
    3719              :                         }
    3720              :                     }
    3721            0 :                 }
    3722              :             }
    3723              :         }
    3724        71216 :     } // End of sun-up check
    3725       249960 : }
    3726              : 
    3727       249958 : void InitIntSolarDistribution(EnergyPlusData &state)
    3728              : {
    3729              : 
    3730              :     // SUBROUTINE INFORMATION:
    3731              :     //       AUTHOR         Anonymous
    3732              :     //       DATE WRITTEN   July 1977
    3733              :     //       MODIFIED       Oct 1999 (FW) to handle movable shades
    3734              :     //                      May 2000 (FW) to handle window frame and dividers
    3735              :     //                      May 2001 (FW) to handle window blinds
    3736              :     //                      Jan 2002 (FW) mods for between-glass shade/blind
    3737              :     //                      May 2006 (RR) to handle exterior window screens
    3738              :     //       RE-ENGINEERED  Mar98 (RKS)
    3739              : 
    3740              :     // PURPOSE OF THIS SUBROUTINE:
    3741              :     // This subroutine initializes the arrays associated with solar heat
    3742              :     // gains for both individual surfaces and for zones.
    3743              : 
    3744              :     // METHODOLOGY EMPLOYED:
    3745              :     // If the sun is down, all of the pertinent arrays are zeroed.  If the
    3746              :     // sun is up, various calculations are made.
    3747              : 
    3748              :     // REFERENCES:
    3749              :     // (I)BLAST legacy routine QSUN
    3750              : 
    3751              :     using Dayltg::DistributeTDDAbsorbedSolar;
    3752              :     using namespace DataWindowEquivalentLayer;
    3753              : 
    3754       249958 :     auto &s_mat = state.dataMaterial;
    3755              :     // COMPUTE TOTAL SHORT-WAVE RADIATION ORIGINATING IN ZONE.
    3756              :     // Note: If sun is not up, QS is only internal gains
    3757       602834 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3758       352876 :         Real64 sumSpaceQLTSW = 0.0;
    3759       723131 :         for (int spaceNum : state.dataViewFactor->EnclSolInfo(enclosureNum).spaceNums) {
    3760       370255 :             sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
    3761       352876 :         }
    3762       352876 :         state.dataHeatBal->EnclSolQSWRad(enclosureNum) = state.dataHeatBal->EnclSolQD(enclosureNum) + sumSpaceQLTSW;
    3763       352876 :         state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) = sumSpaceQLTSW;
    3764              :     }
    3765              : 
    3766       249958 :     if (state.dataHeatBalSurf->InterZoneWindow) { // DO INTERZONE DISTRIBUTION.
    3767              : 
    3768            2 :         for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3769              : 
    3770            1 :             if (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(enclosureNum)) {
    3771              : 
    3772            0 :                 for (int OtherenclosureNum = 1; OtherenclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++OtherenclosureNum) {
    3773              : 
    3774            0 :                     if ((OtherenclosureNum != enclosureNum) && (state.dataHeatBalSurf->EnclSolRecDifShortFromZ(OtherenclosureNum))) {
    3775            0 :                         Real64 sumSpaceQLTSW = 0.0;
    3776            0 :                         for (int spaceNum : state.dataViewFactor->EnclSolInfo(OtherenclosureNum).spaceNums) {
    3777            0 :                             sumSpaceQLTSW += state.dataHeatBal->spaceIntGain(spaceNum).QLTSW;
    3778            0 :                         }
    3779            0 :                         state.dataHeatBal->EnclSolQSWRad(enclosureNum) +=
    3780            0 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
    3781            0 :                             (state.dataHeatBal->EnclSolQD(OtherenclosureNum) + sumSpaceQLTSW);
    3782            0 :                         state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) +=
    3783            0 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) * sumSpaceQLTSW;
    3784            0 :                         state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) +=
    3785            0 :                             state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, OtherenclosureNum) *
    3786            0 :                             state.dataHeatBal->EnclSolQD(OtherenclosureNum);
    3787            0 :                         state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclosureNum) =
    3788            0 :                             state.dataHeatBal->ZoneDifSolFrIntWinsRep(enclosureNum) * state.dataGlobal->TimeStepZoneSec;
    3789              :                     }
    3790              :                 }
    3791              :             }
    3792              :         }
    3793              :     }
    3794              : 
    3795              :     // Beam and diffuse solar on inside surfaces from interior windows (for reporting)
    3796              : 
    3797       249958 :     if (state.dataEnvrn->SunIsUp) {
    3798      1133860 :         for (int SurfNum : state.dataSurface->AllHTSurfaceList) {
    3799      1012414 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    3800              :             //!!! Following may need to be removed or changed when shelves are considered in adjacent reflection calculations
    3801      1012414 :             if (surface.Class == DataSurfaces::SurfaceClass::Shading) {
    3802            0 :                 continue;
    3803              :             }
    3804      1012414 :             int const enclosureNum = surface.SolarEnclIndex;
    3805      1012414 :             state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) =
    3806      1012414 :                 state.dataHeatBal->ZoneBmSolFrIntWinsRep(enclosureNum) / state.dataViewFactor->EnclSolInfo(enclosureNum).TotalSurfArea;
    3807      1012414 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) =
    3808      1012414 :                 state.dataHeatBal->SurfIntBmIncInsSurfIntensRep(SurfNum) * (surface.Area + state.dataSurface->SurfWinDividerArea(SurfNum));
    3809      1012414 :             state.dataHeatBal->SurfIntBmIncInsSurfAmountRepEnergy(SurfNum) =
    3810      1012414 :                 state.dataHeatBal->SurfIntBmIncInsSurfAmountRep(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    3811       121446 :         }
    3812              :     }
    3813              : 
    3814              :     // COMPUTE CONVECTIVE GAINS AND ZONE FLUX DENSITY.
    3815       602834 :     for (int enclosureNum = 1; enclosureNum <= state.dataViewFactor->NumOfSolarEnclosures; ++enclosureNum) {
    3816       352876 :         auto const &thisSolEnclosure = state.dataViewFactor->EnclSolInfo(enclosureNum);
    3817       352876 :         if (state.dataHeatBalSurf->InterZoneWindow) {
    3818            1 :             state.dataHeatBal->EnclSolQSWRad(enclosureNum) *=
    3819            1 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
    3820              :             // CR 8695, VMULT not based on visible
    3821            1 :             state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *=
    3822            1 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(enclosureNum, enclosureNum) * thisSolEnclosure.solVMULT;
    3823              :         } else {
    3824       352875 :             state.dataHeatBal->EnclSolQSWRad(enclosureNum) *= thisSolEnclosure.solVMULT;
    3825       352875 :             state.dataHeatBal->EnclSolQSWRadLights(enclosureNum) *= thisSolEnclosure.solVMULT;
    3826              :         }
    3827              :     }
    3828              : 
    3829              :     // COMPUTE RADIANT GAINS ON SURFACES
    3830       586610 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    3831       706907 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    3832       370255 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    3833       370255 :             int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst;
    3834       370255 :             int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast;
    3835      2350619 :             for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) {
    3836      1980364 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    3837      1980364 :                 int const solEnclosureNum = surface.SolarEnclIndex;
    3838      1980364 :                 int const ConstrNum = surface.Construction;
    3839      1980364 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3840              : 
    3841      1980364 :                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum);
    3842              :                 // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis?
    3843      1980364 :                 Real64 AbsIntSurfVis = thisConstruct.InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to
    3844              : 
    3845      1980364 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf;
    3846      1980364 :                 state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis;
    3847              : 
    3848              :                 // Calculate absorbed solar on outside if movable exterior insulation in place
    3849      1980364 :                 if (state.dataSurface->AnyMovableInsulation) {
    3850            0 :                     auto &movInsul = state.dataSurface->extMovInsuls(SurfNum);
    3851            0 :                     if (movInsul.present) {
    3852            0 :                         Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum);
    3853            0 :                         auto const *thisMaterial = s_mat->materials(thisConstruct.LayerPoint(1));
    3854            0 :                         state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) =
    3855            0 :                             state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / thisMaterial->AbsorpSolar;
    3856              :                         // For transparent insulation, allow some sunlight to get through the movable insulation.
    3857              :                         // The equation below is derived by taking what is transmitted through the layer and applying
    3858              :                         // the fraction that is absorbed plus the back reflected portion (first order reflection only)
    3859              :                         // to the plane between the transparent insulation and the exterior surface face.
    3860            0 :                         auto const *matMovInsul = s_mat->materials(movInsul.matNum);
    3861            0 :                         auto const *matFenMovInsul = dynamic_cast<Material::MaterialFen const *>(matMovInsul);
    3862            0 :                         Real64 transMovInsul = (matFenMovInsul != nullptr) ? matFenMovInsul->Trans : 0.0;
    3863              : 
    3864            0 :                         state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) =
    3865            0 :                             transMovInsul * state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) *
    3866            0 :                             ((thisMaterial->AbsorpSolar / AbsExt) + (1 - thisMaterial->AbsorpSolar));
    3867              :                     }
    3868              :                 }
    3869              :                 // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade
    3870              :                 // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here
    3871      1980364 :                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum);
    3872              :             } // end of opaque
    3873              : 
    3874       370255 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    3875       370255 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    3876       458819 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window
    3877        88564 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    3878        88564 :                 auto const &surfWin = state.dataSurface->SurfaceWindow(SurfNum);
    3879        88564 :                 int const radEnclosureNum = surface.RadEnclIndex;
    3880        88564 :                 int const solEnclosureNum = surface.SolarEnclIndex;
    3881        88564 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    3882        88564 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    3883              : 
    3884        88564 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) {
    3885        86195 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    3886              : 
    3887        86195 :                     int TotGlassLayers = thisConstruct.TotGlassLayers;
    3888        86195 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    3889              : 
    3890              :                     // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
    3891        86195 :                     Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone
    3892        86195 :                     if (!state.dataGlobal->doLoadComponentPulseNow) {
    3893        86189 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3894        86189 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3895        86189 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3896              :                     } else {
    3897              :                         // radiant value prior to adjustment for pulse for load component report
    3898            6 :                         Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
    3899              :                         // for the loads component report during the special sizing run increase the radiant portion
    3900              :                         // a small amount to create a "pulse" of heat that is used for the
    3901              :                         // radiant value including adjustment for pulse for load component report
    3902            6 :                         Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
    3903              :                         // ITABSF is the Inside Thermal Absorptance
    3904              :                         // EnclRadThermAbsMult is a multiplier for each zone/enclosure
    3905              :                         // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
    3906            6 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    3907            6 :                             adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
    3908            6 :                             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    3909              :                     }
    3910              : 
    3911        86195 :                     if (NOT_SHADED(ShadeFlag)) { // No window shading
    3912       196685 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    3913       110490 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3914       110490 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass);
    3915              :                         }
    3916            0 :                     } else if (ConstrNumSh != 0 && ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
    3917              :                         // Interior, exterior or between-glass shade, screen or blind in place
    3918            0 :                         auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    3919            0 :                         for (int IGlass = 1; IGlass <= constrSh.TotGlassLayers; ++IGlass) {
    3920            0 :                             if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    3921            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3922            0 :                                     state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBack(IGlass);
    3923            0 :                             } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind || ShadeFlag == DataSurfaces::WinShadingType::ExtBlind) {
    3924            0 :                                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3925            0 :                                 Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3926            0 :                                 auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxLo];
    3927            0 :                                 auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(IGlass)[surfShade.blind.slatAngIdxHi];
    3928              :                                 // Glass layer back diffuse solar absorptance when blind in place
    3929            0 :                                 Real64 BlAbsDiffBk = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
    3930              : 
    3931            0 :                                 state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3932            0 :                                     state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk;
    3933              :                             }
    3934              :                         }
    3935            0 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
    3936            0 :                             state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3937            0 :                                                                                  constrSh.ShadeAbsorpThermal *
    3938            0 :                                                                                  state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
    3939            0 :                         } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    3940            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3941            0 :                             Real64 EffBlEmiss = surfShade.effShadeEmi; // Blind emissivity (thermal absorptance) as part of glazing system
    3942            0 :                             state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3943            0 :                                                                                  EffBlEmiss *
    3944            0 :                                                                                  state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult;
    3945              :                         }
    3946              : 
    3947            0 :                         if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    3948            0 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) =
    3949            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * constrSh.AbsDiffBackShade;
    3950            0 :                         } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
    3951            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    3952            0 :                             auto const &btarLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
    3953            0 :                             auto const &btarHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
    3954            0 :                             Real64 interpFac = surfShade.blind.slatAngInterpFac;
    3955            0 :                             Real64 AbsDiffBkBl = Interp(btarLo.Sol.Bk.Df.Abs, btarHi.Sol.Bk.Df.Abs, interpFac);
    3956              : 
    3957            0 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl;
    3958              :                         }
    3959              :                         // Correct for divider shadowing
    3960            0 :                         if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) {
    3961            0 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= surfWin.glazedFrac;
    3962              :                         }
    3963              : 
    3964            0 :                     } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {       // Switchable glazing
    3965            0 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh); // What was here before?
    3966            0 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    3967              : 
    3968            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) +=
    3969            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
    3970            0 :                                 Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    3971            0 :                                                  thisConstruct.AbsDiffBack(IGlass),
    3972            0 :                                                  constructionSh.AbsDiffBack(IGlass));
    3973              :                         }
    3974              : 
    3975              :                     } // End of shading flag check
    3976              : 
    3977              :                     // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains
    3978        86195 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
    3979            3 :                         state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) +=
    3980            3 :                             (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) +
    3981            3 :                              (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    3982            3 :                                   state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
    3983            3 :                               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
    3984            3 :                                  state.dataSurface->SurfWinFrameEmis(SurfNum)) *
    3985            3 :                             (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); // Window has a frame
    3986              :                     }
    3987        86195 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {                     // Window has dividers
    3988            3 :                         Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum);    // Window divider thermal absorptance
    3989            3 :                         Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    3990            3 :                         if (state.dataSurface->SurfWinDividerType(SurfNum) ==
    3991              :                             DataSurfaces::FrameDividerType::Suspended) {                         // Suspended divider; account for inside glass
    3992            0 :                             Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass layer material number
    3993            0 :                             auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
    3994            0 :                             assert(thisMaterial != nullptr);
    3995            0 :                             Real64 TransGl = thisMaterial->Trans; // Glass layer solar transmittance, reflectance, absorptance
    3996            0 :                             Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
    3997            0 :                             Real64 AbsGl = 1.0 - TransGl - ReflGl;
    3998            0 :                             Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance
    3999            0 :                             DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl);
    4000            0 :                             DividerThermAbs = thisMaterial->AbsorpThermalBack;
    4001              :                         }
    4002              :                         // Correct for interior shade transmittance
    4003            3 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntShade) {
    4004            0 :                             auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4005            0 :                             int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers); // Shade layer material number
    4006            0 :                             auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
    4007            0 :                             assert(matSh != nullptr);
    4008            0 :                             DividerSolAbs *= matSh->Trans;
    4009            0 :                             DividerThermAbs *= matSh->TransThermal;
    4010              : 
    4011            3 :                         } else if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    4012            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4013            0 :                             Real64 SolBackDiffDiffTrans = surfShade.blind.TAR.Sol.Bk.Df.Tra;
    4014            0 :                             Real64 IRBackTrans = surfShade.blind.TAR.IR.Bk.Tra;
    4015              : 
    4016            0 :                             DividerSolAbs *= SolBackDiffDiffTrans;
    4017            0 :                             DividerThermAbs *= IRBackTrans;
    4018              :                         }
    4019              :                         // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains
    4020            3 :                         state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) +=
    4021            3 :                             (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs +
    4022            3 :                              (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    4023            3 :                                   state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult +
    4024            3 :                               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) *
    4025            3 :                                  DividerThermAbs) *
    4026            3 :                             (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum));
    4027              :                     }
    4028              :                 } else {
    4029              :                     // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report
    4030         2369 :                     Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone
    4031         2369 :                     if (!state.dataGlobal->doLoadComponentPulseNow) {
    4032         2369 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    4033         2369 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad *
    4034         2369 :                             state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4035              :                     } else {
    4036              :                         // radiant value prior to adjustment for pulse for load component report
    4037            0 :                         Real64 const curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad;
    4038              :                         // for the loads component report during the special sizing run increase the radiant portion
    4039              :                         // a small amount to create a "pulse" of heat that is used for the
    4040              :                         // radiant value including adjustment for pulse for load component report
    4041            0 :                         Real64 const adjQL = curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler;
    4042              :                         // ITABSF is the Inside Thermal Absorptance
    4043              :                         // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure
    4044              :                         // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces
    4045            0 :                         state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) =
    4046            0 :                             adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult *
    4047            0 :                             state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4048              :                     }
    4049              :                     // Radiations absorbed by the window layers coming from zone side
    4050         2369 :                     int EQLNum = thisConstruct.EQLConsPtr;
    4051         8580 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4052         6211 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) +=
    4053         6211 :                             state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffBackEQL(Lay);
    4054              :                     }
    4055              :                     // Window frame has not been included for equivalent layer model yet
    4056              : 
    4057              :                 } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN
    4058              : 
    4059        88564 :                 if (surface.ExtBoundCond > 0) { // Interzone surface
    4060              :                     // Short-wave radiation absorbed in panes of corresponding window in adjacent zone
    4061            0 :                     int SurfNumAdjZone = surface.ExtBoundCond; // Surface number in adjacent zone for interzone surfaces
    4062            0 :                     if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != DataSurfaces::WindowModel::EQL) {
    4063            0 :                         int TotGlassLayers = thisConstruct.TotGlassLayers;
    4064            0 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4065            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) +=
    4066            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) *
    4067            0 :                                 state.dataConstruction->Construct(state.dataSurface->Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass);
    4068              :                             // Note that AbsDiff rather than AbsDiffBack is used in the above since the
    4069              :                             // radiation from the current zone is incident on the outside of the adjacent
    4070              :                             // zone's window.
    4071              :                         }
    4072              :                     } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN
    4073            0 :                         int const AdjConstrNum = state.dataSurface->Surface(SurfNumAdjZone).Construction;
    4074            0 :                         int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr;
    4075            0 :                         for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4076            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) +=
    4077            0 :                                 state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * thisConstruct.AbsDiffFrontEQL(Lay);
    4078              :                             // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above
    4079              :                             // since the radiation from the current zone is incident on the outside of the
    4080              :                             // adjacent zone's window.
    4081              :                         }
    4082              :                     }
    4083              :                 }
    4084              : 
    4085        88564 :                 if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) {
    4086        86195 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4087        86195 :                     int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers;
    4088        86195 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4089        86195 :                     if (DataSurfaces::NOT_SHADED(ShadeFlag)) { // No window shading
    4090       196685 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4091       110490 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4092              :                         }
    4093            0 :                     } else if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) { // Switchable glazing
    4094            0 :                         for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4095            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4096              :                         }
    4097              :                     } else {
    4098            0 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4099              :                         // Interior, exterior or between-glass shade, screen or blind in place
    4100            0 :                         for (int IGlass = 1; IGlass <= constructionSh.TotGlassLayers; ++IGlass) {
    4101            0 :                             state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4102              :                         }
    4103            0 :                         if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag) || DataSurfaces::ANY_BLIND(ShadeFlag)) {
    4104            0 :                             state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum);
    4105              :                         }
    4106              :                     } // End of shading flag check
    4107         2369 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::BSDF) {
    4108            0 :                     int TotGlassLayers = thisConstruct.TotGlassLayers;
    4109            0 :                     for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) {
    4110            0 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass);
    4111              :                     }
    4112         2369 :                 } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::EQL) {
    4113              : 
    4114              :                     // ConstrNum   = Surface(SurfNum)%Construction
    4115         2369 :                     int EQLNum = thisConstruct.EQLConsPtr;
    4116              : 
    4117         8580 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) {
    4118         6211 :                         state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay);
    4119              :                     }
    4120              :                 }
    4121              : 
    4122              :             } // End of window
    4123       336652 :         }
    4124              :     }
    4125       249958 :     Dayltg::DistributeTDDAbsorbedSolar(state);
    4126       249958 : }
    4127              : 
    4128       249957 : void ComputeIntThermalAbsorpFactors(EnergyPlusData &state)
    4129              : {
    4130              : 
    4131              :     // SUBROUTINE INFORMATION:
    4132              :     //       AUTHOR         Legacy Code (George Walton)
    4133              :     //       DATE WRITTEN   Legacy: Dec 1976
    4134              :     //       MODIFIED       Nov. 99, FCW: to take into account movable interior shades and switchable glazing
    4135              :     //                      June 01, FCW: to take into account interior blinds.
    4136              : 
    4137              :     // PURPOSE OF THIS SUBROUTINE:
    4138              :     // This routine computes the fractions of long-wave radiation from lights, equipment and people
    4139              :     // that is absorbed by each zone surface.
    4140              : 
    4141              :     // METHODOLOGY EMPLOYED:
    4142              :     // The fraction is assumed to be proportional to the product of the surface area times its thermal absorptivity.
    4143              : 
    4144              :     // REFERENCES:
    4145              :     // BLAST Routine: CITAF - Compute Interior Thermal Absorption Factors
    4146       249957 :     auto &s_mat = state.dataMaterial;
    4147              : 
    4148       602832 :     for (auto const &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    4149       352875 :         if (!thisEnclosure.radReCalc) {
    4150       342688 :             continue;
    4151              :         }
    4152        20424 :         for (int spaceNum : thisEnclosure.spaceNums) {
    4153        10237 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4154        10237 :             int const firstSurfWin = thisSpace.WindowSurfaceFirst;
    4155        10237 :             int const lastSurfWin = thisSpace.WindowSurfaceLast;
    4156        14173 :             for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) {
    4157         3936 :                 DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4158         3936 :                 if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4159            1 :                     auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4160            1 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
    4161              :                 } else {
    4162         3935 :                     int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    4163         3935 :                     state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal;
    4164              :                 }
    4165              :             }
    4166        10187 :         }
    4167       249957 :     }
    4168       249957 :     if (state.dataSurface->AnyMovableSlat) {
    4169            0 :         for (int SurfNum : state.dataHeatBalSurf->SurfMovSlatsIndexList) {
    4170              :             // For window with an interior shade or blind, emissivity is a combination of glass and shade/blind emissivity
    4171            0 :             DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4172              :             // Not sure we need to do this anymore
    4173            0 :             if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4174            0 :                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4175            0 :                 state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = surfShade.effShadeEmi + surfShade.effGlassEmi;
    4176              :             }
    4177            0 :         }
    4178              :     }
    4179              : 
    4180       602832 :     for (auto &thisRadEnclosure : state.dataViewFactor->EnclRadInfo) {
    4181       352875 :         if (!thisRadEnclosure.radReCalc) {
    4182       342688 :             continue;
    4183              :         }
    4184        10187 :         Real64 SUM1 = 0.0;
    4185        69403 :         for (int const SurfNum : thisRadEnclosure.SurfacePtr) {
    4186        59216 :             auto &surf = state.dataSurface->Surface(SurfNum);
    4187        59216 :             int const ConstrNum = surf.Construction;
    4188        59216 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4189        59216 :             DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4190        59216 :             if (ShadeFlag != DataSurfaces::WinShadingType::SwitchableGlazing) {
    4191        59216 :                 SUM1 += surf.Area * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum);
    4192              :             } else { // Switchable glazing
    4193            0 :                 SUM1 += surf.Area * Window::InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum),
    4194            0 :                                                      thisConstruct.InsideAbsorpThermal,
    4195            0 :                                                      state.dataConstruction->Construct(surf.activeShadedConstruction).InsideAbsorpThermal);
    4196              :             }
    4197              : 
    4198              :             // Window frame and divider effects
    4199        59216 :             if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
    4200            1 :                 SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) *
    4201            1 :                         state.dataSurface->SurfWinFrameEmis(SurfNum);
    4202              :             }
    4203        59216 :             if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    4204            1 :                 Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance
    4205              :                 // Suspended (between-glass) divider; relevant emissivity is inner glass emissivity
    4206            1 :                 if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    4207            0 :                     DividerThermAbs = thisConstruct.InsideAbsorpThermal;
    4208              :                 }
    4209            1 :                 if (DataSurfaces::ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4210              :                     // Interior shade or blind in place
    4211            0 :                     int const ConstrNumSh = surf.activeShadedConstruction;
    4212            0 :                     auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4213              : 
    4214            0 :                     if (state.dataSurface->SurfWinHasShadeOrBlindLayer(SurfNum)) {
    4215            0 :                         auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4216              :                         // Shade layer material number
    4217            0 :                         int MatNumSh = constructionSh.LayerPoint(constructionSh.TotLayers);
    4218            0 :                         auto const *matSh = dynamic_cast<Material::MaterialFen const *>(s_mat->materials(MatNumSh));
    4219            0 :                         assert(matSh != nullptr);
    4220              :                         // Shade or blind IR transmittance
    4221            0 :                         Real64 TauShIR = matSh->TransThermal;
    4222              :                         // Effective emissivity of shade or blind
    4223            0 :                         Real64 EffShDevEmiss = surfShade.effShadeEmi;
    4224              : 
    4225            0 :                         if (ShadeFlag == DataSurfaces::WinShadingType::IntBlind) {
    4226            0 :                             TauShIR = surfShade.blind.TAR.IR.Bk.Tra;
    4227              :                         }
    4228            0 :                         SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (EffShDevEmiss + DividerThermAbs * TauShIR);
    4229              :                     } else {
    4230              :                         // this is for EMS activated shade/blind but the window construction has no shade/blind layer
    4231            0 :                         SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    4232              :                                 DividerThermAbs;
    4233              :                     }
    4234              :                 } else {
    4235            1 :                     SUM1 +=
    4236            1 :                         state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * DividerThermAbs;
    4237              :                 }
    4238              :             }
    4239              : 
    4240              :         } // End of loop over surfaces in zone/enclosure
    4241        10187 :         thisRadEnclosure.radThermAbsMult = 1.0 / SUM1;
    4242              : 
    4243       249957 :     } // End of loop over enclosures
    4244       249957 : }
    4245              : 
    4246       249956 : void ComputeIntSWAbsorpFactors(EnergyPlusData &state)
    4247              : {
    4248              : 
    4249              :     // SUBROUTINE INFORMATION:
    4250              :     //       AUTHOR         Legacy (George Walton)
    4251              :     //       DATE WRITTEN   Legacy (December 1980)
    4252              :     //       MODIFIED       Nov. 99, FW; now called every time step to account for movable
    4253              :     //                      window shades and insulation
    4254              :     //                      Mar. 00, FW; change name from ComputeVisLightingAbsorpFactors
    4255              :     //                      to ComputeIntSWAbsorpFactors
    4256              :     //                      May 00, FW; add window frame and divider effects
    4257              :     //                      June 01, FW: account for window blinds
    4258              :     //                      Nov 01, FW: account for absorptance of exterior shades and interior or exterior blinds
    4259              :     //                      Jan 03, FW: add between-glass shade/blind
    4260              :     //                      May 06, RR: account for exterior window screens
    4261              : 
    4262              :     // PURPOSE OF THIS SUBROUTINE:
    4263              :     // Computes VMULT, the inverse of the sum of area*(short-wave absorptance+transmittance) for
    4264              :     // the surfaces in a zone. VMULT is used to calculate the zone interior diffuse short-wave radiation
    4265              :     // absorbed by the inside of opaque zone surfaces or by the glass and shade/blind layers of zone windows.
    4266              : 
    4267              :     // Sets VCONV to zero (VCONV was formerly used to calculate convective gain due to short-wave
    4268              :     // radiation absorbed by interior window shades).
    4269              : 
    4270              :     // REFERENCES:
    4271              :     // BLAST Routine - CIVAF - Compute Surface Absorption Factors For Short Wave Radiation
    4272              :     //                         From Zone Lights And Diffuse Solar.
    4273              : 
    4274              :     // Avoid a division by zero of the user has entered a bunch of surfaces with zero absorptivity on the inside
    4275       249956 :     Real64 constexpr SmallestAreaAbsProductAllowed(0.01);
    4276              : 
    4277       249956 :     auto &s_mat = state.dataMaterial;
    4278              : 
    4279       602830 :     for (auto &thisSolEnclosure : state.dataViewFactor->EnclSolInfo) {
    4280       352874 :         if (!thisSolEnclosure.radReCalc) {
    4281       342688 :             continue;
    4282              :         }
    4283        10186 :         Real64 SUM1 = 0.0; // Intermediate calculation value for solar absorbed and transmitted
    4284              : 
    4285        69401 :         for (int const SurfNum : thisSolEnclosure.SurfacePtr) {
    4286        59215 :             auto &thisSurf = state.dataSurface->Surface(SurfNum);
    4287        59215 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    4288        59215 :             auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    4289        59215 :             if (thisConstruct.TransDiff <= 0.0) {
    4290              :                 // Opaque surface
    4291        55342 :                 Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); // Inside surface short-wave absorptance
    4292        55342 :                 SUM1 += thisSurf.Area * AbsIntSurf;
    4293              : 
    4294              :             } else {
    4295              :                 // Window
    4296         3873 :                 if (!state.dataConstruction->Construct(thisSurf.Construction).WindowTypeEQL) {
    4297         1566 :                     DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum);
    4298              : 
    4299         1566 :                     Real64 AbsDiffTotWin = 0.0; // Sum of window layer short-wave absorptances
    4300         1566 :                     int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum);
    4301         1566 :                     Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum);
    4302              : 
    4303              :                     // Sum of absorptances of glass layers
    4304         3201 :                     for (int Lay = 1; Lay <= thisConstruct.TotGlassLayers; ++Lay) {
    4305         1635 :                         Real64 AbsDiffLayWin = thisConstruct.AbsDiffBack(Lay); // Window layer short-wave absorptance
    4306              : 
    4307              :                         // Window with shade, screen or blind
    4308         1635 :                         if (ConstrNumSh != 0) {
    4309           64 :                             auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4310           64 :                             if (DataSurfaces::ANY_SHADE_SCREEN(ShadeFlag)) {
    4311            0 :                                 AbsDiffLayWin = constrSh.AbsDiffBack(Lay);
    4312           64 :                             } else if (DataSurfaces::ANY_BLIND(ShadeFlag)) {
    4313            0 :                                 auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4314            0 :                                 auto const &dfAbsSlatLo = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxLo];
    4315            0 :                                 auto const &dfAbsSlatHi = constrSh.layerSlatBlindDfAbs(Lay)[surfShade.blind.slatAngIdxHi];
    4316            0 :                                 Real64 interpFac = surfShade.blind.slatAngInterpFac;
    4317            0 :                                 AbsDiffLayWin = Interp(dfAbsSlatLo.Sol.Bk.Df.Abs, dfAbsSlatHi.Sol.Bk.Df.Abs, interpFac);
    4318              :                             }
    4319              :                         }
    4320              : 
    4321              :                         // Switchable glazing
    4322         1635 :                         if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    4323            0 :                             assert(ConstrNumSh > 0); // Should this be included in the if above
    4324            0 :                             auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4325            0 :                             AbsDiffLayWin = Window::InterpSw(SwitchFac, AbsDiffLayWin, constrSh.AbsDiffBack(Lay));
    4326              :                         }
    4327         1635 :                         AbsDiffTotWin += AbsDiffLayWin;
    4328              :                     }
    4329              : 
    4330         1566 :                     Real64 TransDiffWin = thisConstruct.TransDiff; // Window diffuse short-wave transmittance
    4331         1566 :                     Real64 DiffAbsShade = 0.0;                     // Diffuse short-wave shade or blind absorptance
    4332              : 
    4333              :                     // Window with shade, screen or blind
    4334              : 
    4335         1566 :                     if (ConstrNumSh != 0) {
    4336           64 :                         auto const &constrSh = state.dataConstruction->Construct(ConstrNumSh);
    4337           64 :                         if (ANY_SHADE_SCREEN(ShadeFlag)) {
    4338            0 :                             TransDiffWin = constrSh.TransDiff;
    4339            0 :                             DiffAbsShade = constrSh.AbsDiffBackShade;
    4340           64 :                         } else if (ANY_BLIND(ShadeFlag)) {
    4341            0 :                             auto const &surfShade = state.dataSurface->surfShades(SurfNum);
    4342            0 :                             auto const &btarSlatLo = constrSh.blindTARs[surfShade.blind.slatAngIdxLo];
    4343            0 :                             auto const &btarSlatHi = constrSh.blindTARs[surfShade.blind.slatAngIdxHi];
    4344            0 :                             Real64 interpFac = surfShade.blind.slatAngInterpFac;
    4345            0 :                             TransDiffWin = Interp(btarSlatLo.Sol.Ft.Df.Tra, btarSlatHi.Sol.Ft.Df.Tra, interpFac);
    4346            0 :                             DiffAbsShade = Interp(btarSlatLo.Sol.Bk.Df.Abs, btarSlatHi.Sol.Bk.Df.Abs, interpFac);
    4347              :                         }
    4348              :                     }
    4349              : 
    4350              :                     // Switchable glazing
    4351              : 
    4352         1566 :                     if (ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    4353            0 :                         assert(ConstrNumSh > 0);
    4354            0 :                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    4355            0 :                         TransDiffWin = Window::InterpSw(SwitchFac, TransDiffWin, constructionSh.TransDiff);
    4356              :                     }
    4357              : 
    4358         1566 :                     SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin + DiffAbsShade);
    4359              : 
    4360              :                     // Window frame and divider effects (shade area is glazed area plus divider area)
    4361              : 
    4362         1566 :                     if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) {
    4363            1 :                         SUM1 += state.dataSurface->SurfWinFrameArea(SurfNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) *
    4364            1 :                                 (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum));
    4365              :                     }
    4366         1566 :                     if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) {
    4367            1 :                         Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance
    4368            1 :                         if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) {
    4369              :                             // Suspended (between-glass) divider: account for glass on inside of divider
    4370            0 :                             Real64 MatNumGl = thisConstruct.LayerPoint(thisConstruct.TotLayers); // Glass material number
    4371            0 :                             auto const *thisMaterial = dynamic_cast<const Material::MaterialGlass *>(s_mat->materials(MatNumGl));
    4372            0 :                             assert(thisMaterial != nullptr);
    4373            0 :                             Real64 TransGl = thisMaterial->Trans; // Glass layer short-wave transmittance, reflectance, absorptance
    4374            0 :                             Real64 ReflGl = thisMaterial->ReflectSolBeamBack;
    4375            0 :                             Real64 AbsGl = 1.0 - TransGl - ReflGl;
    4376            0 :                             Real64 DividerRefl = 1.0 - DividerAbs; // Window divider short-wave reflectance
    4377            0 :                             DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl);
    4378              :                         }
    4379            1 :                         if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) {
    4380            0 :                             SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (DividerAbs + DiffAbsShade);
    4381              :                         } else {
    4382            1 :                             SUM1 += state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) *
    4383              :                                     DividerAbs;
    4384              :                         }
    4385              :                     }
    4386              :                 } else { // equivalent layer window
    4387              :                     // In equivalent layer window solid layers (Glazing and shades) are treated equally
    4388              :                     // frames and dividers are not supported
    4389         2307 :                     Real64 AbsDiffTotWin = 0.0;
    4390         2307 :                     Real64 AbsDiffLayWin = 0.0;
    4391         2307 :                     Real64 TransDiffWin = thisConstruct.TransDiff;
    4392         8358 :                     for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL; ++Lay) {
    4393         6051 :                         AbsDiffLayWin = thisConstruct.AbsDiffBackEQL(Lay);
    4394         6051 :                         AbsDiffTotWin += AbsDiffLayWin;
    4395              :                     }
    4396         2307 :                     SUM1 += thisSurf.Area * (TransDiffWin + AbsDiffTotWin);
    4397              :                 }
    4398              :             } // End of check if opaque surface or window
    4399              :         } // End of loop over surfaces in zone
    4400              : 
    4401        10186 :         if (SUM1 > SmallestAreaAbsProductAllowed) { // Everything is okay, proceed with the regular calculation
    4402        10186 :             thisSolEnclosure.solVMULT = 1.0 / SUM1;
    4403              : 
    4404              :         } else { // the sum of area*solar absorptance for all surfaces in the zone is zero--either the user screwed up
    4405              :             // or they really want to disallow any solar from being absorbed on the inside surfaces.  Fire off a
    4406              :             // nasty warning message and then assume that no solar is ever absorbed (basically everything goes
    4407              :             // back out whatever window is there.  Note that this also assumes that the shade has no effect.
    4408              :             // That's probably not correct, but how correct is it to assume that no solar is absorbed anywhere
    4409              :             // in the zone?
    4410            0 :             if (thisSolEnclosure.solAbsFirstCalc) {
    4411            0 :                 ShowWarningError(
    4412              :                     state,
    4413            0 :                     format("ComputeIntSWAbsorbFactors: Sum of area times inside solar absorption for all surfaces is zero in Enclosure: {}",
    4414            0 :                            thisSolEnclosure.Name));
    4415            0 :                 thisSolEnclosure.solAbsFirstCalc = false;
    4416              :             }
    4417            0 :             thisSolEnclosure.solVMULT = 0.0;
    4418              :         }
    4419       249956 :     } // End of enclosure loop
    4420       249956 : }
    4421              : 
    4422            4 : void ComputeDifSolExcZonesWIZWindows(EnergyPlusData &state)
    4423              : {
    4424              : 
    4425              :     // SUBROUTINE INFORMATION:
    4426              :     //       MODIFIED       Jun 2007 - Lawrie - Speed enhancements.
    4427              :     //       RE-ENGINEERED  Winkelmann, Lawrie
    4428              : 
    4429              :     // PURPOSE OF THIS SUBROUTINE:
    4430              :     // This subroutine computes the diffuse solar exchange factors between enclosures with
    4431              :     // interzone windows.
    4432              : 
    4433            4 :     int const numEnclosures = state.dataViewFactor->NumOfSolarEnclosures;
    4434            4 :     if (!allocated(state.dataHeatBalSurf->ZoneFractDifShortZtoZ)) {
    4435            2 :         state.dataHeatBalSurf->ZoneFractDifShortZtoZ.allocate(numEnclosures, numEnclosures);
    4436            2 :         state.dataHeatBalSurf->EnclSolRecDifShortFromZ.allocate(numEnclosures);
    4437            2 :         state.dataHeatBalSurfMgr->DiffuseArray.allocate(numEnclosures, numEnclosures);
    4438              :     }
    4439              : 
    4440            4 :     state.dataHeatBalSurf->EnclSolRecDifShortFromZ = false;
    4441            4 :     state.dataHeatBalSurf->ZoneFractDifShortZtoZ.to_identity();
    4442            4 :     state.dataHeatBalSurfMgr->DiffuseArray.to_identity();
    4443              : 
    4444              :     //      IF (.not. ANY(Zone%HasInterZoneWindow)) RETURN  ! this caused massive diffs
    4445            4 :     if (state.dataGlobal->KickOffSimulation || state.dataGlobal->KickOffSizing) {
    4446            2 :         return;
    4447              :     }
    4448              :     //            Compute fraction transmitted in one pass.
    4449              : 
    4450            6 :     for (int const SurfNum : state.dataSurface->AllHTWindowSurfaceList) {
    4451            4 :         auto &surface = state.dataSurface->Surface(SurfNum);
    4452            4 :         if (surface.ExtBoundCond <= 0) {
    4453            0 :             continue;
    4454              :         }
    4455            4 :         if (surface.ExtBoundCond == SurfNum) {
    4456            0 :             continue;
    4457              :         }
    4458            4 :         if (state.dataConstruction->Construct(surface.Construction).TransDiff <= 0.0) {
    4459            0 :             continue;
    4460              :         }
    4461              : 
    4462            4 :         int surfEnclNum = surface.SolarEnclIndex;
    4463            4 :         if (!state.dataViewFactor->EnclSolInfo(surfEnclNum).HasInterZoneWindow) {
    4464            2 :             continue;
    4465              :         }
    4466            2 :         int MZ = state.dataSurface->Surface(surface.ExtBoundCond).SolarEnclIndex;
    4467            4 :         state.dataHeatBalSurf->ZoneFractDifShortZtoZ(surfEnclNum, MZ) += state.dataConstruction->Construct(surface.Construction).TransDiff *
    4468            2 :                                                                          state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT * surface.Area;
    4469            2 :         if (state.dataViewFactor->EnclSolInfo(surfEnclNum).solVMULT != 0.0) {
    4470            2 :             state.dataHeatBalSurf->EnclSolRecDifShortFromZ(surfEnclNum) = true;
    4471              :         }
    4472            2 :     }
    4473              :     //          Compute fractions for multiple passes.
    4474              : 
    4475            2 :     Array2D<Real64>::size_type l(0u), m(0u), d(0u);
    4476            8 :     for (int NZ = 1; NZ <= numEnclosures; ++NZ, d += numEnclosures + 1) {
    4477            6 :         m = NZ - 1;
    4478            6 :         Real64 D_d(0.0); // Local accumulator
    4479           24 :         for (int MZ = 1; MZ <= numEnclosures; ++MZ, ++l, m += numEnclosures) {
    4480           18 :             if (MZ == NZ) {
    4481            6 :                 continue;
    4482              :             }
    4483           12 :             state.dataHeatBalSurfMgr->DiffuseArray[l] =
    4484           12 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] /
    4485           24 :                 (1.0 - state.dataHeatBalSurf->ZoneFractDifShortZtoZ[l] *
    4486           12 :                            state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m]); // [ l ] == ( MZ, NZ ), [ m ] == ( NZ, MZ )
    4487           12 :             D_d += state.dataHeatBalSurf->ZoneFractDifShortZtoZ[m] * state.dataHeatBalSurfMgr->DiffuseArray[l];
    4488              :         }
    4489            6 :         state.dataHeatBalSurfMgr->DiffuseArray[d] += D_d; // [ d ] == ( NZ, NZ )
    4490              :     }
    4491              : 
    4492            2 :     state.dataHeatBalSurf->ZoneFractDifShortZtoZ = state.dataHeatBalSurfMgr->DiffuseArray;
    4493              :     // added for CR 7999 & 7869
    4494            2 :     assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize1() == numEnclosures);
    4495            2 :     assert(state.dataHeatBalSurf->ZoneFractDifShortZtoZ.isize2() == numEnclosures);
    4496            8 :     for (int NZ = 1; NZ <= numEnclosures; ++NZ) {
    4497           19 :         for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
    4498           15 :             if (MZ == NZ) {
    4499            5 :                 continue;
    4500              :             }
    4501           10 :             if (state.dataHeatBalSurf->ZoneFractDifShortZtoZ(MZ, NZ) > 0.0) {
    4502            2 :                 state.dataHeatBalSurf->EnclSolRecDifShortFromZ(NZ) = true;
    4503            2 :                 break;
    4504              :             }
    4505              :         }
    4506              :     }
    4507              : 
    4508              :     //           Compute fractions for multiple zones.
    4509              : 
    4510            8 :     for (int IZ = 1; IZ <= numEnclosures; ++IZ) {
    4511            6 :         if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(IZ)) {
    4512            4 :             continue;
    4513              :         }
    4514              : 
    4515            8 :         for (int JZ = 1; JZ <= numEnclosures; ++JZ) {
    4516            6 :             if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(JZ)) {
    4517            2 :                 continue;
    4518              :             }
    4519            4 :             if (IZ == JZ) {
    4520            2 :                 continue;
    4521              :             }
    4522            2 :             if (state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ) == 0.0) {
    4523            0 :                 continue;
    4524              :             }
    4525              : 
    4526            8 :             for (int KZ = 1; KZ <= numEnclosures; ++KZ) {
    4527            6 :                 if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(KZ)) {
    4528            2 :                     continue;
    4529              :                 }
    4530            4 :                 if (IZ == KZ) {
    4531            2 :                     continue;
    4532              :                 }
    4533            2 :                 if (JZ == KZ) {
    4534            2 :                     continue;
    4535              :                 }
    4536            0 :                 if (state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) == 0.0) {
    4537            0 :                     continue;
    4538              :                 }
    4539            0 :                 state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, KZ) +=
    4540            0 :                     state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4541              : 
    4542            0 :                 for (int LZ = 1; LZ <= numEnclosures; ++LZ) {
    4543            0 :                     if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(LZ)) {
    4544            0 :                         continue;
    4545              :                     }
    4546            0 :                     if (IZ == LZ) {
    4547            0 :                         continue;
    4548              :                     }
    4549            0 :                     if (JZ == LZ) {
    4550            0 :                         continue;
    4551              :                     }
    4552            0 :                     if (KZ == LZ) {
    4553            0 :                         continue;
    4554              :                     }
    4555            0 :                     if (state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) == 0.0) {
    4556            0 :                         continue;
    4557              :                     }
    4558            0 :                     state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, LZ) += state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
    4559            0 :                                                                             state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) *
    4560            0 :                                                                             state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4561              : 
    4562            0 :                     for (int MZ = 1; MZ <= numEnclosures; ++MZ) {
    4563            0 :                         if (!state.dataHeatBalSurf->EnclSolRecDifShortFromZ(MZ)) {
    4564            0 :                             continue;
    4565              :                         }
    4566            0 :                         if (IZ == MZ) {
    4567            0 :                             continue;
    4568              :                         }
    4569            0 :                         if (JZ == MZ) {
    4570            0 :                             continue;
    4571              :                         }
    4572            0 :                         if (KZ == MZ) {
    4573            0 :                             continue;
    4574              :                         }
    4575            0 :                         if (LZ == MZ) {
    4576            0 :                             continue;
    4577              :                         }
    4578            0 :                         if (state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) == 0.0) {
    4579            0 :                             continue;
    4580              :                         }
    4581            0 :                         state.dataHeatBalSurf->ZoneFractDifShortZtoZ(IZ, MZ) +=
    4582            0 :                             state.dataHeatBalSurfMgr->DiffuseArray(LZ, MZ) * state.dataHeatBalSurfMgr->DiffuseArray(KZ, LZ) *
    4583            0 :                             state.dataHeatBalSurfMgr->DiffuseArray(JZ, KZ) * state.dataHeatBalSurfMgr->DiffuseArray(IZ, JZ);
    4584              :                     } // MZ Loop
    4585              : 
    4586              :                 } // LZ Loop
    4587              : 
    4588              :             } // KZ Loop
    4589              : 
    4590              :         } // JZ Loop
    4591              : 
    4592              :     } // IZ Loop
    4593              : } // ComputeDifSolExcZoneWIZWindows()
    4594              : 
    4595       116073 : void InitEMSControlledSurfaceProperties(EnergyPlusData &state)
    4596              : {
    4597              : 
    4598              :     // SUBROUTINE INFORMATION:
    4599              :     //       AUTHOR         B. Griffith
    4600              :     //       DATE WRITTEN   April 2011
    4601              : 
    4602              :     // PURPOSE OF THIS SUBROUTINE:
    4603              :     // initialize material and construction surface properties if being overridden by EMS
    4604              : 
    4605              :     // METHODOLOGY EMPLOYED:
    4606              :     // update solar, thermal and visible absorptance values when actuated by EMS
    4607              : 
    4608              :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    4609              :     int TotLayers;       // count of material layers in a construction
    4610              :     int InsideMaterNum;  // integer pointer for inside face's material layer
    4611              :     int OutsideMaterNum; // integer pointer for outside face's material layer
    4612              : 
    4613       116073 :     auto &s_mat = state.dataMaterial;
    4614              : 
    4615       116073 :     state.dataGlobal->AnySurfPropOverridesInModel = false;
    4616              :     // first determine if anything needs to be done, once yes, then always init
    4617       736781 :     for (auto const *mat : s_mat->materials) {
    4618       620708 :         if (mat->group != Material::Group::Regular) {
    4619         7431 :             continue;
    4620              :         }
    4621              : 
    4622       613277 :         if ((mat->AbsorpSolarEMSOverrideOn) || (mat->AbsorpThermalEMSOverrideOn) || (mat->AbsorpVisibleEMSOverrideOn)) {
    4623            0 :             state.dataGlobal->AnySurfPropOverridesInModel = true;
    4624            0 :             break;
    4625              :         }
    4626              :     }
    4627              : 
    4628       116073 :     if (!state.dataGlobal->AnySurfPropOverridesInModel) {
    4629       116073 :         return; // quick return if nothing has ever needed to be done
    4630              :     }
    4631              : 
    4632              :     // first, loop over materials
    4633              :     // why is this a second loop?
    4634            0 :     for (auto *mat : s_mat->materials) {
    4635            0 :         if (mat->group != Material::Group::Regular) {
    4636            0 :             continue;
    4637              :         }
    4638              : 
    4639            0 :         mat->AbsorpSolar = mat->AbsorpSolarEMSOverrideOn ? max(min(mat->AbsorpSolarEMSOverride, 0.9999), 0.0001) : mat->AbsorpSolarInput;
    4640            0 :         mat->AbsorpThermal = mat->AbsorpThermalEMSOverrideOn ? max(min(mat->AbsorpThermalEMSOverride, 0.9999), 0.0001) : mat->AbsorpThermalInput;
    4641            0 :         mat->AbsorpVisible = mat->AbsorpVisibleEMSOverrideOn ? max(min(mat->AbsorpVisibleEMSOverride, 0.9999), 0.0001) : mat->AbsorpVisibleInput;
    4642              :     } // loop over materials
    4643              : 
    4644              :     // second, loop over constructions
    4645            0 :     for (auto &thisConstruct : state.dataConstruction->Construct) {
    4646            0 :         if (thisConstruct.TypeIsWindow) {
    4647            0 :             continue; // only override opaque constructions
    4648              :         }
    4649            0 :         TotLayers = thisConstruct.TotLayers;
    4650            0 :         if (TotLayers == 0) {
    4651            0 :             continue; // error condition
    4652              :         }
    4653            0 :         InsideMaterNum = thisConstruct.LayerPoint(TotLayers);
    4654            0 :         if (InsideMaterNum != 0) {
    4655            0 :             auto const *mat = s_mat->materials(InsideMaterNum);
    4656            0 :             thisConstruct.InsideAbsorpVis = mat->AbsorpVisible;
    4657            0 :             thisConstruct.InsideAbsorpSolar = mat->AbsorpSolar;
    4658            0 :             thisConstruct.InsideAbsorpThermal = mat->AbsorpThermal;
    4659              :         }
    4660              : 
    4661            0 :         OutsideMaterNum = thisConstruct.LayerPoint(1);
    4662            0 :         if (OutsideMaterNum != 0) {
    4663            0 :             auto const *mat = s_mat->materials(OutsideMaterNum);
    4664            0 :             thisConstruct.OutsideAbsorpVis = mat->AbsorpVisible;
    4665            0 :             thisConstruct.OutsideAbsorpSolar = mat->AbsorpSolar;
    4666            0 :             thisConstruct.OutsideAbsorpThermal = mat->AbsorpThermal;
    4667              :         }
    4668              :     } // for (ConstrNum)
    4669              : } // InitEMSControlledSurfaceProperties()
    4670              : 
    4671       116073 : void InitEMSControlledConstructions(EnergyPlusData &state)
    4672              : {
    4673              : 
    4674              :     // SUBROUTINE INFORMATION:
    4675              :     //       AUTHOR         B. Griffith
    4676              :     //       DATE WRITTEN   Jan 2012
    4677              : 
    4678              :     // PURPOSE OF THIS SUBROUTINE:
    4679              :     // change construction on surface if overridden by EMS
    4680              : 
    4681       116073 :     state.dataGlobal->AnyConstrOverridesInModel = false;
    4682       854204 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4683       745241 :         if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum)) {
    4684         7110 :             state.dataGlobal->AnyConstrOverridesInModel = true;
    4685         7110 :             break;
    4686              :         }
    4687              :     }
    4688       116073 :     if (!state.dataGlobal->AnyConstrOverridesInModel) {
    4689       108963 :         return;
    4690              :     }
    4691              : 
    4692        45714 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    4693        38604 :         auto &surface = state.dataSurface->Surface(SurfNum);
    4694              : 
    4695        38604 :         if (state.dataSurface->SurfEMSConstructionOverrideON(SurfNum) && (state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum) > 0)) {
    4696              : 
    4697         7110 :             if (state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
    4698         7110 :                     .TypeIsWindow) { // okay, always allow windows
    4699         1352 :                 state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
    4700         1352 :                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) = true;
    4701              :             }
    4702              : 
    4703        14216 :             if ((state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) &&
    4704         7106 :                 (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum))) {
    4705              : 
    4706         7106 :                 surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4707         7106 :                 state.dataConstruction->Construct(surface.Construction).IsUsed = true;
    4708         7106 :                 state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4709              : 
    4710              :             } else { // have not checked yet or is not okay, so see if we need to warn about incompatible
    4711            4 :                 if (!state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum)) {
    4712              :                     // check if constructions appear compatible
    4713              : 
    4714            4 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    4715            0 :                         surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    4716              :                         // compare old construction to new construction and see if terms match
    4717              :                         // set as okay and turn false if find a big problem
    4718            4 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4719              :                             true;
    4720            4 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4721              :                             true;
    4722            4 :                         if (state.dataConstruction->Construct(surface.Construction).NumHistories !=
    4723            4 :                             state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories) {
    4724              :                             // throw warning, but allow
    4725            0 :                             ShowWarningError(state,
    4726              :                                              "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
    4727              :                                              "CTF timescales are being used.");
    4728            0 :                             ShowContinueError(state,
    4729            0 :                                               format("Construction named = {} has CTF timesteps = {}",
    4730            0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4731            0 :                                                      state.dataConstruction->Construct(surface.Construction).NumHistories));
    4732            0 :                             ShowContinueError(
    4733              :                                 state,
    4734            0 :                                 format("While construction named = {} has CTF timesteps = {}",
    4735            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4736            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumHistories));
    4737            0 :                             ShowContinueError(
    4738              :                                 state,
    4739            0 :                                 format("Transient heat transfer modeling may not be valid for surface name = {}, and the simulation continues",
    4740            0 :                                        surface.Name));
    4741              :                         }
    4742            4 :                         if (state.dataConstruction->Construct(surface.Construction).NumCTFTerms !=
    4743            4 :                             state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms) {
    4744              :                             // throw warning, but allow
    4745            4 :                             ShowWarningError(state,
    4746              :                                              "InitEMSControlledConstructions: EMS Construction State Actuator may be unrealistic, incompatible "
    4747              :                                              "CTF terms are being used.");
    4748            4 :                             ShowContinueError(state,
    4749            4 :                                               format("Construction named = {} has number of CTF terms = {}",
    4750            2 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4751            2 :                                                      state.dataConstruction->Construct(surface.Construction).NumCTFTerms));
    4752            4 :                             ShowContinueError(
    4753              :                                 state,
    4754            4 :                                 format("While construction named = {} has number of CTF terms = {}",
    4755            2 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4756            2 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).NumCTFTerms));
    4757            4 :                             ShowContinueError(state,
    4758            4 :                                               format("The actuator is allowed but the transient heat transfer modeling may not be valid for surface "
    4759              :                                                      "name = {}, and the simulation continues",
    4760            2 :                                                      surface.Name));
    4761              :                         }
    4762              : 
    4763            4 :                         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    4764            0 :                             if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
    4765              :                                 // throw warning, and do not allow
    4766            0 :                                 ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4767            0 :                                 ShowContinueError(state,
    4768            0 :                                                   format("Construction named = {} has internal source/sink",
    4769            0 :                                                          state.dataConstruction->Construct(surface.Construction).Name));
    4770            0 :                                 ShowContinueError(
    4771              :                                     state,
    4772            0 :                                     format("While construction named = {} is not an internal source/sink construction",
    4773            0 :                                            state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
    4774            0 :                                 ShowContinueError(
    4775              :                                     state,
    4776            0 :                                     format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4777            0 :                                            surface.Name));
    4778              : 
    4779            0 :                                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4780            0 :                                                                                   SurfNum) = false;
    4781              :                             }
    4782              :                         }
    4783              : 
    4784            8 :                         if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4785              :                                                                               SurfNum)) {
    4786            4 :                             surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4787              :                         }
    4788              : 
    4789            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    4790            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4791              :                             true;
    4792            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4793              :                             true;
    4794            0 :                         if (state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes !=
    4795            0 :                             state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).TotNodes) {
    4796              :                             // throw warning, and do not allow
    4797            0 :                             ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4798            0 :                             ShowContinueError(state,
    4799            0 :                                               format("Construction named = {} has number of finite difference nodes ={}",
    4800            0 :                                                      state.dataConstruction->Construct(surface.Construction).Name,
    4801            0 :                                                      state.dataHeatBalFiniteDiffMgr->ConstructFD(surface.Construction).TotNodes));
    4802            0 :                             ShowContinueError(
    4803              :                                 state,
    4804            0 :                                 format("While construction named = {}has number of finite difference nodes ={}",
    4805            0 :                                        state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name,
    4806            0 :                                        state.dataHeatBalFiniteDiffMgr->ConstructFD(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum))
    4807            0 :                                            .TotNodes));
    4808            0 :                             ShowContinueError(
    4809              :                                 state,
    4810            0 :                                 format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4811            0 :                                        surface.Name));
    4812              : 
    4813            0 :                             state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4814              :                                 false;
    4815              :                         }
    4816              : 
    4817            0 :                         if (state.dataConstruction->Construct(surface.Construction).SourceSinkPresent) {
    4818            0 :                             if (!state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).SourceSinkPresent) {
    4819              :                                 // throw warning, and do not allow
    4820            0 :                                 ShowSevereError(state, "InitEMSControlledConstructions: EMS Construction State Actuator not valid.");
    4821            0 :                                 ShowContinueError(state,
    4822            0 :                                                   format("Construction named = {} has internal source/sink",
    4823            0 :                                                          state.dataConstruction->Construct(surface.Construction).Name));
    4824            0 :                                 ShowContinueError(
    4825              :                                     state,
    4826            0 :                                     format("While construction named = {} is not an internal source/sink construction",
    4827            0 :                                            state.dataConstruction->Construct(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum)).Name));
    4828            0 :                                 ShowContinueError(
    4829              :                                     state,
    4830            0 :                                     format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4831            0 :                                            surface.Name));
    4832              : 
    4833            0 :                                 state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4834            0 :                                                                                   SurfNum) = false;
    4835              :                             }
    4836              :                         }
    4837              : 
    4838            0 :                         if (state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum),
    4839              :                                                                               SurfNum)) {
    4840            0 :                             surface.Construction = state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum);
    4841              :                         }
    4842              : 
    4843            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { // don't allow
    4844            0 :                         ShowSevereError(state,
    4845              :                                         "InitEMSControlledConstructions: EMS Construction State Actuator not available with Heat transfer "
    4846              :                                         "algorithm CombinedHeatAndMoistureFiniteElement.");
    4847            0 :                         ShowContinueError(
    4848              :                             state,
    4849            0 :                             format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4850            0 :                                    surface.Name));
    4851            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4852              :                             true;
    4853            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4854              :                             false;
    4855              : 
    4856            0 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) { // don't allow
    4857            0 :                         ShowSevereError(state,
    4858              :                                         "InitEMSControlledConstructions: EMS Construction State Actuator not available for Surfaces with "
    4859              :                                         "Foundation Outside Boundary Condition.");
    4860            0 :                         ShowContinueError(
    4861              :                             state,
    4862            0 :                             format("This actuator is not allowed for surface name = {}, and the simulation continues without the override",
    4863            0 :                                    surface.Name));
    4864            0 :                         state.dataRuntimeLang->EMSConstructActuatorChecked(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4865              :                             true;
    4866            0 :                         state.dataRuntimeLang->EMSConstructActuatorIsOkay(state.dataSurface->SurfEMSConstructionOverrideValue(SurfNum), SurfNum) =
    4867              :                             false;
    4868              :                     }
    4869              : 
    4870              :                 } else {
    4871              :                     // do nothing, has been checked and is not okay with single warning already issued.
    4872              :                 }
    4873              :             }
    4874              :         } else {
    4875        31494 :             surface.Construction = surface.ConstructionStoredInputValue;
    4876        31494 :             state.dataSurface->SurfActiveConstruction(SurfNum) = surface.ConstructionStoredInputValue;
    4877              :         }
    4878              :     } // for (SurfNum)
    4879              : } // InitEMSControlledConstructions()
    4880              : 
    4881              : // End Initialization Section of the Module
    4882              : //******************************************************************************
    4883              : 
    4884              : // Begin Algorithm Section of the Module
    4885              : //******************************************************************************
    4886              : 
    4887              : // Beginning of Record Keeping subroutines for the HB Module
    4888              : // *****************************************************************************
    4889              : 
    4890       249967 : void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
    4891              : {
    4892       249967 :     int firstZone = 1;
    4893       249967 :     int lastZone = state.dataGlobal->NumOfZones;
    4894              : 
    4895       249967 :     if (present(ZoneToResimulate)) {
    4896            8 :         firstZone = ZoneToResimulate;
    4897            8 :         lastZone = ZoneToResimulate;
    4898              :     }
    4899              : 
    4900       586629 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4901       706951 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4902       370289 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4903       370289 :             int const firstSurf = thisSpace.WindowSurfaceFirst;
    4904       370289 :             int const lastSurf = thisSpace.WindowSurfaceLast;
    4905       458851 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4906        88562 :                 if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss
    4907        88560 :                     state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum);
    4908              :                 }
    4909              :             }
    4910              :             // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport)
    4911       370289 :             if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) {
    4912       338968 :                 state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum);
    4913       338968 :                 state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) =
    4914       338968 :                     state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    4915              :             } else {
    4916        31321 :                 state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum);
    4917        31321 :                 state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) =
    4918        31321 :                     state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    4919              :             }
    4920       336662 :         }
    4921              :     }
    4922              : 
    4923       249967 :     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    4924            0 :         UpdateNonRepresentativeSurfaceResults(state, ZoneToResimulate);
    4925              :     }
    4926              : 
    4927              :     // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.)
    4928       586629 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4929       706951 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4930       370289 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4931       370289 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    4932       370289 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    4933      2439226 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4934      2068937 :                 state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) =
    4935      2068937 :                     -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
    4936      2068937 :                     (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    4937              :             }
    4938       336662 :         }
    4939              :     }
    4940              :     // Opaque surfaces
    4941       586629 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4942       706951 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4943       370289 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4944       370289 :             int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    4945       370289 :             int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    4946      2350668 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4947      1980379 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) =
    4948      1980379 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum);
    4949              :             }
    4950       336662 :         }
    4951              :     }
    4952              :     // Inside face conduction calculation for Kiva surfaces
    4953       249968 :     for (int surfNum : state.dataSurface->AllHTKivaSurfaceList) {
    4954            1 :         state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) =
    4955            1 :             -(state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    4956            1 :               state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    4957            1 :               state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum));
    4958       249967 :     }
    4959       249967 : }
    4960              : 
    4961            0 : void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, ObjexxFCL::Optional_int_const ZoneToResimulate)
    4962              : {
    4963            0 :     int firstZone = 1;
    4964            0 :     int lastZone = state.dataGlobal->NumOfZones;
    4965              : 
    4966            0 :     if (present(ZoneToResimulate)) {
    4967            0 :         firstZone = ZoneToResimulate;
    4968            0 :         lastZone = ZoneToResimulate;
    4969              :     }
    4970              : 
    4971            0 :     for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) {
    4972            0 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    4973            0 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    4974              :             // Heat transfer surfaces
    4975            0 :             int firstSurf = thisSpace.HTSurfaceFirst;
    4976            0 :             int lastSurf = thisSpace.HTSurfaceLast;
    4977            0 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    4978            0 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    4979            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    4980              : 
    4981            0 :                 if (surfNum != repSurfNum) {
    4982              : #if 0
    4983              :                 // Check for divergence
    4984              :                 Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) *
    4985              :                                   (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    4986              :                 Real64 repSurfConv = -state.dataHeatBalSurf->SurfHConvInt(repSurfNum) *
    4987              :                                      (state.dataHeatBalSurf->SurfTempIn(repSurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum));
    4988              :                 Real64 diff = surfConv - repSurfConv;
    4989              :                 if (std::abs(diff) > 3.0 && state.dataSurface->Surface(repSurfNum).ConstituentSurfaceNums.size() == 2) {
    4990              :                     ShowWarningError(state, format("Difference in representative surface convection {:.3R} W/m2", diff));
    4991              :                     ShowContinueErrorTimeStamp(state, "");
    4992              :                     ShowContinueError(state, format("  Original Surface: {}", surface.Name));
    4993              :                     ShowContinueError(state, format("    Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(surfNum)));
    4994              :                     ShowContinueError(state,
    4995              :                                       format("    Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(surfNum)));
    4996              :                     ShowContinueError(state,
    4997              :                                       format("    Sunlit fraction: {:.3R}",
    4998              :                                              state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum)));
    4999              :                     ShowContinueError(state, format("    Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum)));
    5000              :                     ShowContinueError(state,
    5001              :                                       format("    Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(surfNum)));
    5002              :                     ShowContinueError(state, format("  Representative Surface: {}", state.dataSurface->Surface(repSurfNum).Name));
    5003              :                     ShowContinueError(state, format("    Inside surface temperature: {:.3R} C", state.dataHeatBalSurf->SurfTempIn(repSurfNum)));
    5004              :                     ShowContinueError(state,
    5005              :                                       format("    Inside convection coefficient: {:.3R} W/m2-K", state.dataHeatBalSurf->SurfHConvInt(repSurfNum)));
    5006              :                     ShowContinueError(state,
    5007              :                                       format("    Sunlit fraction: {:.3R}",
    5008              :                                              state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, repSurfNum)));
    5009              :                     ShowContinueError(state,
    5010              :                                       format("    Outside absorbed solar: {:.3R} W/m2", state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum)));
    5011              :                     ShowContinueError(
    5012              :                         state, format("    Outside long wave radiation: {:.3R} W/m2", state.dataHeatBalSurf->QdotRadOutRepPerArea(repSurfNum)));
    5013              :                 }
    5014              : #endif
    5015              : 
    5016              :                     // Surface Heat Balance Arrays
    5017            0 :                     state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum);
    5018            0 :                     state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum);
    5019            0 :                     state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum);
    5020            0 :                     state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum);
    5021            0 :                     state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum);
    5022            0 :                     state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum);
    5023            0 :                     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum);
    5024              : 
    5025            0 :                     state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum);
    5026            0 :                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvExt(repSurfNum);
    5027            0 :                     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum);
    5028            0 :                     state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum);
    5029            0 :                     state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum);
    5030            0 :                     state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum);
    5031              : 
    5032            0 :                     state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum);
    5033            0 :                     if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) {
    5034            0 :                         state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)];
    5035              :                     }
    5036              : 
    5037            0 :                     state.dataSurface->surfExtConv(surfNum).hfModelEq = state.dataSurface->surfExtConv(repSurfNum).hfModelEq;
    5038            0 :                     state.dataSurface->surfExtConv(surfNum).hnModelEq = state.dataSurface->surfExtConv(repSurfNum).hnModelEq;
    5039              : 
    5040            0 :                     state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    5041            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum);
    5042            0 :                     state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) =
    5043            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum);
    5044              : 
    5045              :                     // Internal (non reporting variables)
    5046            0 :                     state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum);
    5047            0 :                     state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum);
    5048              :                 }
    5049              :             }
    5050              : 
    5051              :             // Opaque surfaces
    5052            0 :             firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    5053            0 :             lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    5054            0 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    5055            0 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    5056            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    5057              : 
    5058            0 :                 if (surfNum != repSurfNum) {
    5059              :                     // Surface Heat Balance Arrays
    5060            0 :                     state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum);
    5061            0 :                     state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum);
    5062            0 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum);
    5063              :                 }
    5064              :             }
    5065              : 
    5066              :             // Window surfaces
    5067            0 :             firstSurf = thisSpace.WindowSurfaceFirst;
    5068            0 :             lastSurf = thisSpace.WindowSurfaceLast;
    5069            0 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    5070            0 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    5071            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    5072              : 
    5073            0 :                 if (surfNum != repSurfNum) {
    5074            0 :                     Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
    5075              : 
    5076              :                     // Glazing
    5077            0 :                     state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    5078            0 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
    5079            0 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
    5080              : 
    5081              :                     // Frame
    5082            0 :                     Real64 frameHeatGain = 0.0;
    5083            0 :                     if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) {
    5084            0 :                         Real64 frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum);
    5085            0 :                         state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio;
    5086            0 :                         state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio;
    5087            0 :                         state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum);
    5088            0 :                         state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum);
    5089            0 :                         frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum);
    5090              :                     }
    5091              : 
    5092              :                     // Divider
    5093            0 :                     Real64 dividerHeatGain = 0.0;
    5094            0 :                     if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) {
    5095            0 :                         Real64 dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum);
    5096            0 :                         state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio;
    5097            0 :                         state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio;
    5098            0 :                         state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum);
    5099            0 :                         state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum);
    5100            0 :                         dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum);
    5101              :                     }
    5102              : 
    5103            0 :                     state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain;
    5104              : 
    5105              :                     // Whole window
    5106            0 :                     state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) -
    5107            0 :                                                                    state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) +
    5108            0 :                                                                   state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum);
    5109              :                 }
    5110              :             }
    5111            0 :         }
    5112              :     }
    5113            0 : }
    5114              : 
    5115       249945 : void UpdateFinalSurfaceHeatBalance(EnergyPlusData &state)
    5116              : {
    5117              : 
    5118              :     // SUBROUTINE INFORMATION:
    5119              :     //       AUTHOR         Rick Strand
    5120              :     //       DATE WRITTEN   December 2000
    5121              : 
    5122              :     // PURPOSE OF THIS SUBROUTINE:
    5123              :     // If a radiant system is present and was on for part of the time step,
    5124              :     // then we probably need to make yet another pass through the heat balance.
    5125              :     // This is necessary because the heat source/sink to the surface that is
    5126              :     // the radiant system may have varied during the system time steps.
    5127              : 
    5128              :     // METHODOLOGY EMPLOYED:
    5129              :     // First, determine whether or not the radiant system was running.  If
    5130              :     // any of the Qsource terms are non-zero, then it was running.  Then,
    5131              :     // update the current source terms with the "average" value calculated
    5132              :     // by the radiant system algorithm.  This requires the "USE" of the
    5133              :     // radiant algorithm module.  Finally, using this source value, redo
    5134              :     // the inside and outside heat balances.
    5135              : 
    5136              :     bool LowTempRadSysOn;     // .TRUE. if a low temperature radiant system is running
    5137              :     bool HighTempRadSysOn;    // .TRUE. if a high temperature radiant system is running
    5138              :     bool HWBaseboardSysOn;    // .TRUE. if a water baseboard heater is running
    5139              :     bool SteamBaseboardSysOn; // .TRUE. if a steam baseboard heater is running
    5140              :     bool ElecBaseboardSysOn;  // .TRUE. if a steam baseboard heater is running
    5141              :     bool CoolingPanelSysOn;   // true if a simple cooling panel is running
    5142              :     bool SwimmingPoolOn;      // true if a pool is present (running)
    5143              : 
    5144       249945 :     LowTempRadiantSystem::UpdateRadSysSourceValAvg(state, LowTempRadSysOn);
    5145       249945 :     HighTempRadiantSystem::UpdateHTRadSourceValAvg(state, HighTempRadSysOn);
    5146       249945 :     HWBaseboardRadiator::UpdateBBRadSourceValAvg(state, HWBaseboardSysOn);
    5147       249945 :     SteamBaseboardRadiator::UpdateBBSteamRadSourceValAvg(state, SteamBaseboardSysOn);
    5148       249945 :     ElectricBaseboardRadiator::UpdateBBElecRadSourceValAvg(state, ElecBaseboardSysOn);
    5149       249945 :     CoolingPanelSimple::UpdateCoolingPanelSourceValAvg(state, CoolingPanelSysOn);
    5150       249945 :     SwimmingPool::UpdatePoolSourceValAvg(state, SwimmingPoolOn);
    5151              : 
    5152       249945 :     if (LowTempRadSysOn || HighTempRadSysOn || HWBaseboardSysOn || SteamBaseboardSysOn || ElecBaseboardSysOn || CoolingPanelSysOn || SwimmingPoolOn) {
    5153              :         // Solve the zone heat balance 'Detailed' solution
    5154              :         // Call the outside and inside surface heat balances
    5155            4 :         CalcHeatBalanceOutsideSurf(state);
    5156            4 :         CalcHeatBalanceInsideSurf(state);
    5157              :     }
    5158       249945 : }
    5159              : 
    5160       200977 : void UpdateThermalHistories(EnergyPlusData &state)
    5161              : {
    5162              : 
    5163              :     // SUBROUTINE INFORMATION:
    5164              :     //       AUTHOR         Russ Taylor
    5165              :     //       DATE WRITTEN   June 1990
    5166              :     //       RE-ENGINEERED  Mar98 (RKS)
    5167              : 
    5168              :     // PURPOSE OF THIS SUBROUTINE:
    5169              :     // This subroutine updates and shifts the thermal and flux histories.
    5170              : 
    5171              :     // METHODOLOGY EMPLOYED:
    5172              :     // If a surface runs on the user selected subhourly time step, then the
    5173              :     // history terms for the temperatures and fluxes must simply be updated
    5174              :     // and shifted.  However, if the surface runs at a different (longer) time
    5175              :     // step, then the "master" history series is used for the interpolated
    5176              :     // update scheme.
    5177              : 
    5178              :     // REFERENCES:
    5179              :     // (I)BLAST legacy routine UTHRMH
    5180              :     // Taylor et.al., Impact of Simultaneous Simulation of Buildings and
    5181              :     // Mechanical Systems in Heat Balance Based Energy Analysis Programs
    5182              :     // on System Response and Control, Building Simulation '91, IBPSA, Nice, France.
    5183              : 
    5184       200977 :     if (state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag) {
    5185          103 :         state.dataHeatBalSurfMgr->QExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5186          103 :         state.dataHeatBalSurfMgr->QInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5187          103 :         state.dataHeatBalSurfMgr->TempInt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5188          103 :         state.dataHeatBalSurfMgr->TempExt1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5189          103 :         state.dataHeatBalSurfMgr->SumTime.dimension(state.dataSurface->TotSurfaces, 0.0);
    5190          103 :         if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5191            1 :             state.dataHeatBalSurfMgr->Qsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5192            1 :             state.dataHeatBalSurfMgr->Tsrc1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5193            1 :             state.dataHeatBalSurfMgr->Tuser1.dimension(state.dataSurface->TotSurfaces, 0.0);
    5194              :         }
    5195          103 :         state.dataHeatBalSurfMgr->UpdateThermalHistoriesFirstTimeFlag = false;
    5196              :     }
    5197              : 
    5198       488650 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5199       608949 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5200       321276 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5201       321276 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5202       321276 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5203      2007735 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5204              :                 // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5205      1686459 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5206              : 
    5207      1686459 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5208            0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5209            0 :                     continue;
    5210              :                 }
    5211              : 
    5212      1686459 :                 int const ConstrNum = surface.Construction;
    5213      1686459 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5214              : 
    5215      1686459 :                 if (construct.NumCTFTerms == 0) {
    5216            0 :                     continue; // Skip surfaces with no history terms
    5217              :                 }
    5218              : 
    5219              :                 // Sign convention for the various terms in the following two equations
    5220              :                 // is based on the form of the Conduction Transfer Function equation
    5221              :                 // given by:
    5222              :                 // Qin,now  = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc)
    5223              :                 // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc)
    5224              :                 // In both equations, flux is positive from outside to inside.  The V and W terms are for radiant systems only.
    5225              : 
    5226              :                 // Set current inside flux:
    5227      1686459 :                 Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    5228      1686459 :                 Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross[0] -
    5229      1686459 :                                                 state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside[0] +
    5230      1686459 :                                                 state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems
    5231              :                 // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall ||
    5232              :                 // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are
    5233              :                 // redundant.
    5234      1686459 :                 if (construct.SourceSinkPresent) {
    5235            2 :                     SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn[0];
    5236              :                 }
    5237      1686459 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr;
    5238      1686459 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting
    5239      1686459 :                 state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr;
    5240              : 
    5241              :                 // Update the temperature at the source/sink location (if one is present)
    5242      1686459 :                 if (construct.SourceSinkPresent) {
    5243            2 :                     state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) =
    5244            2 :                         SurfOutsideTempCurr * construct.CTFTSourceOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn[0] +
    5245            2 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ[0] +
    5246            2 :                         state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
    5247            2 :                     state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) =
    5248            2 :                         SurfOutsideTempCurr * construct.CTFTUserOut[0] + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn[0] +
    5249            2 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource[0] +
    5250            2 :                         state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum);
    5251              :                 }
    5252              : 
    5253              :                 // Set current outside flux:
    5254      1686459 :                 if (construct.SourceSinkPresent) {
    5255            2 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) =
    5256            2 :                         SurfOutsideTempCurr * construct.CTFOutside[0] - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
    5257            2 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut[0] +
    5258            2 :                         state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems
    5259              :                 } else {
    5260      3372914 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside[0] -
    5261      1686457 :                                                                              state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross[0] +
    5262      1686457 :                                                                              state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum);
    5263              :                 }
    5264              :                 // switch sign for balance at outside face
    5265      1686459 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
    5266      1686459 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum);
    5267              :             }
    5268       287673 :         }
    5269              :     } // ...end of loop over all (heat transfer) surfaces...
    5270              : 
    5271       200977 :     if (state.dataHeatBal->SimpleCTFOnly && !state.dataGlobal->AnyConstrOverridesInModel) {
    5272              :         // Temporarily save the rvalue references of the last term arrays
    5273       193863 :         Array1D<Real64> insideTemp(std::move(state.dataHeatBalSurf->SurfInsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5274       193863 :         Array1D<Real64> outsideTemp(std::move(state.dataHeatBalSurf->SurfOutsideTempHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5275       193863 :         Array1D<Real64> insideFlux(std::move(state.dataHeatBalSurf->SurfInsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5276       193863 :         Array1D<Real64> outsideFlux(std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(state.dataHeatBal->MaxCTFTerms + 1)));
    5277              :         // Shifting its internal pointer to data to the new object; Using the (Array1D && a) overload of the "=" operator
    5278      1325627 :         for (int HistTermNum = state.dataHeatBal->MaxCTFTerms + 1; HistTermNum >= 3; --HistTermNum) {
    5279      1131764 :             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum - 1));
    5280      1131764 :             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum - 1));
    5281      1131764 :             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum - 1));
    5282      1131764 :             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum) = std::move(state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum - 1));
    5283              :         }
    5284              :         // Reuse the pointers of the last term arrays for the second term arrays
    5285       193863 :         state.dataHeatBalSurf->SurfInsideTempHist(2) = std::move(insideTemp);
    5286       193863 :         state.dataHeatBalSurf->SurfOutsideTempHist(2) = std::move(outsideTemp);
    5287       193863 :         state.dataHeatBalSurf->SurfInsideFluxHist(2) = std::move(insideFlux);
    5288       193863 :         state.dataHeatBalSurf->SurfOutsideFluxHist(2) = std::move(outsideFlux);
    5289              :         // Hard copy the values of the the 1st term to the 2nd (copying data instead of pointers to protect the 1st term arrays used in run time)
    5290       193863 :         state.dataHeatBalSurf->SurfInsideTempHist(2) = state.dataHeatBalSurf->SurfInsideTempHist(1);
    5291       193863 :         state.dataHeatBalSurf->SurfOutsideTempHist(2) = state.dataHeatBalSurf->SurfOutsideTempHist(1);
    5292       193863 :         state.dataHeatBalSurf->SurfInsideFluxHist(2) = state.dataHeatBalSurf->SurfInsideFluxHist(1);
    5293       193863 :         state.dataHeatBalSurf->SurfOutsideFluxHist(2) = state.dataHeatBalSurf->SurfOutsideFluxHist(1);
    5294       193863 :         return;
    5295       193863 :     }
    5296              : 
    5297        14230 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5298        14232 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5299         7116 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5300         7116 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5301         7116 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5302        44374 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5303        37258 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5304              :                 // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5305        37258 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5306            0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5307            0 :                     continue;
    5308              :                 }
    5309        37258 :                 if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5310        37258 :                     state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    5311        37258 :                     state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
    5312        37258 :                     state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum);
    5313        37258 :                     state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum);
    5314              :                 }
    5315              :             }
    5316         7116 :         }
    5317              : 
    5318              :     } // ...end of loop over all (heat transfer) surfaces...
    5319         7114 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5320            4 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5321            4 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5322            2 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5323            2 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5324            2 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5325            4 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5326            2 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
    5327              :                     // Loop through all (heat transfer) surfaces...  [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum )
    5328            2 :                     if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5329            0 :                         (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5330            0 :                         continue;
    5331              :                     }
    5332            2 :                     if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5333            2 :                         state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1);
    5334            2 :                         state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1);
    5335            2 :                         state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1);
    5336              :                     }
    5337              :                 }
    5338            2 :             }
    5339              :         } // ...end of loop over all (heat transfer) surfaces...
    5340              :     }
    5341              : 
    5342              :     // SHIFT TEMPERATURE AND FLUX HISTORIES:
    5343              :     // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE.
    5344        14230 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5345        14232 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5346         7116 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5347         7116 :             int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5348         7116 :             int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5349        44374 :             for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5350        37258 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    5351              : 
    5352        37258 :                 if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5353            0 :                     (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5354            0 :                     continue;
    5355              :                 }
    5356              : 
    5357        37258 :                 int const ConstrNum = surface.Construction;
    5358        37258 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5359              : 
    5360        37258 :                 ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum);
    5361        37258 :                 state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone;
    5362              : 
    5363        37258 :                 if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) {
    5364        37258 :                     state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0;
    5365              : 
    5366        37258 :                     if (construct.NumCTFTerms > 1) {
    5367         7126 :                         int const numCTFTerms(construct.NumCTFTerms);
    5368        35612 :                         for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
    5369        28486 :                             state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) =
    5370        28486 :                                 state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5371        28486 :                             state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) =
    5372        28486 :                                 state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5373        28486 :                             state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) =
    5374        28486 :                                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5375        28486 :                             state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) =
    5376        28486 :                                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5377        28486 :                             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) =
    5378        28486 :                                 state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5379        28486 :                             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) =
    5380        28486 :                                 state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum);
    5381        28486 :                             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) =
    5382        28486 :                                 state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5383        28486 :                             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) =
    5384        28486 :                                 state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum);
    5385              :                         }
    5386              :                     }
    5387              : 
    5388        37258 :                     state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum);
    5389        37258 :                     state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum);
    5390        37258 :                     state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum);
    5391        37258 :                     state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum);
    5392              : 
    5393        37258 :                     state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum);
    5394        37258 :                     state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum);
    5395        37258 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum);
    5396        37258 :                     state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum);
    5397              :                 } else {
    5398            0 :                     Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
    5399            0 :                     if (construct.NumCTFTerms > 1) {
    5400            0 :                         int const numCTFTerms(construct.NumCTFTerms);
    5401            0 :                         for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing
    5402              :                             // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) -
    5403              :                             //                                 (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps;
    5404            0 :                             Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum));
    5405            0 :                             Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum));
    5406            0 :                             Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum));
    5407            0 :                             Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum));
    5408            0 :                             state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps;
    5409            0 :                             state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps;
    5410              : 
    5411            0 :                             Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum));
    5412            0 :                             Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum));
    5413            0 :                             Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum));
    5414            0 :                             Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum));
    5415            0 :                             state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps;
    5416            0 :                             state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps;
    5417              :                         }
    5418              :                     }
    5419              :                     // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps;
    5420            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) =
    5421            0 :                         state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) -
    5422            0 :                         (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps;
    5423            0 :                     state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) =
    5424            0 :                         state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) -
    5425            0 :                         (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps;
    5426            0 :                     state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) =
    5427            0 :                         state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) -
    5428            0 :                         (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps;
    5429            0 :                     state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) =
    5430            0 :                         state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) -
    5431            0 :                         (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps;
    5432              :                 }
    5433              :             }
    5434         7116 :         }
    5435              :     } // ...end of loop over all (heat transfer) surfaces
    5436              : 
    5437         7114 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    5438            4 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    5439            4 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    5440            2 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5441            2 :                 int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst;
    5442            2 :                 int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast;
    5443            4 :                 for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) {
    5444            2 :                     auto const &surface = state.dataSurface->Surface(SurfNum);
    5445            2 :                     int const ConstrNum = surface.Construction;
    5446            2 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    5447            2 :                     if (!construct.SourceSinkPresent) {
    5448            0 :                         continue;
    5449              :                     }
    5450            2 :                     if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) &&
    5451            0 :                         (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) {
    5452            0 :                         continue;
    5453              :                     }
    5454              : 
    5455            2 :                     if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays
    5456            2 :                         if (construct.NumCTFTerms > 1) {
    5457            2 :                             int const numCTFTerms = construct.NumCTFTerms;
    5458            2 :                             int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
    5459            2 :                             int m1 = m + 1;
    5460            4 :                             for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing
    5461              :                                 // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1
    5462              :                                 // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum -
    5463              :                                 // 1 );
    5464            2 :                                 state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] =
    5465            2 :                                     state.dataHeatBalSurf->SurfTsrcHistM[m];
    5466            2 :                                 state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] =
    5467            2 :                                     state.dataHeatBalSurf->SurfQsrcHistM[m];
    5468            2 :                                 state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] =
    5469            2 :                                     state.dataHeatBalSurf->SurfTuserHistM[m];
    5470              :                             }
    5471              :                         }
    5472            2 :                         state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum);
    5473            2 :                         state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum);
    5474            2 :                         state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum);
    5475            2 :                         state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2);
    5476            2 :                         state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2);
    5477            2 :                         state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2);
    5478              :                     } else {
    5479            0 :                         Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep);
    5480              : 
    5481            0 :                         if (construct.NumCTFTerms > 1) {
    5482            0 :                             int const numCTFTerms = construct.NumCTFTerms;
    5483            0 :                             int m = state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms);
    5484            0 :                             int m1 = m + 1;
    5485            0 :                             for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == ()
    5486              :                                 // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) );
    5487              :                                 // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum,
    5488              :                                 // HistTermNum
    5489              :                                 // - 1 ) ) * sum_steps;  Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) );  SurfQsrcHist( SurfNum,
    5490              :                                 // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps;
    5491            0 :                                 Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]);
    5492            0 :                                 state.dataHeatBalSurf->SurfTsrcHist[m1] =
    5493            0 :                                     TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps;
    5494            0 :                                 Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]);
    5495            0 :                                 state.dataHeatBalSurf->SurfQsrcHist[m1] =
    5496            0 :                                     QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps;
    5497            0 :                                 Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]);
    5498            0 :                                 state.dataHeatBalSurf->SurfTuserHist[m1] =
    5499            0 :                                     TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps;
    5500              :                             }
    5501              :                         }
    5502              :                         // Tuned Linear indexing
    5503              :                         // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps;
    5504              :                         // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps;
    5505            0 :                         int const l2 = state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2);
    5506            0 :                         state.dataHeatBalSurf->SurfTsrcHist[l2] =
    5507            0 :                             state.dataHeatBalSurf->SurfTsrcHistM[l2] -
    5508            0 :                             (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps;
    5509            0 :                         state.dataHeatBalSurf->SurfQsrcHist[l2] =
    5510            0 :                             state.dataHeatBalSurf->SurfQsrcHistM[l2] -
    5511            0 :                             (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps;
    5512            0 :                         state.dataHeatBalSurf->SurfTuserHist[l2] =
    5513            0 :                             state.dataHeatBalSurf->SurfTuserHistM[l2] -
    5514            0 :                             (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps;
    5515              :                     }
    5516              :                 }
    5517            2 :             }
    5518              :         } // ...end of loop over all (heat transfer) surfaces...
    5519              :     } // ...end of AnyInternalHeatSourceInInput
    5520              : }
    5521              : 
    5522       249966 : void CalculateZoneMRT(EnergyPlusData &state,
    5523              :                       ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    5524              : {
    5525              : 
    5526              :     // SUBROUTINE INFORMATION:
    5527              :     //       AUTHOR         Rick Strand
    5528              :     //       DATE WRITTEN   November 2000
    5529              : 
    5530              :     // PURPOSE OF THIS SUBROUTINE:
    5531              :     // Calculates the current zone and enclosure MRT for thermal comfort and radiation
    5532              :     // calculation purposes.
    5533              : 
    5534       249966 :     if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5535          109 :         state.dataHeatBalSurfMgr->SurfaceAE.allocate(state.dataSurface->TotSurfaces);
    5536          109 :         state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones);
    5537          109 :         state.dataHeatBalSurfMgr->SurfaceAE = 0.0;
    5538          109 :         state.dataHeatBalSurfMgr->ZoneAESum = 0.0;
    5539          249 :         for (auto &encl : state.dataViewFactor->EnclRadInfo) {
    5540          140 :             encl.sumAE = 0.0;
    5541          109 :         }
    5542          902 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    5543          793 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    5544          793 :             if (surface.HeatTransSurf) {
    5545          777 :                 auto &thisSurfAE = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum);
    5546          777 :                 thisSurfAE = surface.Area * state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal;
    5547          777 :                 int ZoneNum = surface.Zone;
    5548          777 :                 if (ZoneNum > 0) {
    5549          777 :                     state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += thisSurfAE;
    5550              :                 }
    5551          777 :                 if (surface.RadEnclIndex > 0) {
    5552          777 :                     state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).sumAE += thisSurfAE;
    5553              :                 }
    5554              :             }
    5555              :         }
    5556              :     }
    5557              : 
    5558              :     // Zero sumAET for applicable enclosures
    5559       249966 :     if (present(ZoneToResimulate)) {
    5560           32 :         for (int spaceNum : state.dataHeatBal->Zone(ZoneToResimulate).spaceIndexes) {
    5561           24 :             int enclNum = state.dataHeatBal->space(spaceNum).radiantEnclosureNum;
    5562           24 :             state.dataViewFactor->EnclRadInfo(enclNum).sumAET = 0.0;
    5563           24 :             state.dataViewFactor->EnclRadInfo(enclNum).reCalcMRT = true;
    5564            8 :         }
    5565              :     } else {
    5566       602842 :         for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    5567       352884 :             thisEnclosure.reCalcMRT = true;
    5568       249958 :         }
    5569              :     }
    5570       586633 :     for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5571       336667 :         if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) {
    5572            0 :             continue;
    5573              :         }
    5574       336667 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    5575       336667 :         if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) {
    5576       336664 :             Real64 zoneSumAET = 0.0;
    5577       706955 :             for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
    5578       370291 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    5579      2439240 :                 for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    5580      2068949 :                     Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum);
    5581      2068949 :                     zoneSumAET += surfAET;
    5582      2068949 :                     state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex).sumAET += surfAET;
    5583              :                 }
    5584       336664 :             }
    5585       336664 :             thisZoneHB.MRT = zoneSumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum);
    5586              :         } else {
    5587            3 :             if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5588            6 :                 ShowWarningError(
    5589              :                     state,
    5590            6 :                     format("Zone areas*inside surface emissivities are summing to zero, for Zone=\"{}\"", state.dataHeatBal->Zone(ZoneNum).Name));
    5591            9 :                 ShowContinueError(state, "As a result, MRT will be set to MAT for that zone");
    5592              :             }
    5593            3 :             thisZoneHB.MRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    5594              :         }
    5595              :     }
    5596              :     // Calculate MRT for applicable enclosures
    5597       602866 :     for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) {
    5598       352900 :         if (!thisEnclosure.reCalcMRT) {
    5599            0 :             continue;
    5600              :         }
    5601       352900 :         if (thisEnclosure.sumAE > 0.01) {
    5602       352898 :             thisEnclosure.sumAET = 0.0;
    5603      2421819 :             for (int surfNum : thisEnclosure.SurfacePtr) {
    5604      2068921 :                 Real64 surfAET = state.dataHeatBalSurfMgr->SurfaceAE(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum);
    5605      2068921 :                 thisEnclosure.sumAET += surfAET;
    5606              :             }
    5607       352898 :             thisEnclosure.MRT = thisEnclosure.sumAET / thisEnclosure.sumAE;
    5608              :         } else {
    5609            2 :             if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) {
    5610            4 :                 ShowWarningError(state,
    5611            4 :                                  format("Enclosure areas*inside surface emissivities are summing to zero, for Enclosure=\"{}\"", thisEnclosure.Name));
    5612            6 :                 ShowContinueError(state, "As a result, MRT will be set to the volume weighted average MAT for that enclosure");
    5613              :             }
    5614            2 :             Real64 sumMATVol = 0.0;
    5615            2 :             Real64 sumVol = 0.0;
    5616            2 :             Real64 sumMAT = 0.0;
    5617            5 :             for (auto &spaceNum : thisEnclosure.spaceNums) {
    5618            3 :                 Real64 spaceVolume = state.dataHeatBal->space(spaceNum).Volume;
    5619            3 :                 Real64 spaceMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT;
    5620            3 :                 sumVol += spaceVolume;
    5621            3 :                 sumMATVol += spaceMAT * spaceVolume;
    5622            3 :                 sumMAT += spaceMAT;
    5623            2 :             }
    5624            2 :             if (sumVol > 0.01) {
    5625            2 :                 thisEnclosure.MRT = sumMATVol / sumVol;
    5626              :             } else {
    5627            0 :                 thisEnclosure.MRT = sumMAT / (int)thisEnclosure.spaceNums.size();
    5628              :             }
    5629              :         }
    5630              :         // Set space MRTs
    5631       723194 :         for (int spaceNum : thisEnclosure.spaceNums) {
    5632       370294 :             state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MRT = thisEnclosure.MRT;
    5633       352900 :         }
    5634       249966 :     }
    5635              : 
    5636       249966 :     state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime = false;
    5637       249966 : }
    5638              : 
    5639              : // End of Record Keeping subroutines for the HB Module
    5640              : // *****************************************************************************
    5641              : 
    5642              : // Beginning of Reporting subroutines for the HB Module
    5643              : // *****************************************************************************
    5644              : 
    5645       249953 : void CalcThermalResilience(EnergyPlusData &state)
    5646              : {
    5647              :     // This function calculate timestep-wise heat index and humidex.
    5648              : 
    5649              :     // The computation of the heat index is a refinement of a result obtained by multiple regression analysis
    5650              :     // carried out by Lans P. Rothfusz and described in a 1990 National Weather Service (NWS)
    5651              :     // Technical Attachment (SR 90-23).
    5652              :     // Reference: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
    5653              : 
    5654              :     // The current formula for determining the humidex was developed by J. M. Masterton and F. A. Richardson of
    5655              :     // Canada's Atmospheric Environment Service in 1979.
    5656              :     // Reference: Masterson, J., and F. Richardson, 1979: Humidex, a method of quantifying human
    5657              :     // discomfort due to excessive heat and humidity CLI 1-79, Environment Canada, Atmospheric Environment Service
    5658              :     //        using OutputProcessor::ReqRepVars;
    5659       249953 :     if (state.dataHeatBalSurfMgr->ManageSurfaceHeatBalancefirstTime) {
    5660          242 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5661          262 :             SetupOutputVariable(state,
    5662              :                                 "Zone Heat Index",
    5663              :                                 Constant::Units::C,
    5664          131 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex,
    5665              :                                 OutputProcessor::TimeStepType::Zone,
    5666              :                                 OutputProcessor::StoreType::Average,
    5667          131 :                                 state.dataHeatBal->Zone(ZoneNum).Name);
    5668          262 :             SetupOutputVariable(state,
    5669              :                                 "Zone Humidity Index",
    5670              :                                 Constant::Units::None,
    5671          131 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex,
    5672              :                                 OutputProcessor::TimeStepType::Zone,
    5673              :                                 OutputProcessor::StoreType::Average,
    5674          131 :                                 state.dataHeatBal->Zone(ZoneNum).Name);
    5675              :         }
    5676          580 :         for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
    5677          469 :             if (reqVar->name == "Zone Heat Index") {
    5678            0 :                 state.dataHeatBalSurfMgr->reportVarHeatIndex = true;
    5679          469 :             } else if (reqVar->name == "Zone Humidity Index") {
    5680            0 :                 state.dataHeatBalSurfMgr->reportVarHumidex = true;
    5681              :             }
    5682          111 :         }
    5683              :     }
    5684              : 
    5685              :     // Calculate Heat Index and Humidex.
    5686              :     // The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
    5687              :     // then heat index is calculated and converted back to C.
    5688       249953 :     if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
    5689       145262 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5690        75319 :             Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5691        75319 :             Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
    5692        75319 :             Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0;
    5693        75319 :             Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0;
    5694        75319 :             if (state.dataHeatBal->heatIndexMethod == DataHeatBalance::HeatIndexMethod::Simplified) {
    5695        75319 :                 Real64 constexpr c1 = -42.379;
    5696        75319 :                 Real64 constexpr c2 = 2.04901523;
    5697        75319 :                 Real64 constexpr c3 = 10.14333127;
    5698        75319 :                 Real64 constexpr c4 = -.22475541;
    5699        75319 :                 Real64 constexpr c5 = -.00683783;
    5700        75319 :                 Real64 constexpr c6 = -.05481717;
    5701        75319 :                 Real64 constexpr c7 = .00122874;
    5702        75319 :                 Real64 constexpr c8 = .00085282;
    5703        75319 :                 Real64 constexpr c9 = -.00000199;
    5704              :                 Real64 HI;
    5705              : 
    5706        75319 :                 if (ZoneTF < 80) {
    5707        40740 :                     HI = 0.5 * (ZoneTF + 61.0 + (ZoneTF - 68.0) * 1.2 + (ZoneRH * 0.094));
    5708              :                 } else {
    5709        34579 :                     HI = c1 + c2 * ZoneTF + c3 * ZoneRH + c4 * ZoneTF * ZoneRH + c5 * ZoneTF * ZoneTF + c6 * ZoneRH * ZoneRH +
    5710        34579 :                          c7 * ZoneTF * ZoneTF * ZoneRH + c8 * ZoneTF * ZoneRH * ZoneRH + c9 * ZoneTF * ZoneTF * ZoneRH * ZoneRH;
    5711        34579 :                     if (ZoneRH < 13 && ZoneTF < 112) {
    5712          450 :                         HI -= (13 - ZoneRH) / 4 * std::sqrt((17 - abs(ZoneTF - 95)) / 17);
    5713        34129 :                     } else if (ZoneRH > 85 && ZoneTF < 87) {
    5714           86 :                         HI += (ZoneRH - 85) / 10 * (87 - ZoneTF) / 5;
    5715              :                     }
    5716              :                 }
    5717        75319 :                 HI = (HI - 32.0) * (5.0 / 9.0);
    5718        75319 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex = HI;
    5719              :             } else {
    5720              :                 // calculate extended heat index
    5721            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex =
    5722            0 :                     ExtendedHI::heatindex(state, ZoneT + Constant::Kelvin, ZoneRH / 100.0) - Constant::Kelvin;
    5723              :             }
    5724              :         }
    5725              :     }
    5726       249953 :     if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) {
    5727       145262 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5728        75319 :             Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRatAvg;
    5729        75319 :             Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5730        75319 :             Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + Constant::Kelvin;
    5731        75319 :             Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK)));
    5732        75319 :             Real64 const h = 5.0 / 9.0 * (e - 10.0);
    5733        75319 :             Real64 const Humidex = ZoneT + h;
    5734        75319 :             state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex = Humidex;
    5735              :         }
    5736              :     }
    5737       249953 : }
    5738              : 
    5739        69975 : void ReportThermalResilience(EnergyPlusData &state)
    5740              : {
    5741              : 
    5742        69975 :     Array1D_bool reportPeriodFlags;
    5743        69975 :     if (state.dataWeather->TotReportPers > 0) {
    5744           20 :         reportPeriodFlags.dimension(state.dataWeather->TotThermalReportPers, false);
    5745           20 :         General::findReportPeriodIdx(state, state.dataWeather->ThermalReportPeriodInput, state.dataWeather->TotThermalReportPers, reportPeriodFlags);
    5746              :     }
    5747              : 
    5748        69975 :     auto &ort = state.dataOutRptTab;
    5749        70015 :     for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5750           40 :         if (reportPeriodFlags(i)) {
    5751           18 :             int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    5752           18 :             state.dataWeather->ThermalReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    5753              :         }
    5754              :     }
    5755              : 
    5756        69975 :     if (state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime) {
    5757           40 :         int constexpr HINoBins = 5;                     // Heat Index range - number of bins
    5758           40 :         int constexpr HumidexNoBins = 5;                // Humidex range - number of bins
    5759           40 :         int constexpr SETNoBins = 5;                    // SET report column numbers
    5760           40 :         int constexpr ColdHourOfSafetyNoBins = 5;       // Cold Stress Hour of Safety number of columns
    5761           40 :         int constexpr HeatHourOfSafetyNoBins = 5;       // Heat Stress Hour of Safety number of columns
    5762           40 :         int constexpr UnmetDegreeHourNoBins = 6;        // Unmet Degree Hour number of columns
    5763           40 :         int constexpr DiscomfortWtExceedHourNoBins = 4; // Unmet Degree Hour number of columns
    5764              : 
    5765           40 :         if (state.dataHeatBal->TotPeople == 0) {
    5766           32 :             state.dataHeatBalSurfMgr->hasPierceSET = false;
    5767              :         }
    5768           54 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    5769           14 :             if (!state.dataHeatBal->People(iPeople).Pierce) {
    5770           12 :                 state.dataHeatBalSurfMgr->hasPierceSET = false;
    5771              :             }
    5772              :         }
    5773           86 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5774              :             // the whole period
    5775              :             // user specified reporting period
    5776           48 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5777            2 :                 state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5778            2 :                 state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5779            2 :                 state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HINoBins, 0.0);
    5780            2 :                 state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5781            2 :                 state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5782            2 :                 state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, i).assign(HumidexNoBins, 0.0);
    5783            2 :                 if (state.dataHeatBalSurfMgr->hasPierceSET) {
    5784            2 :                     state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
    5785            2 :                     state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, i).assign(SETNoBins, 0.0);
    5786              :                 }
    5787            2 :                 state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(ColdHourOfSafetyNoBins, 0.0);
    5788            2 :                 state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, i).assign(HeatHourOfSafetyNoBins, 0.0);
    5789            2 :                 state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, i).assign(UnmetDegreeHourNoBins, 0.0);
    5790            2 :                 state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
    5791            2 :                 state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, i).assign(DiscomfortWtExceedHourNoBins, 0.0);
    5792              :             }
    5793           46 :             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod = 0.0;
    5794           46 :             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod = 0.0;
    5795           46 :             state.dataHeatBalFanSys->lowSETLongestStartRepPeriod = 0.0;
    5796           46 :             state.dataHeatBalFanSys->highSETLongestStartRepPeriod = 0.0;
    5797              :         }
    5798           40 :         state.dataHeatBalSurfMgr->lowSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
    5799           40 :         state.dataHeatBalSurfMgr->highSETLongestHours.assign(state.dataGlobal->NumOfZones, 0.0);
    5800           40 :         state.dataHeatBalSurfMgr->lowSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
    5801           40 :         state.dataHeatBalSurfMgr->highSETLongestStart.assign(state.dataGlobal->NumOfZones, 0.0);
    5802           40 :         state.dataHeatBalSurfMgr->reportThermalResilienceFirstTime = false;
    5803              :     }
    5804              : 
    5805              :     // Count hours only during weather simulation periods
    5806        69975 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    5807              :         // use default value if there are no user inputs
    5808           40 :         Real64 ColdTempThresh = 15.56;
    5809           40 :         Real64 HeatTempThresh = 30.0;
    5810              :         // Trace current time step Zone Pierce SET; NaN if no occupant or SET not calculated
    5811              :         // Record last time step SET to trace SET unmet duration;
    5812              : 
    5813           40 :         Real64 valueNotInit = -999.0;
    5814           40 :         Real64 nearThreshold = 1.0;
    5815           80 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    5816           40 :             state.dataHeatBal->Resilience(ZoneNum).PierceSET = valueNotInit;
    5817           40 :             state.dataHeatBal->Resilience(ZoneNum).PMV = valueNotInit;
    5818              :         }
    5819           80 :         for (int iPeople = 1; iPeople <= state.dataHeatBal->TotPeople; ++iPeople) {
    5820           40 :             int ZoneNum = state.dataHeatBal->People(iPeople).ZonePtr;
    5821           40 :             state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc =
    5822           40 :                 state.dataHeatBal->People(iPeople).NumberOfPeople * state.dataHeatBal->People(iPeople).sched->getCurrentVal();
    5823           40 :             state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5824           40 :             if (state.dataHeatBal->People(iPeople).Pierce) {
    5825           40 :                 state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = state.dataThermalComforts->ThermalComfortData(iPeople).PierceSET;
    5826              :             } else {
    5827            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET = -1;
    5828              :             }
    5829              : 
    5830           40 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    5831           40 :             Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    5832           40 :             ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
    5833           40 :             bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh;
    5834           40 :             if (Temperature > ColdTempThresh) { // safe
    5835           36 :                 if (!CrossedColdThresh) {
    5836              :                     // compute the number of hours before threshold is reached
    5837           36 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
    5838              :                 }
    5839              :             } else { // danger
    5840              :                 // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5841            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
    5842            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5843            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5844              :                 // first time crossing threshold
    5845            4 :                 if (!CrossedColdThresh) {
    5846              :                     // compute the time when the zone crosses the threshold temperature
    5847              :                     int encodedMonDayHrMin;
    5848            2 :                     General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5849            2 :                                                state.dataEnvrn->Month,
    5850            2 :                                                state.dataEnvrn->DayOfMonth,
    5851            2 :                                                state.dataGlobal->HourOfDay,
    5852            2 :                                                state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5853              :                     // fixme: not sure how to aggregate by zone
    5854            2 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneColdHourOfSafetyBins[1] = encodedMonDayHrMin;
    5855            2 :                     CrossedColdThresh = true;
    5856              :                 }
    5857              :             }
    5858           40 :             HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
    5859           40 :             bool &CrossedHeatThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedHeatThresh;
    5860           40 :             if (Temperature < HeatTempThresh) { // safe
    5861           16 :                 if (!CrossedHeatThresh) {
    5862              :                     // compute the number of hours before threshold is reached
    5863            6 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[0] += state.dataGlobal->TimeStepZone;
    5864              :                 }
    5865              :             } else { // danger
    5866              :                 // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5867           24 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[2] += state.dataGlobal->TimeStepZone;
    5868           24 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    5869           24 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5870              :                 // first time crossing threshold
    5871           24 :                 if (!CrossedHeatThresh) {
    5872              :                     // compute the time when the zone crosses the threshold temperature
    5873              :                     int encodedMonDayHrMin;
    5874            2 :                     General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5875            2 :                                                state.dataEnvrn->Month,
    5876            2 :                                                state.dataEnvrn->DayOfMonth,
    5877            2 :                                                state.dataGlobal->HourOfDay,
    5878            2 :                                                state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5879            2 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHeatHourOfSafetyBins[1] = encodedMonDayHrMin;
    5880            2 :                     CrossedHeatThresh = true;
    5881              :                 }
    5882              :             }
    5883              : 
    5884           40 :             Real64 VeryHotPMVThresh = 3.0;
    5885           40 :             Real64 WarmPMVThresh = 0.7;
    5886           40 :             Real64 CoolPMVThresh = -0.7;
    5887           40 :             Real64 VeryColdPMVThresh = -3.0;
    5888           40 :             Real64 PMV = state.dataThermalComforts->ThermalComfortData(iPeople).FangerPMV;
    5889           40 :             if (PMV < VeryColdPMVThresh) {
    5890           14 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[0] +=
    5891           14 :                     (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5892           14 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[0] +=
    5893           14 :                     (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5894              :             }
    5895           40 :             if (PMV < CoolPMVThresh) {
    5896           20 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[1] +=
    5897           20 :                     (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5898           20 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[1] +=
    5899           20 :                     (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5900              :             }
    5901           40 :             if (PMV > WarmPMVThresh) {
    5902           16 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[2] +=
    5903           16 :                     (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5904           16 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[2] +=
    5905           16 :                     (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5906              :             }
    5907           40 :             if (PMV > VeryHotPMVThresh) {
    5908            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccuHourBins[3] +=
    5909            0 :                     (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    5910            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneDiscomfortWtExceedOccupiedHourBins[3] +=
    5911            0 :                     (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5912              :             }
    5913              : 
    5914              :             // check whether PierceSET changed for people in a zone
    5915           40 :             if (state.dataHeatBal->Resilience(ZoneNum).PierceSET < valueNotInit + nearThreshold) {
    5916           40 :                 state.dataHeatBal->Resilience(ZoneNum).PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    5917              :             } else {
    5918            0 :                 if (state.dataHeatBal->Resilience(ZoneNum).PierceSET != state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET) {
    5919            0 :                     ShowRecurringWarningErrorAtEnd(state,
    5920            0 :                                                    fmt::format("Zone {} has multiple people objects with different PierceSet.", ZoneNum),
    5921            0 :                                                    state.dataHeatBalFanSys->PierceSETerrorIndex);
    5922              :                 }
    5923              :             }
    5924              : 
    5925              :             // check whether PierceSET, PMV, etc. changed for different people in a zone
    5926           40 :             if (state.dataHeatBal->Resilience(ZoneNum).PMV < valueNotInit + nearThreshold) {
    5927           40 :                 state.dataHeatBal->Resilience(ZoneNum).PMV = PMV;
    5928              :             } else {
    5929            0 :                 if (state.dataHeatBal->Resilience(ZoneNum).PMV != PMV) {
    5930            0 :                     ShowRecurringWarningErrorAtEnd(state,
    5931            0 :                                                    fmt::format("Zone {} has multiple people objects with different PMV.", ZoneNum),
    5932            0 :                                                    state.dataHeatBalFanSys->PMVerrorIndex);
    5933              :                 }
    5934              :             }
    5935              : 
    5936           80 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    5937           40 :                 if (reportPeriodFlags(i)) {
    5938           18 :                     int ReportPeriodIdx = i;
    5939           18 :                     ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh;
    5940           18 :                     bool &CrossedColdThreshRepPeriod = state.dataHeatBalFanSys->CrossedColdThreshRepPeriod(ZoneNum, ReportPeriodIdx);
    5941           18 :                     if (Temperature > ColdTempThresh) { // safe
    5942           16 :                         if (!CrossedColdThreshRepPeriod) {
    5943              :                             // compute the number of hours before threshold is reached
    5944           16 :                             state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5945              :                         }
    5946              :                     } else { // danger
    5947              :                         // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5948            2 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    5949            2 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5950            2 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5951            2 :                         state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    5952            2 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5953              :                         // first time crossing threshold
    5954            2 :                         if (!CrossedColdThreshRepPeriod) {
    5955              :                             // compute the time when the zone crosses the threshold temperature
    5956              :                             int encodedMonDayHrMin;
    5957            1 :                             General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5958            1 :                                                        state.dataEnvrn->Month,
    5959            1 :                                                        state.dataEnvrn->DayOfMonth,
    5960            1 :                                                        state.dataGlobal->HourOfDay,
    5961            1 :                                                        state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5962              :                             // fixme: not sure how to aggregate by zone
    5963            1 :                             state.dataHeatBalFanSys->ZoneColdHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
    5964            1 :                             CrossedColdThreshRepPeriod = true;
    5965              :                         }
    5966              :                     }
    5967           18 :                     HeatTempThresh = state.dataHeatBal->People(iPeople).HeatStressTempThresh;
    5968           18 :                     bool &CrossedHeatThreshRepPeriod = state.dataHeatBalFanSys->CrossedHeatThreshRepPeriod(ZoneNum, ReportPeriodIdx);
    5969           18 :                     if (Temperature < HeatTempThresh) { // safe
    5970            8 :                         if (!CrossedHeatThreshRepPeriod) {
    5971              :                             // compute the number of hours before threshold is reached
    5972            3 :                             state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    5973              :                         }
    5974              :                     } else { // danger
    5975              :                         // compute the total number of hours when the zone temperature falls in the dangerous range throughout the reporting period
    5976           10 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    5977           10 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    5978           10 :                             NumOcc * state.dataGlobal->TimeStepZone;
    5979           10 :                         state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    5980           10 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    5981              :                         // first time crossing threshold
    5982           10 :                         if (!CrossedHeatThreshRepPeriod) {
    5983              :                             // compute the time when the zone crosses the threshold temperature
    5984              :                             int encodedMonDayHrMin;
    5985            2 :                             General::EncodeMonDayHrMin(encodedMonDayHrMin,
    5986            2 :                                                        state.dataEnvrn->Month,
    5987            2 :                                                        state.dataEnvrn->DayOfMonth,
    5988            2 :                                                        state.dataGlobal->HourOfDay,
    5989            2 :                                                        state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    5990            2 :                             state.dataHeatBalFanSys->ZoneHeatHourOfSafetyBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] = encodedMonDayHrMin;
    5991            2 :                             CrossedHeatThreshRepPeriod = true;
    5992              :                         }
    5993              :                     }
    5994              : 
    5995           18 :                     if (PMV < VeryColdPMVThresh) {
    5996            7 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5997            7 :                             (VeryColdPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    5998            7 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    5999            7 :                             (VeryColdPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6000              :                     }
    6001           18 :                     if (PMV < CoolPMVThresh) {
    6002           10 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6003           10 :                             (CoolPMVThresh - PMV) * NumOcc * state.dataGlobal->TimeStepZone;
    6004           10 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6005           10 :                             (CoolPMVThresh - PMV) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6006              :                     }
    6007           18 :                     if (PMV > WarmPMVThresh) {
    6008            8 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6009            8 :                             (PMV - WarmPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    6010            8 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6011            8 :                             (PMV - WarmPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6012              :                     }
    6013           18 :                     if (PMV > VeryHotPMVThresh) {
    6014            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6015            0 :                             (PMV - VeryHotPMVThresh) * NumOcc * state.dataGlobal->TimeStepZone;
    6016            0 :                         state.dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6017            0 :                             (PMV - VeryHotPMVThresh) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6018              :                     }
    6019              :                 }
    6020              :             }
    6021              :         }
    6022           80 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6023           40 :             Real64 HI = state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndex;
    6024           40 :             Real64 Humidex = state.dataHeatBal->Resilience(ZoneNum).ZoneHumidex;
    6025              : 
    6026           40 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6027           40 :             if (HI <= 26.7) {
    6028            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[0] += state.dataGlobal->TimeStepZone;
    6029            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6030            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6031           36 :             } else if (HI > 26.7 && HI <= 32.2) {
    6032            2 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[1] += state.dataGlobal->TimeStepZone;
    6033            2 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6034            2 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6035           34 :             } else if (HI > 32.2 && HI <= 39.4) {
    6036           34 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[2] += state.dataGlobal->TimeStepZone;
    6037           34 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6038           34 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6039            0 :             } else if (HI > 39.4 && HI <= 51.7) {
    6040            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[3] += state.dataGlobal->TimeStepZone;
    6041            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    6042            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6043              :             } else {
    6044            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexHourBins[4] += state.dataGlobal->TimeStepZone;
    6045            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
    6046            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHeatIndexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6047              :             }
    6048              : 
    6049           40 :             if (Humidex <= 29) {
    6050            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[0] += state.dataGlobal->TimeStepZone;
    6051            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6052            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6053           36 :             } else if (Humidex > 29 && Humidex <= 40) {
    6054           36 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[1] += state.dataGlobal->TimeStepZone;
    6055           36 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6056           36 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6057            0 :             } else if (Humidex > 40 && Humidex <= 45) {
    6058            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[2] += state.dataGlobal->TimeStepZone;
    6059            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6060            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6061            0 :             } else if (Humidex > 45 && Humidex <= 50) {
    6062            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[3] += state.dataGlobal->TimeStepZone;
    6063            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    6064            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6065              :             } else {
    6066            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexHourBins[4] += state.dataGlobal->TimeStepZone;
    6067            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccuHourBins[4] += NumOcc * state.dataGlobal->TimeStepZone;
    6068            0 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6069              :             }
    6070              : 
    6071           40 :             Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV;
    6072           40 :             auto const &zoneTstatSetpt = state.dataHeatBalFanSys->zoneTstatSetpts(ZoneNum);
    6073           40 :             Real64 CoolingSetpoint = zoneTstatSetpt.setptHi;
    6074           40 :             Real64 HeatingSetpoint = zoneTstatSetpt.setptLo;
    6075              : 
    6076           40 :             if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
    6077           30 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[0] += (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6078           30 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[1] +=
    6079           30 :                     NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6080           30 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[2] +=
    6081           30 :                     (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6082              :             }
    6083           40 :             if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
    6084            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[3] += (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6085            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[4] +=
    6086            4 :                     NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6087            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneUnmetDegreeHourBins[5] +=
    6088            4 :                     (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6089              :             }
    6090              : 
    6091           40 :             if (state.dataHeatBalSurfMgr->hasPierceSET) {
    6092              :                 int encodedMonDayHrMin;
    6093           40 :                 Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    6094           40 :                 Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
    6095              : 
    6096           40 :                 if (PierceSET <= 12.2) {
    6097           22 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[0] += (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
    6098           22 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[1] += (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
    6099           22 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[2] += (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6100              :                     // Reset duration when last step is out of range.
    6101           22 :                     if (PierceSETLast == -1 || PierceSETLast > 12.2) {
    6102            4 :                         General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6103            4 :                                                    state.dataEnvrn->Month,
    6104            4 :                                                    state.dataEnvrn->DayOfMonth,
    6105            4 :                                                    state.dataGlobal->HourOfDay,
    6106            4 :                                                    state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6107            4 :                         state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
    6108            4 :                         state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
    6109              :                     }
    6110              :                     // Keep the longest duration record.
    6111           22 :                     state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
    6112           36 :                     if (state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] &&
    6113           14 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6114           12 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[3] = state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1];
    6115           12 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneLowSETHours[4] = state.dataHeatBalSurfMgr->lowSETLongestStart[ZoneNum - 1];
    6116              :                     }
    6117           18 :                 } else if (PierceSET > 30) {
    6118           14 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[0] += (PierceSET - 30) * state.dataGlobal->TimeStepZone;
    6119           14 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[1] += (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
    6120           14 :                     state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[2] += (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6121           14 :                     if (PierceSETLast == -1 || PierceSETLast <= 30) {
    6122            4 :                         General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6123            4 :                                                    state.dataEnvrn->Month,
    6124            4 :                                                    state.dataEnvrn->DayOfMonth,
    6125            4 :                                                    state.dataGlobal->HourOfDay,
    6126            4 :                                                    state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6127            4 :                         state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
    6128            4 :                         state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1] = encodedMonDayHrMin;
    6129              :                     }
    6130           14 :                     state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] += state.dataGlobal->TimeStepZone;
    6131           28 :                     if (state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] > state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] &&
    6132           14 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6133            6 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[3] = state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1];
    6134            6 :                         state.dataHeatBal->Resilience(ZoneNum).ZoneHighSETHours[4] = state.dataHeatBalSurfMgr->highSETLongestStart[ZoneNum - 1];
    6135              :                     }
    6136              :                 }
    6137              : 
    6138           40 :                 if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
    6139           12 :                     state.dataHeatBalSurfMgr->lowSETLongestHours[ZoneNum - 1] = 0;
    6140           12 :                     state.dataHeatBalSurfMgr->highSETLongestHours[ZoneNum - 1] = 0;
    6141              :                 }
    6142              :             }
    6143              : 
    6144           80 :             for (int i = 1; i <= state.dataWeather->TotThermalReportPers; i++) {
    6145           40 :                 if (reportPeriodFlags(i)) {
    6146           18 :                     int ReportPeriodIdx = i;
    6147              : 
    6148           18 :                     if (HI <= 26.7) {
    6149            2 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6150            2 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6151            2 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6152            2 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6153            2 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6154           16 :                     } else if (HI > 26.7 && HI <= 32.2) {
    6155            1 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6156            1 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6157            1 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6158            1 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6159            1 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6160           15 :                     } else if (HI > 32.2 && HI <= 39.4) {
    6161           15 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6162           15 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6163           15 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6164           15 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6165           15 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6166            0 :                     } else if (HI > 39.4 && HI <= 51.7) {
    6167            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6168            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6169            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6170            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6171            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6172              :                     } else {
    6173            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
    6174            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6175            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6176            0 :                         state.dataHeatBalFanSys->ZoneHeatIndexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6177            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6178              :                     }
    6179              : 
    6180           18 :                     if (Humidex <= 29) {
    6181            2 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6182            2 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6183            2 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6184            2 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6185            2 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6186           16 :                     } else if (Humidex > 29 && Humidex <= 40) {
    6187           16 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6188           16 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6189           16 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6190           16 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6191           16 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6192            0 :                     } else if (Humidex > 40 && Humidex <= 45) {
    6193            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6194            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6195            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6196            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6197            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6198            0 :                     } else if (Humidex > 45 && Humidex <= 50) {
    6199            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6200            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6201            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6202            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6203            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6204              :                     } else {
    6205            0 :                         state.dataHeatBalFanSys->ZoneHumidexHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] += state.dataGlobal->TimeStepZone;
    6206            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6207            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6208            0 :                         state.dataHeatBalFanSys->ZoneHumidexOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6209            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6210              :                     }
    6211              : 
    6212           18 :                     if (state.dataHeatBalSurfMgr->hasPierceSET) {
    6213              :                         int encodedMonDayHrMin;
    6214           18 :                         Real64 PierceSET = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSET;
    6215           18 :                         Real64 PierceSETLast = state.dataHeatBal->Resilience(ZoneNum).ZonePierceSETLastStep;
    6216           18 :                         if (PierceSET <= 12.2) {
    6217           11 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6218           11 :                                 (12.2 - PierceSET) * state.dataGlobal->TimeStepZone;
    6219           11 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6220           11 :                                 (12.2 - PierceSET) * NumOcc * state.dataGlobal->TimeStepZone;
    6221           11 :                             state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6222           11 :                                 (12.2 - PierceSET) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6223              :                             // Reset duration when last step is out of range
    6224           11 :                             if (PierceSETLast == -1 || PierceSETLast > 12.2) {
    6225            2 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6226            2 :                                                            state.dataEnvrn->Month,
    6227            2 :                                                            state.dataEnvrn->DayOfMonth,
    6228            2 :                                                            state.dataGlobal->HourOfDay,
    6229            2 :                                                            state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6230            2 :                                 state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6231            2 :                                 state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6232            9 :                             } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
    6233            0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6234            0 :                                                            state.dataEnvrn->Month,
    6235            0 :                                                            state.dataEnvrn->DayOfMonth,
    6236            0 :                                                            state.dataGlobal->HourOfDay,
    6237            0 :                                                            state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
    6238            0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6239            0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6240              :                             }
    6241              :                             // Keep the longest duration record.
    6242           11 :                             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
    6243           11 :                             if (state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
    6244           21 :                                     state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
    6245           10 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6246            9 :                                 state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
    6247            9 :                                     state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
    6248            9 :                                 state.dataHeatBalFanSys->ZoneLowSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
    6249            9 :                                     state.dataHeatBalFanSys->lowSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
    6250              :                             }
    6251            7 :                         } else if (PierceSET > 30) {
    6252            7 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6253            7 :                                 (PierceSET - 30) * state.dataGlobal->TimeStepZone;
    6254            7 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6255            7 :                                 (PierceSET - 30) * NumOcc * state.dataGlobal->TimeStepZone;
    6256            7 :                             state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6257            7 :                                 (PierceSET - 30) * (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6258              :                             // Reset duration when last step is out of range.
    6259            7 :                             if (PierceSETLast == -1 || PierceSETLast <= 30) {
    6260            2 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6261            2 :                                                            state.dataEnvrn->Month,
    6262            2 :                                                            state.dataEnvrn->DayOfMonth,
    6263            2 :                                                            state.dataGlobal->HourOfDay,
    6264            2 :                                                            state.dataGlobal->TimeStepZone * (state.dataGlobal->TimeStep - 1) * 60);
    6265            2 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6266            2 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6267            5 :                             } else if (General::isReportPeriodBeginning(state, ReportPeriodIdx)) { // or when it is the start of the period
    6268            0 :                                 General::EncodeMonDayHrMin(encodedMonDayHrMin,
    6269            0 :                                                            state.dataEnvrn->Month,
    6270            0 :                                                            state.dataEnvrn->DayOfMonth,
    6271            0 :                                                            state.dataGlobal->HourOfDay,
    6272            0 :                                                            state.dataGlobal->TimeStepZone * state.dataGlobal->TimeStep * 60);
    6273            0 :                                 state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6274            0 :                                 state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx) = encodedMonDayHrMin;
    6275              :                             }
    6276            7 :                             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) += state.dataGlobal->TimeStepZone;
    6277            7 :                             if (state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) >
    6278           14 :                                     state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] &&
    6279            7 :                                 state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc > 0) {
    6280            3 :                                 state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[3] =
    6281            3 :                                     state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx);
    6282            3 :                                 state.dataHeatBalFanSys->ZoneHighSETHoursRepPeriod(ZoneNum, ReportPeriodIdx)[4] =
    6283            3 :                                     state.dataHeatBalFanSys->highSETLongestStartRepPeriod(ZoneNum, ReportPeriodIdx);
    6284              :                             }
    6285              :                         }
    6286           18 :                         if (state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc == 0) {
    6287            6 :                             state.dataHeatBalFanSys->lowSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6288            6 :                             state.dataHeatBalFanSys->highSETLongestHoursRepPeriod(ZoneNum, ReportPeriodIdx) = 0;
    6289              :                         }
    6290              :                     }
    6291              : 
    6292           18 :                     if ((CoolingSetpoint > 0) && (Temperature > CoolingSetpoint)) {
    6293           13 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6294           13 :                             (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6295           13 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6296           13 :                             NumOcc * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6297           13 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6298           13 :                             (NumOcc > 0) * (Temperature - CoolingSetpoint) * state.dataGlobal->TimeStepZone;
    6299              :                     }
    6300           18 :                     if ((HeatingSetpoint > 0) && (Temperature < HeatingSetpoint)) {
    6301            2 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6302            2 :                             (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6303            2 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[4] +=
    6304            2 :                             NumOcc * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6305            2 :                         state.dataHeatBalFanSys->ZoneUnmetDegreeHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[5] +=
    6306            2 :                             (NumOcc > 0) * (HeatingSetpoint - Temperature) * state.dataGlobal->TimeStepZone;
    6307              :                     }
    6308              :                 }
    6309              :             }
    6310              :         } // loop over zones
    6311              :     }
    6312        69975 : }
    6313              : 
    6314           55 : void ReportCO2Resilience(EnergyPlusData &state)
    6315              : {
    6316           55 :     if (state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime) {
    6317           40 :         int NoBins = 3;
    6318           86 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6319           48 :             for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6320            2 :                 state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6321            2 :                 state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6322            2 :                 state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6323              :             }
    6324              :         }
    6325           40 :         state.dataHeatBalSurfMgr->reportCO2ResilienceFirstTime = false;
    6326           40 :         if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
    6327           38 :             if (state.dataOutRptTab->displayCO2ResilienceSummaryExplicitly) {
    6328            0 :                 ShowWarningError(state,
    6329              :                                  "Writing Annual CO2 Resilience Summary - CO2 Level Hours reports: "
    6330              :                                  "Zone Air CO2 Concentration output is required, "
    6331              :                                  "but no ZoneAirContaminantBalance object is defined.");
    6332              :             }
    6333           38 :             state.dataOutRptTab->displayCO2ResilienceSummary = false;
    6334           38 :             return;
    6335              :         }
    6336              :     }
    6337              : 
    6338           17 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    6339           34 :         for (auto const &people : state.dataHeatBal->People) {
    6340           17 :             state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
    6341           17 :         }
    6342              : 
    6343           17 :         Array1D_bool reportPeriodFlags;
    6344           17 :         if (state.dataWeather->TotReportPers > 0) {
    6345           16 :             reportPeriodFlags.dimension(state.dataWeather->TotCO2ReportPers, false);
    6346           16 :             General::findReportPeriodIdx(state, state.dataWeather->CO2ReportPeriodInput, state.dataWeather->TotCO2ReportPers, reportPeriodFlags);
    6347              :         }
    6348              : 
    6349           17 :         auto &ort = state.dataOutRptTab;
    6350           49 :         for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6351           32 :             if (reportPeriodFlags(i)) {
    6352           16 :                 int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    6353           16 :                 state.dataWeather->CO2ReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    6354              :             }
    6355              :         }
    6356              : 
    6357           34 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6358           17 :             Real64 ZoneAirCO2 = state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum);
    6359              : 
    6360           17 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6361           17 :             if (ZoneAirCO2 <= 1000) {
    6362            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[0] += state.dataGlobal->TimeStepZone;
    6363            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6364            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6365           13 :             } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
    6366           12 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[1] += state.dataGlobal->TimeStepZone;
    6367           12 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6368           12 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6369              :             } else {
    6370            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelHourBins[2] += state.dataGlobal->TimeStepZone;
    6371            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6372            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneCO2LevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6373              :             }
    6374           49 :             for (int i = 1; i <= state.dataWeather->TotCO2ReportPers; i++) {
    6375           32 :                 if (reportPeriodFlags(i)) {
    6376           16 :                     int ReportPeriodIdx = i;
    6377           16 :                     if (ZoneAirCO2 <= 1000) {
    6378            4 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6379            4 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6380            4 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6381            4 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6382            4 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6383           12 :                     } else if (ZoneAirCO2 > 1000 && ZoneAirCO2 <= 5000) {
    6384           11 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6385           11 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6386           11 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6387           11 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6388           11 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6389              :                     } else {
    6390            1 :                         state.dataHeatBalFanSys->ZoneCO2LevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6391            1 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6392            1 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6393            1 :                         state.dataHeatBalFanSys->ZoneCO2LevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6394            1 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6395              :                     }
    6396              :                 }
    6397              :             }
    6398              :         }
    6399           17 :     } // loop over zones
    6400              : }
    6401              : 
    6402           55 : void ReportVisualResilience(EnergyPlusData &state)
    6403              : {
    6404           55 :     if (state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime) {
    6405           40 :         int NoBins = 4;
    6406           86 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6407           48 :             for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6408            2 :                 state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6409            2 :                 state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6410            2 :                 state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, i).assign(NoBins, 0.0);
    6411              :             }
    6412              :         }
    6413           40 :         state.dataHeatBalSurfMgr->reportVisualResilienceFirstTime = false;
    6414           40 :         if ((int)state.dataDayltg->daylightControl.size() == 0) {
    6415           38 :             if (state.dataOutRptTab->displayVisualResilienceSummaryExplicitly) {
    6416            0 :                 ShowWarningError(state,
    6417              :                                  "Writing Annual Visual Resilience Summary - Lighting Level Hours reports: "
    6418              :                                  "Zone Average Daylighting Reference Point Illuminance output is required, "
    6419              :                                  "but no Daylighting Control Object is defined.");
    6420              :             }
    6421           38 :             state.dataOutRptTab->displayVisualResilienceSummary = false;
    6422           38 :             return;
    6423              :         }
    6424              :     }
    6425              : 
    6426           17 :     if (Constant::KindOfSim::RunPeriodWeather == state.dataGlobal->KindOfSim && !state.dataGlobal->WarmupFlag) {
    6427           34 :         for (auto const &people : state.dataHeatBal->People) {
    6428           17 :             state.dataHeatBal->Resilience(people.ZonePtr).ZoneNumOcc = people.NumberOfPeople * people.sched->getCurrentVal();
    6429           17 :         }
    6430              :         // Accumulate across daylighting controls first
    6431           34 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6432           17 :             state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum = 0.0;
    6433              :         }
    6434           34 :         for (int daylightCtrlNum = 1; daylightCtrlNum <= (int)state.dataDayltg->daylightControl.size(); ++daylightCtrlNum) {
    6435           17 :             auto &thisDaylightControl = state.dataDayltg->daylightControl(daylightCtrlNum);
    6436           17 :             if (thisDaylightControl.PowerReductionFactor > 0) {
    6437           34 :                 for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
    6438           17 :                     state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum += thisDaylightControl.refPts(refPt).illumSetPoint;
    6439              :                 }
    6440              :             } else {
    6441            0 :                 for (int refPt = 1; refPt <= thisDaylightControl.TotalDaylRefPoints; ++refPt) {
    6442            0 :                     state.dataDayltg->ZoneDaylight(thisDaylightControl.zoneIndex).zoneAvgIllumSum +=
    6443            0 :                         thisDaylightControl.refPts(refPt).lums[(int)DataSurfaces::Lum::Illum];
    6444              :                 }
    6445              :             }
    6446              :         }
    6447              : 
    6448           17 :         Array1D_bool reportPeriodFlags;
    6449           17 :         if (state.dataWeather->TotReportPers > 0) {
    6450           16 :             reportPeriodFlags.dimension(state.dataWeather->TotVisualReportPers, false);
    6451           32 :             General::findReportPeriodIdx(
    6452           16 :                 state, state.dataWeather->VisualReportPeriodInput, state.dataWeather->TotVisualReportPers, reportPeriodFlags);
    6453              :         }
    6454              : 
    6455           17 :         auto &ort = state.dataOutRptTab;
    6456           49 :         for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6457           32 :             if (reportPeriodFlags(i)) {
    6458           16 :                 int curResMeterNumber = ort->meterNumTotalsBEPS(1);
    6459           16 :                 state.dataWeather->VisualReportPeriodInput(i).totalElectricityUse += GetCurrentMeterValue(state, curResMeterNumber);
    6460              :             }
    6461              :         }
    6462              : 
    6463           34 :         for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) {
    6464           17 :             if (state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts == 0) {
    6465            0 :                 continue;
    6466              :             }
    6467              :             // Now divide by total reference points to get average
    6468           17 :             Real64 avgZoneIllum = state.dataDayltg->ZoneDaylight(ZoneNum).zoneAvgIllumSum / state.dataDayltg->ZoneDaylight(ZoneNum).totRefPts;
    6469              : 
    6470           17 :             Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc;
    6471           17 :             if (avgZoneIllum <= 100) {
    6472            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[0] += state.dataGlobal->TimeStepZone;
    6473            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[0] += NumOcc * state.dataGlobal->TimeStepZone;
    6474            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[0] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6475           11 :             } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
    6476            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[1] += state.dataGlobal->TimeStepZone;
    6477            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[1] += NumOcc * state.dataGlobal->TimeStepZone;
    6478            4 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[1] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6479            7 :             } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
    6480            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[2] += state.dataGlobal->TimeStepZone;
    6481            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[2] += NumOcc * state.dataGlobal->TimeStepZone;
    6482            1 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[2] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6483              :             } else {
    6484            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelHourBins[3] += state.dataGlobal->TimeStepZone;
    6485            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccuHourBins[3] += NumOcc * state.dataGlobal->TimeStepZone;
    6486            6 :                 state.dataHeatBal->Resilience(ZoneNum).ZoneLightingLevelOccupiedHourBins[3] += (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6487              :             }
    6488           49 :             for (int i = 1; i <= state.dataWeather->TotVisualReportPers; i++) {
    6489           32 :                 if (reportPeriodFlags(i)) {
    6490           16 :                     int ReportPeriodIdx = i;
    6491           16 :                     if (avgZoneIllum <= 100) {
    6492            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] += state.dataGlobal->TimeStepZone;
    6493            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6494            6 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6495            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[0] +=
    6496            6 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6497           10 :                     } else if (avgZoneIllum > 100 && avgZoneIllum <= 300) {
    6498            4 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] += state.dataGlobal->TimeStepZone;
    6499            4 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6500            4 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6501            4 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[1] +=
    6502            4 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6503            6 :                     } else if (avgZoneIllum > 300 && avgZoneIllum <= 500) {
    6504            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] += state.dataGlobal->TimeStepZone;
    6505            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6506            0 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6507            0 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[2] +=
    6508            0 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6509              :                     } else {
    6510            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] += state.dataGlobal->TimeStepZone;
    6511            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccuHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6512            6 :                             NumOcc * state.dataGlobal->TimeStepZone;
    6513            6 :                         state.dataHeatBalFanSys->ZoneLightingLevelOccupiedHourBinsRepPeriod(ZoneNum, ReportPeriodIdx)[3] +=
    6514            6 :                             (NumOcc > 0) * state.dataGlobal->TimeStepZone;
    6515              :                     }
    6516              :                 }
    6517              :             }
    6518              :         }
    6519           17 :     } // loop over zones
    6520              : }
    6521              : 
    6522       249948 : void ReportSurfaceHeatBalance(EnergyPlusData &state)
    6523              : {
    6524              : 
    6525              :     // SUBROUTINE INFORMATION:
    6526              :     //       AUTHOR         Linda Lawrie
    6527              :     //       DATE WRITTEN   Oct 2000
    6528              : 
    6529              :     // PURPOSE OF THIS SUBROUTINE:
    6530              :     // This subroutine puts the reporting part of the HBSurface Module in one area.
    6531              : 
    6532       249948 :     SolarShading::ReportSurfaceShading(state);
    6533              : 
    6534       249948 :     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    6535            0 :         ReportNonRepresentativeSurfaceResults(state);
    6536              :     }
    6537              : 
    6538              :     // Set derived surface output variables and other record keeping - after iterations are complete - all HT surfaces
    6539              : 
    6540              :     // Opaque or window surfaces
    6541       586590 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6542       706887 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6543       370245 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6544       370245 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    6545       370245 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    6546      2439100 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6547      2068855 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6548              :                 // Inside Face Convection - sign convention is positive means energy going into inside face from the air.
    6549      2068855 :                 state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum);
    6550      2068855 :                 state.dataHeatBalSurf->SurfQConvInRep(surfNum) =
    6551      2068855 :                     state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6552              : 
    6553      2068855 :                 state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
    6554      2068855 :                 state.dataHeatBalSurf->SurfQRadNetSurfInRep(surfNum) =
    6555      2068855 :                     state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6556              : 
    6557      2068855 :                 state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area;
    6558      2068855 :                 state.dataHeatBalSurf->SurfQRadIntGainsInRep(surfNum) =
    6559      2068855 :                     state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6560              : 
    6561      2068855 :                 state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area;
    6562      2068855 :                 state.dataHeatBalSurf->SurfQRadHVACInRep(surfNum) =
    6563      2068855 :                     state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6564              : 
    6565      2068855 :                 state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area;
    6566              : 
    6567      2068855 :                 state.dataHeatBalSurf->SurfQConvOutReport(surfNum) =
    6568      2068855 :                     state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6569              : 
    6570      2068855 :                 state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area;
    6571      2068855 :                 state.dataHeatBalSurf->SurfQRadOutReport(surfNum) =
    6572      2068855 :                     state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6573              : 
    6574              :                 // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside
    6575      2068855 :                 state.dataHeatBalSurf->SurfQAirExtReport(surfNum) =
    6576      2068855 :                     surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) *
    6577      2068855 :                     (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum));
    6578              : 
    6579              :                 // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface)
    6580      2068855 :                 state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) =
    6581      2068855 :                     state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum);
    6582              :             }
    6583       336642 :         }
    6584              :     }
    6585              : 
    6586       249948 :     if (state.dataOutRptTab->displayHeatEmissionsSummary) {
    6587        69935 :         state.dataHeatBalSurf->SumSurfaceHeatEmission = 0.0;
    6588       508457 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    6589       438522 :             if (state.dataSurface->Surface(SurfNum).ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    6590       350203 :                 state.dataHeatBalSurf->SumSurfaceHeatEmission +=
    6591       350203 :                     state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) * state.dataGlobal->TimeStepZoneSec;
    6592              :             }
    6593              :         }
    6594              :     }
    6595              : 
    6596              :     // Window surfaces
    6597       586590 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6598       706887 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6599       370245 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6600       370245 :             int const firstSurf = thisSpace.WindowSurfaceFirst;
    6601       370245 :             int const lastSurf = thisSpace.WindowSurfaceLast;
    6602       458806 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6603        88561 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6604        88561 :                 state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) =
    6605        88561 :                     state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area;
    6606              : 
    6607              :                 // Absorbed short wave radiation
    6608              :                 int TotGlassLayers;
    6609        88561 :                 int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum);
    6610        88561 :                 auto const &thisConstruct = state.dataConstruction->Construct(constrNum);
    6611        88561 :                 int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum);
    6612        88561 :                 DataSurfaces::WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum);
    6613        88561 :                 if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::EQL) {
    6614         2367 :                     TotGlassLayers = state.dataWindowEquivLayer->CFS(thisConstruct.EQLConsPtr).NL;
    6615        86194 :                 } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == DataSurfaces::WindowModel::BSDF) {
    6616            0 :                     TotGlassLayers = thisConstruct.TotSolidLayers;
    6617        86194 :                 } else if (DataSurfaces::NOT_SHADED(ShadeFlag) || ShadeFlag == DataSurfaces::WinShadingType::SwitchableGlazing) {
    6618        86194 :                     TotGlassLayers = thisConstruct.TotGlassLayers;
    6619              :                 } else {
    6620              :                     // Interior, exterior or between-glass shade, screen or blind in place
    6621            0 :                     TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers;
    6622              :                 }
    6623        88561 :                 state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0;
    6624        88561 :                 state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0;
    6625        88561 :                 state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0;
    6626       205255 :                 for (int lay = 1; lay <= TotGlassLayers; ++lay) {
    6627              :                     // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
    6628       116694 :                     state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) +=
    6629       116694 :                         state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area;
    6630              :                     // Total Shortwave Radiation Absorbed on Inside of Surface[W]
    6631       116694 :                     state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
    6632              :                     // Total Shortwave Absorbed:All solid Layers[W]
    6633       116694 :                     state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area;
    6634              :                 }
    6635              : 
    6636              :                 // Window heat gain/loss
    6637        88561 :                 if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) {
    6638        32908 :                     state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum);
    6639        32908 :                     state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) =
    6640        32908 :                         state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6641              :                 } else {
    6642        55653 :                     state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum);
    6643        55653 :                     state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) =
    6644        55653 :                         state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6645              :                 }
    6646        88561 :                 state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) =
    6647        88561 :                     state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6648        88561 :                 if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    6649            0 :                     int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
    6650            0 :                     state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum);
    6651            0 :                     state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum);
    6652              :                 }
    6653              :             }
    6654       336642 :         }
    6655              :     }
    6656              : 
    6657       249948 :     if (state.dataSurface->AnyMovableInsulation) {
    6658            0 :         ReportIntMovInsInsideSurfTemp(state);
    6659              :     }
    6660              : 
    6661              :     // Opaque heat transfer surfaces
    6662       586590 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6663       706887 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6664       370245 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6665       370245 :             int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6666       370245 :             int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6667      2350539 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6668      1980294 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6669              : 
    6670      1980294 :                 state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area;
    6671      1980294 :                 state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) =
    6672      1980294 :                     state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6673              : 
    6674      1980294 :                 state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area;
    6675      1980294 :                 state.dataHeatBalSurf->SurfQRadSolarInRep(surfNum) =
    6676      1980294 :                     state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6677              : 
    6678      1980294 :                 state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area;
    6679      1980294 :                 state.dataHeatBalSurf->SurfQRadLightsInRep(surfNum) =
    6680      1980294 :                     state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6681              : 
    6682              :                 // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W]
    6683      1980294 :                 state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area;
    6684              :                 // Total Shortwave Radiation Absorbed on Inside of Surface[W]
    6685      1980294 :                 state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area;
    6686              : 
    6687              :                 // inside face conduction updates
    6688      1980294 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area;
    6689      1980294 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) =
    6690      1980294 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6691      1980294 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0;
    6692      1980294 :                 state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0;
    6693      1980294 :                 if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) {
    6694       842732 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6695              :                 } else {
    6696      1137562 :                     state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6697              :                 }
    6698              : 
    6699              :                 // outside face conduction updates
    6700      1980294 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum);
    6701      1980294 :                 state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) =
    6702      1980294 :                     state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6703      1980294 :                 state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0;
    6704      1980294 :                 state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0;
    6705      1980294 :                 if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) {
    6706      1320256 :                     state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6707              :                 } else {
    6708       660038 :                     state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6709              :                 }
    6710              :             }
    6711      2350539 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6712              :                 // do average surface conduction updates
    6713              : 
    6714      1980294 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) =
    6715      1980294 :                     (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0;
    6716      1980294 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) =
    6717      1980294 :                     (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0;
    6718      1980294 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) =
    6719      1980294 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6720      1980294 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0;
    6721      1980294 :                 state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0;
    6722      1980294 :                 if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) {
    6723       806811 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
    6724              :                 } else {
    6725      1173483 :                     state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum);
    6726              :                 }
    6727              : 
    6728              :                 // do surface storage rate updates
    6729      1980294 :                 state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) =
    6730      1980294 :                     -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum));
    6731      1980294 :                 state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) =
    6732      1980294 :                     -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum));
    6733      1980294 :                 state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) =
    6734      1980294 :                     state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec;
    6735      1980294 :                 state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0;
    6736      1980294 :                 state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0;
    6737      1980294 :                 if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) {
    6738      1045196 :                     state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
    6739              :                 } else {
    6740       935098 :                     state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum);
    6741              :                 }
    6742              :             }
    6743       336642 :         }
    6744              :     }
    6745              : 
    6746       249948 :     if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) {
    6747              :         // This is by surface, so it works for both space and zone component loads
    6748        14868 :         int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
    6749        14868 :         auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
    6750        43206 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6751        56676 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6752        28338 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6753        28338 :                 int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6754        28338 :                 int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6755       171426 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6756       143088 :                     surfCLDayTS.surf[surfNum - 1].lightSWRadSeq = state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum);
    6757       143088 :                     surfCLDayTS.surf[surfNum - 1].feneSolarRadSeq = state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum);
    6758              :                 }
    6759        28338 :                 firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    6760        28338 :                 lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    6761       178212 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6762       149874 :                     auto const &surface = state.dataSurface->Surface(surfNum);
    6763       149874 :                     if (!state.dataGlobal->WarmupFlag) {
    6764        20640 :                         if (state.dataGlobal->isPulseZoneSizing) {
    6765        10320 :                             surfCLDayTS.surf[surfNum - 1].loadConvectedWithPulse = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
    6766              :                         } else {
    6767        10320 :                             surfCLDayTS.surf[surfNum - 1].loadConvectedNormal = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum);
    6768        10320 :                             surfCLDayTS.surf[surfNum - 1].netSurfRadSeq = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area;
    6769              :                         }
    6770              :                     }
    6771              :                 }
    6772        28338 :             }
    6773              :         }
    6774              :     }
    6775              : 
    6776       249948 :     if (state.dataGlobal->DisplayAdvancedReportVariables) {
    6777            0 :         for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6778            0 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6779            0 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6780            0 :                 int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    6781            0 :                 int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    6782            0 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6783            0 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum);
    6784            0 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum);
    6785              :                 }
    6786            0 :                 if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) {
    6787            0 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
    6788            0 :                     state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) =
    6789            0 :                         state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6790              :                 } else {
    6791            0 :                     state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum);
    6792            0 :                     state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) =
    6793            0 :                         state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6794              :                 }
    6795              : 
    6796            0 :                 if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) {
    6797            0 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
    6798            0 :                     state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) =
    6799            0 :                         state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6800              :                 } else {
    6801            0 :                     state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum);
    6802            0 :                     state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) =
    6803            0 :                         state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec;
    6804              :                 }
    6805            0 :             }
    6806              :         }
    6807              :     }
    6808       249948 : }
    6809              : 
    6810            0 : void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state)
    6811              : {
    6812            0 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) {
    6813            0 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6814            0 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    6815              :             // Heat transfer surfaces
    6816            0 :             int firstSurf = thisSpace.HTSurfaceFirst;
    6817            0 :             int lastSurf = thisSpace.HTSurfaceLast;
    6818            0 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6819            0 :                 auto const &surface = state.dataSurface->Surface(surfNum);
    6820            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    6821            0 :                 if (surfNum != repSurfNum) {
    6822            0 :                     state.dataSurface->surfIntConv(surfNum).convClassRpt = state.dataSurface->surfIntConv(repSurfNum).convClassRpt;
    6823            0 :                     state.dataSurface->surfExtConv(surfNum).convClassRpt = state.dataSurface->surfExtConv(repSurfNum).convClassRpt;
    6824              :                 }
    6825              :             }
    6826              : 
    6827              :             // Windows
    6828            0 :             if (state.dataGlobal->DisplayAdvancedReportVariables) {
    6829            0 :                 firstSurf = thisSpace.WindowSurfaceFirst;
    6830            0 :                 lastSurf = thisSpace.WindowSurfaceLast;
    6831            0 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    6832            0 :                     auto const &surface = state.dataSurface->Surface(surfNum);
    6833            0 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    6834            0 :                     if (surfNum != repSurfNum) {
    6835            0 :                         Real64 areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area;
    6836            0 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    6837            0 :                             state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio;
    6838            0 :                         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
    6839            0 :                             state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio;
    6840            0 :                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
    6841            0 :                             state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio;
    6842              :                     }
    6843              :                 }
    6844              :             }
    6845            0 :         }
    6846              :     }
    6847            0 : }
    6848              : 
    6849            1 : void ReportIntMovInsInsideSurfTemp(EnergyPlusData &state)
    6850              : {
    6851            1 :     state.dataHeatBalSurf->SurfTempInMovInsRep = state.dataHeatBalSurf->SurfTempIn;
    6852            3 :     for (int SurfNum : state.dataSurface->intMovInsulSurfNums) {
    6853            2 :         if (state.dataSurface->intMovInsuls(SurfNum).present) {
    6854            1 :             state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    6855              :         }
    6856            1 :     }
    6857            1 : }
    6858              : // End of Reporting subroutines for the HB Module
    6859              : // *****************************************************************************
    6860              : 
    6861              : // *****************************************************************************
    6862              : // *****************************************************************************
    6863              : // *****************************************************************************
    6864              : // *****************************************************************************
    6865              : 
    6866              : // Formerly EXTERNAL SUBROUTINES (heavily related to HeatBalanceSurfaceManager) now moved into namespace
    6867              : 
    6868       249962 : void CalcHeatBalanceOutsideSurf(EnergyPlusData &state,
    6869              :                                 ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    6870              : {
    6871              : 
    6872              :     // SUBROUTINE INFORMATION:
    6873              :     //       AUTHOR         George Walton
    6874              :     //       DATE WRITTEN   December 1979
    6875              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays);
    6876              :     //                      Aug 2000 (RJL for MTF moisture calculations)
    6877              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    6878              :     //                      Dec 2000 (RKS for radiant system model addition)
    6879              :     //                      Apr 2002 (COP removed denominator from OSC calculation
    6880              :     //                      Jul 2008 (P.Biddulph include calls to HAMT)
    6881              :     //                      Jul 2011, M.J. Witte and C.O. Pedersen, add new fields to OSC for last T, max and min
    6882              :     //                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    6883              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    6884              : 
    6885              :     // PURPOSE OF THIS SUBROUTINE:
    6886              :     // This subroutine performs a heat balance on the outside face of each
    6887              :     // surface in the building.
    6888              : 
    6889              :     // METHODOLOGY EMPLOYED:
    6890              :     // Various boundary conditions are set and additional parameters are set-
    6891              :     // up.  Then, the proper heat balance equation is selected based on the
    6892              :     // presence of movable insulation, thermal mass of the surface construction,
    6893              :     // and convection model being used.
    6894              : 
    6895              :     // REFERENCES:
    6896              :     // (I)BLAST legacy routine HBOUT
    6897              :     // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
    6898              : 
    6899              :     //    // Using/Aliasing
    6900              :     //    using namespace DataEnvironment;
    6901              :     //    using namespace DataHeatBalance;
    6902              :     //    using namespace DataHeatBalSurface;
    6903              :     //    using namespace DataSurfaces;
    6904              :     //    using HeatBalanceIntRadExchange::CalcInteriorRadExchange;
    6905              :     //    using namespace Psychrometrics;
    6906              :     //    using EcoRoofManager::CalcEcoRoof;
    6907              :     //
    6908              :     //    // Locals
    6909              :     //    // SUBROUTINE ARGUMENT DEFINITIONS:
    6910              :     //
    6911              :     //>>>>>>> origin/develop
    6912              :     // SUBROUTINE PARAMETER DEFINITIONS:
    6913       249962 :     constexpr std::string_view RoutineNameGroundTemp("CalcHeatBalanceOutsideSurf:GroundTemp");
    6914       249962 :     constexpr std::string_view RoutineNameGroundTempFC("CalcHeatBalanceOutsideSurf:GroundTempFC");
    6915       249962 :     constexpr std::string_view RoutineNameOtherSideCoefNoCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefNoCalcExt");
    6916       249962 :     constexpr std::string_view RoutineNameOtherSideCoefCalcExt("CalcHeatBalanceOutsideSurf:OtherSideCoefCalcExt");
    6917       249962 :     constexpr std::string_view RoutineNameOSCM("CalcHeatBalanceOutsideSurf:OSCM");
    6918       249962 :     constexpr std::string_view RoutineNameExtEnvWetSurf("CalcHeatBalanceOutsideSurf:extEnvWetSurf");
    6919       249962 :     constexpr std::string_view RoutineNameExtEnvDrySurf("CalcHeatBalanceOutsideSurf:extEnvDrySurf");
    6920       249962 :     constexpr std::string_view RoutineNameNoWind("CalcHeatBalanceOutsideSurf:nowind");
    6921       249962 :     constexpr std::string_view RoutineNameOther("CalcHeatBalanceOutsideSurf:interior/other");
    6922       249962 :     constexpr std::string_view RoutineNameIZPart("CalcHeatBalanceOutsideSurf:IZPart");
    6923       249962 :     constexpr std::string_view HBSurfManGroundHAMT("HBSurfMan:Ground:HAMT");
    6924       249962 :     constexpr std::string_view HBSurfManRainHAMT("HBSurfMan:Rain:HAMT");
    6925       249962 :     constexpr std::string_view HBSurfManDrySurfCondFD("HBSurfMan:DrySurf:CondFD");
    6926       249962 :     constexpr std::string_view Outside("Outside");
    6927              : 
    6928       249962 :     auto &s_mat = state.dataMaterial;
    6929              : 
    6930       249962 :     bool MovInsulErrorFlag = false; // Movable Insulation error flag
    6931              : 
    6932              :     // set ground surfaces average temperature
    6933       249962 :     GetGroundSurfacesTemperatureAverage(state);
    6934              : 
    6935              :     // set surrounding surfaces average temperature
    6936       249962 :     GetSurroundingSurfacesTemperatureAverage(state);
    6937              : 
    6938       249962 :     auto &Surface = state.dataSurface->Surface;
    6939              : 
    6940       249962 :     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    6941            0 :         for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    6942              :             // Need to transfer any source/sink for a surface to the local array.  Note that
    6943              :             // the local array is flux (W/m2) while the QRadSysSource is heat transfer (W).
    6944              :             // This must be done at this location so that this is always updated correctly.
    6945            0 :             if (Surface(SurfNum).Area > 0.0) {
    6946            0 :                 state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) =
    6947            0 :                     state.dataHeatBalFanSys->QRadSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
    6948              :             }
    6949              : 
    6950              :             // next we add source (actually a sink) from any integrated PV
    6951            0 :             if (Surface(SurfNum).Area > 0.0) {
    6952            0 :                 state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +=
    6953            0 :                     state.dataHeatBalFanSys->QPVSysSource(SurfNum) / Surface(SurfNum).Area; // Make sure we don't divide by zero...
    6954              :             }
    6955              :         }
    6956              :     }
    6957              : 
    6958       249962 :     if (present(ZoneToResimulate)) {
    6959           16 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(
    6960            8 :             state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, ZoneToResimulate, Outside);
    6961              :     } else {
    6962       499908 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(
    6963       249954 :             state, state.dataHeatBalSurf->SurfInsideTempHist(1), 0, state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea, _, Outside);
    6964              :     }
    6965              : 
    6966              :     // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    6967       249963 :     for (int surfNum : state.dataSurface->allOutsideSourceSurfaceList) {
    6968            1 :         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = Surface(surfNum).outsideHeatSourceTermSched->getCurrentVal();
    6969       249962 :     }
    6970       586618 :     for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces...
    6971       706939 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    6972       370283 :             auto &thisSpace = state.dataHeatBal->space(spaceNum);
    6973      2439206 :             for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
    6974      2068923 :                 if (Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) {
    6975        88560 :                     continue;
    6976              :                 }
    6977      1980363 :                 if (present(ZoneToResimulate)) {
    6978           32 :                     if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) {
    6979            0 :                         continue; // skip surfaces that are not associated with this zone
    6980              :                     }
    6981              :                 }
    6982              :                 // Interior windows in partitions use "normal" heat balance calculations
    6983              :                 // For rest, Outside surface temp of windows not needed in Window5 calculation approach.
    6984              :                 // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf
    6985              : 
    6986              :                 // Initializations for this surface
    6987      1980363 :                 int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum);
    6988      1980363 :                 auto const &thisConstruct = state.dataConstruction->Construct(ConstrNum);
    6989      1980363 :                 Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation
    6990      1980363 :                 Real64 HSky = 0.0;      // "Convection" coefficient from sky to surface
    6991      1980363 :                 Real64 HGround = 0.0;   // "Convection" coefficient from ground to surface
    6992      1980363 :                 Real64 HAir = 0.0;      // "Convection" coefficient from air to surface (radiation)
    6993      1980363 :                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 0.0;
    6994      1980363 :                 state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0;
    6995      1980363 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0;
    6996      1980363 :                 state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0;
    6997      1980363 :                 state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0;
    6998              : 
    6999              :                 // Calculate the current outside surface temperature TH(SurfNum,1,1) for the
    7000              :                 // various different boundary conditions
    7001      1980363 :                 switch (Surface(SurfNum).ExtBoundCond) {
    7002       119149 :                 case DataSurfaces::Ground: { // Surface in contact with ground
    7003       119149 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    7004       119149 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    7005              : 
    7006              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7007       119149 :                     if (thisConstruct.SourceSinkPresent) {
    7008            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7009              :                     }
    7010              : 
    7011              :                     // start HAMT
    7012       119149 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7013              :                         // Set variables used in the HAMT moisture balance
    7014            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7015            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    7016            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
    7017            0 :                             state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0, HBSurfManGroundHAMT);
    7018            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7019              : 
    7020            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7021            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7022            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7023              :                                   state,
    7024            0 :                                   state.dataEnvrn->OutBaroPress,
    7025            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    7026              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7027            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    7028              :                                                                 1.0,
    7029            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7030            0 :                                                                 RoutineNameGroundTemp)) +
    7031            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7032            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7033              : 
    7034            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7035            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7036            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7037              :                     }
    7038              :                     // end HAMT
    7039              : 
    7040       119149 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7041              :                         // Set variables used in the FD moisture balance
    7042            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7043            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface];
    7044            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
    7045            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface], 1.0);
    7046            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7047            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7048            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7049            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7050              :                                   state,
    7051            0 :                                   state.dataEnvrn->OutBaroPress,
    7052            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    7053              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7054            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface],
    7055              :                                                                 1.0,
    7056            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7057            0 :                                                                 RoutineNameGroundTemp)) +
    7058            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7059            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7060            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7061            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7062            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7063              :                     }
    7064              :                     // Added for FCfactor grounds
    7065       119149 :                 } break;
    7066            0 :                 case DataSurfaces::GroundFCfactorMethod: { // Surface in contact with ground
    7067            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    7068            0 :                         state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    7069              : 
    7070              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7071            0 :                     if (thisConstruct.SourceSinkPresent) {
    7072            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7073              :                     }
    7074              : 
    7075            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7076              :                         // Set variables used in the HAMT moisture balance
    7077            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7078            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    7079            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRh(
    7080            0 :                             state, state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0, HBSurfManGroundHAMT);
    7081            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7082              : 
    7083            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7084            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7085            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7086              :                                   state,
    7087            0 :                                   state.dataEnvrn->OutBaroPress,
    7088            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7089              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7090            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7091              :                                                                 1.0,
    7092            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7093            0 :                                                                 RoutineNameGroundTempFC)) +
    7094            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7095            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7096              : 
    7097            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7098            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7099            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7100              :                     }
    7101              : 
    7102            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7103              :                         // Set variables used in the FD moisture balance
    7104            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) =
    7105            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod];
    7106            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbRhLBnd0C(
    7107            0 :                             state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod], 1.0);
    7108            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7109            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7110            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7111            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7112              :                                   state,
    7113            0 :                                   state.dataEnvrn->OutBaroPress,
    7114            0 :                                   state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7115              :                                   Psychrometrics::PsyWFnTdbRhPb(state,
    7116            0 :                                                                 state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::FCFactorMethod],
    7117              :                                                                 1.0,
    7118            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7119            0 :                                                                 RoutineNameGroundTempFC)) +
    7120            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7121            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7122            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7123            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7124            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7125              :                     }
    7126            0 :                 } break;
    7127            0 :                 case DataSurfaces::OtherSideCoefNoCalcExt: {
    7128              :                     // Use Other Side Coefficients to determine the surface film coefficient and
    7129              :                     // the exterior boundary condition temperature
    7130              : 
    7131            0 :                     int OPtr = Surface(SurfNum).OSCPtr;
    7132              :                     // Set surface temp from previous timestep
    7133            0 :                     if (state.dataGlobal->BeginTimeStepFlag) {
    7134            0 :                         state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7135              :                     }
    7136              : 
    7137            0 :                     if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
    7138            0 :                         state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
    7139              :                     }
    7140              : 
    7141              :                     //  Allow for modification of TemperatureCoefficient with unitary sine wave.
    7142              :                     Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod
    7143            0 :                     if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4
    7144            0 :                         ConstantTempCoef = std::sin(2 * Constant::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod);
    7145              :                     } else {
    7146            0 :                         ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef;
    7147              :                     }
    7148              : 
    7149            0 :                     state.dataSurface->OSC(OPtr).OSCTempCalc =
    7150            0 :                         (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    7151            0 :                          state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7152            0 :                          ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
    7153            0 :                          state.dataSurface->OSC(OPtr).GroundTempCoef *
    7154            0 :                              state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
    7155            0 :                          state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
    7156            0 :                              state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7157            0 :                          state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
    7158              : 
    7159              :                     // Enforce max/min limits if applicable
    7160            0 :                     if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
    7161            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7162            0 :                             max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7163              :                     }
    7164            0 :                     if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
    7165            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7166            0 :                             min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7167              :                     }
    7168              : 
    7169            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc;
    7170              : 
    7171              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7172            0 :                     if (thisConstruct.SourceSinkPresent) {
    7173            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7174              :                     }
    7175              : 
    7176            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7177            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7178              :                         // Set variables used in the FD moisture balance and HAMT
    7179            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7180            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7181            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7182            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit;
    7183            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7184            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7185            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7186            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7187            0 :                                                                 state.dataMstBal->TempOutsideAirFD(SurfNum),
    7188              :                                                                 Psychrometrics::PsyWFnTdbRhPb(state,
    7189            0 :                                                                                               state.dataMstBal->TempOutsideAirFD(SurfNum),
    7190              :                                                                                               1.0,
    7191            0 :                                                                                               state.dataEnvrn->OutBaroPress,
    7192            0 :                                                                                               RoutineNameOtherSideCoefNoCalcExt)) +
    7193            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7194            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7195            0 :                         state.dataMstBal->HSkyFD(SurfNum) = HSky;
    7196            0 :                         state.dataMstBal->HGrndFD(SurfNum) = HGround;
    7197            0 :                         state.dataMstBal->HAirFD(SurfNum) = HAir;
    7198              :                     }
    7199              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7200            0 :                 } break;
    7201            0 :                 case DataSurfaces::OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment
    7202              :                     // First, set up the outside convection coefficient and the exterior temperature
    7203              :                     // boundary condition for the surface
    7204            0 :                     int OPtr = Surface(SurfNum).OSCPtr;
    7205              :                     // Set surface temp from previous timestep
    7206            0 :                     if (state.dataGlobal->BeginTimeStepFlag) {
    7207            0 :                         state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7208              :                     }
    7209              : 
    7210            0 :                     if (state.dataSurface->OSC(OPtr).constTempSched != nullptr) { // Determine outside temperature from schedule
    7211            0 :                         state.dataSurface->OSC(OPtr).ConstTemp = state.dataSurface->OSC(OPtr).constTempSched->getCurrentVal();
    7212              :                     }
    7213              : 
    7214            0 :                     state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef;
    7215              : 
    7216            0 :                     state.dataSurface->OSC(OPtr).OSCTempCalc =
    7217            0 :                         (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    7218            0 :                          state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7219            0 :                          state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp +
    7220            0 :                          state.dataSurface->OSC(OPtr).GroundTempCoef *
    7221            0 :                              state.dataEnvrn->GroundTemp[(int)DataEnvironment::GroundTempType::BuildingSurface] +
    7222            0 :                          state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) *
    7223            0 :                              state.dataSurface->SurfOutDryBulbTemp(SurfNum) +
    7224            0 :                          state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast);
    7225              : 
    7226              :                     // Enforce max/min limits if applicable
    7227            0 :                     if (state.dataSurface->OSC(OPtr).MinLimitPresent) {
    7228            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7229            0 :                             max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7230              :                     }
    7231            0 :                     if (state.dataSurface->OSC(OPtr).MaxLimitPresent) {
    7232            0 :                         state.dataSurface->OSC(OPtr).OSCTempCalc =
    7233            0 :                             min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc);
    7234              :                     }
    7235              : 
    7236            0 :                     Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc;
    7237              : 
    7238              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7239            0 :                     if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
    7240            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7241              :                     }
    7242              : 
    7243            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7244            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7245              :                         // Set variables used in the FD moisture balance and HAMT
    7246            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7247            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7248            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7249            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7250            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7251            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7252            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7253            0 :                                                                 state.dataEnvrn->OutBaroPress,
    7254            0 :                                                                 state.dataMstBal->TempOutsideAirFD(SurfNum),
    7255              :                                                                 Psychrometrics::PsyWFnTdbRhPb(state,
    7256            0 :                                                                                               state.dataMstBal->TempOutsideAirFD(SurfNum),
    7257              :                                                                                               1.0,
    7258            0 :                                                                                               state.dataEnvrn->OutBaroPress,
    7259            0 :                                                                                               RoutineNameOtherSideCoefCalcExt)) +
    7260            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7261            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7262            0 :                         state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7263            0 :                         state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7264            0 :                         state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7265              :                     }
    7266              : 
    7267              :                     // Call the outside surface temp calculation and pass the necessary terms
    7268            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7269            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7270            0 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7271            0 :                         if (MovInsulErrorFlag) {
    7272            0 :                             ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7273              :                         }
    7274              :                     }
    7275              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7276            0 :                 } break;
    7277            0 :                 case DataSurfaces::OtherSideCondModeledExt: { // A surface with other side conditions determined from separate, dynamic component
    7278              :                     // modeling that defines the "outside environment"
    7279              :                     // First, set up the outside convection coefficient and the exterior temperature
    7280              :                     // boundary condition for the surface
    7281            0 :                     int OPtr = Surface(SurfNum).OSCMPtr;
    7282              :                     // EMS overrides
    7283            0 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv) {
    7284            0 :                         state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue;
    7285              :                     }
    7286            0 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv) {
    7287            0 :                         state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue;
    7288              :                     }
    7289            0 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad) {
    7290            0 :                         state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue;
    7291              :                     }
    7292            0 :                     if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad) {
    7293            0 :                         state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue;
    7294              :                     }
    7295            0 :                     state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv;
    7296              : 
    7297            0 :                     Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv;
    7298              : 
    7299              :                     // Set the only radiant system heat balance coefficient that is non-zero for this case
    7300            0 :                     if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) {
    7301            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7302              :                     }
    7303              : 
    7304            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7305            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7306              :                         // Set variables used in the FD moisture balance and HAMT
    7307            0 :                         state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7308            0 :                         state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7309            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7310            0 :                         state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7311            0 :                         state.dataMstBal->HMassConvExtFD(SurfNum) =
    7312            0 :                             state.dataMstBal->HConvExtFD(SurfNum) /
    7313            0 :                             ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7314              :                                   state,
    7315            0 :                                   state.dataEnvrn->OutBaroPress,
    7316            0 :                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7317              :                                   Psychrometrics::PsyWFnTdbRhPb(
    7318            0 :                                       state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) +
    7319            0 :                               state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7320            0 :                              Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7321            0 :                         state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR
    7322            0 :                         state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR
    7323            0 :                         state.dataMstBal->HAirFD(SurfNum) = 0.0;  // CR 8046, null out and use only sky term for surface to baffle IR
    7324              :                     }
    7325              : 
    7326              :                     // Call the outside surface temp calculation and pass the necessary terms
    7327            0 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7328            0 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7329              : 
    7330            0 :                         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    7331            0 :                             CalcExteriorVentedCavity(state, SurfNum);
    7332              :                         }
    7333              : 
    7334            0 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7335            0 :                         if (MovInsulErrorFlag) {
    7336            0 :                             ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7337              :                         }
    7338              : 
    7339            0 :                     } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7340            0 :                                Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7341            0 :                         if (state.dataSurface->SurfExtCavityPresent(SurfNum)) {
    7342            0 :                             CalcExteriorVentedCavity(state, SurfNum);
    7343              :                         }
    7344              :                     }
    7345              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7346            0 :                 } break;
    7347      1295912 :                 case DataSurfaces::ExternalEnvironment: {
    7348              :                     // checking the EcoRoof presented in the external environment
    7349              :                     // recompute each load by calling ecoroof
    7350              : 
    7351              :                     Real64 TempExt;
    7352              : 
    7353      1295912 :                     if (state.dataSurface->SurfExtEcoRoof(SurfNum)) {
    7354            0 :                         EcoRoofManager::CalcEcoRoof(state, SurfNum, ConstrNum, TempExt);
    7355            0 :                         continue;
    7356              :                     }
    7357              :                     // Roughness index of the exterior surface
    7358      1295912 :                     Material::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum);
    7359              :                     // Thermal absorptance of the exterior surface
    7360      1295912 :                     Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum);
    7361      1295912 :                     HMovInsul = 0;
    7362              :                     // Check for outside movable insulation
    7363      1295912 :                     if (state.dataSurface->AnyMovableInsulation && state.dataSurface->extMovInsuls(SurfNum).present) {
    7364            0 :                         HMovInsul = state.dataSurface->extMovInsuls(SurfNum).H;
    7365              :                     }
    7366              : 
    7367              :                     // Check for exposure to wind (exterior environment)
    7368      1295912 :                     if (Surface(SurfNum).ExtWind) {
    7369              : 
    7370              :                         // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine)
    7371      1212250 :                         Convect::InitExtConvCoeff(state,
    7372              :                                                   SurfNum,
    7373              :                                                   HMovInsul,
    7374              :                                                   RoughSurf,
    7375              :                                                   AbsThermSurf,
    7376      1212250 :                                                   state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7377      1212250 :                                                   state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7378      1212250 :                                                   state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7379      1212250 :                                                   state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7380      1212250 :                                                   state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7381      1212250 :                                                   state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7382              : 
    7383      1212250 :                         if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet
    7384              : 
    7385            0 :                             if (state.dataSurface->surfExtConv(SurfNum).userModelNum == 0) { // Reset SurfHcExt because of wetness
    7386            0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0;
    7387              :                             } else { // User set
    7388            0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    7389              :                             }
    7390              : 
    7391            0 :                             TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum);
    7392              : 
    7393              :                             // start HAMT
    7394            0 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7395              :                                 // Set variables used in the HAMT moisture balance
    7396            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7397            0 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) =
    7398            0 :                                     Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT);
    7399            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7400            0 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7401            0 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7402            0 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7403            0 :                                                                         state.dataEnvrn->OutBaroPress,
    7404            0 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7405              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7406            0 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7407              :                                                                                                       1.0,
    7408            0 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7409            0 :                                                                                                       RoutineNameExtEnvWetSurf)) +
    7410            0 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7411            0 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7412            0 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7413            0 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7414            0 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7415              :                             }
    7416              :                             // end HAMT
    7417            0 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    7418              :                                 // Set variables used in the FD moisture balance
    7419            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7420            0 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) =
    7421            0 :                                     Psychrometrics::PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0);
    7422            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7423            0 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7424            0 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7425            0 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7426            0 :                                                                         state.dataEnvrn->OutBaroPress,
    7427            0 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7428              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7429            0 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7430              :                                                                                                       1.0,
    7431            0 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7432            0 :                                                                                                       RoutineNameExtEnvWetSurf)) +
    7433            0 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7434            0 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7435            0 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7436            0 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7437            0 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7438              :                             }
    7439              : 
    7440              :                         } else { // Surface is dry, use the normal correlation
    7441              : 
    7442      1212250 :                             TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    7443              : 
    7444      2179640 :                             if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7445       967390 :                                 Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7446              :                                 // Set variables used in the FD moisture balance and HAMT
    7447       244860 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7448       244860 :                                 state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7449       244860 :                                     state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7450       244860 :                                 state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7451       244860 :                                 state.dataMstBal->HMassConvExtFD(SurfNum) =
    7452       244860 :                                     state.dataMstBal->HConvExtFD(SurfNum) /
    7453       489720 :                                     ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7454       244860 :                                                                         state.dataEnvrn->OutBaroPress,
    7455       244860 :                                                                         state.dataMstBal->TempOutsideAirFD(SurfNum),
    7456              :                                                                         Psychrometrics::PsyWFnTdbRhPb(state,
    7457       244860 :                                                                                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7458              :                                                                                                       1.0,
    7459       244860 :                                                                                                       state.dataEnvrn->OutBaroPress,
    7460       244860 :                                                                                                       RoutineNameExtEnvDrySurf)) +
    7461       489720 :                                       state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7462       244860 :                                      Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7463              :                                 //  check for saturation conditions of air
    7464              :                                 // Local temporary saturated vapor density for checking
    7465              :                                 Real64 RhoVaporSat =
    7466       244860 :                                     Psychrometrics::PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD);
    7467       244860 :                                 if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) {
    7468       144030 :                                     state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat;
    7469              :                                 }
    7470       244860 :                                 state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7471       244860 :                                 state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7472       244860 :                                 state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7473              :                             }
    7474              :                         }
    7475              : 
    7476              :                     } else { // No wind
    7477              : 
    7478              :                         // Calculate exterior heat transfer coefficients for windspeed = 0
    7479        83662 :                         Convect::InitExtConvCoeff(state,
    7480              :                                                   SurfNum,
    7481              :                                                   HMovInsul,
    7482              :                                                   RoughSurf,
    7483              :                                                   AbsThermSurf,
    7484        83662 :                                                   state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7485        83662 :                                                   state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7486        83662 :                                                   state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7487        83662 :                                                   state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7488        83662 :                                                   state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7489        83662 :                                                   state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7490              : 
    7491        83662 :                         TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    7492              : 
    7493       167324 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7494        83662 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7495              :                             // Set variables used in the FD moisture balance and HAMT
    7496            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt;
    7497            0 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = Psychrometrics::PsyRhovFnTdbWPb(
    7498            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
    7499            0 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvExt(SurfNum);
    7500            0 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7501            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7502            0 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7503            0 :                                                                     state.dataEnvrn->OutBaroPress,
    7504            0 :                                                                     state.dataMstBal->TempOutsideAirFD(SurfNum),
    7505              :                                                                     Psychrometrics::PsyWFnTdbRhPb(state,
    7506            0 :                                                                                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7507              :                                                                                                   1.0,
    7508            0 :                                                                                                   state.dataEnvrn->OutBaroPress,
    7509            0 :                                                                                                   RoutineNameNoWind)) +
    7510            0 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7511            0 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7512            0 :                             state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum);
    7513            0 :                             state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum);
    7514            0 :                             state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum);
    7515              :                         }
    7516              :                     }
    7517              :                     // Calculate LWR from surrounding surfaces if defined for an exterior surface
    7518      1295912 :                     if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) {
    7519            6 :                         int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum;
    7520              :                         // Absolute temperature of the outside surface of an exterior surface
    7521            6 :                         Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + Constant::Kelvin;
    7522           14 :                         for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface;
    7523              :                              SrdSurfNum++) {
    7524              :                             // View factor of a surrounding surface
    7525            8 :                             Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor;
    7526              :                             // Absolute temperature of a surrounding surface
    7527              :                             Real64 SrdSurfTempAbs =
    7528            8 :                                 state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() +
    7529            8 :                                 Constant::Kelvin;
    7530            8 :                             state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) +=
    7531            8 :                                 Constant::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf));
    7532              :                         }
    7533              :                     }
    7534              : 
    7535      1295912 :                     if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7536      1540772 :                         Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD ||
    7537       244860 :                         Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    7538      1051052 :                         CalcOutsideSurfTemp(state, SurfNum, spaceNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag);
    7539      1051052 :                         if (MovInsulErrorFlag) {
    7540            0 :                             ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions.");
    7541              :                         }
    7542              :                     }
    7543      1295912 :                 } break;
    7544              : 
    7545            0 :                 case DataSurfaces::KivaFoundation: {
    7546            0 :                     auto const *thisMaterial = s_mat->materials(state.dataConstruction->Construct(ConstrNum).LayerPoint(1));
    7547            0 :                     Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness;
    7548            0 :                     Real64 AbsThermSurf = thisMaterial->AbsorpThermal;
    7549              : 
    7550              :                     // Set Kiva exterior convection algorithms
    7551            0 :                     Convect::InitExtConvCoeff(state,
    7552              :                                               SurfNum,
    7553              :                                               HMovInsul,
    7554              :                                               RoughSurf,
    7555              :                                               AbsThermSurf,
    7556            0 :                                               state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum),
    7557            0 :                                               state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    7558            0 :                                               state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    7559            0 :                                               state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    7560            0 :                                               state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    7561            0 :                                               state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    7562            0 :                 } break;
    7563              : 
    7564       565302 :                 default: { // for interior or other zone surfaces
    7565              : 
    7566       565302 :                     if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass
    7567              : 
    7568       402090 :                         state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    7569              : 
    7570              :                         // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
    7571              : 
    7572       755208 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7573       353118 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7574              :                             // Set variables used in the FD moisture balance HAMT
    7575        48972 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    7576        48972 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum);
    7577        48972 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    7578        48972 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7579        48972 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7580        97944 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(
    7581              :                                       state,
    7582        48972 :                                       state.dataEnvrn->OutBaroPress,
    7583        48972 :                                       state.dataMstBal->TempOutsideAirFD(SurfNum),
    7584              :                                       Psychrometrics::PsyWFnTdbRhPb(
    7585        48972 :                                           state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) +
    7586        97944 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7587        48972 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7588        48972 :                             state.dataMstBal->HSkyFD(SurfNum) = 0.0;
    7589        48972 :                             state.dataMstBal->HGrndFD(SurfNum) = 0.0;
    7590        48972 :                             state.dataMstBal->HAirFD(SurfNum) = 0.0;
    7591              :                         }
    7592              : 
    7593              :                     } else { // Interzone partition
    7594              : 
    7595       163212 :                         state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    7596       163212 :                             state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
    7597              : 
    7598              :                         // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance
    7599              : 
    7600       326424 :                         if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    7601       163212 :                             Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    7602              :                             // Set variables used in the FD moisture balance and HAMT
    7603            0 :                             state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond);
    7604            0 :                             state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond);
    7605            0 :                             state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond);
    7606            0 :                             state.dataMstBal->HMassConvExtFD(SurfNum) =
    7607            0 :                                 state.dataMstBal->HConvExtFD(SurfNum) /
    7608            0 :                                 ((Psychrometrics::PsyRhoAirFnPbTdbW(state,
    7609            0 :                                                                     state.dataEnvrn->OutBaroPress,
    7610            0 :                                                                     state.dataMstBal->TempOutsideAirFD(SurfNum),
    7611              :                                                                     Psychrometrics::PsyWFnTdbRhPb(state,
    7612            0 :                                                                                                   state.dataMstBal->TempOutsideAirFD(SurfNum),
    7613              :                                                                                                   1.0,
    7614            0 :                                                                                                   state.dataEnvrn->OutBaroPress,
    7615            0 :                                                                                                   RoutineNameIZPart)) +
    7616            0 :                                   state.dataMstBal->RhoVaporAirOut(SurfNum)) *
    7617            0 :                                  Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat));
    7618            0 :                             state.dataMstBal->HSkyFD(SurfNum) = 0.0;
    7619            0 :                             state.dataMstBal->HGrndFD(SurfNum) = 0.0;
    7620            0 :                             state.dataMstBal->HAirFD(SurfNum) = 0.0;
    7621              :                         }
    7622              :                     }
    7623              :                     // This ends the calculations for this surface and goes on to the next SurfNum
    7624       565302 :                 } break;
    7625              :                 }
    7626              : 
    7627      1980363 :                 state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum);
    7628              :             }
    7629       336656 :         }
    7630              :     } // ...end of DO loop over all surface (actually heat transfer surfaces)
    7631       249962 : }
    7632              : 
    7633      1980365 : Real64 GetQdotConvOutPerArea(EnergyPlusData &state, int const SurfNum)
    7634              : {
    7635      1980365 :     auto const &surface = state.dataSurface->Surface(SurfNum);
    7636      1980365 :     int OPtr = surface.OSCMPtr;
    7637      1980365 :     if (surface.OSCMPtr > 0) { // Optr is set above in this case, use OSCM boundary data
    7638            0 :         return -state.dataSurface->OSCM(OPtr).HConv * (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->OSCM(OPtr).TConv);
    7639              :     } else {
    7640      1980365 :         if (state.dataEnvrn->IsRain) {
    7641            1 :             return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
    7642            1 :                    (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutWetBulbTemp(SurfNum));
    7643              :         } else {
    7644      1980364 :             return -state.dataHeatBalSurf->SurfHConvExt(SurfNum) *
    7645      1980364 :                    (state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) - state.dataSurface->SurfOutDryBulbTemp(SurfNum));
    7646              :         }
    7647              :     }
    7648              : }
    7649              : 
    7650       249963 : void CalcHeatBalanceInsideSurf(EnergyPlusData &state,
    7651              :                                ObjexxFCL::Optional_int_const ZoneToResimulate) // if passed in, then only calculate surfaces that have this zone
    7652              : {
    7653       249963 :     if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime) {
    7654          107 :         if (state.dataHeatBal->AnyEMPD) {
    7655            0 :             state.dataHeatBalSurf->MinIterations = DataHeatBalSurface::MinEMPDIterations;
    7656              :         }
    7657          107 :         if (state.dataGlobal->DisplayAdvancedReportVariables) {
    7658            0 :             SetupOutputVariable(state,
    7659              :                                 "Surface Inside Face Heat Balance Calculation Iteration Count",
    7660              :                                 Constant::Units::None,
    7661            0 :                                 state.dataHeatBal->InsideSurfIterations,
    7662              :                                 OutputProcessor::TimeStepType::Zone,
    7663              :                                 OutputProcessor::StoreType::Sum,
    7664              :                                 "Simulation");
    7665              :         }
    7666              :         // Precompute whether CTF temperature limits will be needed
    7667          107 :         state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false);
    7668          235 :         for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) {
    7669          273 :             for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) {
    7670          145 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    7671          898 :                 for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) {
    7672          756 :                     DataSurfaces::HeatTransferModel const alg = state.dataSurface->Surface(iSurf).HeatTransferAlgorithm;
    7673          756 :                     if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) ||
    7674              :                         (alg == DataSurfaces::HeatTransferModel::Kiva)) {
    7675            3 :                         state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true;
    7676            3 :                         break;
    7677              :                     }
    7678              :                 }
    7679          128 :             }
    7680              :         }
    7681          107 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfFirstTime = false;
    7682              :     }
    7683              : 
    7684       249963 :     if (state.dataGlobal->BeginEnvrnFlag && state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag) {
    7685          483 :         state.dataHeatBalSurf->SurfTempInsOld = 23.0;
    7686          483 :         state.dataHeatBalSurfMgr->RefAirTemp = 23.0;
    7687          483 :         state.dataHeatBal->SurfTempEffBulkAir = 23.0;
    7688          483 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount = 0;
    7689          483 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = false;
    7690              : 
    7691              :         // Initialize Kiva instances ground temperatures
    7692          483 :         if (state.dataHeatBal->AnyKiva) {
    7693            0 :             state.dataSurfaceGeometry->kivaManager.initKivaInstances(state);
    7694              :         }
    7695              :     }
    7696       249963 :     if (!state.dataGlobal->BeginEnvrnFlag) {
    7697       249480 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurEnvrnFlag = true;
    7698              :     }
    7699              : 
    7700       249963 :     sumSurfQdotRadHVAC(state);
    7701              : 
    7702              :     // Pass correct list of surfaces to CalcHeatBalanceInsideSurf2
    7703       249963 :     bool const PartialResimulate(present(ZoneToResimulate));
    7704              : 
    7705       249963 :     if (!PartialResimulate) {
    7706       249955 :         if (state.dataHeatBal->AllCTF) {
    7707       200983 :             CalcHeatBalanceInsideSurf2CTFOnly(state, 1, state.dataGlobal->NumOfZones, state.dataSurface->AllIZSurfaceList);
    7708              :         } else {
    7709        97944 :             CalcHeatBalanceInsideSurf2(state,
    7710        48972 :                                        state.dataSurface->AllHTSurfaceList,
    7711        48972 :                                        state.dataSurface->AllIZSurfaceList,
    7712        48972 :                                        state.dataSurface->AllHTNonWindowSurfaceList,
    7713        48972 :                                        state.dataSurface->AllHTWindowSurfaceList);
    7714              :         }
    7715              :     } else {
    7716            8 :         auto const &zoneHTSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTSurfaceList;
    7717            8 :         auto const &zoneIZSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneIZSurfaceList;
    7718            8 :         auto const &zoneHTNonWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTNonWindowSurfaceList;
    7719            8 :         auto const &zoneHTWindowSurfList = state.dataHeatBal->Zone(ZoneToResimulate).ZoneHTWindowSurfaceList;
    7720              :         // Cannot use CalcHeatBalanceInsideSurf2CTFOnly because resimulated zone includes adjacent interzone surfaces
    7721            8 :         CalcHeatBalanceInsideSurf2(state, zoneHTSurfList, zoneIZSurfList, zoneHTNonWindowSurfList, zoneHTWindowSurfList, ZoneToResimulate);
    7722              :     }
    7723       249963 :     CalculateZoneMRT(state, ZoneToResimulate); // Update here so that the proper value of MRT is available to radiant systems
    7724       249963 :     UpdateIntermediateSurfaceHeatBalanceResults(state, ZoneToResimulate);
    7725       249963 : }
    7726              : 
    7727        48980 : void CalcHeatBalanceInsideSurf2(EnergyPlusData &state,
    7728              :                                 const std::vector<int> &HTSurfs,          // Heat transfer surfaces to simulate (opaque and windows)
    7729              :                                 const std::vector<int> &IZSurfs,          // Interzone heat transfer surfaces to simulate
    7730              :                                 const std::vector<int> &HTNonWindowSurfs, // Non-window heat transfer surfaces to simulate
    7731              :                                 const std::vector<int> &HTWindowSurfs,    // Window heat transfer surfaces to simulate
    7732              :                                 ObjexxFCL::Optional_int_const ZoneToResimulate)
    7733              : {
    7734              :     // SUBROUTINE INFORMATION:
    7735              :     //       AUTHOR         George Walton
    7736              :     //       DATE WRITTEN   December 1979
    7737              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays)
    7738              :     //                      Dec 1999 (FCW for window calculation)
    7739              :     //                      May 2000 (FCW for window frame and dividers)
    7740              :     //                      Aug 2000 (RJL for MTF moisture calculations)
    7741              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    7742              :     //                      Dec 2000 (RKS for radiant system model addition)
    7743              :     //                      Jul 2003 (CC) set the reference temperatures for inside surface heat balance
    7744              :     //                                    depending on convection algorithms and/or air models used
    7745              :     //                      May 2006 (RR  account for exterior window screen)
    7746              :     //                      Jul 2008 (P. Biddulph include calls to HAMT)
    7747              :     //                      Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
    7748              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    7749              : 
    7750              :     // PURPOSE OF THIS SUBROUTINE:
    7751              :     // This subroutine performs a heat balance on the inside face of each
    7752              :     // surface in the building.
    7753              : 
    7754              :     // METHODOLOGY EMPLOYED:
    7755              :     // Various boundary conditions are set and additional parameters are set-
    7756              :     // up.  Then, the proper heat balance equation is selected based on whether
    7757              :     // the surface is a partition or not and on whether or not movable
    7758              :     // insulation is present on the inside face.
    7759              : 
    7760              :     // REFERENCES:
    7761              :     // (I)BLAST legacy routine HBSRF
    7762              : 
    7763        48980 :     constexpr std::string_view rhoAirZone("RhoAirZone");
    7764        48980 :     constexpr std::string_view wsurf("Wsurf");
    7765        48980 :     constexpr std::string_view HBSurfManInsideSurf("HB,SurfMan:InsideSurf");
    7766        48980 :     constexpr std::string_view Inside("Inside");
    7767              : 
    7768              :     Real64 TempSurfOutTmp; // Local Temporary Surface temperature for the outside surface face
    7769              :     Real64 SurfTempInSat;  // Local temporary surface dew point temperature
    7770              : 
    7771              :     Real64 Wsurf;         // Moisture ratio for HAMT
    7772              :     Real64 RhoAirZone;    // Zone moisture density for HAMT
    7773              :     int OtherSideZoneNum; // Zone Number index for other side of an interzone partition HAMT
    7774              : 
    7775        48980 :     auto &s_mat = state.dataMaterial;
    7776              :     // determine reference air temperatures
    7777       342844 :     for (int SurfNum : HTSurfs) {
    7778              : 
    7779              :         // These conditions are not used in every SurfNum loop here so we don't use them to skip surfaces
    7780       293864 :         if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    7781            0 :             continue; // Skip TDD:DOME objects.  Inside temp is handled by TDD:DIFFUSER.
    7782              :         }
    7783       293864 :         Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum);
    7784       293864 :         state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) = RefAirTemp;
    7785       293864 :         state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = state.dataHeatBalSurfMgr->RefAirTemp(SurfNum);
    7786        48980 :     }
    7787              : 
    7788              :     // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
    7789              :     // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
    7790              :     // CalcWindowHeatBalance.
    7791              :     // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
    7792        48980 :     for (int surfNum : HTWindowSurfs) {
    7793            0 :         state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
    7794            0 :         state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
    7795            0 :         state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
    7796            0 :         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
    7797            0 :         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
    7798            0 :         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
    7799            0 :         state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
    7800            0 :         state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
    7801            0 :         state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
    7802            0 :         state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
    7803            0 :         state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
    7804            0 :         state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
    7805            0 :         state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
    7806        48980 :     }
    7807              : 
    7808        48980 :     state.dataHeatBal->InsideSurfIterations = 0;
    7809              : 
    7810              :     // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    7811        48980 :     for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
    7812            0 :         state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    7813            0 :             state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
    7814        48980 :     }
    7815              : 
    7816              :     // Calculate Kiva instances
    7817        48980 :     if (state.dataHeatBal->AnyKiva) {
    7818            0 :         if (((state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::HOURLY &&
    7819            0 :               state.dataGlobal->TimeStep == 1) ||
    7820            0 :              state.dataSurfaceGeometry->kivaManager.settings.timestepType == HeatBalanceKivaManager::KivaManager::Settings::TIMESTEP) &&
    7821            0 :             !state.dataGlobal->WarmupFlag) {
    7822            0 :             state.dataSurfaceGeometry->kivaManager.calcKivaInstances(state);
    7823              :         }
    7824              :     }
    7825              : 
    7826        48980 :     bool Converged = false; // .TRUE. if inside heat balance has converged
    7827       148861 :     while (!Converged) {    // Start of main inside heat balance DO loop...
    7828              : 
    7829        99881 :         state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
    7830              : 
    7831        99881 :         if (state.dataHeatBal->AnyKiva) {
    7832            0 :             for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
    7833            0 :                 state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = kivaSurf.second.results.Trad - Constant::Kelvin;
    7834            0 :             }
    7835              :         }
    7836              : 
    7837       199762 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
    7838        99881 :                                                            state.dataHeatBalSurf->SurfTempIn,
    7839        99881 :                                                            state.dataHeatBal->InsideSurfIterations,
    7840        99881 :                                                            state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
    7841              :                                                            ZoneToResimulate,
    7842              :                                                            Inside); // Update the radiation balance
    7843              : 
    7844        99881 :         if (state.dataHeatBal->AnyKiva) {
    7845            0 :             for (auto const &kivaSurf : state.dataSurfaceGeometry->kivaManager.surfaceMap) {
    7846            0 :                 state.dataHeatBalSurf->SurfTempIn(kivaSurf.first) = state.dataHeatBalSurf->SurfTempInsOld(kivaSurf.first);
    7847            0 :             }
    7848              :         }
    7849              : 
    7850              :         // Every 30 iterations, recalculate the inside convection coefficients in case
    7851              :         // there has been a significant drift in the surface temperatures predicted.
    7852              :         // This is not fool-proof and it basically means that the outside surface
    7853              :         // heat balance is in error (potentially) once HConvIn is re-evaluated.
    7854              :         // The choice of 30 is not significant--just want to do this a couple of
    7855              :         // times before the iteration limit is hit.
    7856       150782 :         if ((state.dataHeatBal->InsideSurfIterations > 0) &&
    7857        50901 :             (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
    7858           16 :             Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
    7859              :         }
    7860              : 
    7861        99881 :         if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
    7862            0 :             for (int SurfNum : HTSurfs) {
    7863            0 :                 auto const &surface = state.dataSurface->Surface(SurfNum);
    7864            0 :                 if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    7865            0 :                     continue; // Skip TDD:DOME objects.  Inside temp is handled by TDD:DIFFUSER.
    7866              :                 }
    7867              : 
    7868              :                 // Calculate the inside surface moisture quantities
    7869              :                 // calculate the inside surface moisture transfer conditions
    7870              :                 // check for saturation conditions of air
    7871            0 :                 if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) ||
    7872            0 :                     (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) {
    7873            0 :                     int ZoneNum = surface.Zone;
    7874            0 :                     Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
    7875            0 :                     Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).airHumRat, 1.0e-5));
    7876            0 :                     Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    7877              : 
    7878            0 :                     state.dataMstBal->RhoVaporAirIn(SurfNum) =
    7879            0 :                         min(Psychrometrics::PsyRhovFnTdbWPb_fast(MAT_zone, ZoneAirHumRat_zone, state.dataEnvrn->OutBaroPress),
    7880              :                             Psychrometrics::PsyRhovFnTdbRh(state, MAT_zone, 1.0, HBSurfManInsideSurf));
    7881            0 :                     state.dataMstBal->HMassConvInFD(SurfNum) =
    7882            0 :                         HConvIn_surf / (Psychrometrics::PsyRhoAirFnPbTdbW_fast(state, state.dataEnvrn->OutBaroPress, MAT_zone, ZoneAirHumRat_zone) *
    7883            0 :                                         Psychrometrics::PsyCpAirFnW_fast(ZoneAirHumRat_zone));
    7884              :                 }
    7885            0 :             }
    7886              :         }
    7887              : 
    7888       699129 :         for (int SurfNum : HTNonWindowSurfs) {
    7889              :             // Perform heat balance on the inside face of the surface ...
    7890              :             // The following are possibilities here:
    7891              :             //   (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
    7892              :             //   (b) the surface is a partition, in which case the temperature of both sides are the same
    7893              :             //   (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
    7894              :             //   (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
    7895              :             //   (e) standard opaque surface with movable insulation, special two-part equation
    7896              :             // In the surface calculation there are the following Algorithm types for opaque surfaces that
    7897              :             // do not have movable insulation:
    7898              :             //   (a) the regular CTF calc (SolutionAlgo = UseCTF)
    7899              :             //   (b) the EMPD calc (Solutionalgo = UseEMPD)
    7900              :             //   (c) the CondFD calc (SolutionAlgo = UseCondFD)
    7901              :             //   (d) the HAMT calc (solutionalgo = UseHAMT).
    7902              : 
    7903       599248 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    7904       599248 :             if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    7905            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    7906            0 :                 if (SurfNum != repSurfNum) {
    7907            0 :                     continue;
    7908              :                 }
    7909              :             }
    7910       599248 :             int const ZoneNum = surface.Zone;
    7911       599248 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    7912       599248 :             int const ConstrNum = surface.Construction;
    7913       599248 :             auto const &construct = state.dataConstruction->Construct(ConstrNum);
    7914       599248 :             Real64 const MAT_zone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
    7915       599248 :             Real64 const HConvIn_surf = state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
    7916              : 
    7917       599248 :             if (surface.ExtBoundCond == SurfNum) {
    7918              :                 // CR6869 -- let Window HB take care of it      IF (Surface(SurfNum)%ExtBoundCond == SurfNum) THEN
    7919              :                 // Surface is adiabatic
    7920        99862 :                 if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    7921        99862 :                     surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
    7922              : 
    7923            0 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7924            0 :                         MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
    7925            0 :                             state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
    7926              :                     }
    7927              :                     // Pre-calculate a few terms
    7928              :                     Real64 const TempTerm(
    7929            0 :                         state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    7930            0 :                         state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    7931            0 :                         HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    7932            0 :                         state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    7933            0 :                         (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
    7934            0 :                     Real64 const TempDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
    7935              :                     // Calculate the current inside surface temperature
    7936            0 :                     if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
    7937            0 :                         ((state.dataSurface->SurfIsPool(SurfNum)) &&
    7938            0 :                          (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
    7939            0 :                          (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
    7940            0 :                         if (construct.SourceSinkPresent) {
    7941            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7942            0 :                                 (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    7943            0 :                                  DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
    7944              :                                 TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
    7945              :                             // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
    7946              :                             // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
    7947              :                             // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
    7948              :                             // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
    7949              :                             // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
    7950              :                             // same temp) | Convection and damping term | Radiation from AFN ducts
    7951              :                         } else {
    7952            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7953            0 :                                 (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) *
    7954              :                                 TempDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW radiation
    7955              :                             // from internal sources | Convection from surface to zone air | Net radiant exchange with other zone
    7956              :                             // surfaces | Heat source/sink term for radiant systems | (if there is one present) | Radiant flux from a
    7957              :                             // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant flux from a
    7958              :                             // steam baseboard heater | Radiant flux from an electric baseboard heater | Iterative damping term (for
    7959              :                             // stability) | Conduction term (both partition sides same temp) | Conduction term (both partition sides
    7960              :                             // same temp) | Convection and damping term | Radiation from AFN ducts
    7961              :                         }
    7962              :                     } else { // this is a pool and it has been simulated this time step
    7963            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7964            0 :                             (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
    7965            0 :                              DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum)) /
    7966            0 :                             (construct.CTFInside[0] - construct.CTFCross[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
    7967              :                              DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms (see
    7968              :                         // non-pool equation for details) | Iterative damping term (for stability) |
    7969              :                         // Conduction term (both partition sides same temp) | Pool and damping term
    7970              :                     }
    7971            0 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    7972            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
    7973            0 :                             state.dataMstBalEMPD->HeatFluxLatent(SurfNum) * TempDiv; // Conduction term (both partition sides same temp) |
    7974              :                         // Conduction term (both partition sides same temp) |
    7975              :                         // Convection and damping term
    7976            0 :                         if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
    7977            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
    7978              :                         }
    7979              :                     }
    7980              :                     // if any mixed heat transfer models in zone, apply limits to CTF result
    7981            0 :                     if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
    7982            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    7983            0 :                             max(DataHeatBalSurface::MinSurfaceTempLimit,
    7984            0 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    7985            0 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    7986              :                     }
    7987              : 
    7988            0 :                     if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
    7989              : 
    7990              :                         // Radiant system does not need the damping coefficient terms (hopefully) // Partitions are assumed to be symmetric
    7991            0 :                         Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] - construct.CTFCross[0] + HConvIn_surf));
    7992            0 :                         state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
    7993            0 :                             TempTerm * RadSysDiv; // Constant portion of conduction eq (history terms) | LW radiation from internal sources | SW
    7994              :                         // radiation from internal sources | Convection from surface to zone air | Radiant flux from
    7995              :                         // high temperature radiant heater | Radiant flux from a hot water baseboard heater | Radiant
    7996              :                         // flux from a steam baseboard heater | Radiant flux from an electric baseboard heater | Net
    7997              :                         // radiant exchange with other zone surfaces | Cond term (both partition sides same temp) | Cond
    7998              :                         // term (both partition sides same temp) | Convection and damping term
    7999            0 :                         state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
    8000              :                             0.0; // The outside temp is assumed to be equal to the inside temp for a partition
    8001            0 :                         state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
    8002            0 :                             construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both partition sides same temp) | Cond
    8003              :                         // term (both partition sides same temp) | Convection and damping term
    8004              :                     }
    8005              : 
    8006        99862 :                 } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    8007            0 :                            surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8008              : 
    8009        99862 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8010            0 :                         HeatBalanceHAMTManager::ManageHeatBalHAMT(state,
    8011              :                                                                   SurfNum,
    8012            0 :                                                                   state.dataHeatBalSurf->SurfTempInTmp(SurfNum),
    8013              :                                                                   TempSurfOutTmp); // HAMT
    8014              :                     }
    8015              : 
    8016        99862 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    8017       199724 :                         HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
    8018        99862 :                             state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    8019              :                     }
    8020              : 
    8021        99862 :                     TH11 = TempSurfOutTmp;
    8022              :                 }
    8023              : 
    8024        99862 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8025              : 
    8026              :             } else { // Standard surface or interzone surface
    8027       499386 :                 bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataSurface->intMovInsuls(SurfNum).present;
    8028       499386 :                 if (!movableInsulPresent) { // No movable insulation present, normal heat balance equation
    8029              : 
    8030       499386 :                     if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF ||
    8031       499310 :                         surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // Regular CTF Surface and/or EMPD surface
    8032              : 
    8033           76 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    8034            0 :                             MoistureBalanceEMPDManager::CalcMoistureBalanceEMPD(
    8035            0 :                                 state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), MAT_zone, SurfTempInSat);
    8036              :                         }
    8037              :                         // Pre-calculate a few terms
    8038              :                         Real64 const TempTerm(
    8039           76 :                             state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    8040           76 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    8041           76 :                             HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    8042           76 :                             state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    8043           76 :                             (state.dataHeatBalFanSys->QRadSurfAFNDuct(SurfNum) / state.dataGlobal->TimeStepZoneSec));
    8044           76 :                         Real64 const TempDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf + DataHeatBalSurface::IterDampConst));
    8045              :                         // Calculate the current inside surface temperature
    8046           76 :                         if ((!state.dataSurface->SurfIsPool(SurfNum)) ||
    8047            0 :                             ((state.dataSurface->SurfIsPool(SurfNum)) &&
    8048            0 :                              (std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit) &&
    8049            0 :                              (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum)) < DataHeatBalSurface::PoolIsOperatingLimit))) {
    8050           76 :                             if (construct.SourceSinkPresent) {
    8051            0 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8052            0 :                                     (TempTerm + construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    8053            0 :                                      DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    8054            0 :                                      construct.CTFCross[0] * TH11) *
    8055              :                                     TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    8056              :                                 // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
    8057              :                                 // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
    8058              :                                 // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
    8059              :                                 // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
    8060              :                                 // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
    8061              :                                 // outside surface | Coefficient for conduction (current time) | Convection and damping term |
    8062              :                                 // Radiation from AFN ducts
    8063              :                             } else {
    8064           76 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8065           76 :                                     (TempTerm + DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    8066           76 :                                      construct.CTFCross[0] * TH11) *
    8067              :                                     TempDiv; // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    8068              :                                 // radiation from internal sources | Convection from surface to zone air | Net radiant exchange
    8069              :                                 // with other zone surfaces | Heat source/sink term for radiant systems | (if there is one
    8070              :                                 // present) | Radiant flux from high temp radiant heater | Radiant flux from a hot water
    8071              :                                 // baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from an electric
    8072              :                                 // baseboard heater | Iterative damping term (for stability) | Current conduction from | the
    8073              :                                 // outside surface | Coefficient for conduction (current time) | Convection and damping term |
    8074              :                                 // Radiation from AFN ducts
    8075              :                             }
    8076              :                         } else { // surface is a pool and the pool has been simulated this time step
    8077            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8078            0 :                                 (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) +
    8079            0 :                                  DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) /
    8080            0 :                                 (construct.CTFInside[0] + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) +
    8081              :                                  DataHeatBalSurface::IterDampConst); // Constant part of conduction eq (history terms) | Pool modified terms
    8082              :                             // (see non-pool equation for details) | Iterative damping term (for
    8083              :                             // stability) | Current conduction from | the outside surface |
    8084              :                             // Coefficient for conduction (current time) | Pool and damping term
    8085              :                         }
    8086           76 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    8087            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) -=
    8088            0 :                                 state.dataMstBalEMPD->HeatFluxLatent(SurfNum) *
    8089              :                                 TempDiv; // Coefficient for conduction (current time) | Convection and damping term
    8090            0 :                             if (SurfTempInSat > state.dataHeatBalSurf->SurfTempInTmp(SurfNum)) {
    8091            0 :                                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfTempInSat; // Surface temp cannot be below dew point
    8092              :                             }
    8093              :                         }
    8094              :                         // if any mixed heat transfer models in zone, apply limits to CTF result
    8095           76 :                         if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
    8096            0 :                             state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = max(
    8097              :                                 DataHeatBalSurface::MinSurfaceTempLimit,
    8098            0 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    8099            0 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    8100              :                         }
    8101              : 
    8102           76 :                         if (construct.SourceSinkPresent) { // Set the appropriate parameters for the radiant system
    8103              : 
    8104              :                             // Radiant system does not need the damping coefficient terms (hopefully)
    8105            0 :                             Real64 const RadSysDiv(1.0 / (construct.CTFInside[0] + HConvIn_surf));
    8106            0 :                             state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) =
    8107            0 :                                 TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
    8108              :                             // radiation from internal sources | Convection from surface to zone air | Radiant flux
    8109              :                             // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
    8110              :                             // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
    8111              :                             // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
    8112              :                             // sides same temp) | Convection and damping term
    8113            0 :                             state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) =
    8114            0 :                                 construct.CTFCross[0] * RadSysDiv; // Outside temp=inside temp for a partition |
    8115              :                             // Cond term (both partition sides same temp) |
    8116              :                             // Convection and damping term
    8117            0 :                             state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) =
    8118            0 :                                 construct.CTFSourceIn[0] * RadSysDiv; // QTF term for the source | Cond term (both
    8119              :                             // partition sides same temp) | Convection and
    8120              :                             // damping term
    8121              : 
    8122            0 :                             if (surface.ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
    8123              :                                 // The inside coefficients of one side are equal to the outside coefficients of the other side.  But,
    8124              :                                 // the inside coefficients are set up once the heat balance equation for that side has been calculated.
    8125              :                                 // For both sides to actually have been set, we have to wait until we get to the second side in the surface
    8126              :                                 // derived type.  At that point, both inside coefficient sets have been evaluated.
    8127            0 :                                 if (surface.ExtBoundCond < SurfNum) { // Both of the inside coefficients have now been set
    8128            0 :                                     int OtherSideSurfNum = surface.ExtBoundCond;
    8129            0 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
    8130            0 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
    8131            0 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
    8132            0 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
    8133            0 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
    8134            0 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
    8135            0 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
    8136            0 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
    8137            0 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) =
    8138            0 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
    8139            0 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) =
    8140            0 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
    8141              :                                 }
    8142              :                             }
    8143              :                         }
    8144              : 
    8145       499386 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD ||
    8146            0 :                                surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8147              : 
    8148       499310 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8149            0 :                             if (surface.ExtBoundCond > 0) {
    8150              :                                 // HAMT get the correct other side zone zone air temperature --
    8151            0 :                                 int OtherSideSurfNum = surface.ExtBoundCond;
    8152              :                                 // ZoneNum = surface.Zone;
    8153            0 :                                 OtherSideZoneNum = state.dataSurface->Surface(OtherSideSurfNum).Zone;
    8154            0 :                                 state.dataMstBal->TempOutsideAirFD(SurfNum) =
    8155            0 :                                     state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT;
    8156              :                             }
    8157            0 :                             HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    8158              :                         }
    8159              : 
    8160       499310 :                         if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    8161       998620 :                             HeatBalFiniteDiffManager::ManageHeatBalFiniteDiff(
    8162       499310 :                                 state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp);
    8163              :                         }
    8164              : 
    8165       499310 :                         TH11 = TempSurfOutTmp;
    8166              : 
    8167       499310 :                     } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::Kiva) {
    8168              :                         // Read Kiva results for each surface
    8169            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8170            0 :                             state.dataSurfaceGeometry->kivaManager.surfaceMap[SurfNum].results.Tconv - Constant::Kelvin;
    8171              : 
    8172            0 :                         TH11 = 0.0;
    8173              :                     }
    8174              : 
    8175       499386 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8176              : 
    8177              :                 } else { // Movable insulation present
    8178            0 :                     Real64 HMovInsul = state.dataSurface->intMovInsuls(SurfNum).H;
    8179            0 :                     if (construct.SourceSinkPresent) {
    8180              : 
    8181            0 :                         ShowSevereError(state, "Interior movable insulation is not valid with embedded sources/sinks");
    8182            0 :                         ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
    8183            0 :                         ShowContinueError(state,
    8184            0 :                                           format("interior movable insulation {} for a surface with that construction.",
    8185            0 :                                                  s_mat->materials(state.dataSurface->intMovInsuls(SurfNum).matNum)->Name));
    8186            0 :                         ShowContinueError(state,
    8187              :                                           "This is not currently allowed because the heat balance equations do not currently accommodate "
    8188              :                                           "this combination.");
    8189            0 :                         ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    8190              :                     }
    8191              : 
    8192            0 :                     Real64 F1 = HMovInsul / (HMovInsul + HConvIn_surf + DataHeatBalSurface::IterDampConst);
    8193              : 
    8194            0 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) =
    8195            0 :                         (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    8196            0 :                          construct.CTFCross[0] * TH11 +
    8197            0 :                          F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    8198            0 :                                HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
    8199            0 :                                state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) +
    8200            0 :                                state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) +
    8201            0 :                                DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum))) /
    8202            0 :                         (construct.CTFInside[0] + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
    8203              : 
    8204            0 :                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8205            0 :                         (construct.CTFInside[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    8206            0 :                          HMovInsul * state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) -
    8207            0 :                          state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) - construct.CTFCross[0] * TH11) /
    8208              :                         (HMovInsul);
    8209              :                     // if any mixed heat transfer models in zone, apply limits to CTF result
    8210            0 :                     if (state.dataHeatBalSurf->Zone_has_mixed_HT_models[ZoneNum]) {
    8211            0 :                         state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8212            0 :                             max(DataHeatBalSurface::MinSurfaceTempLimit,
    8213            0 :                                 min(state.dataHeatBalSurf->MaxSurfaceTempLimit,
    8214            0 :                                     state.dataHeatBalSurf->SurfTempInTmp(SurfNum))); // Limit Check //Tuned Precomputed condition to eliminate loop
    8215              :                     }
    8216              :                 }
    8217              :             }
    8218        99881 :         }
    8219        99881 :         for (int SurfNum : HTWindowSurfs) {
    8220            0 :             auto &surface = state.dataSurface->Surface(SurfNum);
    8221            0 :             if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8222            0 :                 int repSurfNum = surface.RepresentativeCalcSurfNum;
    8223            0 :                 if (SurfNum != repSurfNum) {
    8224            0 :                     continue;
    8225              :                 }
    8226              :             }
    8227            0 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    8228            0 :             int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // Not const, because storm window may change this
    8229            0 :             auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8230            0 :             if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8231              :                 // Lookup up the TDD:DOME object
    8232            0 :                 int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    8233            0 :                 int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
    8234              :                 // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    8235            0 :                 Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
    8236              : 
    8237              :                 // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
    8238              :                 // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    8239              :                 //   = SurfWinQRadSWwinAbs(SurfNum,1)/2.0
    8240            0 :                 Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    8241            0 :                 state.dataHeatBalSurf->SurfTempInTmp(SurfNum) =
    8242            0 :                     (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
    8243            0 :                      state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(SurfNum) + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(SurfNum) +
    8244            0 :                      state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum) +
    8245            0 :                      DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(SurfNum) +
    8246            0 :                      Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
    8247            0 :                     (Ueff + HConvIn_surf +
    8248              :                      DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
    8249              :                                                          // solar | Convection from surface to zone air | Net radiant exchange with
    8250              :                                                          // other zone surfaces | Iterative damping term (for stability) | Current
    8251              :                                                          // conduction from the outside surface | Coefficient for conduction (current
    8252              :                                                          // time) | Convection and damping term
    8253            0 :                 state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8254              : 
    8255            0 :                 Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(SurfNum) + Constant::Kelvin));
    8256              : 
    8257              :                 // fill out report vars for components of Window Heat Gain
    8258            0 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) =
    8259            0 :                     HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurfMgr->RefAirTemp(SurfNum));
    8260            0 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) =
    8261            0 :                     state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
    8262            0 :                     (Sigma_Temp_4 - (state.dataSurface->SurfWinIRfromParentZone(SurfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)));
    8263            0 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) =
    8264            0 :                     state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
    8265            0 :                         (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
    8266            0 :                     state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(SurfNum);
    8267              : 
    8268              :                 // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
    8269            0 :                 state.dataSurface->SurfWinHeatGain(SurfNum) =
    8270            0 :                     state.dataSurface->SurfWinTransSolar(SurfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) +
    8271            0 :                     state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) -
    8272            0 :                     surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum);
    8273              :                 // Net transmitted solar | Convection | IR exchange | IR
    8274              :                 // Zone diffuse interior shortwave reflected back into the TDD
    8275              : 
    8276              :             } else {                                                // Regular window
    8277            0 :                 if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
    8278              :                     // Get outside convection coeff for exterior window here to avoid calling
    8279              :                     // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
    8280              :                     // (HeatBalanceSurfaceManager USEing and WindowManager and
    8281              :                     // WindowManager USEing HeatBalanceSurfaceManager)
    8282            0 :                     if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    8283            0 :                         auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
    8284            0 :                         Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
    8285            0 :                         Real64 EmisOut = thisMaterial->AbsorpThermalFront;              // Glass outside surface emissivity
    8286            0 :                         DataSurfaces::WinShadingType const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum));
    8287            0 :                         if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
    8288              :                             // Exterior shade in place
    8289            0 :                             int const ConstrNumSh = surface.activeShadedConstruction;
    8290            0 :                             if (ConstrNumSh != 0) {
    8291            0 :                                 auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    8292            0 :                                 auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
    8293            0 :                                 assert(thisMaterial2 != nullptr);
    8294            0 :                                 RoughSurf = thisMaterial2->Roughness;
    8295            0 :                                 EmisOut = thisMaterial2->AbsorpThermal;
    8296              :                             }
    8297              :                         }
    8298              : 
    8299              :                         // Get the outside effective emissivity for Equivalent layer model
    8300            0 :                         if (construct.WindowTypeEQL) {
    8301            0 :                             EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
    8302              :                         }
    8303              :                         // Set Exterior Convection Coefficient...
    8304            0 :                         if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
    8305              : 
    8306            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    8307              : 
    8308            0 :                         } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
    8309              : 
    8310              :                             // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
    8311              :                             // subroutine)
    8312            0 :                             Convect::InitExtConvCoeff(state,
    8313              :                                                       SurfNum,
    8314              :                                                       0.0,
    8315              :                                                       RoughSurf,
    8316              :                                                       EmisOut,
    8317              :                                                       TH11,
    8318            0 :                                                       state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    8319            0 :                                                       state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    8320            0 :                                                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    8321            0 :                                                       state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    8322            0 :                                                       state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    8323              : 
    8324            0 :                             if (state.dataEnvrn->IsRain) {                             // Raining: since wind exposed, outside window surface gets wet
    8325            0 :                                 state.dataHeatBalSurf->SurfHConvExt(SurfNum) = 1000.0; // Reset SurfHcExt because of wetness
    8326              :                             }
    8327              : 
    8328              :                         } else { // Not Wind exposed
    8329              : 
    8330              :                             // Calculate exterior heat transfer coefficients for windspeed = 0
    8331            0 :                             Convect::InitExtConvCoeff(state,
    8332              :                                                       SurfNum,
    8333              :                                                       0.0,
    8334              :                                                       RoughSurf,
    8335              :                                                       EmisOut,
    8336              :                                                       TH11,
    8337            0 :                                                       state.dataHeatBalSurf->SurfHConvExt(SurfNum),
    8338            0 :                                                       state.dataHeatBalSurf->SurfHSkyExt(SurfNum),
    8339            0 :                                                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum),
    8340            0 :                                                       state.dataHeatBalSurf->SurfHAirExt(SurfNum),
    8341            0 :                                                       state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    8342              :                         }
    8343              :                     } else { // Interior Surface
    8344              : 
    8345            0 :                         if (state.dataSurface->surfExtConv(SurfNum).userModelNum != 0) {
    8346            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = Convect::SetExtConvCoeff(state, SurfNum);
    8347              :                         } else {
    8348              :                             // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
    8349              :                             // same
    8350            0 :                             state.dataHeatBalSurf->SurfHConvExt(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
    8351              :                         }
    8352              :                     }
    8353              : 
    8354              :                     // Following call determines inside surface temperature of glazing, and of
    8355              :                     // frame and/or divider, if present
    8356            0 :                     Window::CalcWindowHeatBalance(
    8357            0 :                         state, SurfNum, state.dataHeatBalSurf->SurfHConvExt(SurfNum), state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TH11);
    8358            0 :                     state.dataHeatBalSurf->SurfTempIn(SurfNum) = state.dataHeatBalSurf->SurfTempInTmp(SurfNum);
    8359              :                 }
    8360              :             }
    8361        99881 :         } // ...end of inside surface heat balance equation selection
    8362              : 
    8363       699129 :         for (int SurfNum : HTSurfs) {
    8364       599248 :             int const ZoneNum = state.dataSurface->Surface(SurfNum).Zone;
    8365       599248 :             auto &zone = state.dataHeatBal->Zone(ZoneNum);
    8366       599248 :             Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum);
    8367       599248 :             Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum);
    8368       599248 :             TH12 = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    8369       599248 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = TH11; // For reporting
    8370       599248 :             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Dome) {
    8371            0 :                 continue;
    8372              :             }
    8373       599248 :             if (state.dataSurface->Surface(SurfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8374              :                 // Tubular daylighting devices are treated as one big object with an effective R value.
    8375              :                 // The outside face temperature of the TDD:DOME and the inside face temperature of the
    8376              :                 // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
    8377              :                 // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
    8378              :                 // and the outside face of the TDD:DIFFUSER for reporting.
    8379              : 
    8380              :                 // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
    8381            0 :                 int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome;
    8382            0 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
    8383            0 :                     state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum);
    8384              : 
    8385              :                 // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
    8386              :                 // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
    8387            0 :                 TH11 = state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
    8388            0 :                     state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
    8389              :             }
    8390              : 
    8391       599248 :             if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    8392            0 :                 TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, SurfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
    8393              :             }
    8394              : 
    8395        99881 :         } // ...end of main loops over all surfaces for inside heat balances
    8396              : 
    8397              :         // Interzone surface updating: interzone surfaces have other side temperatures
    8398              :         // which can vary as the simulation iterates through the inside heat
    8399              :         // balance.  This block is intended to "lock" the opposite side (outside)
    8400              :         // temperatures to the correct value, namely the value calculated by the
    8401              :         // inside surface heat balance for the other side.
    8402              :         //        assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
    8403              :         //        int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
    8404        99881 :         for (int SurfNum : IZSurfs) {
    8405            0 :             int const surfExtBoundCond = state.dataSurface->Surface(SurfNum).ExtBoundCond;
    8406              :             // Set the outside surface temperature to the inside surface temperature of the interzone pair.
    8407              :             // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
    8408              :             // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
    8409              :             // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
    8410            0 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    8411            0 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
    8412        99881 :         }
    8413              : 
    8414        99881 :         ++state.dataHeatBal->InsideSurfIterations;
    8415              : 
    8416              :         // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
    8417        99881 :         Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
    8418       699129 :         for (int SurfNum : HTNonWindowSurfs) {
    8419       599248 :             MaxDelTemp = max(std::abs(state.dataHeatBalSurf->SurfTempIn(SurfNum) - state.dataHeatBalSurf->SurfTempInsOld(SurfNum)), MaxDelTemp);
    8420       599248 :             if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) {
    8421              :                 // also check all internal nodes as well as surface faces
    8422       599172 :                 MaxDelTemp = max(MaxDelTemp, state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).MaxNodeDelTemp);
    8423              :             }
    8424        99881 :         } // ...end of loop to check for convergence
    8425              : 
    8426        99881 :         if (!state.dataHeatBal->AnyCondFD) {
    8427           19 :             if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
    8428            8 :                 Converged = true;
    8429              :             }
    8430              :         } else {
    8431        99862 :             if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTempCondFD) {
    8432        48972 :                 Converged = true;
    8433              :             }
    8434              : 
    8435              :             // resets relaxation factor to speed up iterations when under-relaxation is not needed.
    8436        99862 :             if (state.dataHeatBal->InsideSurfIterations <= 1) {
    8437        48972 :                 state.dataHeatBal->CondFDRelaxFactor = state.dataHeatBal->CondFDRelaxFactorInput;
    8438              :             }
    8439        99862 :             if ((state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::IterationsForCondFDRelaxChange) && !Converged) {
    8440              :                 // adjust relaxation factor down, assume large number of iterations is result of instability
    8441          492 :                 state.dataHeatBal->CondFDRelaxFactor *= 0.9;
    8442          492 :                 if (state.dataHeatBal->CondFDRelaxFactor < 0.1) {
    8443          400 :                     state.dataHeatBal->CondFDRelaxFactor = 0.1;
    8444              :                 }
    8445              :             }
    8446              :         }
    8447              : 
    8448              : #ifdef EP_Count_Calls
    8449              :         state.dataTimingsData->NumMaxInsideSurfIterations =
    8450              :             max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
    8451              : #endif
    8452              : 
    8453        99881 :         if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
    8454            0 :             Converged = false;
    8455              :         }
    8456              : 
    8457        99881 :         if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
    8458            0 :             if (!state.dataGlobal->WarmupFlag) {
    8459            0 :                 ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
    8460            0 :                 if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
    8461            0 :                     if (!state.dataHeatBal->AnyCondFD) {
    8462            0 :                         ShowWarningError(state,
    8463            0 :                                          format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
    8464              :                                                 "Allowed Temp Diff [C] ={:.3R}",
    8465              :                                                 MaxDelTemp,
    8466            0 :                                                 state.dataHeatBal->MaxAllowedDelTemp));
    8467            0 :                         ShowContinueErrorTimeStamp(state, "");
    8468              :                     } else {
    8469            0 :                         ShowWarningError(state,
    8470            0 :                                          format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max "
    8471              :                                                 "Allowed Temp Diff [C] ={:.6R}",
    8472              :                                                 MaxDelTemp,
    8473            0 :                                                 state.dataHeatBal->MaxAllowedDelTempCondFD));
    8474            0 :                         ShowContinueErrorTimeStamp(state, "");
    8475              :                     }
    8476              :                 } else {
    8477            0 :                     ShowRecurringWarningErrorAtEnd(state,
    8478              :                                                    "Inside surface heat balance convergence problem continues",
    8479            0 :                                                    state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
    8480              :                                                    MaxDelTemp,
    8481              :                                                    MaxDelTemp,
    8482              :                                                    _,
    8483              :                                                    "[C]",
    8484              :                                                    "[C]");
    8485              :                 }
    8486              :             }
    8487            0 :             break; // iteration loop
    8488              :         }
    8489              : 
    8490              :     } // ...end of main inside heat balance DO loop (ends when Converged)
    8491              : 
    8492              :     // Update SumHmXXXX for non-window EMPD or HAMT surfaces
    8493        48980 :     if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) {
    8494              : 
    8495              :         // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration)
    8496            0 :         for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) {
    8497            0 :             thisZoneHB.SumHmAW = 0.0;
    8498            0 :             thisZoneHB.SumHmARa = 0.0;
    8499            0 :             thisZoneHB.SumHmARaW = 0.0;
    8500            0 :         }
    8501              : 
    8502            0 :         for (int SurfNum : HTNonWindowSurfs) {
    8503            0 :             auto const &surface = state.dataSurface->Surface(SurfNum);
    8504            0 :             int ZoneNum = surface.Zone;
    8505            0 :             auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
    8506              : 
    8507            0 :             if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) {
    8508            0 :                 HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum);
    8509              : 
    8510            0 :                 Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
    8511              : 
    8512            0 :                 thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
    8513              : 
    8514            0 :                 Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT);
    8515            0 :                 RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW(
    8516              :                     state,
    8517            0 :                     state.dataEnvrn->OutBaroPress,
    8518              :                     MAT_zone,
    8519            0 :                     Psychrometrics::PsyWFnTdbRhPb(
    8520              :                         state,
    8521              :                         MAT_zone,
    8522            0 :                         Psychrometrics::PsyRhFnTdbRhov(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum), rhoAirZone),
    8523            0 :                         state.dataEnvrn->OutBaroPress));
    8524              : 
    8525            0 :                 Real64 const surfInTemp(state.dataHeatBalSurf->SurfTempInTmp(SurfNum));
    8526              :                 Wsurf =
    8527            0 :                     Psychrometrics::PsyWFnTdbRhPb(state,
    8528              :                                                   surfInTemp,
    8529            0 :                                                   Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf),
    8530            0 :                                                   state.dataEnvrn->OutBaroPress);
    8531              : 
    8532            0 :                 thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone;
    8533              : 
    8534            0 :                 thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf;
    8535              : 
    8536            0 :             } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) {
    8537              :                 // need to calculate the amount of moisture that is entering or
    8538              :                 // leaving the zone  Qm [kg/sec] = hmi * Area * (Del Rhov)
    8539              :                 // {Hmi [m/sec];     Area [m2];    Rhov [kg moist/m3]  }
    8540              :                 // Positive values are into the zone and negative values are
    8541              :                 // leaving the zone.  SumHmAw is the sum of the moisture entering or
    8542              :                 // leaving the zone from all of the surfaces and is a rate.  Multiply
    8543              :                 // by time to get the actual amount affecting the zone volume of air.
    8544              : 
    8545            0 :                 MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum);
    8546            0 :                 state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum);
    8547            0 :                 Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area);
    8548            0 :                 thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum));
    8549            0 :                 Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT);
    8550            0 :                 thisZoneHB.SumHmARa +=
    8551            0 :                     FD_Area_fac *
    8552            0 :                     Psychrometrics::PsyRhoAirFnPbTdbW(
    8553              :                         state,
    8554            0 :                         state.dataEnvrn->OutBaroPress,
    8555              :                         MAT_zone,
    8556            0 :                         Psychrometrics::PsyWFnTdbRhPb(state,
    8557              :                                                       MAT_zone,
    8558            0 :                                                       Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)),
    8559            0 :                                                       state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C(
    8560              :                 // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) );
    8561            0 :                 thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum);
    8562              :             }
    8563            0 :         }
    8564              :     }
    8565        48980 : }
    8566              : 
    8567       200983 : void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state,
    8568              :                                        const int FirstZone,             // First zone to simulate
    8569              :                                        const int LastZone,              // Last zone to simulate
    8570              :                                        const std::vector<int> &IZSurfs, // Last zone to simulate
    8571              :                                        ObjexxFCL::Optional_int_const ZoneToResimulate)
    8572              : {
    8573              : 
    8574              :     // This function performs a heat balance on the inside face of each
    8575              :     // surface in the building. It is a copy of CalcHeatBalanceInsideSurf,
    8576              :     // simplified for CTF surfaces only.
    8577              : 
    8578              :     // REFERENCES:
    8579              :     // (I)BLAST legacy routine HBSRF
    8580              : 
    8581       200983 :     auto &s_mat = state.dataMaterial;
    8582       200983 :     auto &Surface = state.dataSurface->Surface;
    8583              : 
    8584       200983 :     constexpr std::string_view Inside("Inside");
    8585              : 
    8586       200983 :     if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) {
    8587              :         // Set up coefficient arrays that never change - loop over non-window HT surfaces
    8588          231 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8589          269 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8590          143 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8591          143 :                 int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8592          143 :                 int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8593          851 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8594          708 :                     int const ConstrNum = Surface(surfNum).Construction;
    8595          708 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8596          708 :                     if (Surface(surfNum).ExtBoundCond == surfNum) {
    8597          143 :                         state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1;
    8598              :                     } else {
    8599          565 :                         state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0;
    8600              :                     }
    8601          708 :                     if (construct.SourceSinkPresent) {
    8602            0 :                         state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1;
    8603              :                     } else {
    8604          708 :                         state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0;
    8605              :                     }
    8606              :                 }
    8607          126 :             }
    8608              :         }
    8609              : 
    8610          105 :         state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime = false;
    8611              :     }
    8612              : 
    8613       488661 :     for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8614       608967 :         for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8615       321289 :             auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8616              :             // loop over all heat transfer surface except TDD Dome.
    8617       321289 :             int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    8618       321289 :             int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    8619              :             // determine reference air temperatures and other variable terms - loop over all surfaces
    8620      2096362 :             for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8621      1775073 :                 auto const &surface = Surface(surfNum);
    8622      1775073 :                 if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8623            0 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    8624            0 :                     if (surfNum != repSurfNum) {
    8625            0 :                         continue;
    8626              :                     }
    8627              :                 }
    8628              : 
    8629      1775073 :                 int const ConstrNum = Surface(surfNum).Construction;
    8630      1775073 :                 auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8631      1775073 :                 state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross[0];
    8632      1775073 :                 state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside[0];
    8633      1775073 :                 state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn[0];
    8634      1775073 :                 state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
    8635      1775073 :                 if (construct.SourceSinkPresent) {
    8636            0 :                     state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1);
    8637              :                 }
    8638              : 
    8639              :                 // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change
    8640      1775073 :                 if (state.dataSurface->SurfIsPool(surfNum)) {
    8641            0 :                     if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit) ||
    8642            0 :                         (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= DataHeatBalSurface::PoolIsOperatingLimit)) {
    8643            0 :                         state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1;
    8644              :                     } else {
    8645            0 :                         state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0;
    8646              :                     }
    8647              :                 }
    8648      1775073 :                 Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum);
    8649      1775073 :                 state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp;
    8650      1775073 :                 state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum);
    8651              :             }
    8652              : 
    8653              :             // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines.
    8654              :             // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to
    8655              :             // CalcWindowHeatBalance.
    8656              :             // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window
    8657       321289 :             int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
    8658       321289 :             int const lastWindowSurf = thisSpace.WindowSurfaceLast;
    8659       409851 :             for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
    8660        88562 :                 state.dataSurface->SurfWinHeatGain(surfNum) = 0.0;
    8661        88562 :                 state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0;
    8662        88562 :                 state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0;
    8663        88562 :                 state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0;
    8664        88562 :                 state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0;
    8665        88562 :                 state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0;
    8666        88562 :                 state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0;
    8667        88562 :                 state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0;
    8668        88562 :                 state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0;
    8669        88562 :                 state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0;
    8670        88562 :                 state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0;
    8671        88562 :                 state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0;
    8672        88562 :                 state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0;
    8673              :             }
    8674              : 
    8675              :             // Calculate heat extract due to additional heat flux source term as the surface boundary condition
    8676       321290 :             for (int surfNum : state.dataSurface->allInsideSourceSurfaceList) {
    8677            1 :                 state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) =
    8678            1 :                     state.dataSurface->Surface(surfNum).insideHeatSourceTermSched->getCurrentVal();
    8679       321289 :             }
    8680              : 
    8681              :             // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces
    8682       321289 :             int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8683       321289 :             int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8684       321289 :             Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
    8685       321289 :             Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst;    // local for vectorization
    8686              :             // this loop auto-vectorizes
    8687      2007800 :             for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8688      1686511 :                 auto const &surface = Surface(surfNum);
    8689      1686511 :                 if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8690            0 :                     int repSurfNum = surface.RepresentativeCalcSurfNum;
    8691            0 :                     if (surfNum != repSurfNum) {
    8692            0 :                         continue;
    8693              :                     }
    8694              :                 }
    8695              : 
    8696              :                 // Pre-calculate a few terms before the iteration loop
    8697      1686511 :                 state.dataHeatBalSurf->SurfTempTerm(surfNum) =
    8698      1686511 :                     state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8699      1686511 :                     state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8700      1686511 :                     state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8701      1686511 :                     state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8702      1686511 :                     (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
    8703      1686511 :                 state.dataHeatBalSurf->SurfTempDiv(surfNum) =
    8704      1686511 :                     1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
    8705      1686511 :                            state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
    8706      1686511 :                            state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
    8707      1686511 :                            (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant);
    8708              :             }
    8709       287678 :         }
    8710              :     }
    8711              : 
    8712       200983 :     state.dataHeatBal->InsideSurfIterations = 0;
    8713       200983 :     bool Converged = false; // .TRUE. if inside heat balance has converged
    8714       978391 :     while (!Converged) {    // Start of main inside heat balance iteration loop...
    8715              : 
    8716       777408 :         state.dataHeatBalSurf->SurfTempInsOld = state.dataHeatBalSurf->SurfTempIn; // Keep track of last iteration's temperature values
    8717              : 
    8718      1554816 :         HeatBalanceIntRadExchange::CalcInteriorRadExchange(state,
    8719       777408 :                                                            state.dataHeatBalSurf->SurfTempIn,
    8720       777408 :                                                            state.dataHeatBal->InsideSurfIterations,
    8721       777408 :                                                            state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea,
    8722              :                                                            ZoneToResimulate,
    8723              :                                                            Inside); // Update the radiation balance
    8724              : 
    8725              :         // Every 30 iterations, recalculate the inside convection coefficients in case
    8726              :         // there has been a significant drift in the surface temperatures predicted.
    8727              :         // This is not fool-proof and it basically means that the outside surface
    8728              :         // heat balance is in error (potentially) once HConvIn is re-evaluated.
    8729              :         // The choice of 30 is not significant--just want to do this a couple of
    8730              :         // times before the iteration limit is hit.
    8731      1353833 :         if ((state.dataHeatBal->InsideSurfIterations > 0) &&
    8732       576425 :             (mod(state.dataHeatBal->InsideSurfIterations, DataHeatBalSurface::ItersReevalConvCoeff) == 0)) {
    8733          139 :             Convect::InitIntConvCoeff(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate);
    8734              :             // Since HConvIn has changed re-calculate a few terms - non-window surfaces
    8735          313 :             for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8736          348 :                 for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8737          174 :                     auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8738          174 :                     int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8739          174 :                     int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8740              : 
    8741          174 :                     Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization
    8742          174 :                     Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst;    // local for vectorization
    8743              :                     // this loop auto-vectorizes
    8744         1258 :                     for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    8745         1084 :                         auto const &surface = Surface(surfNum);
    8746         1084 :                         if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8747            0 :                             int repSurfNum = surface.RepresentativeCalcSurfNum;
    8748            0 :                             if (surfNum != repSurfNum) {
    8749            0 :                                 continue;
    8750              :                             }
    8751              :                         }
    8752              : 
    8753         1084 :                         state.dataHeatBalSurf->SurfTempTerm(surfNum) =
    8754         1084 :                             state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8755         1084 :                             state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8756         1084 :                             state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8757         1084 :                             state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8758         1084 :                             (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds);
    8759         1084 :                         state.dataHeatBalSurf->SurfTempDiv(surfNum) =
    8760         1084 :                             1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) -
    8761         1084 :                                    state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) +
    8762         1084 :                                    state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) +
    8763         1084 :                                    (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) +
    8764              :                                    iterDampConstant);
    8765              :                     }
    8766          174 :                 }
    8767              :             }
    8768              :         }
    8769              : 
    8770              :         // Loop over non-window surfaces
    8771      1924501 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    8772      2388278 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    8773      1241185 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    8774      1241185 :                 int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    8775      1241185 :                 int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    8776      1241185 :                 Real64 const iterDampConstant = DataHeatBalSurface::IterDampConst; // local for vectorization
    8777              :                 // this loop auto-vectorizes
    8778      8024415 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8779              :                     // Perform heat balance on the inside face of the surface ...
    8780              :                     // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others):
    8781              :                     //   (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm)
    8782              :                     //   (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same
    8783              :                     //   (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation
    8784              :                     //   (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures
    8785              :                     //   (e) standard opaque surface with movable insulation, special two-part equation
    8786              :                     // In the surface calculation there are the following Algorithm types for opaque surfaces that
    8787              :                     // do not have movable insulation:
    8788              :                     //   (a) the regular CTF calc (SolutionAlgo = UseCTF)
    8789              :                     //   (b) the EMPD calc (Solutionalgo = UseEMPD)
    8790              :                     //   (c) the CondFD calc (SolutionAlgo = UseCondFD)
    8791              :                     //   (d) the HAMT calc (solutionalgo = UseHAMT).
    8792              : 
    8793              :                     // For adiabatic surface:
    8794              :                     // Adiabatic:   TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] + HConvIn_surf + IterDampConst));
    8795              :                     // Adiabatic:   SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
    8796              :                     // Ad+Source:   SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst *
    8797              :                     // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool:     TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross[0] +
    8798              :                     // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool:     SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) +
    8799              :                     // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv;
    8800              : 
    8801              :                     // For standard or interzone surface:
    8802              :                     // Standard:    TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst));
    8803              :                     // Standard:    SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) *
    8804              :                     // TempDiv; Std+Source:  SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) + IterDampConst
    8805              :                     // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool:    TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) +
    8806              :                     // IterDampConst); Std+Pool:    SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) +
    8807              :                     // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross[0] * TH11) * TempDiv;
    8808              : 
    8809              :                     // Composite with Adiabatic/Source/Pool flags:
    8810              :                     //              TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross[0]+
    8811              :                     //              SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst));
    8812              :                     //              SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn[0] * SurfQsrcHist(SurfNum, 1) +
    8813              :                     //              SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum)
    8814              :                     //                                        + IterDampConst * SurfTempInsOld(SurfNum)+
    8815              :                     //                                        IsNotAdiabatic*IsNotSource*construct.CTFCross[0]
    8816              :                     //                                        * TH11) * TempDiv;
    8817              : 
    8818              :                     // Calculate the current inside surface temperature
    8819      6783230 :                     state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8820      6783230 :                         ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) *
    8821      6783230 :                              (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) +
    8822      6783230 :                          state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) *
    8823      6783230 :                              state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) +
    8824      6783230 :                          state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) +
    8825      6783230 :                          state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) +
    8826      6783230 :                          iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
    8827      6783230 :                          (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) *
    8828      6783230 :                              state.dataHeatBalSurf->SurfTempOutHist(surfNum)) *
    8829      6783230 :                         state.dataHeatBalSurf->SurfTempDiv(surfNum);
    8830              :                     // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW
    8831              :                     // radiation from internal sources | Convection from surface to zone air | Net radiant
    8832              :                     // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there
    8833              :                     // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot
    8834              :                     // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from
    8835              :                     // an electric baseboard heater | Iterative damping term (for stability) | Current
    8836              :                     // conduction from | the outside surface | Coefficient for conduction (current time) |
    8837              :                     // Convection and damping term | Radiation from AFN ducts
    8838              : 
    8839      6783230 :                     state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8840              :                 }
    8841              : 
    8842              :                 // Loop over non-window surfaces (includes TubularDaylightingDomes)
    8843      8024415 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    8844      6783230 :                     auto &movInsul = state.dataSurface->intMovInsuls(surfNum);
    8845              : 
    8846      6783230 :                     bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && movInsul.present;
    8847      6783230 :                     if (movableInsulPresent) { // Movable insulation present, recalc surface temps
    8848            0 :                         Real64 HMovInsul = movInsul.H;
    8849            0 :                         Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + DataHeatBalSurface::IterDampConst);
    8850            0 :                         state.dataHeatBalSurf->SurfTempIn(surfNum) =
    8851            0 :                             (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
    8852            0 :                              state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) +
    8853            0 :                              F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8854            0 :                                    state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8855            0 :                                    state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8856            0 :                                    state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) +
    8857            0 :                                    state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8858            0 :                                    DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) /
    8859            0 :                             (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air
    8860              : 
    8861            0 :                         state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8862            0 :                             (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) +
    8863            0 :                              HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) -
    8864            0 :                              state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) -
    8865            0 :                              state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) /
    8866              :                             (HMovInsul);
    8867              :                     }
    8868              : 
    8869      6783230 :                     if (state.dataHeatBal->AnyInternalHeatSourceInInput) {
    8870            0 :                         if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) {
    8871              :                             // Set the appropriate parameters for the radiant system
    8872              :                             // Radiant system does not need the damping coefficient terms (hopefully)
    8873              :                             Real64 const RadSysDiv(1.0 /
    8874            0 :                                                    (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum)));
    8875              :                             Real64 const TempTerm(
    8876            0 :                                 state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) +
    8877            0 :                                 state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) +
    8878            0 :                                 state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8879            0 :                                 state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8880            0 :                                 state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8881            0 :                                 (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec));
    8882            0 :                             state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) =
    8883            0 :                                 TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW
    8884              :                             // radiation from internal sources | Convection from surface to zone air | Radiant flux
    8885              :                             // from high temp radiant heater | Radiant flux from a hot water baseboard heater |
    8886              :                             // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard
    8887              :                             // heater | Net radiant exchange with other zone surfaces | Cond term (both partition
    8888              :                             // sides same temp) | Convection and damping term
    8889            0 :                             state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) =
    8890            0 :                                 state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition |
    8891              :                             // Cond term (both partition sides same temp) |
    8892              :                             // Convection and damping term
    8893            0 :                             state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) =
    8894            0 :                                 state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both
    8895              :                             // partition sides same temp) | Convection and
    8896              :                             // damping term
    8897              : 
    8898            0 :                             if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params
    8899              :                                 // The inside coefficients of one side are equal to the outside coefficients of the other side.  But,
    8900              :                                 // the inside coefficients are set up once the heat balance equation for that side has been calculated.
    8901              :                                 // For both sides to actually have been set, we have to wait until we get to the second side in the surface
    8902              :                                 // derived type.  At that point, both inside coefficient sets have been evaluated.
    8903            0 :                                 if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set
    8904            0 :                                     int OtherSideSurfNum = Surface(surfNum).ExtBoundCond;
    8905            0 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) =
    8906            0 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum);
    8907            0 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) =
    8908            0 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum);
    8909            0 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) =
    8910            0 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum);
    8911            0 :                                     state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) =
    8912            0 :                                         state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum);
    8913            0 :                                     state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) =
    8914            0 :                                         state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum);
    8915            0 :                                     state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) =
    8916            0 :                                         state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum);
    8917              :                                 }
    8918              :                             }
    8919              :                         }
    8920              :                     }
    8921              :                 }
    8922              : 
    8923              :                 // Loop over window surfaces
    8924      1241185 :                 int const firstWindowSurf = thisSpace.WindowSurfaceFirst;
    8925      1241185 :                 int const lastWindowSurf = thisSpace.WindowSurfaceLast;
    8926      1620943 :                 for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) {
    8927       379758 :                     auto &surface = state.dataSurface->Surface(surfNum);
    8928       379758 :                     if (state.dataSurface->UseRepresentativeSurfaceCalculations) {
    8929            0 :                         int repSurfNum = surface.RepresentativeCalcSurfNum;
    8930            0 :                         if (surfNum != repSurfNum) {
    8931            0 :                             continue;
    8932              :                         }
    8933              :                     }
    8934       379758 :                     Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum));
    8935       379758 :                     int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum);
    8936       379758 :                     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    8937       379758 :                     if (surface.OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    8938              :                         // Lookup up the TDD:DOME object
    8939            2 :                         int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum);
    8940            2 :                         int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome;
    8941              :                         // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    8942            2 :                         Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff;
    8943              : 
    8944              :                         // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks.
    8945              :                         // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    8946              :                         //   = SurfWinQRadSWwinAbs(surfNum,1)/2.0
    8947            2 :                         Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum));
    8948            2 :                         state.dataHeatBalSurf->SurfTempInTmp(surfNum) =
    8949            2 :                             (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 +
    8950            2 :                              state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) +
    8951            2 :                              HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) +
    8952            2 :                              state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) +
    8953            2 :                              DataHeatBalSurface::IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) +
    8954            2 :                              Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) /
    8955            2 :                             (Ueff + HConvIn_surf +
    8956              :                              DataHeatBalSurface::IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and
    8957              :                                                                  // solar | Convection from surface to zone air | Net radiant exchange with
    8958              :                                                                  // other zone surfaces | Iterative damping term (for stability) | Current
    8959              :                                                                  // conduction from the outside surface | Coefficient for conduction (current
    8960              :                                                                  // time) | Convection and damping term
    8961            2 :                         state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    8962            2 :                         Real64 const Sigma_Temp_4(Constant::StefanBoltzmann * pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + Constant::Kelvin));
    8963              : 
    8964              :                         // fill out report vars for components of Window Heat Gain
    8965            2 :                         state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) =
    8966            4 :                             HConvIn_surf * surface.Area *
    8967            2 :                             (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum));
    8968            2 :                         state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) =
    8969            2 :                             state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area *
    8970            2 :                             (Sigma_Temp_4 -
    8971            2 :                              (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum)));
    8972            2 :                         state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) =
    8973            2 :                             state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area *
    8974            2 :                                 (1 - state.dataConstruction->Construct(surface.Construction).ReflectSolDiffBack) +
    8975            2 :                             state.dataHeatBalSurf->SurfWinInitialBeamSolInTrans(surfNum);
    8976              : 
    8977              :                         // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager
    8978            2 :                         state.dataSurface->SurfWinHeatGain(surfNum) =
    8979            2 :                             state.dataSurface->SurfWinTransSolar(surfNum) + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) +
    8980            2 :                             state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) -
    8981            2 :                             surface.Area * state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum);
    8982              :                         // Net transmitted solar | Convection | IR exchange | IR
    8983              :                         // Zone diffuse interior shortwave reflected back into the TDD
    8984              :                     } else {                                                // Regular window
    8985       379756 :                         if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once
    8986              :                             // Get outside convection coeff for exterior window here to avoid calling
    8987              :                             // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference
    8988              :                             // (HeatBalanceSurfaceManager USEing and WindowManager and
    8989              :                             // WindowManager USEing HeatBalanceSurfaceManager)
    8990        88560 :                             if (surface.ExtBoundCond == DataSurfaces::ExternalEnvironment) {
    8991        88560 :                                 auto const *thisMaterial = s_mat->materials(construct.LayerPoint(1));
    8992        88560 :                                 assert(thisMaterial != nullptr);
    8993        88560 :                                 Material::SurfaceRoughness RoughSurf = thisMaterial->Roughness; // Outside surface roughness
    8994        88560 :                                 Real64 EmisOut = thisMaterial->AbsorpThermalFront;              // Glass outside surface emissivity
    8995        88560 :                                 DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(surfNum);
    8996        88560 :                                 if (DataSurfaces::ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) {
    8997              :                                     // Exterior shade in place
    8998            0 :                                     int const ConstrNumSh = Surface(surfNum).activeShadedConstruction;
    8999            0 :                                     if (ConstrNumSh != 0) {
    9000            0 :                                         auto const &constructionSh = state.dataConstruction->Construct(ConstrNumSh);
    9001            0 :                                         auto const *thisMaterial2 = s_mat->materials(constructionSh.LayerPoint(1));
    9002            0 :                                         RoughSurf = thisMaterial2->Roughness;
    9003            0 :                                         EmisOut = thisMaterial2->AbsorpThermal;
    9004              :                                     }
    9005              :                                 }
    9006              : 
    9007              :                                 // Get the outside effective emissivity for Equivalent layer model
    9008        88560 :                                 if (construct.WindowTypeEQL) {
    9009         2367 :                                     EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum);
    9010              :                                 }
    9011              :                                 // Set Exterior Convection Coefficient...
    9012        88560 :                                 if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
    9013              : 
    9014            0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
    9015              : 
    9016        88560 :                                 } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain)
    9017              : 
    9018              :                                     // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in
    9019              :                                     // subroutine)
    9020        88560 :                                     Convect::InitExtConvCoeff(state,
    9021              :                                                               surfNum,
    9022              :                                                               0.0,
    9023              :                                                               RoughSurf,
    9024              :                                                               EmisOut,
    9025              :                                                               TH11,
    9026        88560 :                                                               state.dataHeatBalSurf->SurfHConvExt(surfNum),
    9027        88560 :                                                               state.dataHeatBalSurf->SurfHSkyExt(surfNum),
    9028        88560 :                                                               state.dataHeatBalSurf->SurfHGrdExt(surfNum),
    9029        88560 :                                                               state.dataHeatBalSurf->SurfHAirExt(surfNum),
    9030        88560 :                                                               state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
    9031              : 
    9032        88560 :                                     if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet
    9033            0 :                                         state.dataHeatBalSurf->SurfHConvExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness
    9034              :                                     }
    9035              : 
    9036              :                                 } else { // Not Wind exposed
    9037              : 
    9038              :                                     // Calculate exterior heat transfer coefficients for windspeed = 0
    9039            0 :                                     Convect::InitExtConvCoeff(state,
    9040              :                                                               surfNum,
    9041              :                                                               0.0,
    9042              :                                                               RoughSurf,
    9043              :                                                               EmisOut,
    9044              :                                                               TH11,
    9045            0 :                                                               state.dataHeatBalSurf->SurfHConvExt(surfNum),
    9046            0 :                                                               state.dataHeatBalSurf->SurfHSkyExt(surfNum),
    9047            0 :                                                               state.dataHeatBalSurf->SurfHGrdExt(surfNum),
    9048            0 :                                                               state.dataHeatBalSurf->SurfHAirExt(surfNum),
    9049            0 :                                                               state.dataHeatBalSurf->SurfHSrdSurfExt(surfNum));
    9050              :                                 }
    9051              : 
    9052              :                             } else { // Interior Surface
    9053              : 
    9054            0 :                                 if (state.dataSurface->surfExtConv(surfNum).userModelNum != 0) {
    9055            0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = Convect::SetExtConvCoeff(state, surfNum);
    9056              :                                 } else {
    9057              :                                     // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of
    9058              :                                     // same
    9059            0 :                                     state.dataHeatBalSurf->SurfHConvExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond);
    9060              :                                 }
    9061              :                             }
    9062              : 
    9063              :                             // Following call determines inside surface temperature of glazing, and of
    9064              :                             // frame and/or divider, if present
    9065        88560 :                             Window::CalcWindowHeatBalance(
    9066        88560 :                                 state, surfNum, state.dataHeatBalSurf->SurfHConvExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11);
    9067        88560 :                             state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum);
    9068              :                         }
    9069              :                     }
    9070              :                 }
    9071              : 
    9072      1241185 :                 int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst;
    9073      1241185 :                 int const lastSurf = thisSpace.OpaqOrWinSurfaceLast;
    9074      8404173 :                 for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) {
    9075      7162988 :                     auto &zone = state.dataHeatBal->Zone(zoneNum);
    9076              : 
    9077      7162988 :                     Real64 &TH11 = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum);
    9078      7162988 :                     Real64 &TH12 = state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum);
    9079      7162988 :                     TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum);
    9080      7162988 :                     state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11;                                                  // For reporting
    9081      7162988 :                     if (state.dataSurface->Surface(surfNum).OriginalClass == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device
    9082              :                         // Tubular daylighting devices are treated as one big object with an effective R value.
    9083              :                         // The outside face temperature of the TDD:DOME and the inside face temperature of the
    9084              :                         // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively.
    9085              :                         // Below, the resulting temperatures are copied to the inside face of the TDD:DOME
    9086              :                         // and the outside face of the TDD:DIFFUSER for reporting.
    9087              : 
    9088              :                         // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER
    9089            2 :                         int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome;
    9090            2 :                         state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) =
    9091            2 :                             state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum);
    9092              : 
    9093              :                         // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise)
    9094              :                         // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME
    9095            2 :                         TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) =
    9096            2 :                             state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum);
    9097              :                     }
    9098              : 
    9099      7162988 :                     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    9100            0 :                         TestSurfTempCalcHeatBalanceInsideSurf(
    9101            0 :                             state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount);
    9102              :                     }
    9103              :                 }
    9104      1147093 :             }
    9105              :         } // ...end of main loops over all surfaces for inside heat balances
    9106              : 
    9107              :         // Interzone surface updating: interzone surfaces have other side temperatures
    9108              :         // which can vary as the simulation iterates through the inside heat
    9109              :         // balance.  This block is intended to "lock" the opposite side (outside)
    9110              :         // temperatures to the correct value, namely the value calculated by the
    9111              :         // inside surface heat balance for the other side.
    9112              :         //        assert(state.dataHeatBalSurf->TH.index(1, 1, 1) == 0u); // Assumed for linear indexing below
    9113              :         //        int const l211(state.dataHeatBalSurf->TH.index(2, 1, 1) - 1);
    9114      1532122 :         for (int SurfNum : IZSurfs) {
    9115       754714 :             int const surfExtBoundCond = Surface(SurfNum).ExtBoundCond;
    9116              :             // Set the outside surface temperature to the inside surface temperature of the interzone pair.
    9117              :             // By going through all of the surfaces, this should pick up the other side as well as affect the next iteration.
    9118              :             // [ SurfNum - 1 ] == ( 1, 1, SurfNum )
    9119              :             // [ l211 + surfExtBoundCond ] == ( 2, 1, surfExtBoundCond )
    9120       754714 :             state.dataHeatBalSurf->SurfTempOut(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) =
    9121       754714 :                 state.dataHeatBalSurf->SurfInsideTempHist(1)(surfExtBoundCond);
    9122       754714 :             state.dataHeatBalSurf->SurfTempOutHist(SurfNum) = state.dataHeatBalSurf->SurfTempOut(SurfNum);
    9123       777408 :         }
    9124              : 
    9125       777408 :         ++state.dataHeatBal->InsideSurfIterations;
    9126              : 
    9127              :         // Convergence check - Loop through all relevant non-window surfaces to check for convergence...
    9128       777408 :         Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next
    9129      1924501 :         for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) {
    9130      2388278 :             for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) {
    9131      1241185 :                 auto const &thisSpace = state.dataHeatBal->space(spaceNum);
    9132      1241185 :                 int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst;
    9133      1241185 :                 int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast;
    9134      8024415 :                 for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) {
    9135      6783230 :                     Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum);
    9136      6783230 :                     Real64 absDif = std::abs(delta);
    9137      6783230 :                     MaxDelTemp = std::max(absDif, MaxDelTemp);
    9138              :                 }
    9139      1147093 :             }
    9140              :         } // ...end of loop to check for convergence
    9141              : 
    9142       777408 :         if (MaxDelTemp <= state.dataHeatBal->MaxAllowedDelTemp) {
    9143       200983 :             Converged = true;
    9144              :         }
    9145              : 
    9146              : #ifdef EP_Count_Calls
    9147              :         state.dataTimingsData->NumMaxInsideSurfIterations =
    9148              :             max(state.dataTimingsData->NumMaxInsideSurfIterations, state.dataHeatBal->InsideSurfIterations);
    9149              : #endif
    9150              : 
    9151       777408 :         if (state.dataHeatBal->InsideSurfIterations < state.dataHeatBalSurf->MinIterations) {
    9152            0 :             Converged = false;
    9153              :         }
    9154              : 
    9155       777408 :         if (state.dataHeatBal->InsideSurfIterations > DataHeatBalSurface::MaxIterations) {
    9156            0 :             if (!state.dataGlobal->WarmupFlag) {
    9157            0 :                 ++state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount;
    9158            0 :                 if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrCount < 16) {
    9159            0 :                     ShowWarningError(state,
    9160            0 :                                      format("Inside surface heat balance did not converge with Max Temp Difference [C] ={:.3R} vs Max Allowed "
    9161              :                                             "Temp Diff [C] ={:.6R}",
    9162              :                                             MaxDelTemp,
    9163            0 :                                             state.dataHeatBal->MaxAllowedDelTempCondFD));
    9164            0 :                     ShowContinueErrorTimeStamp(state, "");
    9165              :                 } else {
    9166            0 :                     ShowRecurringWarningErrorAtEnd(state,
    9167              :                                                    "Inside surface heat balance convergence problem continues",
    9168            0 :                                                    state.dataHeatBalSurfMgr->calcHeatBalInsideSurfErrPointer,
    9169              :                                                    MaxDelTemp,
    9170              :                                                    MaxDelTemp,
    9171              :                                                    _,
    9172              :                                                    "[C]",
    9173              :                                                    "[C]");
    9174              :                 }
    9175              :             }
    9176            0 :             break; // iteration loop
    9177              :         }
    9178              : 
    9179              :     } // ...end of main inside heat balance iteration loop (ends when Converged)
    9180       200983 : }
    9181              : 
    9182       249963 : void sumSurfQdotRadHVAC(EnergyPlusData &state)
    9183              : {
    9184       249999 :     for (int surfNum : state.dataSurface->allGetsRadiantHeatSurfaceList) {
    9185           36 :         auto const &thisSurfQRadFromHVAC = state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum);
    9186           36 :         state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = thisSurfQRadFromHVAC.HTRadSys + thisSurfQRadFromHVAC.HWBaseboard +
    9187           36 :                                                                    thisSurfQRadFromHVAC.SteamBaseboard + thisSurfQRadFromHVAC.ElecBaseboard +
    9188           36 :                                                                    thisSurfQRadFromHVAC.CoolingPanel;
    9189       249963 :     }
    9190       249963 : }
    9191              : 
    9192            5 : void TestSurfTempCalcHeatBalanceInsideSurf(EnergyPlusData &state, Real64 TH12, int const SurfNum, DataHeatBalance::ZoneData &zone, int WarmupSurfTemp)
    9193              : {
    9194            5 :     std::string surfName = state.dataSurface->Surface(SurfNum).Name;
    9195              : 
    9196            5 :     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimit)) {
    9197            4 :         if (state.dataGlobal->WarmupFlag) {
    9198            0 :             ++WarmupSurfTemp;
    9199              :         }
    9200            4 :         if (!state.dataGlobal->WarmupFlag || WarmupSurfTemp > 10 || state.dataGlobal->DisplayExtraWarnings) {
    9201            4 :             if (TH12 < DataHeatBalSurface::MinSurfaceTempLimit) {
    9202            2 :                 if (state.dataSurface->SurfLowTempErrCount(SurfNum) == 0) {
    9203            4 :                     ShowSevereMessage(
    9204            4 :                         state, format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9205            4 :                     ShowContinueErrorTimeStamp(state, "");
    9206            2 :                     if (!zone.TempOutOfBoundsReported) {
    9207            1 :                         ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9208            1 :                         if (zone.FloorArea > 0.0) {
    9209            1 :                             ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9210              :                         } else {
    9211            0 :                             ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
    9212              :                         }
    9213            1 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9214            1 :                             ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9215            1 :                             ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9216              :                         } else {
    9217            0 :                             ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9218              :                         }
    9219            1 :                         if (zone.IsControlled) {
    9220            3 :                             ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9221              :                         } else {
    9222            0 :                             ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9223              :                         }
    9224            1 :                         zone.TempOutOfBoundsReported = true;
    9225              :                     }
    9226           18 :                     ShowRecurringSevereErrorAtEnd(state,
    9227            4 :                                                   "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9228            2 :                                                   state.dataSurface->SurfLowTempErrCount(SurfNum),
    9229              :                                                   TH12,
    9230              :                                                   TH12,
    9231              :                                                   _,
    9232              :                                                   "C",
    9233              :                                                   "C");
    9234              :                 } else {
    9235            0 :                     ShowRecurringSevereErrorAtEnd(state,
    9236            0 :                                                   "Temperature (low) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9237            0 :                                                   state.dataSurface->SurfLowTempErrCount(SurfNum),
    9238              :                                                   TH12,
    9239              :                                                   TH12,
    9240              :                                                   _,
    9241              :                                                   "C",
    9242              :                                                   "C");
    9243              :                 }
    9244              :             } else {
    9245            2 :                 if (state.dataSurface->SurfHighTempErrCount(SurfNum) == 0) {
    9246            4 :                     ShowSevereMessage(
    9247            4 :                         state, format(R"(Temperature (high) out of bounds ({:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9248            4 :                     ShowContinueErrorTimeStamp(state, "");
    9249            2 :                     if (!zone.TempOutOfBoundsReported) {
    9250            1 :                         ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9251            1 :                         if (zone.FloorArea > 0.0) {
    9252            1 :                             ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9253              :                         } else {
    9254            0 :                             ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains));
    9255              :                         }
    9256            1 :                         if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9257            1 :                             ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9258            1 :                             ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9259              :                         } else {
    9260            0 :                             ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9261              :                         }
    9262            1 :                         if (zone.IsControlled) {
    9263            3 :                             ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9264              :                         } else {
    9265            0 :                             ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9266              :                         }
    9267            1 :                         zone.TempOutOfBoundsReported = true;
    9268              :                     }
    9269           18 :                     ShowRecurringSevereErrorAtEnd(state,
    9270            4 :                                                   "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9271            2 :                                                   state.dataSurface->SurfHighTempErrCount(SurfNum),
    9272              :                                                   TH12,
    9273              :                                                   TH12,
    9274              :                                                   _,
    9275              :                                                   "C",
    9276              :                                                   "C");
    9277              :                 } else {
    9278            0 :                     ShowRecurringSevereErrorAtEnd(state,
    9279            0 :                                                   "Temperature (high) out of bounds for zone=" + zone.Name + " for surface=" + surfName,
    9280            0 :                                                   state.dataSurface->SurfHighTempErrCount(SurfNum),
    9281              :                                                   TH12,
    9282              :                                                   TH12,
    9283              :                                                   _,
    9284              :                                                   "C",
    9285              :                                                   "C");
    9286              :                 }
    9287              :             }
    9288            4 :             if (zone.EnforcedReciprocity) {
    9289            0 :                 if (WarmupSurfTemp > 3) {
    9290            0 :                     ShowSevereError(state, format("CalcHeatBalanceInsideSurf: Zone=\"{}\" has view factor enforced reciprocity", zone.Name));
    9291            0 :                     ShowContinueError(state, " and is having temperature out of bounds errors. Please correct zone geometry and rerun.");
    9292            0 :                     ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    9293              :                 }
    9294            4 :             } else if (WarmupSurfTemp > 10) {
    9295            0 :                 ShowFatalError(state, "CalcHeatBalanceInsideSurf: Program terminates due to preceding conditions.");
    9296              :             }
    9297              :         }
    9298              :     }
    9299            5 :     if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimitBeforeFatal) || (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal)) {
    9300            0 :         if (!state.dataGlobal->WarmupFlag) {
    9301            0 :             if (TH12 < DataHeatBalSurface::MinSurfaceTempLimitBeforeFatal) {
    9302            0 :                 ShowSevereError(state,
    9303            0 :                                 format(R"(Temperature (low) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9304            0 :                 ShowContinueErrorTimeStamp(state, "");
    9305            0 :                 if (!zone.TempOutOfBoundsReported) {
    9306            0 :                     ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9307            0 :                     if (zone.FloorArea > 0.0) {
    9308            0 :                         ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9309              :                     } else {
    9310            0 :                         ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
    9311              :                     }
    9312            0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9313            0 :                         ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9314            0 :                         ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9315              :                     } else {
    9316            0 :                         ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9317              :                     }
    9318            0 :                     if (zone.IsControlled) {
    9319            0 :                         ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9320              :                     } else {
    9321            0 :                         ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9322              :                     }
    9323            0 :                     zone.TempOutOfBoundsReported = true;
    9324              :                 }
    9325            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9326              :             } else {
    9327            0 :                 ShowSevereError(state,
    9328            0 :                                 format(R"(Temperature (high) out of bounds [{:.2R}] for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9329            0 :                 ShowContinueErrorTimeStamp(state, "");
    9330            0 :                 if (!zone.TempOutOfBoundsReported) {
    9331            0 :                     ShowContinueError(state, format("Zone=\"{}\", Diagnostic Details:", zone.Name));
    9332            0 :                     if (zone.FloorArea > 0.0) {
    9333            0 :                         ShowContinueError(state, format("...Internal Heat Gain [{:.3R}] W/m2", zone.InternalHeatGains / zone.FloorArea));
    9334              :                     } else {
    9335            0 :                         ShowContinueError(state, format("...Internal Heat Gain (no floor) [{:.3R}] W", zone.InternalHeatGains / zone.FloorArea));
    9336              :                     }
    9337            0 :                     if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
    9338            0 :                         ShowContinueError(state, format("...Infiltration/Ventilation [{:.3R}] m3/s", zone.NominalInfilVent));
    9339            0 :                         ShowContinueError(state, format("...Mixing/Cross Mixing [{:.3R}] m3/s", zone.NominalMixing));
    9340              :                     } else {
    9341            0 :                         ShowContinueError(state, "...Airflow Network Simulation: Nominal Infiltration/Ventilation/Mixing not available.");
    9342              :                     }
    9343            0 :                     if (zone.IsControlled) {
    9344            0 :                         ShowContinueError(state, "...Zone is part of HVAC controlled system.");
    9345              :                     } else {
    9346            0 :                         ShowContinueError(state, "...Zone is not part of HVAC controlled system.");
    9347              :                     }
    9348            0 :                     zone.TempOutOfBoundsReported = true;
    9349              :                 }
    9350            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9351              :             }
    9352              :         } else {
    9353            0 :             if (TH12 < -10000. || TH12 > 10000.) {
    9354            0 :                 ShowSevereError(
    9355              :                     state,
    9356            0 :                     format(R"(CalcHeatBalanceInsideSurf: The temperature of {:.2R} C for zone="{}", for surface="{}")", TH12, zone.Name, surfName));
    9357            0 :                 ShowContinueError(state, "..is very far out of bounds during warmup. This may be an indication of a malformed zone.");
    9358            0 :                 ShowContinueErrorTimeStamp(state, "");
    9359            0 :                 ShowFatalError(state, "Program terminates due to preceding condition.");
    9360              :             }
    9361              :         }
    9362              :     }
    9363            5 : }
    9364              : 
    9365      1051053 : void CalcOutsideSurfTemp(EnergyPlusData &state,
    9366              :                          int const SurfNum,      // Surface number DO loop counter
    9367              :                          int const spaceNum,     // Space number the current surface is attached to
    9368              :                          int const ConstrNum,    // Construction index for the current surface
    9369              :                          Real64 const HMovInsul, // "Convection" coefficient of movable insulation
    9370              :                          Real64 const TempExt,   // Exterior temperature boundary condition
    9371              :                          bool &ErrorFlag         // Error flag for movable insulation problem
    9372              : )
    9373              : {
    9374              : 
    9375              :     // SUBROUTINE INFORMATION:
    9376              :     //       AUTHOR         George Walton
    9377              :     //       DATE WRITTEN   December 1979
    9378              :     //       MODIFIED       Jun 1990 (RDT for new CTF arrays)
    9379              :     //                      Jul 2000 (RJL for Moisture algorithms)
    9380              :     //                      Sep 2000 (RKS for new radiant exchange algorithm)
    9381              :     //                      Dec 2000 (RKS for radiant system model addition)
    9382              :     //                      Aug 2010 (BG added radiant heat flow rate reporting)
    9383              :     //       RE-ENGINEERED  Mar 1998 (RKS)
    9384              : 
    9385              :     // PURPOSE OF THIS SUBROUTINE:
    9386              :     // This subroutine performs a heat balance on the outside face of each
    9387              :     // surface in the building.  NOTE that this also sets some coefficients
    9388              :     // that are needed for radiant system modeling.  Thus, it is extremely
    9389              :     // important that if someone makes changes to the heat balance equations
    9390              :     // at a later date that they must also make changes to the coefficient
    9391              :     // setting portion of this subroutine as well.
    9392              : 
    9393              :     // METHODOLOGY EMPLOYED:
    9394              :     // Various boundary conditions are set and additional parameters are set-
    9395              :     // up.  Then, the proper heat balance equation is selected based on the
    9396              :     // presence of movable insulation, thermal mass of the surface construction,
    9397              :     // and convection model being used.
    9398              : 
    9399              :     // REFERENCES:
    9400              :     // (I)BLAST legacy routine HBOUT
    9401              :     // 1989 ASHRAE Handbook of Fundamentals (Figure 1 on p. 22.4, convection correlations)
    9402              : 
    9403              :     // Determine whether or not movable insulation is present
    9404      1051053 :     bool MovInsulPresent = (HMovInsul > 0.0); // .TRUE. if movable insulation is currently present for surface
    9405              :     bool QuickConductionSurf;                 // .TRUE. if the cross CTF term is relatively large
    9406              :     Real64 F1;                                // Intermediate calculation variable
    9407              :     Real64 F2;                                // Intermediate calculation variable
    9408              :     // Determine whether this surface is a "slow conductive" or "quick conductive"
    9409              :     // surface.  Designates are inherited from BLAST.  Basically, a "quick" surface
    9410              :     // requires the inside heat balance to be accounted for in the heat balance
    9411              :     // while a "slow" surface can used the last time step's value for inside
    9412              :     // surface temperature.
    9413      1051053 :     auto &s_mat = state.dataMaterial;
    9414              : 
    9415      1051053 :     auto &surface = state.dataSurface->Surface(SurfNum);
    9416      1051053 :     auto const &construct = state.dataConstruction->Construct(ConstrNum);
    9417      1051053 :     if (construct.CTFCross[0] > 0.01) {
    9418       709122 :         QuickConductionSurf = true;
    9419       709122 :         F1 = construct.CTFCross[0] / (construct.CTFInside[0] + state.dataHeatBalSurf->SurfHConvInt(SurfNum));
    9420              :     } else {
    9421       341931 :         QuickConductionSurf = false;
    9422              :     }
    9423              : 
    9424      1051053 :     Real64 TSky = state.dataEnvrn->SkyTemp;
    9425      1051053 :     Real64 TGround = state.dataEnvrn->OutDryBulbTemp;
    9426      1051053 :     Real64 TSrdSurfs = 0.0;
    9427              : 
    9428      1051053 :     if (surface.SurfHasSurroundingSurfProperty) {
    9429            6 :         int SrdSurfsNum = surface.SurfSurroundingSurfacesNum;
    9430            6 :         if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched != nullptr) {
    9431            3 :             TSky = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).skyTempSched->getCurrentVal();
    9432              :         }
    9433            6 :         if (state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched != nullptr) {
    9434            1 :             TGround = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).groundTempSched->getCurrentVal();
    9435              :         }
    9436            6 :         TSrdSurfs = state.dataSurface->Surface(SurfNum).SrdSurfTemp;
    9437              :     }
    9438      1051053 :     if (surface.UseSurfPropertyGndSurfTemp) {
    9439            3 :         TGround = state.dataSurface->GroundSurfsProperty(surface.SurfPropertyGndSurfIndex).SurfsTempAvg;
    9440              :     }
    9441              : 
    9442              :     // Now, calculate the outside surface temperature using the proper heat balance equation.
    9443              :     // Each case has been separated out into its own IF-THEN block for clarity.  Additional
    9444              :     // cases can simply be added anywhere in the following section.  This is the last step
    9445              :     // in the main loop.  Once the proper heat balance is done, the simulation goes on to
    9446              :     // the next SurfNum.
    9447              : 
    9448              :     // Outside heat balance case: Tubular daylighting device
    9449      1051053 :     Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum));
    9450      1051053 :     if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    9451              : 
    9452              :         // Lookup up the TDD:DIFFUSER object
    9453            0 :         int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum);
    9454            0 :         int SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Diffuser;
    9455            0 :         int spaceNum2 = state.dataSurface->Surface(SurfNum2).spaceNum;
    9456            0 :         Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(PipeNum).Reff; // 1 / effective R value between TDD:DOME and TDD:DIFFUSER
    9457            0 :         F1 = Ueff / (Ueff + state.dataHeatBalSurf->SurfHConvInt(SurfNum2));
    9458              : 
    9459              :         // Similar to opaque surface but inside conditions of TDD:DIFFUSER are used, and no embedded sources/sinks.
    9460              :         // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed.
    9461              :         //   SurfOpaqQRadSWOutAbs(SurfNum) does not apply for TDD:DOME, must use SurfWinQRadSWwinAbs(SurfNum,1)/2.0 instead.
    9462              :         //+Construct(ConstrNum)%CTFSourceOut[0]     &   TDDs cannot be radiant systems
    9463              :         // *SurfQsrcHist(1,SurfNum)                     &
    9464              :         //+Construct(ConstrNum)%CTFSourceIn[0] &   TDDs cannot be radiant systems
    9465              :         // *SurfQsrcHist(1,SurfNum)                &
    9466            0 :         TH11 = (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, 1) / 2.0 +
    9467            0 :                 (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9468            0 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) +
    9469            0 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9470            0 :                 F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) +
    9471            0 :                       state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum2).MAT +
    9472            0 :                       state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) /
    9473            0 :                (Ueff + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9474            0 :                 state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9475            0 :                 state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9476            0 :                 F1 * Ueff); // Instead of SurfOpaqQRadSWOutAbs(SurfNum) | ODB used to approx ground surface temp | Use TDD:DIFFUSER surface | Use
    9477              :                             // TDD:DIFFUSER surface | Use TDD:DIFFUSER surface and zone | Use TDD:DIFFUSER surface
    9478              : 
    9479              :         // Outside heat balance case: No movable insulation, slow conduction
    9480      1051053 :     } else if ((!MovInsulPresent) && (!QuickConductionSurf)) {
    9481              :         // Add LWR from surrounding surfaces
    9482       341930 :         if (surface.OSCMPtr == 0) {
    9483       341930 :             if (construct.SourceSinkPresent) {
    9484            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9485            0 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9486            0 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9487            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9488            0 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9489            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
    9490            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9491            0 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9492            0 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
    9493              :             } else {
    9494       341930 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9495       341930 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9496       341930 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9497       341930 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9498       341930 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
    9499       341930 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9500       341930 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9501       341930 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)); // ODB used to approx ground surface temp
    9502              :             }
    9503              :             // Outside Heat Balance case: Other Side Conditions Model
    9504              :         } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
    9505              :             // local copies of variables for clarity in radiation terms
    9506              :             // TODO: - int OSCMPtr; // "Pointer" to OSCM data structure (other side conditions from a model)
    9507              :             Real64 RadTemp =
    9508            0 :                 state.dataSurface->OSCM(surface.OSCMPtr).TRad; // local value for Effective radiation temperature for OtherSideConditions model
    9509            0 :             Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad; // local value for effective (linearized) radiation coefficient
    9510              : 
    9511              :             // patterned after "No movable insulation, slow conduction," but with new radiation terms and no sun,
    9512            0 :             if (construct.SourceSinkPresent) {
    9513            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9514            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9515            0 :                         construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9516            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1)) /
    9517            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
    9518              :             } else {
    9519            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9520            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9521            0 :                         construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum)) /
    9522            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad);
    9523              :             }
    9524              :         }
    9525              :         // Outside heat balance case: No movable insulation, quick conduction
    9526      1051053 :     } else if ((!MovInsulPresent) && (QuickConductionSurf)) {
    9527       709122 :         if (surface.OSCMPtr == 0) {
    9528       709122 :             if (construct.SourceSinkPresent) {
    9529            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9530            0 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9531            0 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9532            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9533            0 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9534            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9535            0 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9536            0 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9537            0 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9538            0 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9539            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9540            0 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9541            0 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9542            0 :                         F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
    9543              :             } else {
    9544       709122 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9545       709122 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9546       709122 :                         (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9547       709122 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9548       709122 :                         state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround +
    9549       709122 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9550       709122 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9551       709122 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9552       709122 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9553       709122 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9554       709122 :                         state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9555       709122 :                         state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) -
    9556       709122 :                         F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp | MAT use here is problem for room air models
    9557              :             }
    9558              :             // Outside Heat Balance case: Other Side Conditions Model
    9559              :         } else { //( Surface(SurfNum)%OSCMPtr > 0 ) THEN
    9560              :             // local copies of variables for clarity in radiation terms
    9561            0 :             Real64 RadTemp = state.dataSurface->OSCM(surface.OSCMPtr).TRad;
    9562            0 :             Real64 HRad = state.dataSurface->OSCM(surface.OSCMPtr).HRad;
    9563              :             // patterned after "No movable insulation, quick conduction," but with new radiation terms and no sun,
    9564            0 :             if (construct.SourceSinkPresent) {
    9565            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9566            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9567            0 :                         construct.CTFSourceOut[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9568            0 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9569            0 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9570            0 :                               construct.CTFSourceIn[0] * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) +
    9571            0 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9572            0 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9573            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
    9574            0 :                         F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
    9575              :             } else {
    9576            0 :                 TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfHConvExt(SurfNum) * TempExt +
    9577            0 :                         state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp +
    9578            0 :                         F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9579            0 :                               state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9580            0 :                               state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9581            0 :                               state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) /
    9582            0 :                        (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + HRad -
    9583            0 :                         F1 * construct.CTFCross[0]); // MAT use here is problem for room air models
    9584              :             }
    9585              :         }
    9586              :         // Outside heat balance case: Movable insulation, slow conduction
    9587       709123 :     } else if ((MovInsulPresent) && (!QuickConductionSurf)) {
    9588              : 
    9589            1 :         F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9590            1 :                           state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9591            1 :                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    9592              : 
    9593            1 :         TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9594            1 :                 construct.CTFCross[0] * state.dataHeatBalSurf->SurfTempIn(SurfNum) +
    9595            1 :                 F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
    9596            1 :                       (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9597            1 :                       state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9598            1 :                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
    9599            1 :                (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul); // ODB used to approx ground surface temp
    9600              : 
    9601              :         // Outside heat balance case: Movable insulation, quick conduction
    9602            0 :     } else if ((MovInsulPresent) && (QuickConductionSurf)) {
    9603              : 
    9604            0 :         F2 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) +
    9605            0 :                           state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) +
    9606            0 :                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum));
    9607              : 
    9608            0 :         TH11 = (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9609            0 :                 F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) +
    9610            0 :                       state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) +
    9611            0 :                       state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).MAT +
    9612            0 :                       state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) +
    9613            0 :                 F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) +
    9614            0 :                       (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9615            0 :                       state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky +
    9616            0 :                       state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs)) /
    9617            0 :                (construct.CTFOutside[0] + HMovInsul - F2 * HMovInsul - F1 * construct.CTFCross[0]); // ODB used to approx ground surface temp
    9618              : 
    9619              :     } // ...end of outside heat balance cases IF-THEN block
    9620              : 
    9621              :     // multiply out linearized radiation coeffs for reporting
    9622              :     Real64 const HExtSurf_fac(
    9623      1051053 :         -(state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * (TH11 - TSky) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) * (TH11 - TempExt) +
    9624      1051053 :           state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * (TH11 - TGround) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * (TH11 - TSrdSurfs)));
    9625      1051053 :     state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = HExtSurf_fac;
    9626              : 
    9627              :     // Set the radiant system heat balance coefficients if this surface is also a radiant system
    9628      1051053 :     if (construct.SourceSinkPresent) {
    9629              : 
    9630            1 :         if (MovInsulPresent) {
    9631              :             // Note: if movable insulation is ever added back in correctly, the heat balance equations above must be fixed
    9632            2 :             ShowSevereError(state, "Exterior movable insulation is not valid with embedded sources/sinks");
    9633            1 :             ShowContinueError(state, format("Construction {} contains an internal source or sink but also uses", construct.Name));
    9634            2 :             ShowContinueError(state,
    9635            2 :                               format("exterior movable insulation {} for a surface with that construction.",
    9636            1 :                                      s_mat->materials(state.dataSurface->extMovInsuls(SurfNum).matNum)->Name));
    9637            2 :             ShowContinueError(state,
    9638              :                               "This is not currently allowed because the heat balance equations do not currently accommodate this combination.");
    9639            1 :             ErrorFlag = true;
    9640            1 :             return;
    9641              : 
    9642              :         } else {
    9643            0 :             Real64 const RadSysDiv(1.0 / (construct.CTFOutside[0] + state.dataHeatBalSurf->SurfHConvExt(SurfNum) +
    9644            0 :                                           state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) +
    9645            0 :                                           state.dataHeatBalSurf->SurfHGrdExt(SurfNum) + state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) +
    9646            0 :                                           state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum)));
    9647              : 
    9648            0 :             state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) =
    9649            0 :                 (-state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) +
    9650            0 :                  state.dataHeatBalSurf->SurfHSrdSurfExt(SurfNum) * TSrdSurfs +
    9651            0 :                  (state.dataHeatBalSurf->SurfHConvExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt +
    9652            0 :                  state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround) *
    9653              :                 RadSysDiv; // ODB used to approx ground surface temp
    9654              : 
    9655            0 :             state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = construct.CTFCross[0] * RadSysDiv;
    9656              : 
    9657            0 :             state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = construct.CTFSourceOut[0] * RadSysDiv;
    9658              :         }
    9659              :     }
    9660              : }
    9661              : 
    9662            0 : void CalcExteriorVentedCavity(EnergyPlusData &state, int const SurfNum) // index of surface
    9663              : {
    9664              : 
    9665              :     // SUBROUTINE INFORMATION:
    9666              :     //       AUTHOR         B Griffith
    9667              :     //       DATE WRITTEN   January 2005
    9668              : 
    9669              :     // PURPOSE OF THIS SUBROUTINE:
    9670              :     // manages calculating the temperatures of baffle and air cavity for
    9671              :     // multi-skin configuration.
    9672              : 
    9673              :     // METHODOLOGY EMPLOYED:
    9674              :     // derived from CalcPassiveTranspiredCollector
    9675              : 
    9676              :     // local working variables
    9677              :     Real64 HrPlen;
    9678              :     Real64 HcPlen;
    9679              :     Real64 Isc;
    9680              :     Real64 MdotVent;
    9681              :     Real64 VdotWind;
    9682              :     Real64 VdotThermal;
    9683              : 
    9684            0 :     int CavNum = state.dataSurface->SurfExtCavNum(SurfNum);
    9685            0 :     Real64 TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    9686            0 :     Real64 OutHumRatExt = Psychrometrics::PsyWFnTdbTwbPb(
    9687            0 :         state, state.dataSurface->SurfOutDryBulbTemp(SurfNum), state.dataSurface->SurfOutWetBulbTemp(SurfNum), state.dataEnvrn->OutBaroPress);
    9688            0 :     Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, OutHumRatExt);
    9689            0 :     Real64 holeArea = state.dataHeatBal->ExtVentedCavity(CavNum).ActualArea * state.dataHeatBal->ExtVentedCavity(CavNum).Porosity;
    9690              :     // Aspect Ratio of gap
    9691            0 :     Real64 AspRat = state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL * 2.0 / state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick;
    9692            0 :     Real64 TmpTscoll = state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast;
    9693            0 :     Real64 TmpTaPlen = state.dataHeatBal->ExtVentedCavity(CavNum).TairLast;
    9694              : 
    9695              :     // all the work is done in this routine located in GeneralRoutines.cc
    9696              : 
    9697            0 :     for (int iter = 1; iter <= 3; ++iter) { // this is a sequential solution approach.
    9698              : 
    9699            0 :         TranspiredCollector::CalcPassiveExteriorBaffleGap(state,
    9700            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).SurfPtrs,
    9701              :                                                           holeArea,
    9702            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Cv,
    9703            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Cd,
    9704            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).HdeltaNPL,
    9705            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).SolAbsorp,
    9706            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).LWEmitt,
    9707            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).Tilt,
    9708              :                                                           AspRat,
    9709            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick,
    9710            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).BaffleRoughness,
    9711            0 :                                                           state.dataHeatBal->ExtVentedCavity(CavNum).QdotSource,
    9712              :                                                           TmpTscoll,
    9713              :                                                           TmpTaPlen,
    9714              :                                                           HcPlen,
    9715              :                                                           HrPlen,
    9716              :                                                           Isc,
    9717              :                                                           MdotVent,
    9718              :                                                           VdotWind,
    9719              :                                                           VdotThermal);
    9720              : 
    9721              :     } // sequential solution
    9722              :     // now fill results into derived types
    9723            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).Isc = Isc;
    9724            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav = TmpTaPlen;
    9725            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle = TmpTscoll;
    9726            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen = HrPlen;
    9727            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen = HcPlen;
    9728            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveACH =
    9729            0 :         (MdotVent / RhoAir) *
    9730            0 :         (1.0 / (state.dataHeatBal->ExtVentedCavity(CavNum).ProjArea * state.dataHeatBal->ExtVentedCavity(CavNum).PlenGapThick)) *
    9731              :         Constant::rSecsInHour;
    9732            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotVent = MdotVent;
    9733            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotWind = VdotWind * RhoAir;
    9734            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).PassiveMdotTherm = VdotThermal * RhoAir;
    9735              : 
    9736              :     // now do some updates
    9737            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).TairLast = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
    9738            0 :     state.dataHeatBal->ExtVentedCavity(CavNum).TbaffleLast = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
    9739              : 
    9740              :     // update the OtherSideConditionsModel coefficients.
    9741            0 :     int thisOSCM = state.dataHeatBal->ExtVentedCavity(CavNum).OSCMPtr;
    9742              : 
    9743            0 :     state.dataSurface->OSCM(thisOSCM).TConv = state.dataHeatBal->ExtVentedCavity(CavNum).TAirCav;
    9744            0 :     state.dataSurface->OSCM(thisOSCM).HConv = state.dataHeatBal->ExtVentedCavity(CavNum).HcPlen;
    9745            0 :     state.dataSurface->OSCM(thisOSCM).TRad = state.dataHeatBal->ExtVentedCavity(CavNum).Tbaffle;
    9746            0 :     state.dataSurface->OSCM(thisOSCM).HRad = state.dataHeatBal->ExtVentedCavity(CavNum).HrPlen;
    9747            0 : }
    9748              : 
    9749        83022 : void GatherComponentLoadsSurfAbsFact(EnergyPlusData &state)
    9750              : {
    9751              :     // SUBROUTINE INFORMATION:
    9752              :     //       AUTHOR         Jason Glazer
    9753              :     //       DATE WRITTEN   September 2012
    9754              : 
    9755              :     // PURPOSE OF THIS SUBROUTINE:
    9756              :     //   Gather values during sizing used for surface absorption factors
    9757              : 
    9758              :     // METHODOLOGY EMPLOYED:
    9759              :     //   Save sequence of values for report during sizing.
    9760              : 
    9761              :     // This is by surface, so it works for both space and zone component loads
    9762        83022 :     if (state.dataGlobal->CompLoadReportIsReq && !state.dataGlobal->isPulseZoneSizing) {
    9763         7452 :         int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->TimeStepsInHour + state.dataGlobal->TimeStep;
    9764         7452 :         auto &surfCLDayTS = state.dataOutRptTab->surfCompLoads[state.dataSize->CurOverallSimDay - 1].ts[TimeStepInDay - 1];
    9765        82566 :         for (int jSurf = 1; jSurf <= state.dataSurface->TotSurfaces; ++jSurf) {
    9766        75114 :             auto const &surface = state.dataSurface->Surface(jSurf);
    9767        75114 :             if (!surface.HeatTransSurf || surface.Zone == 0) {
    9768            0 :                 continue; // Skip non-heat transfer surfaces
    9769              :             }
    9770        75114 :             if (surface.Class == DataSurfaces::SurfaceClass::TDD_Dome) {
    9771            0 :                 continue; // Skip tubular daylighting device domes
    9772              :             }
    9773        75114 :             surfCLDayTS.surf[jSurf - 1].ITABSFseq = state.dataHeatBalSurf->SurfAbsThermalInt(jSurf);
    9774        75114 :             surfCLDayTS.surf[jSurf - 1].TMULTseq = state.dataViewFactor->EnclRadInfo(surface.RadEnclIndex).radThermAbsMult;
    9775              :         }
    9776              :     }
    9777        83022 : }
    9778              : 
    9779       623650 : Real64 GetSurfIncidentSolarMultiplier(EnergyPlusData &state, int SurfNum)
    9780              : {
    9781       623650 :     if (!state.dataSurface->Surface(SurfNum).hasIncSolMultiplier) {
    9782       623648 :         return 1.0;
    9783            2 :     } else if (state.dataSurface->SurfIncSolMultiplier(SurfNum).sched != nullptr) {
    9784            0 :         return state.dataSurface->SurfIncSolMultiplier(SurfNum).sched->getCurrentVal() * state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
    9785              :     } else {
    9786            2 :         return state.dataSurface->SurfIncSolMultiplier(SurfNum).Scaler;
    9787              :     }
    9788              : }
    9789              : 
    9790          116 : void InitSurfacePropertyViewFactors(EnergyPlusData &state)
    9791              : {
    9792              : 
    9793              :     // purpose:
    9794              :     //   Initializes sky and ground surfaces view factors of exterior surfaces
    9795              :     //   used by SurfaceProperty:LocalEnvironment
    9796              :     //   view factors are constant hence should be set only once
    9797              : 
    9798          116 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9799          108 :         return;
    9800              :     }
    9801            8 :     if (!state.dataHeatBalSurfMgr->InitSurfaceHeatBalancefirstTime) {
    9802            0 :         return;
    9803              :     }
    9804              : 
    9805           50 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9806           42 :         auto &Surface = state.dataSurface->Surface(SurfNum);
    9807           42 :         if (Surface.SurfHasSurroundingSurfProperty || Surface.IsSurfPropertyGndSurfacesDefined) {
    9808              : 
    9809           18 :             int GndSurfsNum = 0;
    9810           18 :             int SrdSurfsNum = 0;
    9811           18 :             Real64 SrdSurfsViewFactor = 0.0;
    9812           18 :             Real64 SurfsSkyViewFactor = 0.0;
    9813           18 :             Real64 GroundSurfsViewFactor = 0.0;
    9814           18 :             bool IsSkyViewFactorSet = false;
    9815           18 :             bool IsGroundViewFactorSet = false;
    9816           18 :             bool SetGroundViewFactorObject = false;
    9817           18 :             if (Surface.SurfHasSurroundingSurfProperty) {
    9818           18 :                 SrdSurfsNum = Surface.SurfSurroundingSurfacesNum;
    9819           18 :                 auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum);
    9820           18 :                 SurfsSkyViewFactor = SrdSurfsProperty.SkyViewFactor;
    9821           18 :                 IsSkyViewFactorSet = SrdSurfsProperty.IsSkyViewFactorSet;
    9822           18 :                 if (SurfsSkyViewFactor > 0.0) {
    9823           12 :                     SrdSurfsViewFactor += SurfsSkyViewFactor;
    9824              :                 }
    9825           18 :                 if (!Surface.IsSurfPropertyGndSurfacesDefined) {
    9826            8 :                     SrdSurfsViewFactor += SrdSurfsProperty.GroundViewFactor;
    9827            8 :                     IsGroundViewFactorSet = SrdSurfsProperty.IsGroundViewFactorSet;
    9828            8 :                     GroundSurfsViewFactor = SrdSurfsProperty.GroundViewFactor;
    9829              :                 }
    9830           46 :                 for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
    9831           28 :                     SrdSurfsViewFactor += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor;
    9832              :                 }
    9833              :             }
    9834           18 :             if (Surface.IsSurfPropertyGndSurfacesDefined) {
    9835           10 :                 GndSurfsNum = Surface.SurfPropertyGndSurfIndex;
    9836           10 :                 IsGroundViewFactorSet = state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet;
    9837           10 :                 GroundSurfsViewFactor = state.dataSurface->GroundSurfsProperty(GndSurfsNum).SurfsViewFactorSum;
    9838           10 :                 SrdSurfsViewFactor += GroundSurfsViewFactor;
    9839              :             }
    9840              : 
    9841              :             // Check if the sum of all defined view factors > 1.0
    9842           18 :             if (SrdSurfsViewFactor > 1.0) {
    9843            0 :                 ShowSevereError(state, format("Illegal surrounding surfaces view factors for {}.", Surface.Name));
    9844            0 :                 ShowContinueError(state, " The sum of sky, ground, and all surrounding surfaces view factors should be less than or equal to 1.0.");
    9845              :             }
    9846           18 :             if (IsSkyViewFactorSet && IsGroundViewFactorSet) {
    9847              :                 // If both surface sky and ground view factor defined, overwrite with the defined value
    9848            6 :                 Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
    9849            6 :                 Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
    9850           12 :             } else if (IsSkyViewFactorSet && !IsGroundViewFactorSet) {
    9851              :                 // If only sky view factor defined, ground view factor = 1 - all other defined view factors.
    9852            6 :                 Surface.ViewFactorSkyIR = SurfsSkyViewFactor;
    9853            6 :                 Surface.ViewFactorGroundIR = 1 - SrdSurfsViewFactor;
    9854            6 :                 if (GndSurfsNum > 0) {
    9855            2 :                     SetGroundViewFactorObject = true;
    9856            2 :                     state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
    9857              :                 } else {
    9858            4 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
    9859              :                 }
    9860            6 :             } else if (!IsSkyViewFactorSet && IsGroundViewFactorSet) {
    9861              :                 // If only ground view factor defined, sky view factor = 1 - all other defined view factors.
    9862            2 :                 Surface.ViewFactorGroundIR = GroundSurfsViewFactor;
    9863            2 :                 Surface.ViewFactorSkyIR = 1 - SrdSurfsViewFactor;
    9864            2 :                 if (SrdSurfsNum > 0) {
    9865            2 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
    9866            2 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
    9867              :                 }
    9868              :             } else {
    9869              :                 // If neither ground nor sky view factor specified, continue to use the original proportion.
    9870            4 :                 Surface.ViewFactorSkyIR *= 1 - SrdSurfsViewFactor;
    9871            4 :                 Surface.ViewFactorGroundIR *= 1 - SrdSurfsViewFactor;
    9872            4 :                 if (SrdSurfsNum > 0) {
    9873            4 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsSkyViewFactorSet = true;
    9874            4 :                     state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SkyViewFactor = Surface.ViewFactorSkyIR;
    9875            4 :                     if (GndSurfsNum == 0) {
    9876            0 :                         state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).GroundViewFactor = Surface.ViewFactorGroundIR;
    9877            0 :                         state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).IsGroundViewFactorSet = true;
    9878              :                     }
    9879              :                 }
    9880            4 :                 if (GndSurfsNum > 0) {
    9881            4 :                     SetGroundViewFactorObject = true;
    9882            4 :                     state.dataSurface->GroundSurfsProperty(GndSurfsNum).IsGroundViewFactorSet = true;
    9883              :                 }
    9884              :             }
    9885           18 :             if (SetGroundViewFactorObject) {
    9886            6 :                 ReSetGroundSurfacesViewFactor(state, SurfNum);
    9887              :             }
    9888              :         }
    9889              :     }
    9890              : }
    9891              : 
    9892       249966 : void GetGroundSurfacesTemperatureAverage(EnergyPlusData &state)
    9893              : {
    9894              :     //  returns ground surfaces average temperature (deg C)
    9895              :     //  ground surfaces viewed by a building exterior surface
    9896              :     //  ground surfaces temperature weighed using view factors
    9897              : 
    9898       249966 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9899       249959 :         return;
    9900              :     }
    9901              : 
    9902           37 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9903           30 :         if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
    9904           23 :             continue;
    9905              :         }
    9906            7 :         auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9907            7 :         if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9908            0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9909            0 :             continue;
    9910              :         }
    9911            7 :         Real64 GndSurfaceTemp = 0.0;
    9912            7 :         Real64 GndSurfViewFactor = 0.0;
    9913            7 :         Real64 GndSurfaceTempSum = 0.0;
    9914           24 :         for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
    9915           17 :             GndSurfViewFactor = GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor;
    9916           17 :             if (GndSurfViewFactor == 0.0) {
    9917            6 :                 continue;
    9918              :             }
    9919           11 :             if (GndSurfsProperty.GndSurfs(gSurfNum).tempSched == nullptr) {
    9920            0 :                 continue;
    9921              :             }
    9922           11 :             GndSurfaceTemp = GndSurfsProperty.GndSurfs(gSurfNum).tempSched->getCurrentVal();
    9923           11 :             GndSurfaceTempSum += GndSurfViewFactor * pow_4(GndSurfaceTemp + Constant::Kelvin);
    9924              :         }
    9925            7 :         if (GndSurfaceTempSum == 0.0) {
    9926            0 :             GndSurfsProperty.SurfsTempAvg = 0.0;
    9927            0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9928            0 :             continue;
    9929              :         }
    9930            7 :         GndSurfsProperty.SurfsTempAvg = root_4(GndSurfaceTempSum / GndSurfsProperty.SurfsViewFactorSum) - Constant::Kelvin;
    9931              :     }
    9932              : }
    9933              : 
    9934       249960 : void GetGroundSurfacesReflectanceAverage(EnergyPlusData &state)
    9935              : {
    9936              :     //  returns ground surfaces average reflectance (dimensionless)
    9937              :     //  ground reflectance viewed by a building exterior surface
    9938              :     //  ground surfaces reflectance weighed using view factors
    9939              : 
    9940       249960 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9941       249953 :         return;
    9942              :     }
    9943           37 :     for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) {
    9944              : 
    9945           30 :         if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
    9946           23 :             continue;
    9947              :         }
    9948            7 :         auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9949            7 :         if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9950            0 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9951            0 :             continue;
    9952              :         }
    9953            7 :         Real64 GndSurfRefl = 0.0;
    9954            7 :         Real64 GndSurfsReflSum = 0.0;
    9955           24 :         for (int gSurfNum = 1; gSurfNum <= GndSurfsProperty.NumGndSurfs; gSurfNum++) {
    9956           17 :             if (GndSurfsProperty.GndSurfs(gSurfNum).reflSched == nullptr) {
    9957            5 :                 continue;
    9958              :             }
    9959           12 :             GndSurfRefl = GndSurfsProperty.GndSurfs(gSurfNum).reflSched->getCurrentVal();
    9960           12 :             GndSurfsReflSum += GndSurfsProperty.GndSurfs(gSurfNum).ViewFactor * GndSurfRefl;
    9961              :         }
    9962            7 :         if (GndSurfsReflSum == 0.0) {
    9963            3 :             GndSurfsProperty.SurfsReflAvg = 0.0;
    9964            3 :             state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9965            3 :             continue;
    9966              :         }
    9967            4 :         GndSurfsProperty.SurfsReflAvg = GndSurfsReflSum / GndSurfsProperty.SurfsViewFactorSum;
    9968              :     }
    9969              : }
    9970              : 
    9971            6 : void ReSetGroundSurfacesViewFactor(EnergyPlusData &state, int const SurfNum)
    9972              : {
    9973              :     //  resets ground view factors based on view factors identity
    9974              :     //  the ground view factor value is set to the first element
    9975              :     //  when the ground view factor input field is blank
    9976              : 
    9977            6 :     if (!state.dataSurface->Surface(SurfNum).IsSurfPropertyGndSurfacesDefined) {
    9978            0 :         return;
    9979              :     }
    9980            6 :     auto &GndSurfsProperty = state.dataSurface->GroundSurfsProperty(state.dataSurface->Surface(SurfNum).SurfPropertyGndSurfIndex);
    9981            6 :     GndSurfsProperty.SurfsViewFactorSum = state.dataSurface->Surface(SurfNum).ViewFactorGroundIR;
    9982              : 
    9983            6 :     if (GndSurfsProperty.SurfsViewFactorSum == 0.0) {
    9984            0 :         state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfRefl = false;
    9985            0 :         state.dataSurface->Surface(SurfNum).UseSurfPropertyGndSurfTemp = false;
    9986            0 :         return;
    9987              :     }
    9988            6 :     GndSurfsProperty.GndSurfs(1).ViewFactor = GndSurfsProperty.SurfsViewFactorSum;
    9989              : }
    9990              : 
    9991       249965 : void GetSurroundingSurfacesTemperatureAverage(EnergyPlusData &state)
    9992              : {
    9993              :     //  returns surrounding surfaces average temperature (deg C)
    9994              :     //  surrounding surfaces viewed by an exterior surface
    9995              :     //  surrounding surfaces temperature weighed using view factors
    9996              : 
    9997       249965 :     if (!state.dataGlobal->AnyLocalEnvironmentsInModel) {
    9998       249959 :         return;
    9999              :     }
   10000              : 
   10001           33 :     for (auto &surface : state.dataSurface->Surface) {
   10002           27 :         if (!surface.SurfHasSurroundingSurfProperty) {
   10003           17 :             continue;
   10004              :         }
   10005              :         // local vars
   10006           10 :         Real64 SrdSurfaceTemp = 0.0;
   10007           10 :         Real64 SrdSurfaceTempSum = 0.0;
   10008           10 :         auto &SrdSurfsProperty = state.dataSurface->SurroundingSurfsProperty(surface.SurfSurroundingSurfacesNum);
   10009           26 :         for (int SrdSurfNum = 1; SrdSurfNum <= SrdSurfsProperty.TotSurroundingSurface; SrdSurfNum++) {
   10010           16 :             SrdSurfaceTemp = SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).tempSched->getCurrentVal() + Constant::Kelvin;
   10011           16 :             SrdSurfaceTempSum += SrdSurfsProperty.SurroundingSurfs(SrdSurfNum).ViewFactor * pow_4(SrdSurfaceTemp);
   10012              :         }
   10013           10 :         surface.SrdSurfTemp = root_4(SrdSurfaceTempSum / surface.ViewFactorSrdSurfs) - Constant::Kelvin;
   10014            6 :     }
   10015              : }
   10016              : } // namespace EnergyPlus::HeatBalanceSurfaceManager
        

Generated by: LCOV version 2.0-1